From noreply at buildbot.pypy.org Mon Oct 1 01:10:06 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 01:10:06 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Let handle_bytecode() handle a single bytecode Message-ID: <20120930231006.993571C0012@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57688:99d67454ef52 Date: 2012-09-30 03:08 +0100 http://bitbucket.org/pypy/pypy/changeset/99d67454ef52/ Log: Let handle_bytecode() handle a single bytecode diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -366,9 +366,8 @@ try: self.recorder = self.recording(block) self.frame_finished_execution = False - next_instr = self.last_instr while True: - next_instr = self.handle_bytecode(next_instr) + self.last_instr = self.handle_bytecode(self.last_instr) except ImplicitOperationError, e: if isinstance(e.w_type, Constant): @@ -452,17 +451,13 @@ break def handle_bytecode(self, next_instr): + self.recorder.bytecode_trace(self) + next_instr, methodname, oparg = self.pycode.read(next_instr) try: - while True: - self.last_instr = next_instr - self.recorder.bytecode_trace(self) - next_instr, methodname, oparg = self.pycode.read(next_instr) - res = getattr(self, methodname)(oparg, next_instr) - if res is not None: - next_instr = res + res = getattr(self, methodname)(oparg, next_instr) + return res if res is not None else next_instr except FSException, operr: - next_instr = self.handle_operation_error(operr) - return next_instr + return self.handle_operation_error(operr) def handle_operation_error(self, operr): block = self.unrollstack(SApplicationException.kind) From noreply at buildbot.pypy.org Mon Oct 1 01:10:08 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 01:10:08 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Simplify control flow in FSFrame.mergeblock() Message-ID: <20120930231008.0E33C1C01C4@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57689:a0a0616f6ccb Date: 2012-09-30 18:36 +0100 http://bitbucket.org/pypy/pypy/changeset/a0a0616f6ccb/ Log: Simplify control flow in FSFrame.mergeblock() diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -405,37 +405,35 @@ candidates = self.joinpoints.setdefault(next_instr, []) for block in candidates: newstate = block.framestate.union(currentstate) - if newstate is not None: - # yes - finished = newstate == block.framestate + if newstate is None: + continue + elif newstate == block.framestate: + outputargs = currentstate.getoutputargs(newstate) + currentblock.closeblock(Link(outputargs, block)) + return + else: break else: - # no newstate = currentstate.copy() - finished = False block = None - if finished: - newblock = block - else: - newblock = SpamBlock(newstate) + newblock = SpamBlock(newstate) # unconditionally link the current block to the newblock outputargs = currentstate.getoutputargs(newstate) link = Link(outputargs, newblock) currentblock.closeblock(link) - # phew - if not finished: - if block is not None: - # to simplify the graph, we patch the old block to point - # directly at the new block which is its generalization - block.dead = True - block.operations = () - block.exitswitch = None - outputargs = block.framestate.getoutputargs(newstate) - block.recloseblock(Link(outputargs, newblock)) - candidates.remove(block) - candidates.insert(0, newblock) - self.pendingblocks.append(newblock) + + if block is not None: + # to simplify the graph, we patch the old block to point + # directly at the new block which is its generalization + block.dead = True + block.operations = () + block.exitswitch = None + outputargs = block.framestate.getoutputargs(newstate) + block.recloseblock(Link(outputargs, newblock)) + candidates.remove(block) + candidates.insert(0, newblock) + self.pendingblocks.append(newblock) # hack for unrolling iterables, don't use this def replace_in_stack(self, oldvalue, newvalue): From noreply at buildbot.pypy.org Mon Oct 1 01:10:09 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 01:10:09 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Give names to variables after build_flow(), not within it Message-ID: <20120930231009.4CAC61C05E4@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57690:db8b5b48b23d Date: 2012-10-01 00:09 +0100 http://bitbucket.org/pypy/pypy/changeset/db8b5b48b23d/ Log: Give names to variables after build_flow(), not within it diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -66,6 +66,14 @@ self.last_exception = last_exception def fixeggblocks(graph): + varnames = graph.func.func_code.co_varnames + for block in graph.iterblocks(): + if isinstance(block, SpamBlock): + for name, w_value in zip(varnames, block.framestate.mergeable): + if isinstance(w_value, Variable): + w_value.rename(name) + del block.framestate # memory saver + # EggBlocks reuse the variables of their previous block, # which is deemed not acceptable for simplicity of the operations # that will be performed later on the flow graph. @@ -86,9 +94,6 @@ for a in block.inputargs: mapping[a] = Variable(a) block.renamevariables(mapping) - for block in graph.iterblocks(): - if isinstance(link, SpamBlock): - del link.framestate # memory saver # ____________________________________________________________ @@ -118,13 +123,6 @@ def bytecode_trace(self, frame): if self.enterspamblock: - # If we have a SpamBlock, the first call to bytecode_trace() - # occurs as soon as frame.resume() starts, before interpretation - # really begins. - varnames = frame.pycode.getvarnames() - for name, w_value in zip(varnames, frame.getfastscope()): - if isinstance(w_value, Variable): - w_value.rename(name) self.enterspamblock = False else: # At this point, we progress to the next bytecode. When this From noreply at buildbot.pypy.org Mon Oct 1 02:02:24 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 02:02:24 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Record join points at the end of the bytecode, instead of the beginning of Message-ID: <20121001000224.19E681C05E4@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57691:18f7d2ceda38 Date: 2012-10-01 00:59 +0100 http://bitbucket.org/pypy/pypy/changeset/18f7d2ceda38/ Log: Record join points at the end of the bytecode, instead of the beginning of the next one. * Kill BlockRecorder.enterspamblock and .bytecode_trace() * Rename BlockRecorder.last_join_points to .final_state diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -102,9 +102,6 @@ def append(self, operation): raise NotImplementedError - def bytecode_trace(self, frame): - pass - def guessbool(self, frame, w_condition, **kwds): raise AssertionError, "cannot guessbool(%s)" % (w_condition,) @@ -114,24 +111,13 @@ def __init__(self, block): self.crnt_block = block - # saved state at the join point most recently seen - self.last_join_point = None - self.enterspamblock = isinstance(block, SpamBlock) + # Final frame state after the operations in the block + # If this is set, no new space op may be recorded. + self.final_state = None def append(self, operation): self.crnt_block.operations.append(operation) - def bytecode_trace(self, frame): - if self.enterspamblock: - self.enterspamblock = False - else: - # At this point, we progress to the next bytecode. When this - # occurs, we no longer allow any more operations to be recorded in - # the same block. We will continue, to figure out where the next - # such operation *would* appear, and we make a join point just - # before. - self.last_join_point = frame.getstate() - def guessbool(self, frame, w_condition): block = self.crnt_block vars = block.getvariables() @@ -337,8 +323,8 @@ def record(self, spaceop): """Record an operation into the active block""" recorder = self.recorder - if getattr(recorder, 'last_join_point', None) is not None: - self.mergeblock(recorder.crnt_block, recorder.last_join_point) + if getattr(recorder, 'final_state', None) is not None: + self.mergeblock(recorder.crnt_block, recorder.final_state) raise StopFlowing recorder.append(spaceop) @@ -366,6 +352,7 @@ self.frame_finished_execution = False while True: self.last_instr = self.handle_bytecode(self.last_instr) + self.recorder.final_state = self.getstate() except ImplicitOperationError, e: if isinstance(e.w_type, Constant): @@ -447,7 +434,6 @@ break def handle_bytecode(self, next_instr): - self.recorder.bytecode_trace(self) next_instr, methodname, oparg = self.pycode.read(next_instr) try: res = getattr(self, methodname)(oparg, next_instr) From noreply at buildbot.pypy.org Mon Oct 1 09:17:24 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 1 Oct 2012 09:17:24 +0200 (CEST) Subject: [pypy-commit] pypy default: typoish simplification Message-ID: <20121001071724.41AE21C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57692:b4a68799fb1c Date: 2012-10-01 09:17 +0200 http://bitbucket.org/pypy/pypy/changeset/b4a68799fb1c/ Log: typoish simplification 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 @@ -474,7 +474,7 @@ if f_type == F_BLOCK_LOOP: self.emit_jump(ops.CONTINUE_LOOP, block, True) break - if self.frame_blocks[i][0] == F_BLOCK_FINALLY_END: + if f_type == F_BLOCK_FINALLY_END: self.error("'continue' not supported inside 'finally' " \ "clause", cont) From noreply at buildbot.pypy.org Mon Oct 1 10:24:05 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 1 Oct 2012 10:24:05 +0200 (CEST) Subject: [pypy-commit] pypy default: issue1274 testing Message-ID: <20121001082405.64CA51C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57693:166c5a450114 Date: 2012-10-01 09:31 +0200 http://bitbucket.org/pypy/pypy/changeset/166c5a450114/ Log: issue1274 testing diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -223,7 +223,7 @@ return next_instr if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: - return self.jump_absolute(oparg, next_instr, ec) + return self.jump_absolute(oparg, ec) if we_are_translated(): for opdesc in unrolling_all_opcode_descs: @@ -858,7 +858,8 @@ def YIELD_VALUE(self, oparg, next_instr): raise Yield - def jump_absolute(self, jumpto, next_instr, ec): + def jump_absolute(self, jumpto, ec): + # this function is overridden by pypy.module.pypyjit.interp_jit check_nonneg(jumpto) return jumpto @@ -1268,7 +1269,9 @@ # and jump to the beginning of the loop, stored in the # exception's argument frame.append_block(self) - return r_uint(unroller.jump_to) + jumpto = unroller.jump_to + ec = frame.space.getexecutioncontext() + return r_uint(frame.jump_absolute(jumpto, ec)) else: # jump to the end of the loop self.cleanupstack(frame) 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 @@ -79,7 +79,7 @@ except ExitFrame: return self.popvalue() - def jump_absolute(self, jumpto, _, ec=None): + def jump_absolute(self, jumpto, ec): if we_are_jitted(): # # assume that only threads are using the bytecode counter From noreply at buildbot.pypy.org Mon Oct 1 10:24:06 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 1 Oct 2012 10:24:06 +0200 (CEST) Subject: [pypy-commit] pypy default: Unskip and fix test_continue_in_finally. Message-ID: <20121001082406.B6A391C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57694:da03bb5bb6fc Date: 2012-10-01 08:25 +0000 http://bitbucket.org/pypy/pypy/changeset/da03bb5bb6fc/ Log: Unskip and fix test_continue_in_finally. diff --git a/pypy/module/pypyjit/test_pypy_c/test_exception.py b/pypy/module/pypyjit/test_pypy_c/test_exception.py --- a/pypy/module/pypyjit/test_pypy_c/test_exception.py +++ b/pypy/module/pypyjit/test_pypy_c/test_exception.py @@ -95,7 +95,6 @@ def test_continue_in_finally(self): # check that 'continue' inside a try:finally: block is correctly # detected as closing a loop - py.test.skip("is this case important?") def f(n): i = 0 while 1: @@ -110,10 +109,9 @@ assert log.result == 2001 loop, = log.loops_by_filename(self.filepath) assert loop.match(""" - i40 = int_add_ovf(i31, 1) - guard_no_overflow(descr=...) - i41 = int_lt(i40, i33) - guard_true(i41, descr=...) + i3 = int_lt(i1, i2) + guard_true(i3, descr=...) + i4 = int_add(i1, 1) --TICK-- jump(..., descr=...) """) From noreply at buildbot.pypy.org Mon Oct 1 13:58:54 2012 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Mon, 1 Oct 2012 13:58:54 +0200 (CEST) Subject: [pypy-commit] pypy pytest: add missing __init__.py files for tests Message-ID: <20121001115854.A6BC31C0E70@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r57695:b7d1e8a097f5 Date: 2012-09-29 19:01 +0200 http://bitbucket.org/pypy/pypy/changeset/b7d1e8a097f5/ Log: add missing __init__.py files for tests diff --git a/pypy/doc/test/__init__.py b/pypy/doc/test/__init__.py new file mode 100644 diff --git a/pypy/jit/backend/x86/tool/test/__init__.py b/pypy/jit/backend/x86/tool/test/__init__.py new file mode 100644 diff --git a/pypy/jit/tl/tinyframe/test/__init__.py b/pypy/jit/tl/tinyframe/test/__init__.py new file mode 100644 diff --git a/pypy/module/_csv/test/__init__.py b/pypy/module/_csv/test/__init__.py new file mode 100644 diff --git a/pypy/module/_hashlib/test/__init__.py b/pypy/module/_hashlib/test/__init__.py new file mode 100644 diff --git a/pypy/module/_io/test/__init__.py b/pypy/module/_io/test/__init__.py new file mode 100644 diff --git a/pypy/module/_locale/test/__init__.py b/pypy/module/_locale/test/__init__.py new file mode 100644 diff --git a/pypy/module/_md5/test/__init__.py b/pypy/module/_md5/test/__init__.py new file mode 100644 diff --git a/pypy/module/_multiprocessing/test/__init__.py b/pypy/module/_multiprocessing/test/__init__.py new file mode 100644 diff --git a/pypy/module/_sha/test/__init__.py b/pypy/module/_sha/test/__init__.py new file mode 100644 diff --git a/pypy/module/_sre/test/__init__.py b/pypy/module/_sre/test/__init__.py new file mode 100644 diff --git a/pypy/module/_ssl/test/__init__.py b/pypy/module/_ssl/test/__init__.py new file mode 100644 diff --git a/pypy/module/_warnings/test/__init__.py b/pypy/module/_warnings/test/__init__.py new file mode 100644 diff --git a/pypy/module/_weakref/test/__init__.py b/pypy/module/_weakref/test/__init__.py new file mode 100644 diff --git a/pypy/module/_winreg/test/__init__.py b/pypy/module/_winreg/test/__init__.py new file mode 100644 diff --git a/pypy/module/binascii/test/__init__.py b/pypy/module/binascii/test/__init__.py new file mode 100644 diff --git a/pypy/module/cmath/test/__init__.py b/pypy/module/cmath/test/__init__.py new file mode 100644 diff --git a/pypy/module/errno/test/__init__.py b/pypy/module/errno/test/__init__.py new file mode 100644 diff --git a/pypy/module/fcntl/test/__init__.py b/pypy/module/fcntl/test/__init__.py new file mode 100644 diff --git a/pypy/module/imp/test/__init__.py b/pypy/module/imp/test/__init__.py new file mode 100644 diff --git a/pypy/module/itertools/test/__init__.py b/pypy/module/itertools/test/__init__.py new file mode 100644 diff --git a/pypy/module/marshal/test/__init__.py b/pypy/module/marshal/test/__init__.py new file mode 100644 diff --git a/pypy/module/mmap/test/__init__.py b/pypy/module/mmap/test/__init__.py new file mode 100644 diff --git a/pypy/module/operator/test/__init__.py b/pypy/module/operator/test/__init__.py new file mode 100644 diff --git a/pypy/module/pwd/test/__init__.py b/pypy/module/pwd/test/__init__.py new file mode 100644 diff --git a/pypy/module/rctime/test/__init__.py b/pypy/module/rctime/test/__init__.py new file mode 100644 diff --git a/pypy/module/select/test/__init__.py b/pypy/module/select/test/__init__.py new file mode 100644 diff --git a/pypy/module/struct/test/__init__.py b/pypy/module/struct/test/__init__.py new file mode 100644 diff --git a/pypy/module/termios/test/__init__.py b/pypy/module/termios/test/__init__.py new file mode 100644 diff --git a/pypy/module/time/test/__init__.py b/pypy/module/time/test/__init__.py new file mode 100644 diff --git a/pypy/module/token/test/__init__.py b/pypy/module/token/test/__init__.py new file mode 100644 diff --git a/pypy/module/unicodedata/test/__init__.py b/pypy/module/unicodedata/test/__init__.py new file mode 100644 diff --git a/pypy/module/zlib/test/__init__.py b/pypy/module/zlib/test/__init__.py new file mode 100644 diff --git a/pypy/objspace/fake/test/__init__.py b/pypy/objspace/fake/test/__init__.py new file mode 100644 diff --git a/pypy/rlib/rstruct/test/__init__.py b/pypy/rlib/rstruct/test/__init__.py new file mode 100644 diff --git a/pypy/rpython/ootypesystem/test/__init__.py b/pypy/rpython/ootypesystem/test/__init__.py new file mode 100644 diff --git a/pypy/tool/memusage/test/__init__.py b/pypy/tool/memusage/test/__init__.py new file mode 100644 From noreply at buildbot.pypy.org Mon Oct 1 13:58:56 2012 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Mon, 1 Oct 2012 13:58:56 +0200 (CEST) Subject: [pypy-commit] pypy pytest: move pytest.ini to the toplevel to ensure we always use the addopts Message-ID: <20121001115856.3BF981C0E70@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r57696:ffce716bd352 Date: 2012-09-30 18:32 +0200 http://bitbucket.org/pypy/pypy/changeset/ffce716bd352/ Log: move pytest.ini to the toplevel to ensure we always use the addopts diff --git a/pypy/pytest.ini b/pytest.ini rename from pypy/pytest.ini rename to pytest.ini From noreply at buildbot.pypy.org Mon Oct 1 13:58:57 2012 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Mon, 1 Oct 2012 13:58:57 +0200 (CEST) Subject: [pypy-commit] pypy pytest: kill unused collector _keywords/_haskeywords Message-ID: <20121001115857.8DEDE1C0E70@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r57697:636f8586e53a Date: 2012-10-01 12:30 +0200 http://bitbucket.org/pypy/pypy/changeset/636f8586e53a/ Log: kill unused collector _keywords/_haskeywords diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -477,13 +477,6 @@ class IntClassCollector(PyPyClassCollector): Instance = IntInstanceCollector - def _haskeyword(self, keyword): - return keyword == 'interplevel' or \ - super(IntClassCollector, self)._haskeyword(keyword) - - def _keywords(self): - return super(IntClassCollector, self)._keywords() + ['interplevel'] - class AppClassInstance(py.test.collect.Instance): Function = AppTestMethod @@ -500,13 +493,6 @@ class AppClassCollector(PyPyClassCollector): Instance = AppClassInstance - def _haskeyword(self, keyword): - return keyword == 'applevel' or \ - super(AppClassCollector, self)._haskeyword(keyword) - - def _keywords(self): - return super(AppClassCollector, self)._keywords() + ['applevel'] - def setup(self): super(AppClassCollector, self).setup() cls = self.obj From noreply at buildbot.pypy.org Mon Oct 1 16:26:03 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 1 Oct 2012 16:26:03 +0200 (CEST) Subject: [pypy-commit] pypy default: a test and a fix Message-ID: <20121001142603.47B801C00EE@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r57698:bb0006ff2df4 Date: 2012-10-01 16:25 +0200 http://bitbucket.org/pypy/pypy/changeset/bb0006ff2df4/ Log: a test and a fix 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 @@ -129,6 +129,8 @@ self._prepare_array_index(space, w_index) shape = res_shape + self.get_shape()[len(indexes):] res = W_NDimArray.from_shape(shape, self.get_dtype(), self.get_order()) + if not self.get_size() and not res.get_size(): + return res return loop.getitem_array_int(space, self, res, iter_shape, indexes, prefix) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1999,6 +1999,7 @@ def test_int_array_index(self): from _numpypy import array + assert (array([])[[]] == []).all() a = array([[1, 2], [3, 4], [5, 6]]) assert (a[slice(0, 3), [0, 0]] == [[1, 1], [3, 3], [5, 5]]).all() assert (a[array([0, 2]), slice(0, 2)] == [[1, 2], [5, 6]]).all() From noreply at buildbot.pypy.org Mon Oct 1 16:50:20 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 16:50:20 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Split FrameState.nonmergeable into blocklist and next_instr Message-ID: <20121001145020.0BA2E1C037C@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57699:50cade423a45 Date: 2012-10-01 05:56 +0100 http://bitbucket.org/pypy/pypy/changeset/50cade423a45/ Log: Split FrameState.nonmergeable into blocklist and next_instr diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -285,9 +285,7 @@ data.append(self.last_exception.w_type) data.append(self.last_exception.w_value) recursively_flatten(self.space, data) - nonmergeable = (self.get_blocklist(), - self.last_instr) # == next_instr when between bytecodes - return FrameState(data, nonmergeable) + return FrameState(data, self.get_blocklist(), self.last_instr) def setstate(self, state): """ Reset the frame to the given state. """ @@ -299,8 +297,8 @@ self.last_exception = None else: self.last_exception = FSException(data[-2], data[-1]) - blocklist, self.last_instr = state.nonmergeable - self.set_blocklist(blocklist) + self.last_instr = state.next_instr + self.set_blocklist(state.blocklist) def recording(self, block): """ Setup recording of the block and return the recorder. """ diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -2,10 +2,10 @@ from pypy.objspace.flow.model import * class FrameState: - def __init__(self, mergeable, nonmergeable): + def __init__(self, mergeable, blocklist, next_instr): self.mergeable = mergeable - self.nonmergeable = nonmergeable - self.next_instr = self.nonmergeable[1] + self.blocklist = blocklist + self.next_instr = next_instr for w1 in self.mergeable: assert isinstance(w1, (Variable, Constant)) or w1 is None, ( '%r found in frame state' % w1) @@ -17,7 +17,7 @@ if isinstance(w, Variable): w = Variable() newstate.append(w) - return FrameState(newstate, self.nonmergeable) + return FrameState(newstate, self.blocklist, self.next_instr) def getvariables(self): return [w for w in self.mergeable if isinstance(w, Variable)] @@ -29,7 +29,8 @@ # nonmergeable states assert isinstance(other, FrameState) assert len(self.mergeable) == len(other.mergeable) - assert self.nonmergeable == other.nonmergeable + assert self.blocklist == other.blocklist + assert self.next_instr == other.next_instr for w1, w2 in zip(self.mergeable, other.mergeable): if not (w1 == w2 or (isinstance(w1, Variable) and isinstance(w2, Variable))): @@ -50,7 +51,7 @@ newstate.append(union(w1, w2)) except UnionError: return None - return FrameState(newstate, self.nonmergeable) + return FrameState(newstate, self.blocklist, self.next_instr) def getoutputargs(self, targetstate): "Return the output arguments needed to link self to targetstate." From noreply at buildbot.pypy.org Mon Oct 1 16:50:21 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 16:50:21 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Test cellvar handling Message-ID: <20121001145021.61B9E1C037C@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57700:bac9f9052480 Date: 2012-10-01 11:59 +0100 http://bitbucket.org/pypy/pypy/changeset/bac9f9052480/ Log: Test cellvar handling diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -5,7 +5,8 @@ cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) -from pypy.interpreter.astcompiler.consts import CO_GENERATOR, CO_NEWLOCALS +from pypy.interpreter.astcompiler.consts import (CO_GENERATOR, CO_NEWLOCALS, + CO_VARARGS, CO_VARKEYWORDS) from pypy.interpreter.nestedscope import Cell from pypy.objspace.flow.model import Constant diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1054,6 +1054,15 @@ with py.test.raises(FlowingError): self.codetest(f) + def test_cellvar(self): + def f(): + x = 5 + return x + lambda: x # turn x into a cell variable + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + DATA = {'x': 5, 'y': 6} From noreply at buildbot.pypy.org Mon Oct 1 16:50:22 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 16:50:22 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Move frame state initialisation to _init_graph() Message-ID: <20121001145022.96FED1C037C@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57701:50f876cad94b Date: 2012-10-01 14:26 +0100 http://bitbucket.org/pypy/pypy/changeset/50f876cad94b/ Log: Move frame state initialisation to _init_graph() This will allow the graph to be created before the frame diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -235,6 +235,7 @@ self.joinpoints = {} self._init_graph(func) self.pendingblocks = collections.deque([self.graph.startblock]) + self.setstate(self.graph.startblock.framestate) # for testing def init_locals_stack(self, code): """ @@ -243,14 +244,7 @@ The locals are ordered according to self.pycode.signature(). """ self.valuestackdepth = code.co_nlocals - formalargcount = code.getformalargcount() - n_uninitialised_locals = code.co_nlocals - formalargcount - if n_uninitialised_locals < 0: - raise ValueError, "new fastscope is longer than the allocated area" - arg_list = [Variable() for i in range(formalargcount)] - self.locals_stack_w = (arg_list + - [None] * (code.co_stacksize + n_uninitialised_locals)) - self.init_cells() + self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals) def _init_graph(self, func): # CallableFactory.pycall may add class_ to functions that are methods @@ -261,7 +255,12 @@ for c in "<>&!": name = name.replace(c, '_') - initialblock = SpamBlock(self.getstate()) + code = self.pycode + data = [None] * code.co_nlocals + for i in range(code.getformalargcount()): + data[i] = Variable() + state = FrameState(data + [Constant(None), Constant(None)], [], 0) + initialblock = SpamBlock(state) if self.pycode.is_generator: initialblock.operations.append( SpaceOperation('generator_mark', [], Variable())) From noreply at buildbot.pypy.org Mon Oct 1 16:50:23 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 16:50:23 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Extract graph init into a new class PyGraph Message-ID: <20121001145023.CEDA71C037C@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57702:46d30e3df0cb Date: 2012-10-01 15:49 +0100 http://bitbucket.org/pypy/pypy/changeset/46d30e3df0cb/ Log: Extract graph init into a new class PyGraph diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -9,6 +9,7 @@ from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, recursively_flatten) from pypy.objspace.flow.bytecode import HostCode +from pypy.objspace.flow.pygraph import PyGraph from pypy.objspace.flow.specialcase import (rpython_print_item, rpython_print_newline) @@ -233,7 +234,7 @@ self.w_locals = None # XXX: only for compatibility with PyFrame self.joinpoints = {} - self._init_graph(func) + self.graph = PyGraph(func, code) self.pendingblocks = collections.deque([self.graph.startblock]) self.setstate(self.graph.startblock.framestate) # for testing @@ -246,34 +247,6 @@ self.valuestackdepth = code.co_nlocals self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals) - def _init_graph(self, func): - # CallableFactory.pycall may add class_ to functions that are methods - name = func.func_name - class_ = getattr(func, 'class_', None) - if class_ is not None: - name = '%s.%s' % (class_.__name__, name) - for c in "<>&!": - name = name.replace(c, '_') - - code = self.pycode - data = [None] * code.co_nlocals - for i in range(code.getformalargcount()): - data[i] = Variable() - state = FrameState(data + [Constant(None), Constant(None)], [], 0) - initialblock = SpamBlock(state) - if self.pycode.is_generator: - initialblock.operations.append( - SpaceOperation('generator_mark', [], Variable())) - graph = FunctionGraph(name, initialblock) - graph.func = func - # attach a signature and defaults to the graph - # so that it becomes even more interchangeable with the function - # itself - graph.signature = self.pycode.signature() - graph.defaults = func.func_defaults or () - graph.is_generator = self.pycode.is_generator - self.graph = graph - def getstate(self): # getfastscope() can return real None, for undefined locals data = self.save_locals_stack() diff --git a/pypy/objspace/flow/pygraph.py b/pypy/objspace/flow/pygraph.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/flow/pygraph.py @@ -0,0 +1,39 @@ +""" +Implements flow graphs for Python callables +""" +from pypy.objspace.flow.model import (FunctionGraph, Constant, Variable, + SpaceOperation) +from pypy.objspace.flow.framestate import FrameState + +class PyGraph(FunctionGraph): + """ + Flow graph for a Python function + """ + + def __init__(self, func, code): + from pypy.objspace.flow.flowcontext import SpamBlock + data = [None] * code.co_nlocals + for i in range(code.getformalargcount()): + data[i] = Variable() + state = FrameState(data + [Constant(None), Constant(None)], [], 0) + initialblock = SpamBlock(state) + if code.is_generator: + initialblock.operations.append( + SpaceOperation('generator_mark', [], Variable())) + + super(PyGraph, self).__init__(self._sanitize_funcname(func), initialblock) + self.func = func + self.signature = code.signature() + self.defaults = func.func_defaults or () + self.is_generator = code.is_generator + + @staticmethod + def _sanitize_funcname(func): + # CallableFactory.pycall may add class_ to functions that are methods + name = func.func_name + class_ = getattr(func, 'class_', None) + if class_ is not None: + name = '%s.%s' % (class_.__name__, name) + for c in "<>&!": + name = name.replace(c, '_') + From noreply at buildbot.pypy.org Mon Oct 1 16:56:24 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 1 Oct 2012 16:56:24 +0200 (CEST) Subject: [pypy-commit] pypy default: fix the whatsnew Message-ID: <20121001145624.4FE741C037C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r57703:3a44a4de7397 Date: 2012-10-01 16:56 +0200 http://bitbucket.org/pypy/pypy/changeset/3a44a4de7397/ Log: fix the 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 @@ -18,6 +18,7 @@ .. branch: numpypy_count_nonzero .. branch: numpy-refactor Remove numpy lazy evaluation and simplify everything +.. branch: numpy-reintroduce-jit-drivers .. branch: numpy-fancy-indexing Support for array[array-of-ints] in numpy .. branch: even-more-jit-hooks From noreply at buildbot.pypy.org Mon Oct 1 17:28:13 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 17:28:13 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Instantiate HostCode and PyGraph outside FSFrame Message-ID: <20121001152813.27D2B1C0E70@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57704:7b4ca127653c Date: 2012-10-01 16:20 +0100 http://bitbucket.org/pypy/pypy/changeset/7b4ca127653c/ Log: Instantiate HostCode and PyGraph outside FSFrame diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -219,8 +219,9 @@ class FlowSpaceFrame(pyframe.CPythonFrame): - def __init__(self, space, func): - code = HostCode._from_code(space, func.func_code) + def __init__(self, space, graph, code): + self.graph = graph + func = graph.func self.pycode = code self.space = space self.w_globals = Constant(func.func_globals) @@ -234,9 +235,6 @@ self.w_locals = None # XXX: only for compatibility with PyFrame self.joinpoints = {} - self.graph = PyGraph(func, code) - self.pendingblocks = collections.deque([self.graph.startblock]) - self.setstate(self.graph.startblock.framestate) # for testing def init_locals_stack(self, code): """ @@ -315,6 +313,8 @@ return self.recorder.guessexception(self, *exceptions) def build_flow(self): + graph = self.graph + self.pendingblocks = collections.deque([graph.startblock]) while self.pendingblocks: block = self.pendingblocks.popleft() try: @@ -332,14 +332,14 @@ msg = "implicit %s shouldn't occur" % exc_cls.__name__ w_type = Constant(AssertionError) w_value = Constant(AssertionError(msg)) - link = Link([w_type, w_value], self.graph.exceptblock) + link = Link([w_type, w_value], graph.exceptblock) self.recorder.crnt_block.closeblock(link) except FSException, e: if e.w_type is 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([e.w_type, e.w_value], graph.exceptblock) self.recorder.crnt_block.closeblock(link) except StopFlowing: @@ -348,7 +348,7 @@ except Return: w_result = self.popvalue() assert w_result is not None - link = Link([w_result], self.graph.returnblock) + link = Link([w_result], graph.returnblock) self.recorder.crnt_block.closeblock(link) del self.recorder diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -6,9 +6,11 @@ from pypy.interpreter.argument import ArgumentsForTranslation from pypy.objspace.flow.model import (Constant, Variable, WrapException, UnwrapException, checkgraph, SpaceOperation) +from pypy.objspace.flow.bytecode import HostCode from pypy.objspace.flow import operation from pypy.objspace.flow.flowcontext import (FlowSpaceFrame, fixeggblocks, FSException, FlowingError) +from pypy.objspace.flow.pygraph import PyGraph from pypy.objspace.flow.specialcase import SPECIAL_CASES from pypy.rlib.unroll import unrolling_iterable, _unroller from pypy.rlib import rstackovf, rarithmetic @@ -235,9 +237,10 @@ """ if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): raise Exception, "%r is tagged as NOT_RPYTHON" % (func,) - frame = self.frame = FlowSpaceFrame(self, func) + code = HostCode._from_code(self, func.func_code) + graph = PyGraph(func, code) + frame = self.frame = FlowSpaceFrame(self, graph, code) frame.build_flow() - graph = frame.graph fixeggblocks(graph) checkgraph(graph) if graph.is_generator and tweak_for_generator: diff --git a/pypy/objspace/flow/test/test_framestate.py b/pypy/objspace/flow/test/test_framestate.py --- a/pypy/objspace/flow/test/test_framestate.py +++ b/pypy/objspace/flow/test/test_framestate.py @@ -2,6 +2,8 @@ from pypy.rlib.unroll import SpecTag from pypy.objspace.flow.objspace import FlowObjSpace from pypy.objspace.flow.flowcontext import FlowSpaceFrame +from pypy.objspace.flow.bytecode import HostCode +from pypy.objspace.flow.pygraph import PyGraph class TestFrameState: def setup_class(cls): @@ -12,8 +14,11 @@ func = func.im_func except AttributeError: pass - frame = FlowSpaceFrame(self.space, func) + code = HostCode._from_code(self.space, func.func_code) + graph = PyGraph(func, code) + frame = FlowSpaceFrame(self.space, graph, code) # hack the frame + frame.setstate(graph.startblock.framestate) frame.locals_stack_w[frame.pycode.co_nlocals-1] = Constant(None) return frame From noreply at buildbot.pypy.org Mon Oct 1 18:27:29 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 18:27:29 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Move pypy.interpreter.generator to flow space Message-ID: <20121001162729.8DAA21C037C@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57705:5838c81970ae Date: 2012-10-01 16:53 +0100 http://bitbucket.org/pypy/pypy/changeset/5838c81970ae/ Log: Move pypy.interpreter.generator to flow space diff --git a/pypy/translator/generator.py b/pypy/objspace/flow/generator.py rename from pypy/translator/generator.py rename to pypy/objspace/flow/generator.py diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -10,6 +10,7 @@ from pypy.objspace.flow import operation from pypy.objspace.flow.flowcontext import (FlowSpaceFrame, fixeggblocks, FSException, FlowingError) +from pypy.objspace.flow.generator import tweak_generator_graph from pypy.objspace.flow.pygraph import PyGraph from pypy.objspace.flow.specialcase import SPECIAL_CASES from pypy.rlib.unroll import unrolling_iterable, _unroller @@ -244,7 +245,6 @@ fixeggblocks(graph) checkgraph(graph) if graph.is_generator and tweak_for_generator: - from pypy.translator.generator import tweak_generator_graph tweak_generator_graph(graph) return graph diff --git a/pypy/objspace/flow/test/test_generator.py b/pypy/objspace/flow/test/test_generator.py --- a/pypy/objspace/flow/test/test_generator.py +++ b/pypy/objspace/flow/test/test_generator.py @@ -1,18 +1,153 @@ -from pypy.objspace.flow.test.test_objspace import Base +from pypy.conftest import option +from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.objspace.flow.model import Variable +from pypy.interpreter.argument import Signature +from pypy.objspace.flow.generator import (make_generatoriterator_class, + replace_graph_with_bootstrap, get_variable_names, + tweak_generator_body_graph, attach_next_method) +from pypy.translator.simplify import join_blocks -class TestGenerator(Base): +# ____________________________________________________________ - def test_simple_generator(self): - def f(n): +def f_gen(n): + i = 0 + while i < n: + yield i + i += 1 + +class GeneratorIterator(object): + def __init__(self, entry): + self.current = entry + def next(self): + e = self.current + self.current = None + if isinstance(e, Yield1): + n = e.n_0 + i = e.i_0 + i += 1 + else: + n = e.n_0 i = 0 - while i < n: - yield i - yield i - i += 1 - graph = self.codetest(f, tweak_for_generator=False) - ops = self.all_operations(graph) - assert ops == {'generator_mark': 1, - 'lt': 1, 'is_true': 1, - 'yield': 2, - 'inplace_add': 1} + if i < n: + e = Yield1() + e.n_0 = n + e.i_0 = i + self.current = e + return i + raise StopIteration + + def __iter__(self): + return self + +class AbstractPosition(object): + _immutable_ = True +class Entry1(AbstractPosition): + _immutable_ = True +class Yield1(AbstractPosition): + _immutable_ = True + +def f_explicit(n): + e = Entry1() + e.n_0 = n + return GeneratorIterator(e) + +def test_explicit(): + assert list(f_gen(10)) == list(f_explicit(10)) + +def test_get_variable_names(): + lst = get_variable_names([Variable('a'), Variable('b_'), Variable('a')]) + assert lst == ['g_a', 'g_b', 'g_a_'] + +# ____________________________________________________________ + + +class TestGenerator: + + def test_replace_graph_with_bootstrap(self): + def func(n, x, y, z): + yield n + yield n + # + space = FlowObjSpace() + graph = space.build_flow(func, tweak_for_generator=False) + assert graph.startblock.operations[0].opname == 'generator_mark' + GeneratorIterator = make_generatoriterator_class(graph) + replace_graph_with_bootstrap(GeneratorIterator, graph) + if option.view: + graph.show() + block = graph.startblock + ops = block.operations + assert ops[0].opname == 'simple_call' # e = Entry1() + assert ops[1].opname == 'setattr' # e.g_n = n + assert ops[1].args[1].value == 'g_n' + assert ops[2].opname == 'setattr' # e.g_x = x + assert ops[2].args[1].value == 'g_x' + assert ops[3].opname == 'setattr' # e.g_y = y + assert ops[3].args[1].value == 'g_y' + assert ops[4].opname == 'setattr' # e.g_z = z + assert ops[4].args[1].value == 'g_z' + assert ops[5].opname == 'simple_call' # g = GeneratorIterator(e) + assert ops[5].args[1] == ops[0].result + assert len(ops) == 6 + assert len(block.exits) == 1 + assert block.exits[0].target is graph.returnblock + + def test_tweak_generator_body_graph(self): + def f(n, x, y, z=3): + z *= 10 + yield n + 1 + z -= 10 + # + space = FlowObjSpace() + graph = space.build_flow(f, tweak_for_generator=False) + class Entry: + varnames = ['g_n', 'g_x', 'g_y', 'g_z'] + tweak_generator_body_graph(Entry, graph) + if option.view: + graph.show() + # XXX how to test directly that the graph is correct? :-( + assert len(graph.startblock.inputargs) == 1 + assert graph.signature == Signature(['entry']) + assert graph.defaults == () + + def test_tweak_generator_graph(self): + def f(n, x, y, z): + z *= 10 + yield n + 1 + z -= 10 + # + space = FlowObjSpace() + graph = space.build_flow(f, tweak_for_generator=False) + GeneratorIterator = make_generatoriterator_class(graph) + replace_graph_with_bootstrap(GeneratorIterator, graph) + func1 = attach_next_method(GeneratorIterator, graph) + if option.view: + graph.show() + # + assert func1._generator_next_method_of_ is GeneratorIterator + assert hasattr(GeneratorIterator, 'next') + # + graph_next = space.build_flow(GeneratorIterator.next.im_func) + join_blocks(graph_next) + if option.view: + graph_next.show() + # + graph1 = space.build_flow(func1, tweak_for_generator=False) + tweak_generator_body_graph(GeneratorIterator.Entry, graph1) + if option.view: + graph1.show() + + def test_automatic(self): + def f(n, x, y, z): + z *= 10 + yield n + 1 + z -= 10 + # + space = FlowObjSpace() + graph = space.build_flow(f) # tweak_for_generator=True + if option.view: + graph.show() + block = graph.startblock + assert len(block.exits) == 1 + assert block.exits[0].target is graph.returnblock diff --git a/pypy/translator/test/test_generator.py b/pypy/translator/test/test_generator.py deleted file mode 100644 --- a/pypy/translator/test/test_generator.py +++ /dev/null @@ -1,156 +0,0 @@ -from pypy.conftest import option -from pypy.objspace.flow.objspace import FlowObjSpace -from pypy.objspace.flow.model import Variable -from pypy.interpreter.argument import Signature -from pypy.translator.translator import TranslationContext -from pypy.translator.generator import make_generatoriterator_class -from pypy.translator.generator import replace_graph_with_bootstrap -from pypy.translator.generator import get_variable_names -from pypy.translator.generator import tweak_generator_body_graph -from pypy.translator.generator import attach_next_method -from pypy.translator.simplify import join_blocks - - -# ____________________________________________________________ - -def f_gen(n): - i = 0 - while i < n: - yield i - i += 1 - -class GeneratorIterator(object): - def __init__(self, entry): - self.current = entry - def next(self): - e = self.current - self.current = None - if isinstance(e, Yield1): - n = e.n_0 - i = e.i_0 - i += 1 - else: - n = e.n_0 - i = 0 - if i < n: - e = Yield1() - e.n_0 = n - e.i_0 = i - self.current = e - return i - raise StopIteration - - def __iter__(self): - return self - -class AbstractPosition(object): - _immutable_ = True -class Entry1(AbstractPosition): - _immutable_ = True -class Yield1(AbstractPosition): - _immutable_ = True - -def f_explicit(n): - e = Entry1() - e.n_0 = n - return GeneratorIterator(e) - -def test_explicit(): - assert list(f_gen(10)) == list(f_explicit(10)) - -def test_get_variable_names(): - lst = get_variable_names([Variable('a'), Variable('b_'), Variable('a')]) - assert lst == ['g_a', 'g_b', 'g_a_'] - -# ____________________________________________________________ - - -class TestGenerator: - - def test_replace_graph_with_bootstrap(self): - def func(n, x, y, z): - yield n - yield n - # - space = FlowObjSpace() - graph = space.build_flow(func, tweak_for_generator=False) - assert graph.startblock.operations[0].opname == 'generator_mark' - GeneratorIterator = make_generatoriterator_class(graph) - replace_graph_with_bootstrap(GeneratorIterator, graph) - if option.view: - graph.show() - block = graph.startblock - ops = block.operations - assert ops[0].opname == 'simple_call' # e = Entry1() - assert ops[1].opname == 'setattr' # e.g_n = n - assert ops[1].args[1].value == 'g_n' - assert ops[2].opname == 'setattr' # e.g_x = x - assert ops[2].args[1].value == 'g_x' - assert ops[3].opname == 'setattr' # e.g_y = y - assert ops[3].args[1].value == 'g_y' - assert ops[4].opname == 'setattr' # e.g_z = z - assert ops[4].args[1].value == 'g_z' - assert ops[5].opname == 'simple_call' # g = GeneratorIterator(e) - assert ops[5].args[1] == ops[0].result - assert len(ops) == 6 - assert len(block.exits) == 1 - assert block.exits[0].target is graph.returnblock - - def test_tweak_generator_body_graph(self): - def f(n, x, y, z=3): - z *= 10 - yield n + 1 - z -= 10 - # - space = FlowObjSpace() - graph = space.build_flow(f, tweak_for_generator=False) - class Entry: - varnames = ['g_n', 'g_x', 'g_y', 'g_z'] - tweak_generator_body_graph(Entry, graph) - if option.view: - graph.show() - # XXX how to test directly that the graph is correct? :-( - assert len(graph.startblock.inputargs) == 1 - assert graph.signature == Signature(['entry']) - assert graph.defaults == () - - def test_tweak_generator_graph(self): - def f(n, x, y, z): - z *= 10 - yield n + 1 - z -= 10 - # - space = FlowObjSpace() - graph = space.build_flow(f, tweak_for_generator=False) - GeneratorIterator = make_generatoriterator_class(graph) - replace_graph_with_bootstrap(GeneratorIterator, graph) - func1 = attach_next_method(GeneratorIterator, graph) - if option.view: - graph.show() - # - assert func1._generator_next_method_of_ is GeneratorIterator - assert hasattr(GeneratorIterator, 'next') - # - graph_next = space.build_flow(GeneratorIterator.next.im_func) - join_blocks(graph_next) - if option.view: - graph_next.show() - # - graph1 = space.build_flow(func1, tweak_for_generator=False) - tweak_generator_body_graph(GeneratorIterator.Entry, graph1) - if option.view: - graph1.show() - - def test_automatic(self): - def f(n, x, y, z): - z *= 10 - yield n + 1 - z -= 10 - # - space = FlowObjSpace() - graph = space.build_flow(f) # tweak_for_generator=True - if option.view: - graph.show() - block = graph.startblock - assert len(block.exits) == 1 - assert block.exits[0].target is graph.returnblock From noreply at buildbot.pypy.org Mon Oct 1 18:27:30 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 1 Oct 2012 18:27:30 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Fix PyGraph.name Message-ID: <20121001162730.CEBC81C0ACE@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57706:3f9e93ff1e1d Date: 2012-10-01 17:10 +0100 http://bitbucket.org/pypy/pypy/changeset/3f9e93ff1e1d/ Log: Fix PyGraph.name diff --git a/pypy/objspace/flow/pygraph.py b/pypy/objspace/flow/pygraph.py --- a/pypy/objspace/flow/pygraph.py +++ b/pypy/objspace/flow/pygraph.py @@ -36,4 +36,5 @@ name = '%s.%s' % (class_.__name__, name) for c in "<>&!": name = name.replace(c, '_') + return name From noreply at buildbot.pypy.org Mon Oct 1 21:50:43 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 1 Oct 2012 21:50:43 +0200 (CEST) Subject: [pypy-commit] pypy default: ups, this is enough Message-ID: <20121001195043.1D3FB1C00EE@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r57707:7f6d5c878b90 Date: 2012-10-01 21:50 +0200 http://bitbucket.org/pypy/pypy/changeset/7f6d5c878b90/ Log: ups, this is enough 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 @@ -129,7 +129,7 @@ self._prepare_array_index(space, w_index) shape = res_shape + self.get_shape()[len(indexes):] res = W_NDimArray.from_shape(shape, self.get_dtype(), self.get_order()) - if not self.get_size() and not res.get_size(): + if not res.get_size(): return res return loop.getitem_array_int(space, self, res, iter_shape, indexes, prefix) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1519,7 +1519,7 @@ assert (a == [1, 1]).all() def test_int_array_index(self): - from numpypy import array, arange + from numpypy import array, arange, zeros b = arange(10)[array([3, 2, 1, 5])] assert (b == [3, 2, 1, 5]).all() raises(IndexError, "arange(10)[array([10])]") @@ -1528,6 +1528,7 @@ a = arange(1) a[[0, 0]] += 1 assert a[0] == 1 + assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): from numpypy import array, arange, zeros From noreply at buildbot.pypy.org Mon Oct 1 22:57:41 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 1 Oct 2012 22:57:41 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex: close abandoned branch Message-ID: <20121001205741.2C16C1C037C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: numpypy-complex Changeset: r57708:2a5f4da3fe5a Date: 2012-10-01 22:56 +0200 http://bitbucket.org/pypy/pypy/changeset/2a5f4da3fe5a/ Log: close abandoned branch From noreply at buildbot.pypy.org Mon Oct 1 22:57:42 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 1 Oct 2012 22:57:42 +0200 (CEST) Subject: [pypy-commit] pypy numpy-dtype-refactor-complex: close abandoned branch Message-ID: <20121001205742.7F2411C037C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: numpy-dtype-refactor-complex Changeset: r57709:c26fb4a6e96f Date: 2012-10-01 22:57 +0200 http://bitbucket.org/pypy/pypy/changeset/c26fb4a6e96f/ Log: close abandoned branch From noreply at buildbot.pypy.org Mon Oct 1 23:44:33 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 1 Oct 2012 23:44:33 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: fix dos line endings Message-ID: <20121001214433.E9F8F1C0012@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-complex2 Changeset: r57710:e40bc49712a1 Date: 2012-10-01 23:22 +0200 http://bitbucket.org/pypy/pypy/changeset/e40bc49712a1/ Log: fix dos line endings diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py --- a/pypy/rlib/rcomplex.py +++ b/pypy/rlib/rcomplex.py @@ -1,561 +1,561 @@ -import math -from math import copysign, fabs, pi, e -from pypy.rlib.rfloat import copysign, asinh, log1p, isinf, isnan -from pypy.rlib.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN -from pypy.rlib.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG -from pypy.rlib.constant import M_LN2, M_LN10 -from pypy.rlib.constant import CM_SQRT_LARGE_DOUBLE, CM_SQRT_DBL_MIN -from pypy.rlib.constant import CM_LOG_LARGE_DOUBLE -from pypy.rlib.special_value import isfinite, special_type, INF, NAN -from pypy.rlib.special_value import sqrt_special_values -from pypy.rlib.special_value import acos_special_values -from pypy.rlib.special_value import acosh_special_values -from pypy.rlib.special_value import asinh_special_values -from pypy.rlib.special_value import atanh_special_values -from pypy.rlib.special_value import log_special_values -from pypy.rlib.special_value import exp_special_values -from pypy.rlib.special_value import cosh_special_values -from pypy.rlib.special_value import sinh_special_values -from pypy.rlib.special_value import tanh_special_values -from pypy.rlib.special_value import rect_special_values - -#binary - -def c_add(x, y): - (r1, i1), (r2, i2) = x, y - r = r1 + r2 - i = i1 + i2 - return (r, i) - -def c_sub(x, y): - (r1, i1), (r2, i2) = x, y - r = r1 - r2 - i = i1 - i2 - return (r, i) - -def c_mul(x, y): - (r1, i1), (r2, i2) = x, y - r = r1 * r2 - i1 * i2 - i = r1 * i2 + i1 * r2 - return (r, i) - -def c_div(x, y): #x/y - (r1, i1), (r2, i2) = x, y - if r2 < 0: - abs_r2 = -r2 - else: - abs_r2 = r2 - if i2 < 0: - abs_i2 = -i2 - else: - abs_i2 = i2 - if abs_r2 >= abs_i2: - if abs_r2 == 0.0: - raise ZeroDivisionError - else: - ratio = i2 / r2 - denom = r2 + i2 * ratio - rr = (r1 + i1 * ratio) / denom - ir = (i1 - r1 * ratio) / denom - else: - ratio = r2 / i2 - denom = r2 * ratio + i2 - assert i2 != 0.0 - rr = (r1 * ratio + i1) / denom - ir = (i1 * ratio - r1) / denom - return (rr, ir) - -def c_pow(x, y): - (r1, i1), (r2, i2) = x, y - if i1 == 0 and i2 == 0 and r1>=0: - rr = pow(r1, r2) - ir = 0. - elif r2 == 0.0 and i2 == 0.0: - rr, ir = 1, 0 - elif r1 == 1.0 and i1 == 0.0: - rr, ir = (1.0, 0.0) - elif r1 == 0.0 and i1 == 0.0: - if i2 != 0.0 or r2 < 0.0: - raise ZeroDivisionError - rr, ir = (0.0, 0.0) - else: - vabs = math.hypot(r1,i1) - len = math.pow(vabs,r2) - at = math.atan2(i1,r1) - phase = at * r2 - if i2 != 0.0: - len /= math.exp(at * i2) - phase += i2 * math.log(vabs) - rr = len * math.cos(phase) - ir = len * math.sin(phase) - return (rr, ir) - -#unary - -def c_neg(r, i): - return (-r, -i) - - -def c_sqrt(x, y): - ''' - Method: use symmetries to reduce to the case when x = z.real and y - = z.imag are nonnegative. Then the real part of the result is - given by - - s = sqrt((x + hypot(x, y))/2) - - and the imaginary part is - - d = (y/2)/s - - If either x or y is very large then there's a risk of overflow in - computation of the expression x + hypot(x, y). We can avoid this - by rewriting the formula for s as: - - s = 2*sqrt(x/8 + hypot(x/8, y/8)) - - This costs us two extra multiplications/divisions, but avoids the - overhead of checking for x and y large. - - If both x and y are subnormal then hypot(x, y) may also be - subnormal, so will lack full precision. We solve this by rescaling - x and y by a sufficiently large power of 2 to ensure that x and y - are normal. - ''' - if not isfinite(x) or not isfinite(y): - return sqrt_special_values[special_type(x)][special_type(y)] - - if x == 0. and y == 0.: - return (0., y) - - ax = fabs(x) - ay = fabs(y) - - if ax < DBL_MIN and ay < DBL_MIN and (ax > 0. or ay > 0.): - # here we catch cases where hypot(ax, ay) is subnormal - ax = math.ldexp(ax, CM_SCALE_UP) - ay1= math.ldexp(ay, CM_SCALE_UP) - s = math.ldexp(math.sqrt(ax + math.hypot(ax, ay1)), - CM_SCALE_DOWN) - else: - ax /= 8. - s = 2.*math.sqrt(ax + math.hypot(ax, ay/8.)) - - d = ay/(2.*s) - - if x >= 0.: - return (s, copysign(d, y)) - else: - return (d, copysign(s, y)) - - - -def c_acos(x, y): - if not isfinite(x) or not isfinite(y): - return acos_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - # avoid unnecessary overflow for large arguments - real = math.atan2(fabs(y), x) - # split into cases to make sure that the branch cut has the - # correct continuity on systems with unsigned zeros - if x < 0.: - imag = -copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., y) - else: - imag = copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., -y) - else: - s1x, s1y = c_sqrt(1.-x, -y) - s2x, s2y = c_sqrt(1.+x, y) - real = 2.*math.atan2(s1x, s2x) - imag = asinh(s2x*s1y - s2y*s1x) - return (real, imag) - - -def c_acosh(x, y): - # XXX the following two lines seem unnecessary at least on Linux; - # the tests pass fine without them - if not isfinite(x) or not isfinite(y): - return acosh_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - # avoid unnecessary overflow for large arguments - real = math.log(math.hypot(x/2., y/2.)) + M_LN2*2. - imag = math.atan2(y, x) - else: - s1x, s1y = c_sqrt(x - 1., y) - s2x, s2y = c_sqrt(x + 1., y) - real = asinh(s1x*s2x + s1y*s2y) - imag = 2.*math.atan2(s1y, s2x) - return (real, imag) - - -def c_asin(x, y): - # asin(z) = -i asinh(iz) - sx, sy = c_asinh(-y, x) - return (sy, -sx) - - -def c_asinh(x, y): - if not isfinite(x) or not isfinite(y): - return asinh_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - if y >= 0.: - real = copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., x) - else: - real = -copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., -x) - imag = math.atan2(y, fabs(x)) - else: - s1x, s1y = c_sqrt(1.+y, -x) - s2x, s2y = c_sqrt(1.-y, x) - real = asinh(s1x*s2y - s2x*s1y) - imag = math.atan2(y, s1x*s2x - s1y*s2y) - return (real, imag) - - -def c_atan(x, y): - # atan(z) = -i atanh(iz) - sx, sy = c_atanh(-y, x) - return (sy, -sx) - - -def c_atanh(x, y): - if not isfinite(x) or not isfinite(y): - return atanh_special_values[special_type(x)][special_type(y)] - - # Reduce to case where x >= 0., using atanh(z) = -atanh(-z). - if x < 0.: - return c_neg(*c_atanh(*c_neg(x, y))) - - ay = fabs(y) - if x > CM_SQRT_LARGE_DOUBLE or ay > CM_SQRT_LARGE_DOUBLE: - # if abs(z) is large then we use the approximation - # atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign - # of y - h = math.hypot(x/2., y/2.) # safe from overflow - real = x/4./h/h - # the two negations in the next line cancel each other out - # except when working with unsigned zeros: they're there to - # ensure that the branch cut has the correct continuity on - # systems that don't support signed zeros - imag = -copysign(math.pi/2., -y) - elif x == 1. and ay < CM_SQRT_DBL_MIN: - # C99 standard says: atanh(1+/-0.) should be inf +/- 0i - if ay == 0.: - raise ValueError("math domain error") - #real = INF - #imag = y - else: - real = -math.log(math.sqrt(ay)/math.sqrt(math.hypot(ay, 2.))) - imag = copysign(math.atan2(2., -ay) / 2, y) - else: - real = log1p(4.*x/((1-x)*(1-x) + ay*ay))/4. - imag = -math.atan2(-2.*y, (1-x)*(1+x) - ay*ay) / 2. - return (real, imag) - - -def c_log(x, y): - # The usual formula for the real part is log(hypot(z.real, z.imag)). - # There are four situations where this formula is potentially - # problematic: - # - # (1) the absolute value of z is subnormal. Then hypot is subnormal, - # so has fewer than the usual number of bits of accuracy, hence may - # have large relative error. This then gives a large absolute error - # in the log. This can be solved by rescaling z by a suitable power - # of 2. - # - # (2) the absolute value of z is greater than DBL_MAX (e.g. when both - # z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX) - # Again, rescaling solves this. - # - # (3) the absolute value of z is close to 1. In this case it's - # difficult to achieve good accuracy, at least in part because a - # change of 1ulp in the real or imaginary part of z can result in a - # change of billions of ulps in the correctly rounded answer. - # - # (4) z = 0. The simplest thing to do here is to call the - # floating-point log with an argument of 0, and let its behaviour - # (returning -infinity, signaling a floating-point exception, setting - # errno, or whatever) determine that of c_log. So the usual formula - # is fine here. - - # XXX the following two lines seem unnecessary at least on Linux; - # the tests pass fine without them - if not isfinite(x) or not isfinite(y): - return log_special_values[special_type(x)][special_type(y)] - - ax = fabs(x) - ay = fabs(y) - - if ax > CM_LARGE_DOUBLE or ay > CM_LARGE_DOUBLE: - real = math.log(math.hypot(ax/2., ay/2.)) + M_LN2 - elif ax < DBL_MIN and ay < DBL_MIN: - if ax > 0. or ay > 0.: - # catch cases where hypot(ax, ay) is subnormal - real = math.log(math.hypot(math.ldexp(ax, DBL_MANT_DIG), - math.ldexp(ay, DBL_MANT_DIG))) - real -= DBL_MANT_DIG*M_LN2 - else: - # log(+/-0. +/- 0i) - raise ValueError("math domain error") - #real = -INF - #imag = atan2(y, x) - else: - h = math.hypot(ax, ay) - if 0.71 <= h and h <= 1.73: - am = max(ax, ay) - an = min(ax, ay) - real = log1p((am-1)*(am+1) + an*an) / 2. - else: - real = math.log(h) - imag = math.atan2(y, x) - return (real, imag) - - -def c_log10(x, y): - rx, ry = c_log(x, y) - return (rx / M_LN10, ry / M_LN10) - -def c_exp(x, y): - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = copysign(0., math.cos(y)) - imag = copysign(0., math.sin(y)) - r = (real, imag) - else: - r = exp_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN and not -infinity - if isinf(y) and (isfinite(x) or (isinf(x) and x > 0)): - raise ValueError("math domain error") - return r - - if x > CM_LOG_LARGE_DOUBLE: - l = math.exp(x-1.) - real = l * math.cos(y) * math.e - imag = l * math.sin(y) * math.e - else: - l = math.exp(x) - real = l * math.cos(y) - imag = l * math.sin(y) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - - -def c_cosh(x, y): - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = copysign(INF, math.cos(y)) - imag = -copysign(INF, math.sin(y)) - r = (real, imag) - else: - r = cosh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN - if isinf(y) and not isnan(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - # deal correctly with cases where cosh(x) overflows but - # cosh(z) does not. - x_minus_one = x - copysign(1., x) - real = math.cos(y) * math.cosh(x_minus_one) * math.e - imag = math.sin(y) * math.sinh(x_minus_one) * math.e - else: - real = math.cos(y) * math.cosh(x) - imag = math.sin(y) * math.sinh(x) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - - -def c_sinh(x, y): - # special treatment for sinh(+/-inf + iy) if y is finite and nonzero - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = -copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - r = (real, imag) - else: - r = sinh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN - if isinf(y) and not isnan(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - x_minus_one = x - copysign(1., x) - real = math.cos(y) * math.sinh(x_minus_one) * math.e - imag = math.sin(y) * math.cosh(x_minus_one) * math.e - else: - real = math.cos(y) * math.sinh(x) - imag = math.sin(y) * math.cosh(x) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - - -def c_tanh(x, y): - # Formula: - # - # tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) / - # (1+tan(y)^2 tanh(x)^2) - # - # To avoid excessive roundoff error, 1-tanh(x)^2 is better computed - # as 1/cosh(x)^2. When abs(x) is large, we approximate 1-tanh(x)^2 - # by 4 exp(-2*x) instead, to avoid possible overflow in the - # computation of cosh(x). - - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = 1.0 # vv XXX why is the 2. there? - imag = copysign(0., 2. * math.sin(y) * math.cos(y)) - else: - real = -1.0 - imag = copysign(0., 2. * math.sin(y) * math.cos(y)) - r = (real, imag) - else: - r = tanh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/-infinity and x is finite - if isinf(y) and isfinite(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - real = copysign(1., x) - imag = 4. * math.sin(y) * math.cos(y) * math.exp(-2.*fabs(x)) - else: - tx = math.tanh(x) - ty = math.tan(y) - cx = 1. / math.cosh(x) - txty = tx * ty - denom = 1. + txty * txty - real = tx * (1. + ty*ty) / denom - imag = ((ty / denom) * cx) * cx - return real, imag - - -def c_cos(r, i): - # cos(z) = cosh(iz) - return c_cosh(-i, r) - -def c_sin(r, i): - # sin(z) = -i sinh(iz) - sr, si = c_sinh(-i, r) - return si, -sr - -def c_tan(r, i): - # tan(z) = -i tanh(iz) - sr, si = c_tanh(-i, r) - return si, -sr - - -def c_rect(r, phi): - if not isfinite(r) or not isfinite(phi): - # if r is +/-infinity and phi is finite but nonzero then - # result is (+-INF +-INF i), but we need to compute cos(phi) - # and sin(phi) to figure out the signs. - if isinf(r) and isfinite(phi) and phi != 0.: - if r > 0: - real = copysign(INF, math.cos(phi)) - imag = copysign(INF, math.sin(phi)) - else: - real = -copysign(INF, math.cos(phi)) - imag = -copysign(INF, math.sin(phi)) - z = (real, imag) - else: - z = rect_special_values[special_type(r)][special_type(phi)] - - # need to raise ValueError if r is a nonzero number and phi - # is infinite - if r != 0. and not isnan(r) and isinf(phi): - raise ValueError("math domain error") - return z - - real = r * math.cos(phi) - imag = r * math.sin(phi) - return real, imag - - -def c_phase(x, y): - # Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't - # follow C99 for atan2(0., 0.). - if isnan(x) or isnan(y): - return NAN - if isinf(y): - if isinf(x): - if copysign(1., x) == 1.: - # atan2(+-inf, +inf) == +-pi/4 - return copysign(0.25 * math.pi, y) - else: - # atan2(+-inf, -inf) == +-pi*3/4 - return copysign(0.75 * math.pi, y) - # atan2(+-inf, x) == +-pi/2 for finite x - return copysign(0.5 * math.pi, y) - if isinf(x) or y == 0.: - if copysign(1., x) == 1.: - # atan2(+-y, +inf) = atan2(+-0, +x) = +-0. - return copysign(0., y) - else: - # atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. - return copysign(math.pi, y) - return math.atan2(y, x) - - -def c_abs(r, i): - if not isfinite(r) or not isfinite(i): - # C99 rules: if either the real or the imaginary part is an - # infinity, return infinity, even if the other part is a NaN. - if isinf(r): - return INF - if isinf(i): - return INF - - # either the real or imaginary part is a NaN, - # and neither is infinite. Result should be NaN. - return NAN - - result = math.hypot(r, i) - if not isfinite(result): - raise OverflowError("math range error") - return result - - -def c_polar(r, i): - real = c_abs(r, i) - phi = c_phase(r, i) - return real, phi - - -def c_isinf(r, i): - return isinf(r) or isinf(i) - - -def c_isnan(r, i): - return isnan(r) or isnan(i) - +import math +from math import copysign, fabs, pi, e +from pypy.rlib.rfloat import copysign, asinh, log1p, isinf, isnan +from pypy.rlib.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN +from pypy.rlib.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG +from pypy.rlib.constant import M_LN2, M_LN10 +from pypy.rlib.constant import CM_SQRT_LARGE_DOUBLE, CM_SQRT_DBL_MIN +from pypy.rlib.constant import CM_LOG_LARGE_DOUBLE +from pypy.rlib.special_value import isfinite, special_type, INF, NAN +from pypy.rlib.special_value import sqrt_special_values +from pypy.rlib.special_value import acos_special_values +from pypy.rlib.special_value import acosh_special_values +from pypy.rlib.special_value import asinh_special_values +from pypy.rlib.special_value import atanh_special_values +from pypy.rlib.special_value import log_special_values +from pypy.rlib.special_value import exp_special_values +from pypy.rlib.special_value import cosh_special_values +from pypy.rlib.special_value import sinh_special_values +from pypy.rlib.special_value import tanh_special_values +from pypy.rlib.special_value import rect_special_values + +#binary + +def c_add(x, y): + (r1, i1), (r2, i2) = x, y + r = r1 + r2 + i = i1 + i2 + return (r, i) + +def c_sub(x, y): + (r1, i1), (r2, i2) = x, y + r = r1 - r2 + i = i1 - i2 + return (r, i) + +def c_mul(x, y): + (r1, i1), (r2, i2) = x, y + r = r1 * r2 - i1 * i2 + i = r1 * i2 + i1 * r2 + return (r, i) + +def c_div(x, y): #x/y + (r1, i1), (r2, i2) = x, y + if r2 < 0: + abs_r2 = -r2 + else: + abs_r2 = r2 + if i2 < 0: + abs_i2 = -i2 + else: + abs_i2 = i2 + if abs_r2 >= abs_i2: + if abs_r2 == 0.0: + raise ZeroDivisionError + else: + ratio = i2 / r2 + denom = r2 + i2 * ratio + rr = (r1 + i1 * ratio) / denom + ir = (i1 - r1 * ratio) / denom + else: + ratio = r2 / i2 + denom = r2 * ratio + i2 + assert i2 != 0.0 + rr = (r1 * ratio + i1) / denom + ir = (i1 * ratio - r1) / denom + return (rr, ir) + +def c_pow(x, y): + (r1, i1), (r2, i2) = x, y + if i1 == 0 and i2 == 0 and r1>=0: + rr = pow(r1, r2) + ir = 0. + elif r2 == 0.0 and i2 == 0.0: + rr, ir = 1, 0 + elif r1 == 1.0 and i1 == 0.0: + rr, ir = (1.0, 0.0) + elif r1 == 0.0 and i1 == 0.0: + if i2 != 0.0 or r2 < 0.0: + raise ZeroDivisionError + rr, ir = (0.0, 0.0) + else: + vabs = math.hypot(r1,i1) + len = math.pow(vabs,r2) + at = math.atan2(i1,r1) + phase = at * r2 + if i2 != 0.0: + len /= math.exp(at * i2) + phase += i2 * math.log(vabs) + rr = len * math.cos(phase) + ir = len * math.sin(phase) + return (rr, ir) + +#unary + +def c_neg(r, i): + return (-r, -i) + + +def c_sqrt(x, y): + ''' + Method: use symmetries to reduce to the case when x = z.real and y + = z.imag are nonnegative. Then the real part of the result is + given by + + s = sqrt((x + hypot(x, y))/2) + + and the imaginary part is + + d = (y/2)/s + + If either x or y is very large then there's a risk of overflow in + computation of the expression x + hypot(x, y). We can avoid this + by rewriting the formula for s as: + + s = 2*sqrt(x/8 + hypot(x/8, y/8)) + + This costs us two extra multiplications/divisions, but avoids the + overhead of checking for x and y large. + + If both x and y are subnormal then hypot(x, y) may also be + subnormal, so will lack full precision. We solve this by rescaling + x and y by a sufficiently large power of 2 to ensure that x and y + are normal. + ''' + if not isfinite(x) or not isfinite(y): + return sqrt_special_values[special_type(x)][special_type(y)] + + if x == 0. and y == 0.: + return (0., y) + + ax = fabs(x) + ay = fabs(y) + + if ax < DBL_MIN and ay < DBL_MIN and (ax > 0. or ay > 0.): + # here we catch cases where hypot(ax, ay) is subnormal + ax = math.ldexp(ax, CM_SCALE_UP) + ay1= math.ldexp(ay, CM_SCALE_UP) + s = math.ldexp(math.sqrt(ax + math.hypot(ax, ay1)), + CM_SCALE_DOWN) + else: + ax /= 8. + s = 2.*math.sqrt(ax + math.hypot(ax, ay/8.)) + + d = ay/(2.*s) + + if x >= 0.: + return (s, copysign(d, y)) + else: + return (d, copysign(s, y)) + + + +def c_acos(x, y): + if not isfinite(x) or not isfinite(y): + return acos_special_values[special_type(x)][special_type(y)] + + if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: + # avoid unnecessary overflow for large arguments + real = math.atan2(fabs(y), x) + # split into cases to make sure that the branch cut has the + # correct continuity on systems with unsigned zeros + if x < 0.: + imag = -copysign(math.log(math.hypot(x/2., y/2.)) + + M_LN2*2., y) + else: + imag = copysign(math.log(math.hypot(x/2., y/2.)) + + M_LN2*2., -y) + else: + s1x, s1y = c_sqrt(1.-x, -y) + s2x, s2y = c_sqrt(1.+x, y) + real = 2.*math.atan2(s1x, s2x) + imag = asinh(s2x*s1y - s2y*s1x) + return (real, imag) + + +def c_acosh(x, y): + # XXX the following two lines seem unnecessary at least on Linux; + # the tests pass fine without them + if not isfinite(x) or not isfinite(y): + return acosh_special_values[special_type(x)][special_type(y)] + + if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: + # avoid unnecessary overflow for large arguments + real = math.log(math.hypot(x/2., y/2.)) + M_LN2*2. + imag = math.atan2(y, x) + else: + s1x, s1y = c_sqrt(x - 1., y) + s2x, s2y = c_sqrt(x + 1., y) + real = asinh(s1x*s2x + s1y*s2y) + imag = 2.*math.atan2(s1y, s2x) + return (real, imag) + + +def c_asin(x, y): + # asin(z) = -i asinh(iz) + sx, sy = c_asinh(-y, x) + return (sy, -sx) + + +def c_asinh(x, y): + if not isfinite(x) or not isfinite(y): + return asinh_special_values[special_type(x)][special_type(y)] + + if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: + if y >= 0.: + real = copysign(math.log(math.hypot(x/2., y/2.)) + + M_LN2*2., x) + else: + real = -copysign(math.log(math.hypot(x/2., y/2.)) + + M_LN2*2., -x) + imag = math.atan2(y, fabs(x)) + else: + s1x, s1y = c_sqrt(1.+y, -x) + s2x, s2y = c_sqrt(1.-y, x) + real = asinh(s1x*s2y - s2x*s1y) + imag = math.atan2(y, s1x*s2x - s1y*s2y) + return (real, imag) + + +def c_atan(x, y): + # atan(z) = -i atanh(iz) + sx, sy = c_atanh(-y, x) + return (sy, -sx) + + +def c_atanh(x, y): + if not isfinite(x) or not isfinite(y): + return atanh_special_values[special_type(x)][special_type(y)] + + # Reduce to case where x >= 0., using atanh(z) = -atanh(-z). + if x < 0.: + return c_neg(*c_atanh(*c_neg(x, y))) + + ay = fabs(y) + if x > CM_SQRT_LARGE_DOUBLE or ay > CM_SQRT_LARGE_DOUBLE: + # if abs(z) is large then we use the approximation + # atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign + # of y + h = math.hypot(x/2., y/2.) # safe from overflow + real = x/4./h/h + # the two negations in the next line cancel each other out + # except when working with unsigned zeros: they're there to + # ensure that the branch cut has the correct continuity on + # systems that don't support signed zeros + imag = -copysign(math.pi/2., -y) + elif x == 1. and ay < CM_SQRT_DBL_MIN: + # C99 standard says: atanh(1+/-0.) should be inf +/- 0i + if ay == 0.: + raise ValueError("math domain error") + #real = INF + #imag = y + else: + real = -math.log(math.sqrt(ay)/math.sqrt(math.hypot(ay, 2.))) + imag = copysign(math.atan2(2., -ay) / 2, y) + else: + real = log1p(4.*x/((1-x)*(1-x) + ay*ay))/4. + imag = -math.atan2(-2.*y, (1-x)*(1+x) - ay*ay) / 2. + return (real, imag) + + +def c_log(x, y): + # The usual formula for the real part is log(hypot(z.real, z.imag)). + # There are four situations where this formula is potentially + # problematic: + # + # (1) the absolute value of z is subnormal. Then hypot is subnormal, + # so has fewer than the usual number of bits of accuracy, hence may + # have large relative error. This then gives a large absolute error + # in the log. This can be solved by rescaling z by a suitable power + # of 2. + # + # (2) the absolute value of z is greater than DBL_MAX (e.g. when both + # z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX) + # Again, rescaling solves this. + # + # (3) the absolute value of z is close to 1. In this case it's + # difficult to achieve good accuracy, at least in part because a + # change of 1ulp in the real or imaginary part of z can result in a + # change of billions of ulps in the correctly rounded answer. + # + # (4) z = 0. The simplest thing to do here is to call the + # floating-point log with an argument of 0, and let its behaviour + # (returning -infinity, signaling a floating-point exception, setting + # errno, or whatever) determine that of c_log. So the usual formula + # is fine here. + + # XXX the following two lines seem unnecessary at least on Linux; + # the tests pass fine without them + if not isfinite(x) or not isfinite(y): + return log_special_values[special_type(x)][special_type(y)] + + ax = fabs(x) + ay = fabs(y) + + if ax > CM_LARGE_DOUBLE or ay > CM_LARGE_DOUBLE: + real = math.log(math.hypot(ax/2., ay/2.)) + M_LN2 + elif ax < DBL_MIN and ay < DBL_MIN: + if ax > 0. or ay > 0.: + # catch cases where hypot(ax, ay) is subnormal + real = math.log(math.hypot(math.ldexp(ax, DBL_MANT_DIG), + math.ldexp(ay, DBL_MANT_DIG))) + real -= DBL_MANT_DIG*M_LN2 + else: + # log(+/-0. +/- 0i) + raise ValueError("math domain error") + #real = -INF + #imag = atan2(y, x) + else: + h = math.hypot(ax, ay) + if 0.71 <= h and h <= 1.73: + am = max(ax, ay) + an = min(ax, ay) + real = log1p((am-1)*(am+1) + an*an) / 2. + else: + real = math.log(h) + imag = math.atan2(y, x) + return (real, imag) + + +def c_log10(x, y): + rx, ry = c_log(x, y) + return (rx / M_LN10, ry / M_LN10) + +def c_exp(x, y): + if not isfinite(x) or not isfinite(y): + if isinf(x) and isfinite(y) and y != 0.: + if x > 0: + real = copysign(INF, math.cos(y)) + imag = copysign(INF, math.sin(y)) + else: + real = copysign(0., math.cos(y)) + imag = copysign(0., math.sin(y)) + r = (real, imag) + else: + r = exp_special_values[special_type(x)][special_type(y)] + + # need to raise ValueError if y is +/- infinity and x is not + # a NaN and not -infinity + if isinf(y) and (isfinite(x) or (isinf(x) and x > 0)): + raise ValueError("math domain error") + return r + + if x > CM_LOG_LARGE_DOUBLE: + l = math.exp(x-1.) + real = l * math.cos(y) * math.e + imag = l * math.sin(y) * math.e + else: + l = math.exp(x) + real = l * math.cos(y) + imag = l * math.sin(y) + if isinf(real) or isinf(imag): + raise OverflowError("math range error") + return real, imag + + +def c_cosh(x, y): + if not isfinite(x) or not isfinite(y): + if isinf(x) and isfinite(y) and y != 0.: + if x > 0: + real = copysign(INF, math.cos(y)) + imag = copysign(INF, math.sin(y)) + else: + real = copysign(INF, math.cos(y)) + imag = -copysign(INF, math.sin(y)) + r = (real, imag) + else: + r = cosh_special_values[special_type(x)][special_type(y)] + + # need to raise ValueError if y is +/- infinity and x is not + # a NaN + if isinf(y) and not isnan(x): + raise ValueError("math domain error") + return r + + if fabs(x) > CM_LOG_LARGE_DOUBLE: + # deal correctly with cases where cosh(x) overflows but + # cosh(z) does not. + x_minus_one = x - copysign(1., x) + real = math.cos(y) * math.cosh(x_minus_one) * math.e + imag = math.sin(y) * math.sinh(x_minus_one) * math.e + else: + real = math.cos(y) * math.cosh(x) + imag = math.sin(y) * math.sinh(x) + if isinf(real) or isinf(imag): + raise OverflowError("math range error") + return real, imag + + +def c_sinh(x, y): + # special treatment for sinh(+/-inf + iy) if y is finite and nonzero + if not isfinite(x) or not isfinite(y): + if isinf(x) and isfinite(y) and y != 0.: + if x > 0: + real = copysign(INF, math.cos(y)) + imag = copysign(INF, math.sin(y)) + else: + real = -copysign(INF, math.cos(y)) + imag = copysign(INF, math.sin(y)) + r = (real, imag) + else: + r = sinh_special_values[special_type(x)][special_type(y)] + + # need to raise ValueError if y is +/- infinity and x is not + # a NaN + if isinf(y) and not isnan(x): + raise ValueError("math domain error") + return r + + if fabs(x) > CM_LOG_LARGE_DOUBLE: + x_minus_one = x - copysign(1., x) + real = math.cos(y) * math.sinh(x_minus_one) * math.e + imag = math.sin(y) * math.cosh(x_minus_one) * math.e + else: + real = math.cos(y) * math.sinh(x) + imag = math.sin(y) * math.cosh(x) + if isinf(real) or isinf(imag): + raise OverflowError("math range error") + return real, imag + + +def c_tanh(x, y): + # Formula: + # + # tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) / + # (1+tan(y)^2 tanh(x)^2) + # + # To avoid excessive roundoff error, 1-tanh(x)^2 is better computed + # as 1/cosh(x)^2. When abs(x) is large, we approximate 1-tanh(x)^2 + # by 4 exp(-2*x) instead, to avoid possible overflow in the + # computation of cosh(x). + + if not isfinite(x) or not isfinite(y): + if isinf(x) and isfinite(y) and y != 0.: + if x > 0: + real = 1.0 # vv XXX why is the 2. there? + imag = copysign(0., 2. * math.sin(y) * math.cos(y)) + else: + real = -1.0 + imag = copysign(0., 2. * math.sin(y) * math.cos(y)) + r = (real, imag) + else: + r = tanh_special_values[special_type(x)][special_type(y)] + + # need to raise ValueError if y is +/-infinity and x is finite + if isinf(y) and isfinite(x): + raise ValueError("math domain error") + return r + + if fabs(x) > CM_LOG_LARGE_DOUBLE: + real = copysign(1., x) + imag = 4. * math.sin(y) * math.cos(y) * math.exp(-2.*fabs(x)) + else: + tx = math.tanh(x) + ty = math.tan(y) + cx = 1. / math.cosh(x) + txty = tx * ty + denom = 1. + txty * txty + real = tx * (1. + ty*ty) / denom + imag = ((ty / denom) * cx) * cx + return real, imag + + +def c_cos(r, i): + # cos(z) = cosh(iz) + return c_cosh(-i, r) + +def c_sin(r, i): + # sin(z) = -i sinh(iz) + sr, si = c_sinh(-i, r) + return si, -sr + +def c_tan(r, i): + # tan(z) = -i tanh(iz) + sr, si = c_tanh(-i, r) + return si, -sr + + +def c_rect(r, phi): + if not isfinite(r) or not isfinite(phi): + # if r is +/-infinity and phi is finite but nonzero then + # result is (+-INF +-INF i), but we need to compute cos(phi) + # and sin(phi) to figure out the signs. + if isinf(r) and isfinite(phi) and phi != 0.: + if r > 0: + real = copysign(INF, math.cos(phi)) + imag = copysign(INF, math.sin(phi)) + else: + real = -copysign(INF, math.cos(phi)) + imag = -copysign(INF, math.sin(phi)) + z = (real, imag) + else: + z = rect_special_values[special_type(r)][special_type(phi)] + + # need to raise ValueError if r is a nonzero number and phi + # is infinite + if r != 0. and not isnan(r) and isinf(phi): + raise ValueError("math domain error") + return z + + real = r * math.cos(phi) + imag = r * math.sin(phi) + return real, imag + + +def c_phase(x, y): + # Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't + # follow C99 for atan2(0., 0.). + if isnan(x) or isnan(y): + return NAN + if isinf(y): + if isinf(x): + if copysign(1., x) == 1.: + # atan2(+-inf, +inf) == +-pi/4 + return copysign(0.25 * math.pi, y) + else: + # atan2(+-inf, -inf) == +-pi*3/4 + return copysign(0.75 * math.pi, y) + # atan2(+-inf, x) == +-pi/2 for finite x + return copysign(0.5 * math.pi, y) + if isinf(x) or y == 0.: + if copysign(1., x) == 1.: + # atan2(+-y, +inf) = atan2(+-0, +x) = +-0. + return copysign(0., y) + else: + # atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. + return copysign(math.pi, y) + return math.atan2(y, x) + + +def c_abs(r, i): + if not isfinite(r) or not isfinite(i): + # C99 rules: if either the real or the imaginary part is an + # infinity, return infinity, even if the other part is a NaN. + if isinf(r): + return INF + if isinf(i): + return INF + + # either the real or imaginary part is a NaN, + # and neither is infinite. Result should be NaN. + return NAN + + result = math.hypot(r, i) + if not isfinite(result): + raise OverflowError("math range error") + return result + + +def c_polar(r, i): + real = c_abs(r, i) + phi = c_phase(r, i) + return real, phi + + +def c_isinf(r, i): + return isinf(r) or isinf(i) + + +def c_isnan(r, i): + return isnan(r) or isnan(i) + diff --git a/pypy/rlib/test/test_rcomplex.py b/pypy/rlib/test/test_rcomplex.py --- a/pypy/rlib/test/test_rcomplex.py +++ b/pypy/rlib/test/test_rcomplex.py @@ -1,259 +1,259 @@ -from __future__ import with_statement - -import pypy.rlib.rcomplex as c -from pypy.rlib.rfloat import copysign, isnan, isinf -import os, sys, math, struct - - -def test_add(): - for c1, c2, result in [ - ((0, 0), (0, 0), (0, 0)), - ((1, 0), (2, 0), (3, 0)), - ((0, 3), (0, 2), (0, 5)), - ((10., -3.), (-5, 7), (5, 4)), - ]: - assert c.c_add(c1, c2) == result - -def test_sub(): - for c1, c2, result in [ - ((0, 0), (0, 0), (0, 0)), - ((1, 0), (2, 0), (-1, 0)), - ((0, 3), (0, 2), (0, 1)), - ((10, -3), (-5, 7), (15, -10)), - ((42, 0.3), (42, 0.3), (0, 0)) - ]: - assert c.c_sub(c1, c2) == result - -def test_mul(): - for c1, c2, result in [ - ((0, 0), (0, 0), (0, 0)), - ((1, 0), (2, 0), (2, 0)), - ((0, 3), (0, 2), (-6, 0)), - ((0, -3), (-5, 0), (0, 15)), - ]: - assert c.c_mul(c1, c2) == result - -def parse_testfile2(fname): - """Parse a file with test values - - Empty lines or lines starting with -- are ignored - yields id, fn, arg1_real, arg1_imag, arg2_real, arg2_imag, - exp_real, exp_imag where numbers in file may be expressed as floating point or hex - """ - fname = os.path.join(os.path.dirname(__file__), fname) - with open(fname) as fp: - for line in fp: - # skip comment lines and blank lines - if line.startswith('--') or not line.strip(): - continue - - lhs, rhs = line.split('->') - lhs_pieces = lhs.split() - rhs_pieces = rhs.split() - for i in range(2, len(lhs_pieces)): - if lhs_pieces[i].lower().startswith('0x'): - lhs_pieces[i] = struct.unpack('d', - struct.pack('q',int(lhs_pieces[i]))) - else: - lhs_pieces[i] = float(lhs_pieces[i]) - for i in range(2): - if rhs_pieces[i].lower().startswith('0x'): - rhs_pieces[i] = struct.unpack('d', - struct.pack('l',int(rhs_pieces[i]))) - else: - rhs_pieces[i] = float(rhs_pieces[i]) - #id, fn, arg1_real, arg1_imag arg2_real, arg2_imag = - #exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1] - flags = rhs_pieces[2:] - id_f, fn = lhs_pieces[:2] - if len(lhs_pieces)>4: - args = (lhs_pieces[2:4], lhs_pieces[4:]) - else: - args = lhs_pieces[2:] - yield id_f, fn, args, rhs_pieces[:2], flags - - - -def parse_testfile(fname): - """Parse a file with test values - - Empty lines or lines starting with -- are ignored - yields id, fn, arg_real, arg_imag, exp_real, exp_imag - """ - fname = os.path.join(os.path.dirname(__file__), fname) - with open(fname) as fp: - for line in fp: - # skip comment lines and blank lines - if line.startswith('--') or not line.strip(): - continue - - lhs, rhs = line.split('->') - id, fn, arg_real, arg_imag = lhs.split() - rhs_pieces = rhs.split() - exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1] - flags = rhs_pieces[2:] - - yield (id, fn, - float(arg_real), float(arg_imag), - float(exp_real), float(exp_imag), - flags - ) - -def args_to_str(args): - if isinstance(args[0],(list, tuple)): - return '(complex(%r, %r), complex(%r, %r))' % \ - (args[0][0], args[0][1], args[1][0], args[1][1]) - else: - return '(complex(%r, %r))' % (args[0], args[1]) - -def rAssertAlmostEqual(a, b, rel_err = 2e-15, abs_err = 5e-323, msg=''): - """Fail if the two floating-point numbers are not almost equal. - - Determine whether floating-point values a and b are equal to within - a (small) rounding error. The default values for rel_err and - abs_err are chosen to be suitable for platforms where a float is - represented by an IEEE 754 double. They allow an error of between - 9 and 19 ulps. - """ - - # special values testing - if isnan(a): - if isnan(b): - return - raise AssertionError(msg + '%r should be nan' % (b,)) - - if isinf(a): - if a == b: - return - raise AssertionError(msg + 'finite result where infinity expected: ' - 'expected %r, got %r' % (a, b)) - - # if both a and b are zero, check whether they have the same sign - # (in theory there are examples where it would be legitimate for a - # and b to have opposite signs; in practice these hardly ever - # occur). - if not a and not b: - # only check it if we are running on top of CPython >= 2.6 - if sys.version_info >= (2, 6) and copysign(1., a) != copysign(1., b): - raise AssertionError(msg + 'zero has wrong sign: expected %r, ' - 'got %r' % (a, b)) - - # if a-b overflows, or b is infinite, return False. Again, in - # theory there are examples where a is within a few ulps of the - # max representable float, and then b could legitimately be - # infinite. In practice these examples are rare. - try: - absolute_error = abs(b-a) - except OverflowError: - pass - else: - # test passes if either the absolute error or the relative - # error is sufficiently small. The defaults amount to an - # error of between 9 ulps and 19 ulps on an IEEE-754 compliant - # machine. - if absolute_error <= max(abs_err, rel_err * abs(a)): - return - raise AssertionError(msg + '%r and %r are not sufficiently close' % (a, b)) - -def test_specific_values(): - #if not float.__getformat__("double").startswith("IEEE"): - # return - - for id, fn, arg, expected, flags in parse_testfile2('rcomplex_testcases.txt'): - function = getattr(c, 'c_' + fn) - # - if 'divide-by-zero' in flags or 'invalid' in flags: - try: - actual = function(*arg) - except ValueError: - continue - else: - raise AssertionError('ValueError not raised in test ' - '%s: %s%s' % (id, fn, args_to_str(arg))) - if 'overflow' in flags: - try: - actual = function(*arg) - except OverflowError: - continue - else: - raise AssertionError('OverflowError not raised in test ' - '%s: %s%s' % (id, fn, args_to_str(arg))) - actual = function(*arg) - - if 'ignore-real-sign' in flags: - actual = (abs(actual[0]), actual[1]) - expected = (abs(expected[0]), expected[1]) - if 'ignore-imag-sign' in flags: - actual = (actual[0], abs(actual[1])) - expected = (expected[0], abs(expected[1])) - - # for the real part of the log function, we allow an - # absolute error of up to 2e-15. - if fn in ('log', 'log10'): - real_abs_err = 2e-15 - else: - real_abs_err = 5e-323 - - error_message = ( - '%s: %s%s\n' - 'Expected: complex(%r, %r)\n' - 'Received: complex(%r, %r)\n' - ) % (id, fn, args_to_str(arg), - expected[0], expected[1], - actual[0], actual[1]) - - rAssertAlmostEqual(expected[0], actual[0], - abs_err=real_abs_err, - msg=error_message) - rAssertAlmostEqual(expected[1], actual[1], - abs_err=real_abs_err, - msg=error_message) - - for id, fn, a, expected, flags in parse_testfile2('rcomplex_testcases2.txt'): - function = getattr(c, 'c_' + fn) - # - if 'divide-by-zero' in flags or 'invalid' in flags: - try: - actual = function(*a) - except ValueError: - continue - else: - raise AssertionError('ValueError not raised in test ' - '%s: %s%s' % (id, fn, args_to_str(a))) - if 'overflow' in flags: - try: - actual = function(*a) - except OverflowError: - continue - else: - raise AssertionError('OverflowError not raised in test ' - '%s: %s%s' % (id, fn, args_to_str(a))) - actual = function(*a) - - if 'ignore-real-sign' in flags: - actual = (abs(actual[0]), actual[1]) - expected = (abs(expected[0]), expected[1]) - if 'ignore-imag-sign' in flags: - actual = (actual[0], abs(actual[1])) - expected = (expected[0], abs(expected[1])) - - # for the real part of the log function, we allow an - # absolute error of up to 2e-15. - if fn in ('log', 'log10'): - real_abs_err = 2e-15 - else: - real_abs_err = 5e-323 - error_message = ( - '%s: %s%s\n' - 'Expected: complex(%r, %r)\n' - 'Received: complex(%r, %r)\n' - ) % (id, fn, args_to_str(a), - expected[0], expected[1], - actual[0], actual[1]) - - rAssertAlmostEqual(expected[0], actual[0], - abs_err=real_abs_err, - msg=error_message) - rAssertAlmostEqual(expected[1], actual[1], - abs_err=real_abs_err, - msg=error_message) +from __future__ import with_statement + +import pypy.rlib.rcomplex as c +from pypy.rlib.rfloat import copysign, isnan, isinf +import os, sys, math, struct + + +def test_add(): + for c1, c2, result in [ + ((0, 0), (0, 0), (0, 0)), + ((1, 0), (2, 0), (3, 0)), + ((0, 3), (0, 2), (0, 5)), + ((10., -3.), (-5, 7), (5, 4)), + ]: + assert c.c_add(c1, c2) == result + +def test_sub(): + for c1, c2, result in [ + ((0, 0), (0, 0), (0, 0)), + ((1, 0), (2, 0), (-1, 0)), + ((0, 3), (0, 2), (0, 1)), + ((10, -3), (-5, 7), (15, -10)), + ((42, 0.3), (42, 0.3), (0, 0)) + ]: + assert c.c_sub(c1, c2) == result + +def test_mul(): + for c1, c2, result in [ + ((0, 0), (0, 0), (0, 0)), + ((1, 0), (2, 0), (2, 0)), + ((0, 3), (0, 2), (-6, 0)), + ((0, -3), (-5, 0), (0, 15)), + ]: + assert c.c_mul(c1, c2) == result + +def parse_testfile2(fname): + """Parse a file with test values + + Empty lines or lines starting with -- are ignored + yields id, fn, arg1_real, arg1_imag, arg2_real, arg2_imag, + exp_real, exp_imag where numbers in file may be expressed as floating point or hex + """ + fname = os.path.join(os.path.dirname(__file__), fname) + with open(fname) as fp: + for line in fp: + # skip comment lines and blank lines + if line.startswith('--') or not line.strip(): + continue + + lhs, rhs = line.split('->') + lhs_pieces = lhs.split() + rhs_pieces = rhs.split() + for i in range(2, len(lhs_pieces)): + if lhs_pieces[i].lower().startswith('0x'): + lhs_pieces[i] = struct.unpack('d', + struct.pack('q',int(lhs_pieces[i]))) + else: + lhs_pieces[i] = float(lhs_pieces[i]) + for i in range(2): + if rhs_pieces[i].lower().startswith('0x'): + rhs_pieces[i] = struct.unpack('d', + struct.pack('l',int(rhs_pieces[i]))) + else: + rhs_pieces[i] = float(rhs_pieces[i]) + #id, fn, arg1_real, arg1_imag arg2_real, arg2_imag = + #exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1] + flags = rhs_pieces[2:] + id_f, fn = lhs_pieces[:2] + if len(lhs_pieces)>4: + args = (lhs_pieces[2:4], lhs_pieces[4:]) + else: + args = lhs_pieces[2:] + yield id_f, fn, args, rhs_pieces[:2], flags + + + +def parse_testfile(fname): + """Parse a file with test values + + Empty lines or lines starting with -- are ignored + yields id, fn, arg_real, arg_imag, exp_real, exp_imag + """ + fname = os.path.join(os.path.dirname(__file__), fname) + with open(fname) as fp: + for line in fp: + # skip comment lines and blank lines + if line.startswith('--') or not line.strip(): + continue + + lhs, rhs = line.split('->') + id, fn, arg_real, arg_imag = lhs.split() + rhs_pieces = rhs.split() + exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1] + flags = rhs_pieces[2:] + + yield (id, fn, + float(arg_real), float(arg_imag), + float(exp_real), float(exp_imag), + flags + ) + +def args_to_str(args): + if isinstance(args[0],(list, tuple)): + return '(complex(%r, %r), complex(%r, %r))' % \ + (args[0][0], args[0][1], args[1][0], args[1][1]) + else: + return '(complex(%r, %r))' % (args[0], args[1]) + +def rAssertAlmostEqual(a, b, rel_err = 2e-15, abs_err = 5e-323, msg=''): + """Fail if the two floating-point numbers are not almost equal. + + Determine whether floating-point values a and b are equal to within + a (small) rounding error. The default values for rel_err and + abs_err are chosen to be suitable for platforms where a float is + represented by an IEEE 754 double. They allow an error of between + 9 and 19 ulps. + """ + + # special values testing + if isnan(a): + if isnan(b): + return + raise AssertionError(msg + '%r should be nan' % (b,)) + + if isinf(a): + if a == b: + return + raise AssertionError(msg + 'finite result where infinity expected: ' + 'expected %r, got %r' % (a, b)) + + # if both a and b are zero, check whether they have the same sign + # (in theory there are examples where it would be legitimate for a + # and b to have opposite signs; in practice these hardly ever + # occur). + if not a and not b: + # only check it if we are running on top of CPython >= 2.6 + if sys.version_info >= (2, 6) and copysign(1., a) != copysign(1., b): + raise AssertionError(msg + 'zero has wrong sign: expected %r, ' + 'got %r' % (a, b)) + + # if a-b overflows, or b is infinite, return False. Again, in + # theory there are examples where a is within a few ulps of the + # max representable float, and then b could legitimately be + # infinite. In practice these examples are rare. + try: + absolute_error = abs(b-a) + except OverflowError: + pass + else: + # test passes if either the absolute error or the relative + # error is sufficiently small. The defaults amount to an + # error of between 9 ulps and 19 ulps on an IEEE-754 compliant + # machine. + if absolute_error <= max(abs_err, rel_err * abs(a)): + return + raise AssertionError(msg + '%r and %r are not sufficiently close' % (a, b)) + +def test_specific_values(): + #if not float.__getformat__("double").startswith("IEEE"): + # return + + for id, fn, arg, expected, flags in parse_testfile2('rcomplex_testcases.txt'): + function = getattr(c, 'c_' + fn) + # + if 'divide-by-zero' in flags or 'invalid' in flags: + try: + actual = function(*arg) + except ValueError: + continue + else: + raise AssertionError('ValueError not raised in test ' + '%s: %s%s' % (id, fn, args_to_str(arg))) + if 'overflow' in flags: + try: + actual = function(*arg) + except OverflowError: + continue + else: + raise AssertionError('OverflowError not raised in test ' + '%s: %s%s' % (id, fn, args_to_str(arg))) + actual = function(*arg) + + if 'ignore-real-sign' in flags: + actual = (abs(actual[0]), actual[1]) + expected = (abs(expected[0]), expected[1]) + if 'ignore-imag-sign' in flags: + actual = (actual[0], abs(actual[1])) + expected = (expected[0], abs(expected[1])) + + # for the real part of the log function, we allow an + # absolute error of up to 2e-15. + if fn in ('log', 'log10'): + real_abs_err = 2e-15 + else: + real_abs_err = 5e-323 + + error_message = ( + '%s: %s%s\n' + 'Expected: complex(%r, %r)\n' + 'Received: complex(%r, %r)\n' + ) % (id, fn, args_to_str(arg), + expected[0], expected[1], + actual[0], actual[1]) + + rAssertAlmostEqual(expected[0], actual[0], + abs_err=real_abs_err, + msg=error_message) + rAssertAlmostEqual(expected[1], actual[1], + abs_err=real_abs_err, + msg=error_message) + + for id, fn, a, expected, flags in parse_testfile2('rcomplex_testcases2.txt'): + function = getattr(c, 'c_' + fn) + # + if 'divide-by-zero' in flags or 'invalid' in flags: + try: + actual = function(*a) + except ValueError: + continue + else: + raise AssertionError('ValueError not raised in test ' + '%s: %s%s' % (id, fn, args_to_str(a))) + if 'overflow' in flags: + try: + actual = function(*a) + except OverflowError: + continue + else: + raise AssertionError('OverflowError not raised in test ' + '%s: %s%s' % (id, fn, args_to_str(a))) + actual = function(*a) + + if 'ignore-real-sign' in flags: + actual = (abs(actual[0]), actual[1]) + expected = (abs(expected[0]), expected[1]) + if 'ignore-imag-sign' in flags: + actual = (actual[0], abs(actual[1])) + expected = (expected[0], abs(expected[1])) + + # for the real part of the log function, we allow an + # absolute error of up to 2e-15. + if fn in ('log', 'log10'): + real_abs_err = 2e-15 + else: + real_abs_err = 5e-323 + error_message = ( + '%s: %s%s\n' + 'Expected: complex(%r, %r)\n' + 'Received: complex(%r, %r)\n' + ) % (id, fn, args_to_str(a), + expected[0], expected[1], + actual[0], actual[1]) + + rAssertAlmostEqual(expected[0], actual[0], + abs_err=real_abs_err, + msg=error_message) + rAssertAlmostEqual(expected[1], actual[1], + abs_err=real_abs_err, + msg=error_message) From noreply at buildbot.pypy.org Mon Oct 1 23:44:35 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 1 Oct 2012 23:44:35 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: Merge within branch Message-ID: <20121001214435.572791C0012@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-complex2 Changeset: r57711:64ccb5d32b9f Date: 2012-10-01 23:28 +0200 http://bitbucket.org/pypy/pypy/changeset/64ccb5d32b9f/ Log: Merge within branch 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 @@ -262,7 +262,8 @@ def test_not_complex(self): from _numpypy import (radians, deg2rad, degrees, rad2deg, - isneginf, isposinf, logaddexp, logaddexp2, fmod) + isneginf, isposinf, logaddexp, logaddexp2, fmod, + max, min) raises(TypeError, radians, complex(90,90)) raises(TypeError, deg2rad, complex(90,90)) raises(TypeError, degrees, complex(90,90)) @@ -272,6 +273,8 @@ raises(TypeError, logaddexp, complex(1, 1), complex(3, 3)) raises(TypeError, logaddexp2, complex(1, 1), complex(3, 3)) raises (TypeError, fmod, complex(90,90), 3) + raises (TypeError, min, complex(90,90), 3) + raises (TypeError, max, complex(90,90), 3) def test_isnan_isinf(self): from _numpypy import isnan, isinf, array @@ -414,6 +417,38 @@ if got_err: raise AssertionError('Errors were printed to stdout') + def test_logical_ops(self): + from _numpypy import logical_and, logical_or, logical_xor, logical_not + + c1 = complex(1, 1) + c3 = complex(3, 0) + c0 = complex(0, 0) + assert (logical_and([True, False , True, True], [c1, c1, c3, c0]) + == [True, False, True, False]).all() + assert (logical_or([True, False, True, False], [c1, c3, c0, c0]) + == [True, True, True, False]).all() + assert (logical_xor([True, False, True, False], [c1, c3, c0, c0]) + == [False, True, True, False]).all() + assert (logical_not([c1, c0]) == [False, True]).all() + + def test_minimum(self): + from _numpypy import array, minimum + + a = array([-5.0+5j, -5.0-5j, -0.0-10j, 1.0+10j]) + b = array([ 3.0+10.0j, 3.0, -2.0+2.0j, -3.0+4.0j]) + c = minimum(a, b) + for i in range(4): + assert c[i] == min(a[i], b[i]) + + def test_maximum(self): + from _numpypy import array, maximum + + a = array([-5.0+5j, -5.0-5j, -0.0-10j, 1.0+10j]) + b = array([ 3.0+10.0j, 3.0, -2.0+2.0j, -3.0+4.0j]) + c = maximum(a, b) + for i in range(4): + assert c[i] == max(a[i], b[i]) + def test_basic(self): from _numpypy import (complex128, complex64, add, subtract as sub, multiply, divide, negative, abs, 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 @@ -55,7 +55,7 @@ def dispatcher(self, v): from pypy.module.micronumpy.interp_boxes import W_GenericBox assert isinstance(v, W_GenericBox) - return self.RealBoxType( + return self.box_component( func( self, self.for_computation(self.unbox(v)) @@ -991,6 +991,11 @@ rffi.cast(self._COMPONENTS_T, value), rffi.cast(self._COMPONENTS_T, 0.0)) + @specialize.argtype(1) + def box_component(self, value): + return self.ComponentBoxType( + rffi.cast(self._COMPONENTS_T, value)) + @specialize.argtype(1, 2) def box_complex(self, real, imag): return self.BoxType( @@ -1110,33 +1115,30 @@ def ge(self, v1, v2): return self._lt(v2, v1) or self._eq(v2, v1) + def _bool(self, v): + return bool(v[0]) or bool(v[1]) + @raw_binary_op def logical_and(self, v1, v2): - return bool(v1) and bool(v2) + return self._bool(v1) and self._bool(v2) @raw_binary_op def logical_or(self, v1, v2): - return bool(v1) or bool(v2) + return self._bool(v1) or self._bool(v2) @raw_unary_op def logical_not(self, v): - return not bool(v) + return not self._bool(v) @raw_binary_op def logical_xor(self, v1, v2): - return bool(v1) ^ bool(v2) + return self._bool(v1) ^ self._bool(v2) - def bool(self, v): - return bool(self.for_computation(self.unbox(v))) + def min(self, v1, v2): + return self.fmin(v1, v2) - @simple_binary_op def max(self, v1, v2): - return max(v1, v2) - - @simple_binary_op - def min(self, v1, v2): - return min(v1, v2) - + return self.fmax(v1, v2) @complex_binary_op def floordiv(self, v1, v2): @@ -1244,7 +1246,7 @@ def exp(self, v): if math.isinf(v[1]): if math.isinf(v[0]): - if v[0]<0: + if v[0] < 0: return 0., 0. return rfloat.INFINITY, rfloat.NAN elif (isfinite(v[0]) or \ @@ -1253,7 +1255,7 @@ try: return rcomplex.c_exp(*v) except OverflowError: - if v[1]==0: + if v[1] == 0: return rfloat.INFINITY, 0.0 return rfloat.INFINITY, rfloat.NAN @@ -1272,7 +1274,7 @@ # to implement seterr if math.isinf(v[1]): if math.isinf(v[0]): - if v[0]<0: + if v[0] < 0: return -1., 0. return rfloat.NAN, rfloat.NAN elif (isfinite(v[0]) or \ @@ -1283,7 +1285,7 @@ res = (res[0]-1, res[1]) return res except OverflowError: - if v[1]==0: + if v[1] == 0: return rfloat.INFINITY, 0.0 return rfloat.INFINITY, rfloat.NAN @@ -1325,7 +1327,7 @@ @complex_unary_op def arctan(self, v): - if v[0]==0 and (v[1]==1 or v[1] == -1): + if v[0] == 0 and (v[1] == 1 or v[1] == -1): #This is the place to print a "runtime warning" return rfloat.NAN, math.copysign(rfloat.INFINITY, v[1]) return rcomplex.c_atan(*v) @@ -1438,7 +1440,7 @@ @complex_unary_op def log1p(self, v): try: - return rcomplex.c_log(v[0]+1, v[1]) + return rcomplex.c_log(v[0] + 1, v[1]) except OverflowError: return -rfloat.INFINITY, 0 except ValueError: @@ -1450,7 +1452,7 @@ T = rffi.CHAR _COMPONENTS_T = rffi.FLOAT BoxType = interp_boxes.W_Complex64Box - RealBoxType = interp_boxes.W_Float32Box + ComponentBoxType = interp_boxes.W_Float32Box @@ -1462,7 +1464,7 @@ T = rffi.CHAR _COMPONENTS_T = rffi.DOUBLE BoxType = interp_boxes.W_Complex128Box - RealBoxType = interp_boxes.W_Float64Box + ComponentBoxType = interp_boxes.W_Float64Box NonNativeComplex128 = Complex128 From noreply at buildbot.pypy.org Mon Oct 1 23:44:36 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 1 Oct 2012 23:44:36 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: fix merge Message-ID: <20121001214436.87F4C1C0012@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-complex2 Changeset: r57712:8242ffdd4fb8 Date: 2012-10-01 23:43 +0200 http://bitbucket.org/pypy/pypy/changeset/8242ffdd4fb8/ Log: fix merge 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 @@ -273,8 +273,6 @@ raises(TypeError, logaddexp, complex(1, 1), complex(3, 3)) raises(TypeError, logaddexp2, complex(1, 1), complex(3, 3)) raises (TypeError, fmod, complex(90,90), 3) - raises (TypeError, min, complex(90,90), 3) - raises (TypeError, max, complex(90,90), 3) def test_isnan_isinf(self): from _numpypy import isnan, isinf, array diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py --- a/pypy/rlib/rcomplex.py +++ b/pypy/rlib/rcomplex.py @@ -68,7 +68,7 @@ def c_pow(x, y): (r1, i1), (r2, i2) = x, y if i1 == 0 and i2 == 0 and r1>=0: - rr = pow(r1, r2) + rr = math.pow(r1, r2) ir = 0. elif r2 == 0.0 and i2 == 0.0: rr, ir = 1, 0 From noreply at buildbot.pypy.org Mon Oct 1 23:44:37 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 1 Oct 2012 23:44:37 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: comment out complex64 math tests 'for now' Message-ID: <20121001214437.D040B1C0012@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-complex2 Changeset: r57713:47e3d7309b1b Date: 2012-10-01 23:44 +0200 http://bitbucket.org/pypy/pypy/changeset/47e3d7309b1b/ Log: comment out complex64 math tests 'for now' 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 @@ -547,7 +547,7 @@ ) for complex_, abs_err, testcases in (\ (np.complex128, 5e-323, self.testcases128), - (np.complex64, 5e-32, self.testcases64), + # (np.complex64, 5e-32, self.testcases64), ): for id, fn, ar, ai, er, ei, flags in parse_testfile(testcases): arg = complex_(complex(ar, ai)) From noreply at buildbot.pypy.org Tue Oct 2 16:01:32 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 2 Oct 2012 16:01:32 +0200 (CEST) Subject: [pypy-commit] pypy py3k: remove debug print Message-ID: <20121002140132.41A0A1C00EE@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57714:b66b8ad37991 Date: 2012-10-02 11:18 +0200 http://bitbucket.org/pypy/pypy/changeset/b66b8ad37991/ Log: remove debug print diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -1397,7 +1397,6 @@ if not s: return '%s()' % (s.__class__.__name__,) listrepr = repr([x for x in s]) - print('XXX', listrepr) if type(s) is set: return '{%s}' % (listrepr[1:-1],) else: From noreply at buildbot.pypy.org Tue Oct 2 16:01:33 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 2 Oct 2012 16:01:33 +0200 (CEST) Subject: [pypy-commit] pypy py3k: implement the - operator between dict views and sets Message-ID: <20121002140133.75BE41C03F2@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57715:3cc63ec8ea3d Date: 2012-10-02 11:44 +0200 http://bitbucket.org/pypy/pypy/changeset/3cc63ec8ea3d/ Log: implement the - operator between dict views and sets diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -1029,6 +1029,14 @@ xor__DictViewItems_DictViewItems = xor__DictViewKeys_DictViewKeys xor__DictViewItems_settypedef = xor__DictViewKeys_DictViewKeys +def sub__DictViewKeys_DictViewKeys(space, w_dictview, w_otherview): + w_set = space.call_function(space.w_set, w_dictview) + space.call_method(w_set, "difference_update", w_otherview) + return w_set +sub__DictViewKeys_settypedef = sub__DictViewKeys_DictViewKeys +sub__DictViewItems_DictViewItems = sub__DictViewKeys_DictViewKeys +sub__DictViewItems_settypedef = sub__DictViewKeys_DictViewKeys + # ____________________________________________________________ from pypy.objspace.std import dicttype diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -745,6 +745,13 @@ assert d1.keys() ^ set(d2.keys()) == set('ac') assert d1.keys() ^ set(d3.keys()) == set('abde') + assert d1.keys() - d1.keys() == set() + assert d1.keys() - d2.keys() == set('a') + assert d1.keys() - d3.keys() == set('ab') + assert d1.keys() - set(d1.keys()) == set() + assert d1.keys() - set(d2.keys()) == set('a') + assert d1.keys() - set(d3.keys()) == set('ab') + def test_items_set_operations(self): d1 = {'a': 1, 'b': 2} d2 = {'a': 2, 'b': 2} @@ -773,6 +780,10 @@ assert (d1.items() ^ d3.items() == set([('a', 1), ('b', 2), ('d', 4), ('e', 5)])) + assert d1.items() - d1.items() == set() + assert d1.items() - d2.items() == set([('a', 1)]) + assert d1.items() - d3.items() == set([('a', 1), ('b', 2)]) + class AppTestStrategies(object): def setup_class(cls): From noreply at buildbot.pypy.org Tue Oct 2 16:01:34 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 2 Oct 2012 16:01:34 +0200 (CEST) Subject: [pypy-commit] pypy py3k: make sure that set operations on dict views work with sequences in general and when the dictview is the right operand. Also, reduce a bit the duplicated code with some metaprogramming Message-ID: <20121002140134.A5AE11C0E8B@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57716:25ca3d2037d4 Date: 2012-10-02 14:45 +0200 http://bitbucket.org/pypy/pypy/changeset/25ca3d2037d4/ Log: make sure that set operations on dict views work with sequences in general and when the dictview is the right operand. Also, reduce a bit the duplicated code with some metaprogramming diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -1005,37 +1005,34 @@ repr__DictViewItems = repr__DictViewKeys repr__DictViewValues = repr__DictViewKeys -def and__DictViewKeys_DictViewKeys(space, w_dictview, w_otherview): - w_set = space.call_function(space.w_set, w_dictview) - space.call_method(w_set, "intersection_update", w_otherview) - return w_set -and__DictViewKeys_settypedef = and__DictViewKeys_DictViewKeys -and__DictViewItems_DictViewItems = and__DictViewKeys_DictViewKeys -and__DictViewItems_settypedef = and__DictViewKeys_DictViewKeys -def or__DictViewKeys_DictViewKeys(space, w_dictview, w_otherview): - w_set = space.call_function(space.w_set, w_dictview) - space.call_method(w_set, "update", w_otherview) - return w_set -or__DictViewKeys_settypedef = or__DictViewKeys_DictViewKeys -or__DictViewItems_DictViewItems = or__DictViewKeys_DictViewKeys -or__DictViewItems_settypedef = or__DictViewKeys_DictViewKeys +def generate_setops(): + OPLIST = [ + ('and', 'intersection_update'), + ('or', 'update'), + ('xor', 'symmetric_difference_update'), + ('sub', 'difference_update'), + ] -def xor__DictViewKeys_DictViewKeys(space, w_dictview, w_otherview): - w_set = space.call_function(space.w_set, w_dictview) - space.call_method(w_set, "symmetric_difference_update", w_otherview) - return w_set -xor__DictViewKeys_settypedef = xor__DictViewKeys_DictViewKeys -xor__DictViewItems_DictViewItems = xor__DictViewKeys_DictViewKeys -xor__DictViewItems_settypedef = xor__DictViewKeys_DictViewKeys + for (opname, methodname) in OPLIST: + src = py.code.Source(""" + def {opname}__DictViewKeys_ANY(space, w_dictview, w_other): + w_set = space.call_function(space.w_set, w_dictview) + space.call_method(w_set, '{methodname}', w_other) + return w_set -def sub__DictViewKeys_DictViewKeys(space, w_dictview, w_otherview): - w_set = space.call_function(space.w_set, w_dictview) - space.call_method(w_set, "difference_update", w_otherview) - return w_set -sub__DictViewKeys_settypedef = sub__DictViewKeys_DictViewKeys -sub__DictViewItems_DictViewItems = sub__DictViewKeys_DictViewKeys -sub__DictViewItems_settypedef = sub__DictViewKeys_DictViewKeys + def {opname}__ANY_DictViewKeys(space, w_other, w_dictview): + w_set = space.call_function(space.w_set, w_dictview) + space.call_method(w_set, '{methodname}', w_other) + return w_set + + {opname}__DictViewItems_ANY = {opname}__DictViewKeys_ANY + {opname}__ANY_DictViewItems = {opname}__ANY_DictViewKeys + """.format(opname=opname, methodname=methodname)) + exec src.compile() in globals() + +generate_setops() + # ____________________________________________________________ diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -784,7 +784,16 @@ assert d1.items() - d2.items() == set([('a', 1)]) assert d1.items() - d3.items() == set([('a', 1), ('b', 2)]) - + def test_keys_items_set_operations_any_type(self): + d = {1: 'a', 2: 'b', 3: 'c'} + assert d.keys() & {1} == {1} + assert d.keys() & {1: 'foo'} == {1} + assert d.keys() & [1, 2] == {1, 2} + # + assert {1} & d.keys() == {1} + assert {1: 'foo'} & d.keys() == {1} + assert [1, 2] & d.keys() == {1, 2} + class AppTestStrategies(object): def setup_class(cls): if option.runappdirect: From noreply at buildbot.pypy.org Tue Oct 2 16:01:35 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 2 Oct 2012 16:01:35 +0200 (CEST) Subject: [pypy-commit] pypy py3k: test&fix for the only set operator which is not symmetric Message-ID: <20121002140135.F0A1B1C0E98@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57717:3110468abb0a Date: 2012-10-02 14:56 +0200 http://bitbucket.org/pypy/pypy/changeset/3110468abb0a/ Log: test&fix for the only set operator which is not symmetric diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -1022,8 +1022,8 @@ return w_set def {opname}__ANY_DictViewKeys(space, w_other, w_dictview): - w_set = space.call_function(space.w_set, w_dictview) - space.call_method(w_set, '{methodname}', w_other) + w_set = space.call_function(space.w_set, w_other) + space.call_method(w_set, '{methodname}', w_dictview) return w_set {opname}__DictViewItems_ANY = {opname}__DictViewKeys_ANY diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -793,6 +793,9 @@ assert {1} & d.keys() == {1} assert {1: 'foo'} & d.keys() == {1} assert [1, 2] & d.keys() == {1, 2} + # + assert d.keys() - {1} == {2, 3} + assert {1, 4} - d.keys() == {4} class AppTestStrategies(object): def setup_class(cls): From noreply at buildbot.pypy.org Tue Oct 2 16:01:37 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 2 Oct 2012 16:01:37 +0200 (CEST) Subject: [pypy-commit] pypy py3k: implement containment operators for dict views Message-ID: <20121002140137.4F5011C0E9D@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57718:f35922ab0bb5 Date: 2012-10-02 16:01 +0200 http://bitbucket.org/pypy/pypy/changeset/f35922ab0bb5/ Log: implement containment operators for dict views diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -1031,6 +1031,24 @@ """.format(opname=opname, methodname=methodname)) exec src.compile() in globals() + + for opname in ['lt', 'le', 'eq', 'ne', 'ge', 'gt']: + src = py.code.Source(""" + def {opname}__DictViewKeys_ANY(space, w_dictview, w_other): + w_left = space.call_function(space.w_set, w_dictview) + w_right = space.call_function(space.w_set, w_other) + return space.{opname}(w_left, w_right) + + def {opname}__ANY_DictViewKeys(space, w_other, w_dictview): + w_left = space.call_function(space.w_set, w_other) + w_right = space.call_function(space.w_set, w_dictview) + return space.{opname}(w_left, w_right) + + {opname}__DictViewItems_ANY = {opname}__DictViewKeys_ANY + {opname}__ANY_DictViewItems = {opname}__ANY_DictViewKeys + """.format(opname=opname)) + exec src.compile() in globals() + generate_setops() diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -796,7 +796,53 @@ # assert d.keys() - {1} == {2, 3} assert {1, 4} - d.keys() == {4} - + + def test_keys_items_contained(self): + def helper(fn): + empty = fn(dict()) + empty2 = fn(dict()) + smaller = fn({1:1, 2:2}) + larger = fn({1:1, 2:2, 3:3}) + larger2 = fn({1:1, 2:2, 3:3}) + larger3 = fn({4:1, 2:2, 3:3}) + + assert smaller < larger + assert smaller <= larger + assert larger > smaller + assert larger >= smaller + + assert not smaller >= larger + assert not smaller > larger + assert not larger <= smaller + assert not larger < smaller + + assert not smaller < larger3 + assert not smaller <= larger3 + assert not larger3 > smaller + assert not larger3 >= smaller + + # Inequality strictness + assert larger2 >= larger + assert larger2 <= larger + assert not larger2 > larger + assert not larger2 < larger + + assert larger == larger2 + assert smaller != larger + + # There is an optimization on the zero-element case. + assert empty == empty2 + assert not empty != empty2 + assert not empty == smaller + assert empty != smaller + + # With the same size, an elementwise compare happens + assert larger != larger3 + assert not larger == larger3 + + helper(lambda x: x.keys()) + helper(lambda x: x.items()) + class AppTestStrategies(object): def setup_class(cls): if option.runappdirect: From noreply at buildbot.pypy.org Tue Oct 2 16:31:19 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 2 Oct 2012 16:31:19 +0200 (CEST) Subject: [pypy-commit] pypy py3k: hg merge default Message-ID: <20121002143119.C2D9A1C0E8B@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57719:4fcb841ab9d1 Date: 2012-10-02 16:31 +0200 http://bitbucket.org/pypy/pypy/changeset/4fcb841ab9d1/ Log: hg merge default diff too long, truncating to 2000 out of 2428 lines diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -23,7 +23,7 @@ The tools required to cross translate from a Linux based host to an ARM based Linux target are: -- A checkout of PyPy's arm-backend-2 branch. +- A checkout of PyPy (default branch). - The GCC ARM cross compiler (on Ubuntu it is the ``gcc-arm-linux-gnueabi package``) but other toolchains should also work. - Scratchbox 2, a cross-compilation engine (``scratchbox2`` Ubuntu package). - A 32-bit PyPy or Python. @@ -147,4 +147,4 @@ return 0 def target(*args): - return main, None \ No newline at end of file + return main, None diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -115,13 +115,16 @@ which data structures would be more appropriate? For example, a dict implemented as a hash table will suffer "stm collisions" in all threads whenever one thread writes anything to it; but there could be other - implementations. + implementations. Maybe alternate strategies can be implemented at the + level of the Python interpreter (see list/dict strategies, + ``pypy/objspace/std/{list,dict}object.py``). * More generally, there is the idea that we would need some kind of "debugger"-like tool to "debug" things that are not bugs, but stm conflicts. How would this tool look like to the end Python programmers? Like a profiler? Or like a debugger with breakpoints - on aborted transactions? + on aborted transactions? It would probably be all app-level, with + a few hooks e.g. for transaction conflicts. * Find good ways to have libraries using internally threads and atomics, but not exposing threads to the user. Right now there is a rough draft 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 @@ -18,6 +18,7 @@ .. branch: numpypy_count_nonzero .. branch: numpy-refactor Remove numpy lazy evaluation and simplify everything +.. branch: numpy-reintroduce-jit-drivers .. branch: numpy-fancy-indexing Support for array[array-of-ints] in numpy .. branch: even-more-jit-hooks 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 @@ -490,7 +490,7 @@ if f_type == F_BLOCK_LOOP: self.emit_jump(ops.CONTINUE_LOOP, block, True) break - if self.frame_blocks[i][0] == F_BLOCK_FINALLY_END: + if f_type == F_BLOCK_FINALLY_END: self.error("'continue' not supported inside 'finally' " \ "clause", cont) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -296,7 +296,6 @@ """Base class for the interpreter-level implementations of object spaces. http://pypy.readthedocs.org/en/latest/objspace.html""" - full_exceptions = True # full support for exceptions (normalization & more) py3k = True # are we interpreting py3k bytecode? def __init__(self, config=None): @@ -1099,13 +1098,9 @@ def exception_is_valid_obj_as_class_w(self, w_obj): if not self.isinstance_w(w_obj, self.w_type): return False - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_obj, self.w_BaseException)) def exception_is_valid_class_w(self, w_cls): - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_cls, self.w_BaseException)) def exception_getclass(self, w_obj): @@ -1378,7 +1373,7 @@ if not self.is_true(self.isinstance(w_obj, self.w_str)): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) - return self.str_w(w_obj) + return self.str_w(w_obj) def unicode_w(self, w_obj): return w_obj.unicode_w(self) @@ -1698,7 +1693,7 @@ 'ValueError', 'ZeroDivisionError', ] - + if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -47,11 +47,6 @@ def async(self, space): "Check if this is an exception that should better not be caught." - if not space.full_exceptions: - # flow objspace does not support such exceptions and more - # importantly, raises KeyboardInterrupt if you try to access - # space.w_KeyboardInterrupt - return False return (self.match(space, space.w_SystemExit) or self.match(space, space.w_KeyboardInterrupt)) @@ -172,9 +167,7 @@ # Or 'Class' can also be an old-style class and 'inst' an old-style # instance of it. # - # Note that 'space.full_exceptions' is set to False by the flow - # object space; in this case we must assume that we are in a - # non-advanced case, and ignore the advanced cases. Old-style + # The flow object space only deals with non-advanced case. Old-style # classes and instances *are* advanced. # # input (w_type, w_value)... becomes... advanced case? @@ -189,9 +182,8 @@ # w_type = self.w_type w_value = self.get_w_value(space) - if space.full_exceptions: - while space.is_true(space.isinstance(w_type, space.w_tuple)): - w_type = space.getitem(w_type, space.wrap(0)) + while space.is_true(space.isinstance(w_type, space.w_tuple)): + w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): # this is for all cases of the form (Class, something) @@ -205,8 +197,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.full_exceptions and space.is_true( - space.isinstance(w_value, space.w_tuple)): + if space.is_true(space.isinstance(w_value, space.w_tuple)): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -950,14 +950,6 @@ def appcaller(space, *args_w): if not isinstance(space, ObjSpace): raise TypeError("first argument must be a space instance.") - # redirect if the space handles this specially - # XXX can this be factored a bit less flow space dependently? - if hasattr(space, 'specialcases'): - sc = space.specialcases - if ApplevelClass in sc: - ret_w = sc[ApplevelClass](space, self, name, args_w) - if ret_w is not None: # it was RPython - return ret_w # the last argument can be an Arguments w_func = self.wget(space, name) if not args_w: diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -224,7 +224,7 @@ return next_instr if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: - return self.jump_absolute(oparg, next_instr, ec) + return self.jump_absolute(oparg, ec) if we_are_translated(): for opdesc in unrolling_all_opcode_descs: @@ -497,7 +497,6 @@ operror.set_traceback(tb) raise operror - def LOAD_LOCALS(self, oparg, next_instr): self.pushvalue(self.w_locals) @@ -821,7 +820,8 @@ def YIELD_VALUE(self, oparg, next_instr): raise Yield - def jump_absolute(self, jumpto, next_instr, ec): + def jump_absolute(self, jumpto, ec): + # this function is overridden by pypy.module.pypyjit.interp_jit check_nonneg(jumpto) return jumpto @@ -911,7 +911,6 @@ def WITH_CLEANUP(self, oparg, next_instr): # see comment in END_FINALLY for stack state - # This opcode changed a lot between CPython versions w_unroller = self.popvalue() w_exitfunc = self.popvalue() self.pushvalue(w_unroller) @@ -1174,10 +1173,6 @@ 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): """Signals a 'return' statement. Argument is the wrapped object to return.""" @@ -1188,12 +1183,6 @@ def nomoreblocks(self): return self.w_returnvalue - def state_unpack_variables(self, space): - return [self.w_returnvalue] - def state_pack_variables(space, w_returnvalue): - return SReturnValue(w_returnvalue) - state_pack_variables = staticmethod(state_pack_variables) - class SApplicationException(SuspendedUnroller): """Signals an application-level exception (i.e. an OperationException).""" @@ -1208,13 +1197,6 @@ """Signals a 'break' statement.""" _immutable_ = True kind = 0x04 - - def state_unpack_variables(self, space): - return [] - def state_pack_variables(space): - return SBreakLoop.singleton - state_pack_variables = staticmethod(state_pack_variables) - SBreakLoop.singleton = SBreakLoop() class SContinueLoop(SuspendedUnroller): @@ -1225,12 +1207,6 @@ def __init__(self, jump_to): self.jump_to = jump_to - def state_unpack_variables(self, space): - return [space.wrap(self.jump_to)] - def state_pack_variables(space, w_jump_to): - return SContinueLoop(space.int_w(w_jump_to)) - state_pack_variables = staticmethod(state_pack_variables) - class FrameBlock(object): """Abstract base class for frame blocks from the blockstack, @@ -1285,7 +1261,9 @@ # and jump to the beginning of the loop, stored in the # exception's argument frame.append_block(self) - return r_uint(unroller.jump_to) + jumpto = unroller.jump_to + ec = frame.space.getexecutioncontext() + return r_uint(frame.jump_absolute(jumpto, ec)) else: # jump to the end of the loop self.cleanupstack(frame) @@ -1329,8 +1307,7 @@ self.cleanupstack(frame) assert isinstance(unroller, SApplicationException) operationerr = unroller.operr - if frame.space.full_exceptions: - operationerr.normalize_exception(frame.space) + operationerr.normalize_exception(frame.space) # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. @@ -1365,8 +1342,7 @@ operationerr = None if isinstance(unroller, SApplicationException): operationerr = unroller.operr - if frame.space.full_exceptions: - operationerr.normalize_exception(frame.space) + operationerr.normalize_exception(frame.space) frame.pushvalue(frame.space.wrap(unroller)) if operationerr and self.restore_last_exception: frame.last_exception = operationerr @@ -1380,8 +1356,7 @@ restore_last_exception = False def handle(self, frame, unroller): - if (frame.space.full_exceptions and - isinstance(unroller, SApplicationException)): + if isinstance(unroller, SApplicationException): unroller.operr.normalize_exception(frame.space) return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -131,13 +131,13 @@ def get_latest_value_float(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a float.""" + or from 'args' if it was a FINISH). Returns a FLOATSTORAGE.""" raise NotImplementedError def get_latest_value_ref(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a ptr or an obj.""" + or from 'args' if it was a FINISH). Returns a GCREF.""" raise NotImplementedError def get_latest_value_count(self): 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 @@ -981,7 +981,7 @@ assert strlenaddr == cast(BVoidP, strlen) def test_read_variable(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BVoidP = new_pointer_type(new_void_type()) ll = find_and_load_library('c') @@ -989,7 +989,7 @@ assert stderr == cast(BVoidP, _testfunc(8)) def test_read_variable_as_unknown_length_array(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BCharP = new_pointer_type(new_primitive_type("char")) BArray = new_array_type(BCharP, None) @@ -999,7 +999,7 @@ # ^^ and not 'char[]', which is basically not allowed and would crash def test_write_variable(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BVoidP = new_pointer_type(new_void_type()) ll = find_and_load_library('c') 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 @@ -244,6 +244,7 @@ def setitem_index(self, space, index, value): self.setitem(self._lookup_by_unwrapped_index(space, index), value) + @jit.unroll_safe def _single_item_index(self, space, w_idx): """ Return an index of single item if possible, otherwise raises IndexError 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 @@ -9,8 +9,8 @@ from pypy.interpreter.error import OperationError from pypy.module.micronumpy import interp_boxes from pypy.module.micronumpy.interp_dtype import get_dtype_cache -from pypy.module.micronumpy.interp_numarray import (Scalar, BaseArray, - scalar_w, W_NDimArray, array) +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.interp_numarray import array from pypy.module.micronumpy.interp_arrayops import where from pypy.module.micronumpy import interp_ufuncs from pypy.rlib.objectmodel import specialize, instantiate @@ -147,7 +147,8 @@ def is_true(self, w_obj): assert isinstance(w_obj, BoolObject) - return w_obj.boolval + return False + #return w_obj.boolval def is_w(self, w_obj, w_what): return w_obj is w_what @@ -274,7 +275,7 @@ if isinstance(w_index, FloatObject): w_index = IntObject(int(w_index.floatval)) w_val = self.expr.execute(interp) - assert isinstance(arr, BaseArray) + assert isinstance(arr, W_NDimArray) arr.descr_setitem(interp.space, w_index, w_val) def __repr__(self): @@ -302,11 +303,11 @@ w_rhs = self.rhs.wrap(interp.space) else: w_rhs = self.rhs.execute(interp) - if not isinstance(w_lhs, BaseArray): + if not isinstance(w_lhs, W_NDimArray): # scalar dtype = get_dtype_cache(interp.space).w_float64dtype - w_lhs = scalar_w(interp.space, dtype, w_lhs) - assert isinstance(w_lhs, BaseArray) + w_lhs = W_NDimArray.new_scalar(interp.space, dtype, w_lhs) + assert isinstance(w_lhs, W_NDimArray) if self.name == '+': w_res = w_lhs.descr_add(interp.space, w_rhs) elif self.name == '*': @@ -314,17 +315,16 @@ elif self.name == '-': w_res = w_lhs.descr_sub(interp.space, w_rhs) elif self.name == '->': - assert not isinstance(w_rhs, Scalar) if isinstance(w_rhs, FloatObject): w_rhs = IntObject(int(w_rhs.floatval)) - assert isinstance(w_lhs, BaseArray) + assert isinstance(w_lhs, W_NDimArray) w_res = w_lhs.descr_getitem(interp.space, w_rhs) else: raise NotImplementedError - if (not isinstance(w_res, BaseArray) and + if (not isinstance(w_res, W_NDimArray) and not isinstance(w_res, interp_boxes.W_GenericBox)): dtype = get_dtype_cache(interp.space).w_float64dtype - w_res = scalar_w(interp.space, dtype, w_res) + w_res = W_NDimArray.new_scalar(interp.space, dtype, w_res) return w_res def __repr__(self): @@ -416,7 +416,7 @@ def execute(self, interp): arr = self.args[0].execute(interp) - if not isinstance(arr, BaseArray): + if not isinstance(arr, W_NDimArray): raise ArgumentNotAnArray if self.name in SINGLE_ARG_FUNCTIONS: if len(self.args) != 1 and self.name != 'sum': @@ -440,20 +440,21 @@ elif self.name == "unegative": neg = interp_ufuncs.get(interp.space).negative w_res = neg.call(interp.space, [arr]) + elif self.name == "cos": + cos = interp_ufuncs.get(interp.space).cos + w_res = cos.call(interp.space, [arr]) elif self.name == "flat": w_res = arr.descr_get_flatiter(interp.space) elif self.name == "tostring": arr.descr_tostring(interp.space) w_res = None - elif self.name == "count_nonzero": - w_res = arr.descr_count_nonzero(interp.space) else: assert False # unreachable code elif self.name in TWO_ARG_FUNCTIONS: if len(self.args) != 2: raise ArgumentMismatch arg = self.args[1].execute(interp) - if not isinstance(arg, BaseArray): + if not isinstance(arg, W_NDimArray): raise ArgumentNotAnArray if self.name == "dot": w_res = arr.descr_dot(interp.space, arg) @@ -466,9 +467,9 @@ raise ArgumentMismatch arg1 = self.args[1].execute(interp) arg2 = self.args[2].execute(interp) - if not isinstance(arg1, BaseArray): + if not isinstance(arg1, W_NDimArray): raise ArgumentNotAnArray - if not isinstance(arg2, BaseArray): + if not isinstance(arg2, W_NDimArray): raise ArgumentNotAnArray if self.name == "where": w_res = where(interp.space, arr, arg1, arg2) @@ -476,7 +477,7 @@ assert False else: raise WrongFunctionName - if isinstance(w_res, BaseArray): + if isinstance(w_res, W_NDimArray): return w_res if isinstance(w_res, FloatObject): dtype = get_dtype_cache(interp.space).w_float64dtype @@ -488,7 +489,7 @@ dtype = w_res.get_dtype(interp.space) else: dtype = None - return scalar_w(interp.space, dtype, w_res) + return W_NDimArray.new_scalar(interp.space, dtype, w_res) _REGEXES = [ ('-?[\d\.]+', 'number'), 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 @@ -129,6 +129,8 @@ self._prepare_array_index(space, w_index) shape = res_shape + self.get_shape()[len(indexes):] res = W_NDimArray.from_shape(shape, self.get_dtype(), self.get_order()) + if not res.get_size(): + return res return loop.getitem_array_int(space, self, res, iter_shape, indexes, prefix) @@ -514,7 +516,7 @@ if self.get_size() == 0: raise OperationError(space.w_ValueError, space.wrap("Can't call %s on zero-size arrays" % op_name)) - return space.wrap(loop.argmin_argmax(op_name, self)) + return space.wrap(getattr(loop, 'arg' + op_name)(self)) return func_with_new_name(impl, "reduce_arg%s_impl" % op_name) descr_argmax = _reduce_argmax_argmin_impl("max") 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 @@ -258,7 +258,7 @@ return out shape = shape_agreement(space, w_obj.get_shape(), out, broadcast_down=False) - return loop.call1(shape, self.func, self.name, calc_dtype, res_dtype, + return loop.call1(shape, self.func, calc_dtype, res_dtype, w_obj, out) @@ -322,7 +322,7 @@ return out 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(new_shape, self.func, self.name, calc_dtype, + return loop.call2(new_shape, self.func, calc_dtype, res_dtype, w_lhs, w_rhs, out) 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 @@ -1,21 +1,34 @@ """ This file is the main run loop as well as evaluation loops for various -signatures +operations. This is the place to look for all the computations that iterate +over all the array elements. """ -from pypy.rlib.objectmodel import specialize from pypy.rlib.rstring import StringBuilder from pypy.rlib import jit from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy.base import W_NDimArray -def call2(shape, func, name, calc_dtype, res_dtype, w_lhs, w_rhs, out): +call2_driver = jit.JitDriver(name='numpy_call2', + greens = ['shapelen', 'func', 'calc_dtype', + 'res_dtype'], + reds = ['shape', 'w_lhs', 'w_rhs', 'out', + 'left_iter', 'right_iter', 'out_iter']) + +def call2(shape, func, calc_dtype, res_dtype, w_lhs, w_rhs, out): if out is None: out = W_NDimArray.from_shape(shape, res_dtype) left_iter = w_lhs.create_iter(shape) right_iter = w_rhs.create_iter(shape) out_iter = out.create_iter(shape) + shapelen = len(shape) while not out_iter.done(): + call2_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, res_dtype=res_dtype, + shape=shape, w_lhs=w_lhs, w_rhs=w_rhs, + out=out, + left_iter=left_iter, right_iter=right_iter, + out_iter=out_iter) w_left = left_iter.getitem().convert_to(calc_dtype) w_right = right_iter.getitem().convert_to(calc_dtype) out_iter.setitem(func(calc_dtype, w_left, w_right).convert_to( @@ -25,30 +38,56 @@ out_iter.next() return out -def call1(shape, func, name, calc_dtype, res_dtype, w_obj, out): +call1_driver = jit.JitDriver(name='numpy_call1', + greens = ['shapelen', 'func', 'calc_dtype', + 'res_dtype'], + reds = ['shape', 'w_obj', 'out', 'obj_iter', + 'out_iter']) + +def call1(shape, func, calc_dtype, res_dtype, w_obj, out): if out is None: out = W_NDimArray.from_shape(shape, res_dtype) obj_iter = w_obj.create_iter(shape) out_iter = out.create_iter(shape) + shapelen = len(shape) while not out_iter.done(): + call1_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, res_dtype=res_dtype, + shape=shape, w_obj=w_obj, out=out, + obj_iter=obj_iter, out_iter=out_iter) elem = obj_iter.getitem().convert_to(calc_dtype) out_iter.setitem(func(calc_dtype, elem).convert_to(res_dtype)) out_iter.next() obj_iter.next() return out +setslice_driver = jit.JitDriver(name='numpy_setslice', + greens = ['shapelen', 'dtype'], + reds = ['target', 'source', 'target_iter', + 'source_iter']) + def setslice(shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) source_iter = source.create_iter(shape) dtype = target.dtype + shapelen = len(shape) while not target_iter.done(): + setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + target=target, source=source, + target_iter=target_iter, + source_iter=source_iter) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target +reduce_driver = jit.JitDriver(name='numpy_reduce', + greens = ['shapelen', 'func', 'done_func', + 'calc_dtype', 'identity'], + reds = ['obj', 'obj_iter', 'cur_value']) + def compute_reduce(obj, calc_dtype, func, done_func, identity): obj_iter = obj.create_iter(obj.get_shape()) if identity is None: @@ -56,7 +95,12 @@ obj_iter.next() else: cur_value = identity.convert_to(calc_dtype) + shapelen = len(obj.get_shape()) while not obj_iter.done(): + reduce_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, identity=identity, + done_func=done_func, obj=obj, + obj_iter=obj_iter, cur_value=cur_value) rval = obj_iter.getitem().convert_to(calc_dtype) if done_func is not None and done_func(calc_dtype, rval): return rval @@ -70,6 +114,11 @@ arr_iter.setitem(box) arr_iter.next() +where_driver = jit.JitDriver(name='numpy_where', + greens = ['shapelen', 'dtype', 'arr_dtype'], + reds = ['shape', 'arr', 'x', 'y','arr_iter', 'out', + 'x_iter', 'y_iter', 'iter', 'out_iter']) + def where(out, shape, arr, x, y, dtype): out_iter = out.create_iter(shape) arr_iter = arr.create_iter(shape) @@ -83,7 +132,13 @@ iter = y_iter else: iter = x_iter + shapelen = len(shape) while not iter.done(): + where_driver.jit_merge_point(shapelen=shapelen, shape=shape, + dtype=dtype, iter=iter, x_iter=x_iter, + y_iter=y_iter, arr_iter=arr_iter, + arr=arr, x=x, y=y, arr_dtype=arr_dtype, + out_iter=out_iter, out=out) w_cond = arr_iter.getitem() if arr_dtype.itemtype.bool(w_cond): w_val = x_iter.getitem().convert_to(dtype) @@ -96,12 +151,24 @@ y_iter.next() return out +axis_reduce__driver = jit.JitDriver(name='numpy_axis_reduce', + greens=['shapelen', 'func', 'dtype', + 'identity'], + reds=['axis', 'arr', 'out', 'shape', + 'out_iter', 'arr_iter']) + def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): out_iter = out.create_axis_iter(arr.get_shape(), axis) arr_iter = arr.create_iter(arr.get_shape()) if identity is not None: identity = identity.convert_to(dtype) + shapelen = len(shape) while not out_iter.done(): + axis_reduce__driver.jit_merge_point(shapelen=shapelen, func=func, + dtype=dtype, identity=identity, + axis=axis, arr=arr, out=out, + shape=shape, out_iter=out_iter, + arr_iter=arr_iter) w_val = arr_iter.getitem().convert_to(dtype) if out_iter.first_line: if identity is not None: @@ -114,23 +181,41 @@ out_iter.next() return out - at specialize.arg(0) -def argmin_argmax(op_name, arr): - result = 0 - idx = 1 - dtype = arr.get_dtype() - iter = arr.create_iter(arr.get_shape()) - cur_best = iter.getitem() - iter.next() - while not iter.done(): - w_val = iter.getitem() - new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) - if dtype.itemtype.ne(new_best, cur_best): - result = idx - cur_best = new_best + +def _new_argmin_argmax(op_name): + arg_driver = jit.JitDriver(name='numpy_' + op_name, + greens = ['shapelen', 'dtype'], + reds = ['result', 'idx', 'cur_best', 'arr', + 'iter']) + + def argmin_argmax(arr): + result = 0 + idx = 1 + dtype = arr.get_dtype() + iter = arr.create_iter(arr.get_shape()) + cur_best = iter.getitem() iter.next() - idx += 1 - return result + shapelen = len(arr.get_shape()) + while not iter.done(): + arg_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + result=result, idx=idx, + cur_best=cur_best, arr=arr, iter=iter) + w_val = iter.getitem() + new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) + if dtype.itemtype.ne(new_best, cur_best): + result = idx + cur_best = new_best + iter.next() + idx += 1 + return result + return argmin_argmax +argmin = _new_argmin_argmax('min') +argmax = _new_argmin_argmax('max') + +# note that shapelen == 2 always +dot_driver = jit.JitDriver(name = 'numpy_dot', + greens = ['dtype'], + reds = ['outi', 'lefti', 'righti', 'result']) def multidim_dot(space, left, right, result, dtype, right_critical_dim): ''' assumes left, right are concrete arrays @@ -157,6 +242,8 @@ lefti = left.create_dot_iter(broadcast_shape, left_skip) righti = right.create_dot_iter(broadcast_shape, right_skip) while not outi.done(): + dot_driver.jit_merge_point(dtype=dtype, outi=outi, lefti=lefti, + righti=righti, result=result) lval = lefti.getitem().convert_to(dtype) rval = righti.getitem().convert_to(dtype) outval = outi.getitem().convert_to(dtype) @@ -168,21 +255,45 @@ lefti.next() return result +count_all_true_driver = jit.JitDriver(name = 'numpy_count', + greens = ['shapelen', 'dtype'], + reds = ['s', 'iter']) + 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() while not iter.done(): + count_all_true_driver.jit_merge_point(shapelen=shapelen, iter=iter, + s=s, 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'], + reds = ['res', 'index_iter', 'res_iter', + 'arr_iter']) + def getitem_filter(res, arr, index): res_iter = res.create_iter() index_iter = index.create_iter() arr_iter = arr.create_iter() + shapelen = len(arr.get_shape()) + arr_dtype = arr.get_dtype() + index_dtype = index.get_dtype() + # XXX length of shape of index as well? while not index_iter.done(): + getitem_filter_driver.jit_merge_point(shapelen=shapelen, + index_dtype=index_dtype, + arr_dtype=arr_dtype, + res=res, index_iter=index_iter, + res_iter=res_iter, + arr_iter=arr_iter) if index_iter.getitem_bool(): res_iter.setitem(arr_iter.getitem()) res_iter.next() @@ -190,31 +301,63 @@ arr_iter.next() return res +setitem_filter_driver = jit.JitDriver(name = 'numpy_setitem_bool', + greens = ['shapelen', 'arr_dtype', + 'index_dtype'], + reds = ['index_iter', 'value_iter', + 'arr_iter']) + def setitem_filter(arr, index, value): arr_iter = arr.create_iter() index_iter = index.create_iter() value_iter = value.create_iter() + shapelen = len(arr.get_shape()) + index_dtype = index.get_dtype() + arr_dtype = arr.get_dtype() while not index_iter.done(): + setitem_filter_driver.jit_merge_point(shapelen=shapelen, + index_dtype=index_dtype, + arr_dtype=arr_dtype, + index_iter=index_iter, + value_iter=value_iter, + arr_iter=arr_iter) if index_iter.getitem_bool(): arr_iter.setitem(value_iter.getitem()) value_iter.next() arr_iter.next() index_iter.next() +flatiter_getitem_driver = jit.JitDriver(name = 'numpy_flatiter_getitem', + greens = ['dtype'], + reds = ['step', 'ri', 'res', + 'base_iter']) + def flatiter_getitem(res, base_iter, step): ri = res.create_iter() + dtype = res.get_dtype() while not ri.done(): + flatiter_getitem_driver.jit_merge_point(dtype=dtype, + base_iter=base_iter, + ri=ri, res=res, step=step) ri.setitem(base_iter.getitem()) base_iter.next_skip_x(step) ri.next() return res +flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', + greens = ['dtype'], + reds = ['length', 'step', 'arr_iter', + 'val_iter']) + def flatiter_setitem(arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: + flatiter_setitem_driver.jit_merge_point(dtype=dtype, length=length, + step=step, arr_iter=arr_iter, + val_iter=val_iter) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -223,10 +366,16 @@ # WTF numpy? val_iter.reset() +fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', + greens = ['itemsize', 'dtype'], + reds = ['i', 's', 'ai']) + def fromstring_loop(a, dtype, itemsize, s): i = 0 ai = a.create_iter() while not ai.done(): + fromstring_driver.jit_merge_point(dtype=dtype, s=s, ai=ai, i=i, + itemsize=itemsize) val = dtype.itemtype.runpack_str(s[i*itemsize:i*itemsize + itemsize]) ai.setitem(val) ai.next() @@ -274,12 +423,25 @@ else: self._done = True + @jit.unroll_safe def get_index(self, space): return [space.wrap(i) for i in self.indexes] +getitem_int_driver = jit.JitDriver(name = 'numpy_getitem_int', + greens = ['shapelen', 'indexlen', 'dtype'], + reds = ['arr', 'res', 'iter', 'indexes_w', + 'prefix_w']) + def getitem_array_int(space, arr, res, iter_shape, indexes_w, prefix_w): + shapelen = len(iter_shape) + indexlen = len(indexes_w) + dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): + getitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, + dtype=dtype, arr=arr, res=res, + iter=iter, indexes_w=indexes_w, + prefix_w=prefix_w) # prepare the index index_w = [None] * len(indexes_w) for i in range(len(indexes_w)): @@ -293,10 +455,22 @@ iter.next() return res +setitem_int_driver = jit.JitDriver(name = 'numpy_setitem_int', + greens = ['shapelen', 'indexlen', 'dtype'], + reds = ['arr', 'iter', 'indexes_w', + 'prefix_w', 'val_arr']) + def setitem_array_int(space, arr, iter_shape, indexes_w, val_arr, prefix_w): + shapelen = len(iter_shape) + indexlen = len(indexes_w) + dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): + setitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, + dtype=dtype, arr=arr, + iter=iter, indexes_w=indexes_w, + prefix_w=prefix_w, val_arr=val_arr) # prepare the index index_w = [None] * len(indexes_w) for i in range(len(indexes_w)): diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py --- a/pypy/module/micronumpy/test/test_compile.py +++ b/pypy/module/micronumpy/test/test_compile.py @@ -1,6 +1,5 @@ + import py -py.test.skip("this is going away") - from pypy.module.micronumpy.compile import (numpy_compile, Assignment, ArrayConstant, FloatConstant, Operator, Variable, RangeConstant, Execute, FunctionCall, FakeSpace) @@ -136,7 +135,7 @@ r """ interp = self.run(code) - assert interp.results[0].value.value == 15 + assert interp.results[0].get_scalar_value().value == 15 def test_sum2(self): code = """ @@ -145,7 +144,7 @@ sum(b) """ interp = self.run(code) - assert interp.results[0].value.value == 30 * (30 - 1) + assert interp.results[0].get_scalar_value().value == 30 * (30 - 1) def test_array_write(self): @@ -164,7 +163,7 @@ b = a + a min(b) """) - assert interp.results[0].value.value == -24 + assert interp.results[0].get_scalar_value().value == -24 def test_max(self): interp = self.run(""" @@ -173,7 +172,7 @@ b = a + a max(b) """) - assert interp.results[0].value.value == 256 + assert interp.results[0].get_scalar_value().value == 256 def test_slice(self): interp = self.run(""" @@ -265,6 +264,7 @@ assert interp.results[0].value == 3 def test_take(self): + py.test.skip("unsupported") interp = self.run(""" a = |10| b = take(a, [1, 1, 3, 2]) 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 @@ -1519,7 +1519,7 @@ assert (a == [1, 1]).all() def test_int_array_index(self): - from numpypy import array, arange + from numpypy import array, arange, zeros b = arange(10)[array([3, 2, 1, 5])] assert (b == [3, 2, 1, 5]).all() raises(IndexError, "arange(10)[array([10])]") @@ -1528,6 +1528,7 @@ a = arange(1) a[[0, 0]] += 1 assert a[0] == 1 + assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): from numpypy import array, arange, zeros @@ -1999,6 +2000,7 @@ def test_int_array_index(self): from _numpypy import array + assert (array([])[[]] == []).all() a = array([[1, 2], [3, 4], [5, 6]]) assert (a[slice(0, 3), [0, 0]] == [[1, 1], [3, 3], [5, 5]]).all() assert (a[array([0, 2]), slice(0, 2)] == [[1, 2], [5, 6]]).all() 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 @@ -4,18 +4,12 @@ """ import py -py.test.skip("this is going away") - from pypy.jit.metainterp import pyjitpl from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp.warmspot import reset_stats from pypy.module.micronumpy import interp_boxes -from pypy.module.micronumpy.compile import (FakeSpace, - IntObject, Parser, InterpreterState) -from pypy.module.micronumpy.interp_numarray import (W_NDimArray, - BaseArray, W_FlatIterator) -from pypy.rlib.nonconst import NonConstant - +from pypy.module.micronumpy.compile import FakeSpace, Parser, InterpreterState +from pypy.module.micronumpy.base import W_NDimArray class TestNumpyJIt(LLJitMixin): graph = None @@ -51,11 +45,8 @@ if not len(interp.results): raise Exception("need results") w_res = interp.results[-1] - if isinstance(w_res, BaseArray): - concr = w_res.get_concrete_or_scalar() - sig = concr.find_sig() - frame = sig.create_frame(concr) - w_res = sig.eval(frame, concr) + if isinstance(w_res, W_NDimArray): + w_res = w_res.create_iter().getitem() if isinstance(w_res, interp_boxes.W_Float64Box): return w_res.value if isinstance(w_res, interp_boxes.W_Int64Box): @@ -73,6 +64,7 @@ self.__class__.graph = graph reset_stats() pyjitpl._warmrunnerdesc.memory_manager.alive_loops.clear() + py.test.skip("don't run for now") return self.interp.eval_graph(self.graph, [i]) def define_add(): 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 @@ -79,7 +79,7 @@ except ExitFrame: return self.popvalue() - def jump_absolute(self, jumpto, _, ec=None): + def jump_absolute(self, jumpto, ec): if we_are_jitted(): # # assume that only threads are using the bytecode counter diff --git a/pypy/module/pypyjit/test_pypy_c/test_exception.py b/pypy/module/pypyjit/test_pypy_c/test_exception.py --- a/pypy/module/pypyjit/test_pypy_c/test_exception.py +++ b/pypy/module/pypyjit/test_pypy_c/test_exception.py @@ -95,7 +95,6 @@ def test_continue_in_finally(self): # check that 'continue' inside a try:finally: block is correctly # detected as closing a loop - py.test.skip("is this case important?") def f(n): i = 0 while 1: @@ -110,10 +109,9 @@ assert log.result == 2001 loop, = log.loops_by_filename(self.filepath) assert loop.match(""" - i40 = int_add_ovf(i31, 1) - guard_no_overflow(descr=...) - i41 = int_lt(i40, i33) - guard_true(i41, descr=...) + i3 = int_lt(i1, i2) + guard_true(i3, descr=...) + i4 = int_add(i1, 1) --TICK-- jump(..., descr=...) """) diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,7 +1,8 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import PyCode, BytecodeCorruption +from pypy.interpreter.pycode import (PyCode, BytecodeCorruption, cpython_magic, + cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) from pypy.interpreter.astcompiler.consts import CO_GENERATOR @@ -12,6 +13,57 @@ """ opnames = host_bytecode_spec.method_names + def __init__(self, space, argcount, nlocals, stacksize, flags, + code, consts, names, varnames, filename, + name, firstlineno, lnotab, freevars, cellvars, + hidden_applevel=False, magic=cpython_magic): + """Initialize a new code object""" + self.space = space + self.co_name = name + assert nlocals >= 0 + self.co_argcount = argcount + self.co_nlocals = nlocals + self.co_stacksize = stacksize + self.co_flags = flags + self.co_code = code + self.co_consts_w = consts + self.co_names_w = [space.wrap(aname) for aname in names] + self.co_varnames = varnames + self.co_freevars = freevars + self.co_cellvars = cellvars + self.co_filename = filename + self.co_name = name + self.co_firstlineno = firstlineno + self.co_lnotab = lnotab + self.hidden_applevel = hidden_applevel + self.magic = magic + self._signature = cpython_code_signature(self) + self._initialize() + + def _initialize(self): + # Precompute what arguments need to be copied into cellvars + self._args_as_cellvars = [] + + if self.co_cellvars: + argcount = self.co_argcount + assert argcount >= 0 # annotator hint + if self.co_flags & CO_VARARGS: + argcount += 1 + if self.co_flags & CO_VARKEYWORDS: + argcount += 1 + # Cell vars could shadow already-set arguments. + # See comment in PyCode._initialize() + argvars = self.co_varnames + cellvars = self.co_cellvars + for i in range(len(cellvars)): + cellname = cellvars[i] + for j in range(argcount): + if cellname == argvars[j]: + # argument j has the same name as the cell var i + while len(self._args_as_cellvars) <= i: + self._args_as_cellvars.append(-1) # pad + self._args_as_cellvars[i] = j + def read(self, pos): """ Decode the instruction starting at position ``next_instr``. diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -1,20 +1,18 @@ import collections -import sys from pypy.tool.error import source_lines -from pypy.interpreter.error import OperationError -from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter import pyframe from pypy.interpreter.nestedscope import Cell -from pypy.interpreter.pycode import CO_OPTIMIZED, CO_NEWLOCALS +from pypy.interpreter.pycode import CO_NEWLOCALS from pypy.interpreter.argument import ArgumentsForTranslation -from pypy.interpreter.pyopcode import (Return, Yield, SuspendedUnroller, - SReturnValue, SApplicationException, BytecodeCorruption, - RaiseWithExplicitTraceback) -from pypy.objspace.flow.model import * +from pypy.interpreter.pyopcode import Return, BytecodeCorruption +from pypy.objspace.flow.model import (Constant, Variable, Block, Link, + UnwrapException, SpaceOperation, FunctionGraph, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, recursively_flatten) from pypy.rlib import jit from pypy.objspace.flow.bytecode import HostCode +from pypy.objspace.flow.specialcase import (rpython_print_item, + rpython_print_newline) class FlowingError(Exception): """ Signals invalid RPython in the function being analysed""" @@ -28,16 +26,14 @@ msg += source_lines(self.frame.graph, None, offset=self.frame.last_instr) return "\n".join(msg) - class StopFlowing(Exception): pass -class FSException(OperationError): - def __init__(self, w_type, w_value, tb=None): +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 - self._application_traceback = tb def get_w_value(self, _): return self.w_value @@ -45,45 +41,6 @@ def __str__(self): return '[%s: %s]' % (self.w_type, self.w_value) - def normalize_exception(self, space): - """Normalize the OperationError. In other words, fix w_type and/or - w_value to make sure that the __class__ of w_value is exactly w_type. - """ - w_type = self.w_type - w_value = self.w_value - if space.exception_is_valid_obj_as_class_w(w_type): - # this is for all cases of the form (Class, something) - if space.is_w(w_value, space.w_None): - # raise Type: we assume we have to instantiate Type - w_value = space.call_function(w_type) - w_type = self._exception_getclass(space, w_value) - else: - w_valuetype = space.exception_getclass(w_value) - if space.exception_issubclass_w(w_valuetype, w_type): - # raise Type, Instance: let etype be the exact type of value - w_type = w_valuetype - else: - # raise Type, X: assume X is the constructor argument - w_value = space.call_function(w_type, w_value) - w_type = self._exception_getclass(space, w_value) - - else: - # the only case left here is (inst, None), from a 'raise inst'. - w_inst = w_type - w_instclass = self._exception_getclass(space, w_inst) - if not space.is_w(w_value, space.w_None): - raise FSException(space.w_TypeError, - space.wrap("instance exception may not " - "have a separate value")) - w_value = w_inst - w_type = w_instclass - - self.w_type = w_type - self.w_value = w_value - -class OperationThatShouldNotBePropagatedError(FSException): - pass - class ImplicitOperationError(FSException): pass @@ -263,6 +220,20 @@ # ____________________________________________________________ +compare_method = [ + "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", + ] + class FlowSpaceFrame(pyframe.CPythonFrame): def __init__(self, space, func, constargs=None): @@ -498,38 +469,68 @@ res = getattr(self, methodname)(oparg, next_instr) if res is not None: next_instr = res - except OperationThatShouldNotBePropagatedError, e: - raise Exception( - 'found an operation that always raises %s: %s' % ( - self.space.unwrap(e.w_type).__name__, - self.space.unwrap(e.w_value))) except FSException, operr: - self.attach_traceback(operr) next_instr = self.handle_operation_error(operr) - except RaiseWithExplicitTraceback, e: - next_instr = self.handle_operation_error(e.operr) return next_instr - def attach_traceback(self, operr): - if self.pycode.hidden_applevel: - return - tb = operr.get_traceback() - tb = PyTraceback(self.space, self, self.last_instr, tb) - operr.set_traceback(tb) - def handle_operation_error(self, operr): - block = self.unrollstack(SFlowException.kind) + block = self.unrollstack(SApplicationException.kind) if block is None: - # no handler found for the exception - # try to preserve the CPython-level traceback - import sys - tb = sys.exc_info()[2] - raise operr, None, tb + raise operr else: - unroller = SFlowException(operr) + unroller = SApplicationException(operr) next_instr = block.handle(self, unroller) return next_instr + def BAD_OPCODE(self, _, next_instr): + raise FlowingError(self, "This operation is not RPython") + + def BREAK_LOOP(self, oparg, next_instr): + return self.unrollstack_and_jump(SBreakLoop.singleton) + + def CONTINUE_LOOP(self, startofloop, next_instr): + unroller = SContinueLoop(startofloop) + return self.unrollstack_and_jump(unroller) + + 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)) + + def cmp_exc_match(self, w_1, w_2): + return self.space.newbool(self.space.exception_match(w_1, w_2)) + + def COMPARE_OP(self, testnum, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = getattr(self, compare_method[testnum])(w_1, w_2) + self.pushvalue(w_result) + def RAISE_VARARGS(self, nbargs, next_instr): space = self.space if nbargs == 0: @@ -539,7 +540,7 @@ # re-raising an implicit operation makes it an explicit one operr = FSException(operr.w_type, operr.w_value) self.last_exception = operr - raise RaiseWithExplicitTraceback(operr) + raise operr else: raise FSException(space.w_TypeError, space.wrap("raise: no active exception to re-raise")) @@ -551,8 +552,7 @@ w_value = self.popvalue() if 1: w_type = self.popvalue() - operror = FSException(w_type, w_value) - operror.normalize_exception(space) + operror = space.exc_from_raise(w_type, w_value) raise operror def IMPORT_NAME(self, nameindex, next_instr): @@ -581,17 +581,45 @@ return next_instr # now inside a 'finally' block def END_FINALLY(self, oparg, next_instr): - unroller = self.end_finally() - if isinstance(unroller, SuspendedUnroller): - # go on unrolling the stack - block = self.unrollstack(unroller.kind) - if block is None: - w_result = unroller.nomoreblocks() - self.pushvalue(w_result) - raise Return - else: - next_instr = block.handle(self, unroller) - return next_instr + # unlike CPython, there are two statically distinct cases: the + # END_FINALLY might be closing an 'except' block or a 'finally' + # block. In the first case, the stack contains three items: + # [exception type we are now handling] + # [exception value we are now handling] + # [wrapped 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] + w_top = self.popvalue() + if w_top == self.space.w_None: + # finally: block with no unroller active + return + try: + unroller = self.space.unwrap(w_top) + except UnwrapException: + pass + else: + if isinstance(unroller, SuspendedUnroller): + # case of a finally: block + return self.unroll_finally(unroller) + # case of an except: block. We popped the exception type + self.popvalue() # Now we pop the exception value + unroller = self.space.unwrap(self.popvalue()) + return self.unroll_finally(unroller) + + def unroll_finally(self, unroller): + # go on unrolling the stack + block = self.unrollstack(unroller.kind) + if block is None: + w_result = unroller.nomoreblocks() + self.pushvalue(w_result) + raise Return + else: + return block.handle(self, unroller) + + def POP_BLOCK(self, oparg, next_instr): + block = self.pop_block() + block.cleanupstack(self) # the block knows how to clean up the value stack def JUMP_ABSOLUTE(self, jumpto, next_instr): return jumpto @@ -604,11 +632,48 @@ # isn't popped straightaway. self.pushvalue(None) + PRINT_EXPR = BAD_OPCODE + PRINT_ITEM_TO = BAD_OPCODE + PRINT_NEWLINE_TO = BAD_OPCODE + + def PRINT_ITEM(self, oparg, next_instr): + w_item = self.popvalue() + w_s = self.space.do_operation('str', w_item) + self.space.appcall(rpython_print_item, w_s) + + def PRINT_NEWLINE(self, oparg, next_instr): + self.space.appcall(rpython_print_newline) + + def FOR_ITER(self, jumpby, next_instr): + w_iterator = self.peekvalue() + try: + w_nextitem = self.space.next(w_iterator) + except FSException, e: + if not self.space.exception_match(e.w_type, self.space.w_StopIteration): + raise + # iterator exhausted + self.popvalue() + next_instr += jumpby + else: + self.pushvalue(w_nextitem) + return next_instr + + def SETUP_LOOP(self, offsettoend, next_instr): + block = LoopBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + + def SETUP_EXCEPT(self, offsettoend, next_instr): + block = ExceptBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + + def SETUP_FINALLY(self, offsettoend, next_instr): + block = FinallyBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + def SETUP_WITH(self, offsettoend, next_instr): # A simpler version than the 'real' 2.7 one: # directly call manager.__enter__(), don't use special lookup functions # which don't make sense on the RPython type system. - from pypy.interpreter.pyopcode import WithBlock w_manager = self.peekvalue() w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__")) self.settopvalue(w_exit) @@ -618,10 +683,47 @@ self.lastblock = block self.pushvalue(w_result) + def WITH_CLEANUP(self, oparg, next_instr): + # Note: RPython context managers receive None in lieu of tracebacks + # and cannot suppress the exception. + # This opcode changed a lot between CPython versions + if (self.pycode.magic >= 0xa0df2ef + # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) + or self.pycode.magic >= 0xa0df2d1): + # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) + w_unroller = self.popvalue() + w_exitfunc = self.popvalue() + self.pushvalue(w_unroller) + elif self.pycode.magic >= 0xa0df28c: + # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) + w_exitfunc = self.popvalue() + w_unroller = self.peekvalue(0) + else: + raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") + + unroller = self.space.unwrap(w_unroller) + w_None = self.space.w_None + if isinstance(unroller, SApplicationException): + operr = unroller.operr + # 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) + else: + self.space.call_function(w_exitfunc, w_None, w_None, w_None) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) + def LOAD_ATTR(self, nameindex, next_instr): + "obj.attributename" + w_obj = self.popvalue() + w_attributename = self.getname_w(nameindex) + w_value = self.space.getattr(w_obj, w_attributename) + self.pushvalue(w_value) + LOOKUP_METHOD = LOAD_ATTR + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. @@ -713,23 +815,173 @@ def argument_factory(self, *args): return ArgumentsForTranslation(self.space, *args) - def call_contextmanager_exit_function(self, w_func, w_typ, w_val, w_tb): - if w_typ is not self.space.w_None: - # The annotator won't allow to merge exception types with None. - # Replace it with the exception value... - w_typ = w_val - self.space.call_function(w_func, w_typ, w_val, w_tb) - # Return None so that the flow space statically knows that we didn't - # swallow the exception - return self.space.w_None - ### Frame blocks ### -class SFlowException(SApplicationException): - """Flowspace override for SApplicationException""" +class SuspendedUnroller(object): + """Abstract base class for interpreter-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: + + WHY_NOT, OK, not this one :-) + WHY_EXCEPTION, SApplicationException + WHY_RERAISE, implemented differently, see Reraise + WHY_RETURN, SReturnValue + WHY_BREAK, SBreakLoop + WHY_CONTINUE, SContinueLoop + WHY_YIELD not needed + """ + 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): + """Signals a 'return' statement. + Argument is the wrapped object to return.""" + kind = 0x01 + def __init__(self, w_returnvalue): + self.w_returnvalue = w_returnvalue + + def nomoreblocks(self): + return self.w_returnvalue + + def state_unpack_variables(self, space): + return [self.w_returnvalue] + + @staticmethod + def state_pack_variables(space, w_returnvalue): + return SReturnValue(w_returnvalue) + +class SApplicationException(SuspendedUnroller): + """Signals an application-level exception + (i.e. an OperationException).""" + kind = 0x02 + def __init__(self, operr): + self.operr = operr + + def nomoreblocks(self): + raise self.operr + def state_unpack_variables(self, space): return [self.operr.w_type, self.operr.w_value] @staticmethod def state_pack_variables(space, w_type, w_value): - return SFlowException(FSException(w_type, w_value)) + return SApplicationException(FSException(w_type, w_value)) + +class SBreakLoop(SuspendedUnroller): + """Signals a 'break' statement.""" + kind = 0x04 + + def state_unpack_variables(self, space): + return [] + + @staticmethod + def state_pack_variables(space): + return SBreakLoop.singleton + +SBreakLoop.singleton = SBreakLoop() + +class SContinueLoop(SuspendedUnroller): + """Signals a 'continue' statement. + Argument is the bytecode position of the beginning of the loop.""" + kind = 0x08 + def __init__(self, jump_to): + self.jump_to = jump_to + + def state_unpack_variables(self, space): + return [space.wrap(self.jump_to)] + + @staticmethod + def state_pack_variables(space, w_jump_to): + return SContinueLoop(space.int_w(w_jump_to)) + + +class FrameBlock(object): + """Abstract base class for frame blocks from the blockstack, + used by the SETUP_XXX and POP_BLOCK opcodes.""" + + def __init__(self, frame, handlerposition, previous): + self.handlerposition = handlerposition + self.valuestackdepth = frame.valuestackdepth + self.previous = previous # this makes a linked list of blocks + + def __eq__(self, other): + return (self.__class__ is other.__class__ and + self.handlerposition == other.handlerposition and + self.valuestackdepth == other.valuestackdepth) + + def __ne__(self, other): + return not (self == other) + + def __hash__(self): + return hash((self.handlerposition, self.valuestackdepth)) + + def cleanupstack(self, frame): + frame.dropvaluesuntil(self.valuestackdepth) + + def handle(self, frame, unroller): + raise NotImplementedError + +class LoopBlock(FrameBlock): + """A loop block. Stores the end-of-loop pointer in case of 'break'.""" + + _opname = 'SETUP_LOOP' + handling_mask = SBreakLoop.kind | SContinueLoop.kind + + def handle(self, frame, unroller): + if isinstance(unroller, SContinueLoop): + # 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 + frame.append_block(self) + return unroller.jump_to + else: + # jump to the end of the loop + self.cleanupstack(frame) + return self.handlerposition + +class ExceptBlock(FrameBlock): + """An try:except: block. Stores the position of the exception handler.""" + + _opname = 'SETUP_EXCEPT' + handling_mask = SApplicationException.kind + + 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) + operationerr = unroller.operr + # the stack setup is slightly different than in CPython: + # instead of the traceback, we store the unroller object, + # wrapped. + frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(operationerr.get_w_value(frame.space)) + frame.pushvalue(operationerr.w_type) + frame.last_exception = operationerr + return self.handlerposition # jump to the handler + +class FinallyBlock(FrameBlock): + """A try:finally: block. Stores the position of the exception handler.""" + + _opname = 'SETUP_FINALLY' + handling_mask = -1 # handles every kind of SuspendedUnroller + + def handle(self, frame, unroller): + # any abnormal reason for unrolling a finally: triggers the end of + # the block unrolling and the entering the finally: handler. + self.cleanupstack(frame) + frame.pushvalue(frame.space.wrap(unroller)) + return self.handlerposition # jump to the handler + + +class WithBlock(FinallyBlock): + + def handle(self, frame, unroller): + return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -1,4 +1,3 @@ -from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.rlib.unroll import SpecTag from pypy.objspace.flow.model import * @@ -106,6 +105,7 @@ UNPICKLE_TAGS = {} def recursively_flatten(space, lst): + from pypy.objspace.flow.flowcontext import SuspendedUnroller i = 0 while i < len(lst): item = lst[i] diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -1,14 +1,14 @@ # ______________________________________________________________________ import __builtin__ import sys -import operator import types -from pypy.interpreter.baseobjspace import ObjSpace, Wrappable -from pypy.interpreter import pyframe, argument -from pypy.objspace.flow.model import * +from pypy.interpreter.baseobjspace import ObjSpace +from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.model import (Constant, Variable, WrapException, + UnwrapException, checkgraph, SpaceOperation) from pypy.objspace.flow import operation from pypy.objspace.flow.flowcontext import (FlowSpaceFrame, fixeggblocks, - OperationThatShouldNotBePropagatedError, FSException, FlowingError) + FSException, FlowingError) from pypy.objspace.flow.specialcase import SPECIAL_CASES from pypy.rlib.unroll import unrolling_iterable, _unroller from pypy.rlib import rstackovf, rarithmetic @@ -38,48 +38,33 @@ } # ______________________________________________________________________ -class FlowObjSpace(ObjSpace): +class FlowObjSpace(object): """NOT_RPYTHON. The flow objspace space is used to produce a flow graph by recording the space operations that the interpreter generates when it interprets (the bytecode of) some function. """ + w_None = Constant(None) + builtin = Constant(__builtin__) + sys = Constant(sys) + w_False = Constant(False) + w_True = Constant(True) + w_type = Constant(type) + w_tuple = Constant(tuple) + for exc in [KeyError, ValueError, IndexError, StopIteration, + AssertionError, TypeError, AttributeError, ImportError]: + clsname = exc.__name__ + locals()['w_' + clsname] = Constant(exc) - full_exceptions = False py3k = False # the RPython bytecode is still python2 - FrameClass = FlowSpaceFrame + # the following exceptions should not show up + # during flow graph construction + w_NameError = None + w_UnboundLocalError = None - def initialize(self): - self.w_None = Constant(None) - self.builtin = Constant(__builtin__) - self.sys = Constant(sys) - self.w_False = Constant(False) - self.w_True = Constant(True) - self.w_type = Constant(type) - self.w_tuple = Constant(tuple) - for exc in [KeyError, ValueError, IndexError, StopIteration, - AssertionError, TypeError, AttributeError, ImportError]: - clsname = exc.__name__ - setattr(self, 'w_'+clsname, Constant(exc)) - # the following exceptions are the ones that should not show up - # during flow graph construction; they are triggered by - # non-R-Pythonic constructs or real bugs like typos. - for exc in [NameError, UnboundLocalError]: - clsname = exc.__name__ - setattr(self, 'w_'+clsname, None) - self.specialcases = SPECIAL_CASES.copy() - #self.make_builtins() - #self.make_sys() - # w_str is needed because cmp_exc_match of frames checks against it, - # as string exceptions are deprecated - self.w_str = Constant(str) - # objects which should keep their SomeObjectness - self.not_really_const = NOT_REALLY_CONST - - # disable superclass methods - enter_cache_building_mode = None - leave_cache_building_mode = None - createcompiler = None + specialcases = SPECIAL_CASES + # objects which should keep their SomeObjectness + not_really_const = NOT_REALLY_CONST def is_w(self, w_one, w_two): return self.is_true(self.is_(w_one, w_two)) @@ -104,6 +89,12 @@ def newslice(self, w_start, w_stop, w_step): return self.do_operation('newslice', w_start, w_stop, w_step) + def newbool(self, b): + if b: + return self.w_True + else: + return self.w_False + def wrap(self, obj): if isinstance(obj, (Variable, Constant)): raise TypeError("already wrapped: " + repr(obj)) @@ -182,53 +173,77 @@ raise UnwrapException return obj - def interpclass_w(self, w_obj): - obj = self.unwrap(w_obj) - if isinstance(obj, Wrappable): - return obj - return None + def exception_issubclass_w(self, w_cls1, w_cls2): + return self.is_true(self.issubtype(w_cls1, w_cls2)) - def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj): + def _exception_match(self, w_exc_type, w_check_class): + """Helper for exception_match + + Handles the base case where w_check_class is a constant exception + type. """ - WARNING: this implementation is not complete at all. It's just enough - to be used by end_finally() inside pyopcode.py. - """ - return w_obj == self.w_None or (isinstance(w_obj, Constant) and - isinstance(w_obj.value, RequiredClass)) - - def getexecutioncontext(self): - return self.frame + if self.is_w(w_exc_type, w_check_class): + return True # fast path (also here to handle string exceptions) + try: + return self.exception_issubclass_w(w_exc_type, w_check_class) + except FSException, e: + if e.match(self, self.w_TypeError): # string exceptions maybe + return False + raise def exception_match(self, w_exc_type, w_check_class): + """Checks if the given exception type matches 'w_check_class'.""" try: check_class = self.unwrap(w_check_class) except UnwrapException: - raise Exception, "non-constant except guard" + raise FlowingError(self.frame, "Non-constant except guard.") if check_class in (NotImplementedError, AssertionError): raise FlowingError(self.frame, "Catching %s is not valid in RPython" % check_class.__name__) if not isinstance(check_class, tuple): # the simple case - return ObjSpace.exception_match(self, w_exc_type, w_check_class) + return self._exception_match(w_exc_type, w_check_class) # special case for StackOverflow (see rlib/rstackovf.py) if check_class == rstackovf.StackOverflow: w_real_class = self.wrap(rstackovf._StackOverflow) - return ObjSpace.exception_match(self, w_exc_type, w_real_class) + return self._exception_match(w_exc_type, w_real_class) # checking a tuple of classes for w_klass in self.fixedview(w_check_class): if self.exception_match(w_exc_type, w_klass): return True return False - def getconstclass(space, w_cls): - try: - ecls = space.unwrap(w_cls) - except UnwrapException: - pass + def exc_from_raise(self, w_type, w_value): + """ + Create a wrapped exception from the arguments of a raise statement. + + Returns an FSException object whose w_value is an instance of w_type. + """ + if self.isinstance_w(w_type, self.w_type): + # this is for all cases of the form (Class, something) + if self.is_w(w_value, self.w_None): + # raise Type: we assume we have to instantiate Type + w_value = self.call_function(w_type) + w_type = self.type(w_value) + else: + w_valuetype = self.type(w_value) + if self.exception_issubclass_w(w_valuetype, w_type): + # raise Type, Instance: let etype be the exact type of value + w_type = w_valuetype + else: + # raise Type, X: assume X is the constructor argument + w_value = self.call_function(w_type, w_value) + w_type = self.type(w_value) else: - if isinstance(ecls, (type, types.ClassType)): - return ecls - return None + # the only case left here is (inst, None), from a 'raise inst'. + w_inst = w_type + w_instclass = self.type(w_inst) + if not self.is_w(w_value, self.w_None): + raise FSException(self.w_TypeError, self.wrap( + "instance exception may not have a separate value")) + w_value = w_inst + w_type = w_instclass + return FSException(w_type, w_value) def build_flow(self, func, constargs={}, tweak_for_generator=True): """ @@ -247,7 +262,7 @@ def fixedview(self, w_tuple, expected_length=None): return self.unpackiterable(w_tuple, expected_length) - listview = fixedview + listview = fixedview_unroll = fixedview def unpackiterable(self, w_iterable, expected_length=None): if not isinstance(w_iterable, Variable): @@ -255,19 +270,17 @@ if expected_length is not None and len(l) != expected_length: raise ValueError return [self.wrap(x) for x in l] - if isinstance(w_iterable, Variable) and expected_length is None: - raise UnwrapException, ("cannot unpack a Variable iterable" + elif expected_length is None: + raise UnwrapException("cannot unpack a Variable iterable " "without knowing its length") - elif expected_length is not None: + else: w_len = self.len(w_iterable) w_correct = self.eq(w_len, self.wrap(expected_length)) if not self.is_true(w_correct): - e = FSException(self.w_ValueError, self.w_None) - e.normalize_exception(self) + e = self.exc_from_raise(self.w_ValueError, self.w_None) raise e return [self.do_operation('getitem', w_iterable, self.wrap(i)) From noreply at buildbot.pypy.org Tue Oct 2 16:37:41 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:41 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: hg merge default Message-ID: <20121002143741.B8F841C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57720:2bdf31495e6b Date: 2012-09-30 20:12 +0200 http://bitbucket.org/pypy/pypy/changeset/2bdf31495e6b/ Log: hg merge default diff too long, truncating to 2000 out of 43871 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,5 +1,6 @@ syntax: glob *.py[co] +*.sw[po] *~ .*.swp .idea diff --git a/lib-python/2.7/BaseHTTPServer.py b/lib-python/2.7/BaseHTTPServer.py --- a/lib-python/2.7/BaseHTTPServer.py +++ b/lib-python/2.7/BaseHTTPServer.py @@ -244,14 +244,11 @@ self.request_version = version = self.default_request_version self.close_connection = 1 requestline = self.raw_requestline - if requestline[-2:] == '\r\n': - requestline = requestline[:-2] - elif requestline[-1:] == '\n': - requestline = requestline[:-1] + requestline = requestline.rstrip('\r\n') self.requestline = requestline words = requestline.split() if len(words) == 3: - [command, path, version] = words + command, path, version = words if version[:5] != 'HTTP/': self.send_error(400, "Bad request version (%r)" % version) return False @@ -277,7 +274,7 @@ "Invalid HTTP Version (%s)" % base_version_number) return False elif len(words) == 2: - [command, path] = words + command, path = words self.close_connection = 1 if command != 'GET': self.send_error(400, diff --git a/lib-python/2.7/ConfigParser.py b/lib-python/2.7/ConfigParser.py --- a/lib-python/2.7/ConfigParser.py +++ b/lib-python/2.7/ConfigParser.py @@ -142,6 +142,7 @@ def __init__(self, section): Error.__init__(self, 'No section: %r' % (section,)) self.section = section + self.args = (section, ) class DuplicateSectionError(Error): """Raised when a section is multiply-created.""" @@ -149,6 +150,7 @@ def __init__(self, section): Error.__init__(self, "Section %r already exists" % section) self.section = section + self.args = (section, ) class NoOptionError(Error): """A requested option was not found.""" @@ -158,6 +160,7 @@ (option, section)) self.option = option self.section = section + self.args = (option, section) class InterpolationError(Error): """Base class for interpolation-related exceptions.""" @@ -166,6 +169,7 @@ Error.__init__(self, msg) self.option = option self.section = section + self.args = (option, section, msg) class InterpolationMissingOptionError(InterpolationError): """A string substitution required a setting which was not available.""" @@ -179,6 +183,7 @@ % (section, option, reference, rawval)) InterpolationError.__init__(self, option, section, msg) self.reference = reference + self.args = (option, section, rawval, reference) class InterpolationSyntaxError(InterpolationError): """Raised when the source text into which substitutions are made @@ -194,6 +199,7 @@ "\trawval : %s\n" % (section, option, rawval)) InterpolationError.__init__(self, option, section, msg) + self.args = (option, section, rawval) class ParsingError(Error): """Raised when a configuration file does not follow legal syntax.""" @@ -202,6 +208,7 @@ Error.__init__(self, 'File contains parsing errors: %s' % filename) self.filename = filename self.errors = [] + self.args = (filename, ) def append(self, lineno, line): self.errors.append((lineno, line)) @@ -218,6 +225,7 @@ self.filename = filename self.lineno = lineno self.line = line + self.args = (filename, lineno, line) class RawConfigParser: @@ -570,7 +578,7 @@ def keys(self): result = [] seen = set() - for mapping in self_maps: + for mapping in self._maps: for key in mapping: if key not in seen: result.append(key) diff --git a/lib-python/2.7/HTMLParser.py b/lib-python/2.7/HTMLParser.py --- a/lib-python/2.7/HTMLParser.py +++ b/lib-python/2.7/HTMLParser.py @@ -14,7 +14,6 @@ # Regular expressions used for parsing interesting_normal = re.compile('[&<]') -interesting_cdata = re.compile(r'<(/|\Z)') incomplete = re.compile('&[a-zA-Z#]') entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') @@ -24,25 +23,31 @@ piclose = re.compile('>') commentclose = re.compile(r'--\s*>') tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*') +# see http://www.w3.org/TR/html5/tokenization.html#tag-open-state +# and http://www.w3.org/TR/html5/tokenization.html#tag-name-state +tagfind_tolerant = re.compile('[a-zA-Z][^\t\n\r\f />\x00]*') + attrfind = re.compile( - r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' - r'(\'[^\']*\'|"[^"]*"|[^\s"\'=<>`]*))?') + r'[\s/]*((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' + r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*') locatestarttagend = re.compile(r""" <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name - (?:\s+ # whitespace before attribute name - (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name - (?:\s*=\s* # value indicator + (?:[\s/]* # optional whitespace before attribute name + (?:(?<=['"\s/])[^\s/>][^\s/=>]* # attribute name + (?:\s*=+\s* # value indicator (?:'[^']*' # LITA-enclosed value - |\"[^\"]*\" # LIT-enclosed value - |[^'\">\s]+ # bare value + |"[^"]*" # LIT-enclosed value + |(?!['"])[^>\s]* # bare value ) - )? - ) - )* + )?(?:\s|/(?!>))* + )* + )? \s* # trailing whitespace """, re.VERBOSE) endendtag = re.compile('>') +# the HTML 5 spec, section 8.1.2.2, doesn't allow spaces between +# ') @@ -96,6 +101,7 @@ self.rawdata = '' self.lasttag = '???' self.interesting = interesting_normal + self.cdata_elem = None markupbase.ParserBase.reset(self) def feed(self, data): @@ -120,11 +126,13 @@ """Return full source of start tag: '<...>'.""" return self.__starttag_text - def set_cdata_mode(self): - self.interesting = interesting_cdata + def set_cdata_mode(self, elem): + self.cdata_elem = elem.lower() + self.interesting = re.compile(r'' % self.cdata_elem, re.I) def clear_cdata_mode(self): self.interesting = interesting_normal + self.cdata_elem = None # Internal -- handle data as far as reasonable. May leave state # and data to be processed by a subsequent call. If 'end' is @@ -138,6 +146,8 @@ if match: j = match.start() else: + if self.cdata_elem: + break j = n if i < j: self.handle_data(rawdata[i:j]) i = self.updatepos(i, j) @@ -153,16 +163,23 @@ elif startswith("', i + 1) + if k < 0: + k = rawdata.find('<', i + 1) + if k < 0: + k = i + 1 + else: + k += 1 + self.handle_data(rawdata[i:k]) i = self.updatepos(i, k) elif startswith("&#", i): match = charref.match(rawdata, i) @@ -206,11 +223,46 @@ else: assert 0, "interesting.search() lied" # end while - if end and i < n: + if end and i < n and not self.cdata_elem: self.handle_data(rawdata[i:n]) i = self.updatepos(i, n) self.rawdata = rawdata[i:] + # Internal -- parse html declarations, return length or -1 if not terminated + # See w3.org/TR/html5/tokenization.html#markup-declaration-open-state + # See also parse_declaration in _markupbase + def parse_html_declaration(self, i): + rawdata = self.rawdata + if rawdata[i:i+2] != ' + gtpos = rawdata.find('>', i+9) + if gtpos == -1: + return -1 + self.handle_decl(rawdata[i+2:gtpos]) + return gtpos+1 + else: + return self.parse_bogus_comment(i) + + # Internal -- parse bogus comment, return length or -1 if not terminated + # see http://www.w3.org/TR/html5/tokenization.html#bogus-comment-state + def parse_bogus_comment(self, i, report=1): + rawdata = self.rawdata + if rawdata[i:i+2] not in ('', i+2) + if pos == -1: + return -1 + if report: + self.handle_comment(rawdata[i+2:pos]) + return pos + 1 + # Internal -- parse processing instr, return end or -1 if not terminated def parse_pi(self, i): rawdata = self.rawdata @@ -249,6 +301,7 @@ elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ attrvalue[:1] == '"' == attrvalue[-1:]: attrvalue = attrvalue[1:-1] + if attrvalue: attrvalue = self.unescape(attrvalue) attrs.append((attrname.lower(), attrvalue)) k = m.end() @@ -262,15 +315,15 @@ - self.__starttag_text.rfind("\n") else: offset = offset + len(self.__starttag_text) - self.error("junk characters in start tag: %r" - % (rawdata[k:endpos][:20],)) + self.handle_data(rawdata[i:endpos]) + return endpos if end.endswith('/>'): # XHTML-style empty tag: self.handle_startendtag(tag, attrs) else: self.handle_starttag(tag, attrs) if tag in self.CDATA_CONTENT_ELEMENTS: - self.set_cdata_mode() + self.set_cdata_mode(tag) return endpos # Internal -- check to see if we have a complete starttag; return end @@ -300,8 +353,10 @@ # end of input in or before attribute value, or we have the # '/' from a '/>' ending return -1 - self.updatepos(i, j) - self.error("malformed start tag") + if j > i: + return j + else: + return i + 1 raise AssertionError("we should not get here!") # Internal -- parse endtag, return end or -1 if incomplete @@ -311,14 +366,38 @@ match = endendtag.search(rawdata, i+1) # > if not match: return -1 - j = match.end() + gtpos = match.end() match = endtagfind.match(rawdata, i) # if not match: - self.error("bad end tag: %r" % (rawdata[i:j],)) - tag = match.group(1) - self.handle_endtag(tag.lower()) + if self.cdata_elem is not None: + self.handle_data(rawdata[i:gtpos]) + return gtpos + # find the name: w3.org/TR/html5/tokenization.html#tag-name-state + namematch = tagfind_tolerant.match(rawdata, i+2) + if not namematch: + # w3.org/TR/html5/tokenization.html#end-tag-open-state + if rawdata[i:i+3] == '': + return i+3 + else: + return self.parse_bogus_comment(i) + tagname = namematch.group().lower() + # consume and ignore other stuff between the name and the > + # Note: this is not 100% correct, since we might have things like + # , but looking for > after tha name should cover + # most of the cases and is much simpler + gtpos = rawdata.find('>', namematch.end()) + self.handle_endtag(tagname) + return gtpos+1 + + elem = match.group(1).lower() # script or style + if self.cdata_elem is not None: + if elem != self.cdata_elem: + self.handle_data(rawdata[i:gtpos]) + return gtpos + + self.handle_endtag(elem) self.clear_cdata_mode() - return j + return gtpos # Overridable -- finish processing of start+end tag: def handle_startendtag(self, tag, attrs): @@ -358,7 +437,7 @@ pass def unknown_decl(self, data): - self.error("unknown declaration: %r" % (data,)) + pass # Internal -- helper to remove special character quoting entitydefs = None diff --git a/lib-python/2.7/SocketServer.py b/lib-python/2.7/SocketServer.py --- a/lib-python/2.7/SocketServer.py +++ b/lib-python/2.7/SocketServer.py @@ -82,7 +82,7 @@ data is stored externally (e.g. in the file system), a synchronous class will essentially render the service "deaf" while one request is being handled -- which may be for a very long time if a client is slow -to reqd all the data it has requested. Here a threading or forking +to read all the data it has requested. Here a threading or forking server is appropriate. In some cases, it may be appropriate to process part of a request @@ -589,8 +589,7 @@ """Start a new thread to process the request.""" t = threading.Thread(target = self.process_request_thread, args = (request, client_address)) - if self.daemon_threads: - t.setDaemon (1) + t.daemon = self.daemon_threads t.start() diff --git a/lib-python/2.7/_pyio.py b/lib-python/2.7/_pyio.py --- a/lib-python/2.7/_pyio.py +++ b/lib-python/2.7/_pyio.py @@ -8,6 +8,7 @@ import abc import codecs import warnings +import errno # Import thread instead of threading to reduce startup cost try: from thread import allocate_lock as Lock @@ -720,8 +721,11 @@ def close(self): if self.raw is not None and not self.closed: - self.flush() - self.raw.close() + try: + # may raise BlockingIOError or BrokenPipeError etc + self.flush() + finally: + self.raw.close() def detach(self): if self.raw is None: @@ -1074,13 +1078,9 @@ # XXX we can implement some more tricks to try and avoid # partial writes if len(self._write_buf) > self.buffer_size: - # We're full, so let's pre-flush the buffer - try: - self._flush_unlocked() - except BlockingIOError as e: - # We can't accept anything else. - # XXX Why not just let the exception pass through? - raise BlockingIOError(e.errno, e.strerror, 0) + # We're full, so let's pre-flush the buffer. (This may + # raise BlockingIOError with characters_written == 0.) + self._flush_unlocked() before = len(self._write_buf) self._write_buf.extend(b) written = len(self._write_buf) - before @@ -1111,24 +1111,23 @@ def _flush_unlocked(self): if self.closed: raise ValueError("flush of closed file") - written = 0 - try: - while self._write_buf: - try: - n = self.raw.write(self._write_buf) - except IOError as e: - if e.errno != EINTR: - raise - continue - if n > len(self._write_buf) or n < 0: - raise IOError("write() returned incorrect number of bytes") - del self._write_buf[:n] - written += n - except BlockingIOError as e: - n = e.characters_written + while self._write_buf: + try: + n = self.raw.write(self._write_buf) + except BlockingIOError: + raise RuntimeError("self.raw should implement RawIOBase: it " + "should not raise BlockingIOError") + except IOError as e: + if e.errno != EINTR: + raise + continue + if n is None: + raise BlockingIOError( + errno.EAGAIN, + "write could not complete without blocking", 0) + if n > len(self._write_buf) or n < 0: + raise IOError("write() returned incorrect number of bytes") del self._write_buf[:n] - written += n - raise BlockingIOError(e.errno, e.strerror, written) def tell(self): return _BufferedIOMixin.tell(self) + len(self._write_buf) diff --git a/lib-python/2.7/aifc.py b/lib-python/2.7/aifc.py --- a/lib-python/2.7/aifc.py +++ b/lib-python/2.7/aifc.py @@ -162,6 +162,12 @@ except struct.error: raise EOFError +def _read_ushort(file): + try: + return struct.unpack('>H', file.read(2))[0] + except struct.error: + raise EOFError + def _read_string(file): length = ord(file.read(1)) if length == 0: @@ -194,13 +200,19 @@ def _write_short(f, x): f.write(struct.pack('>h', x)) +def _write_ushort(f, x): + f.write(struct.pack('>H', x)) + def _write_long(f, x): + f.write(struct.pack('>l', x)) + +def _write_ulong(f, x): f.write(struct.pack('>L', x)) def _write_string(f, s): if len(s) > 255: raise ValueError("string exceeds maximum pstring length") - f.write(chr(len(s))) + f.write(struct.pack('B', len(s))) f.write(s) if len(s) & 1 == 0: f.write(chr(0)) @@ -218,7 +230,7 @@ lomant = 0 else: fmant, expon = math.frexp(x) - if expon > 16384 or fmant >= 1: # Infinity or NaN + if expon > 16384 or fmant >= 1 or fmant != fmant: # Infinity or NaN expon = sign|0x7FFF himant = 0 lomant = 0 @@ -234,9 +246,9 @@ fmant = math.ldexp(fmant - fsmant, 32) fsmant = math.floor(fmant) lomant = long(fsmant) - _write_short(f, expon) - _write_long(f, himant) - _write_long(f, lomant) + _write_ushort(f, expon) + _write_ulong(f, himant) + _write_ulong(f, lomant) from chunk import Chunk @@ -840,15 +852,15 @@ if self._aifc: self._file.write('AIFC') self._file.write('FVER') - _write_long(self._file, 4) - _write_long(self._file, self._version) + _write_ulong(self._file, 4) + _write_ulong(self._file, self._version) else: self._file.write('AIFF') self._file.write('COMM') - _write_long(self._file, commlength) + _write_ulong(self._file, commlength) _write_short(self._file, self._nchannels) self._nframes_pos = self._file.tell() - _write_long(self._file, self._nframes) + _write_ulong(self._file, self._nframes) _write_short(self._file, self._sampwidth * 8) _write_float(self._file, self._framerate) if self._aifc: @@ -856,9 +868,9 @@ _write_string(self._file, self._compname) self._file.write('SSND') self._ssnd_length_pos = self._file.tell() - _write_long(self._file, self._datalength + 8) - _write_long(self._file, 0) - _write_long(self._file, 0) + _write_ulong(self._file, self._datalength + 8) + _write_ulong(self._file, 0) + _write_ulong(self._file, 0) def _write_form_length(self, datalength): if self._aifc: @@ -869,8 +881,8 @@ else: commlength = 18 verslength = 0 - _write_long(self._file, 4 + verslength + self._marklength + \ - 8 + commlength + 16 + datalength) + _write_ulong(self._file, 4 + verslength + self._marklength + \ + 8 + commlength + 16 + datalength) return commlength def _patchheader(self): @@ -888,9 +900,9 @@ self._file.seek(self._form_length_pos, 0) dummy = self._write_form_length(datalength) self._file.seek(self._nframes_pos, 0) - _write_long(self._file, self._nframeswritten) + _write_ulong(self._file, self._nframeswritten) self._file.seek(self._ssnd_length_pos, 0) - _write_long(self._file, datalength + 8) + _write_ulong(self._file, datalength + 8) self._file.seek(curpos, 0) self._nframes = self._nframeswritten self._datalength = datalength @@ -905,13 +917,13 @@ length = length + len(name) + 1 + 6 if len(name) & 1 == 0: length = length + 1 - _write_long(self._file, length) + _write_ulong(self._file, length) self._marklength = length + 8 _write_short(self._file, len(self._markers)) for marker in self._markers: id, pos, name = marker _write_short(self._file, id) - _write_long(self._file, pos) + _write_ulong(self._file, pos) _write_string(self._file, name) def open(f, mode=None): diff --git a/lib-python/2.7/asyncore.py b/lib-python/2.7/asyncore.py --- a/lib-python/2.7/asyncore.py +++ b/lib-python/2.7/asyncore.py @@ -132,7 +132,8 @@ is_w = obj.writable() if is_r: r.append(fd) - if is_w: + # accepting sockets should not be writable + if is_w and not obj.accepting: w.append(fd) if is_r or is_w: e.append(fd) @@ -179,7 +180,8 @@ flags = 0 if obj.readable(): flags |= select.POLLIN | select.POLLPRI - if obj.writable(): + # accepting sockets should not be writable + if obj.writable() and not obj.accepting: flags |= select.POLLOUT if flags: # Only check for exceptions if object was either readable diff --git a/lib-python/2.7/cgi.py b/lib-python/2.7/cgi.py --- a/lib-python/2.7/cgi.py +++ b/lib-python/2.7/cgi.py @@ -293,7 +293,7 @@ while s[:1] == ';': s = s[1:] end = s.find(';') - while end > 0 and s.count('"', 0, end) % 2: + while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: end = s.find(';', end + 1) if end < 0: end = len(s) diff --git a/lib-python/2.7/cmd.py b/lib-python/2.7/cmd.py --- a/lib-python/2.7/cmd.py +++ b/lib-python/2.7/cmd.py @@ -209,6 +209,8 @@ if cmd is None: return self.default(line) self.lastcmd = line + if line == 'EOF' : + self.lastcmd = '' if cmd == '': return self.default(line) else: diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -312,6 +312,7 @@ def _asdict(self): 'Return a new OrderedDict which maps field names to their values' return OrderedDict(zip(self._fields, self)) \n + __dict__ = property(_asdict) \n def _replace(_self, **kwds): 'Return a new %(typename)s object replacing specified fields with new values' result = _self._make(map(kwds.pop, %(field_names)r, _self)) diff --git a/lib-python/2.7/compileall.py b/lib-python/2.7/compileall.py --- a/lib-python/2.7/compileall.py +++ b/lib-python/2.7/compileall.py @@ -1,4 +1,4 @@ -"""Module/script to "compile" all .py files to .pyc (or .pyo) file. +"""Module/script to byte-compile all .py files to .pyc (or .pyo) files. When called as a script with arguments, this compiles the directories given as arguments recursively; the -l option prevents it from @@ -26,8 +26,8 @@ dir: the directory to byte-compile maxlevels: maximum recursion level (default 10) - ddir: if given, purported directory name (this is the - directory name that will show up in error messages) + ddir: the directory that will be prepended to the path to the + file as it is compiled into each byte-code file. force: if 1, force compilation, even if timestamps are up-to-date quiet: if 1, be quiet during compilation """ @@ -64,8 +64,8 @@ Arguments (only fullname is required): fullname: the file to byte-compile - ddir: if given, purported directory name (this is the - directory name that will show up in error messages) + ddir: if given, the directory name compiled in to the + byte-code file. force: if 1, force compilation, even if timestamps are up-to-date quiet: if 1, be quiet during compilation """ @@ -157,14 +157,27 @@ print msg print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \ "[-x regexp] [-i list] [directory|file ...]" - print "-l: don't recurse down" + print + print "arguments: zero or more file and directory names to compile; " \ + "if no arguments given, " + print " defaults to the equivalent of -l sys.path" + print + print "options:" + print "-l: don't recurse into subdirectories" print "-f: force rebuild even if timestamps are up-to-date" - print "-q: quiet operation" - print "-d destdir: purported directory name for error messages" - print " if no directory arguments, -l sys.path is assumed" - print "-x regexp: skip files matching the regular expression regexp" - print " the regexp is searched for in the full path of the file" - print "-i list: expand list with its content (file and directory names)" + print "-q: output only error messages" + print "-d destdir: directory to prepend to file paths for use in " \ + "compile-time tracebacks and in" + print " runtime tracebacks in cases where the source " \ + "file is unavailable" + print "-x regexp: skip files matching the regular expression regexp; " \ + "the regexp is searched for" + print " in the full path of each file considered for " \ + "compilation" + print "-i file: add all the files and directories listed in file to " \ + "the list considered for" + print ' compilation; if "-", names are read from stdin' + sys.exit(2) maxlevels = 10 ddir = None @@ -205,7 +218,7 @@ else: success = compile_path() except KeyboardInterrupt: - print "\n[interrupt]" + print "\n[interrupted]" success = 0 return success diff --git a/lib-python/2.7/cookielib.py b/lib-python/2.7/cookielib.py --- a/lib-python/2.7/cookielib.py +++ b/lib-python/2.7/cookielib.py @@ -1014,7 +1014,7 @@ (not erhn.startswith(".") and not ("."+erhn).endswith(domain))): _debug(" effective request-host %s (even with added " - "initial dot) does not end end with %s", + "initial dot) does not end with %s", erhn, domain) return False if (cookie.version > 0 or diff --git a/lib-python/2.7/ctypes/__init__.py b/lib-python/2.7/ctypes/__init__.py --- a/lib-python/2.7/ctypes/__init__.py +++ b/lib-python/2.7/ctypes/__init__.py @@ -263,6 +263,22 @@ from _ctypes import POINTER, pointer, _pointer_type_cache +def _reset_cache(): + _pointer_type_cache.clear() + _c_functype_cache.clear() + if _os.name in ("nt", "ce"): + _win_functype_cache.clear() + # _SimpleCData.c_wchar_p_from_param + POINTER(c_wchar).from_param = c_wchar_p.from_param + # _SimpleCData.c_char_p_from_param + POINTER(c_char).from_param = c_char_p.from_param + _pointer_type_cache[None] = c_void_p + # XXX for whatever reasons, creating the first instance of a callback + # function is needed for the unittests on Win64 to succeed. This MAY + # be a compiler bug, since the problem occurs only when _ctypes is + # compiled with the MS SDK compiler. Or an uninitialized variable? + CFUNCTYPE(c_int)(lambda: None) + try: from _ctypes import set_conversion_mode except ImportError: @@ -279,8 +295,6 @@ class c_wchar(_SimpleCData): _type_ = "u" - POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param - def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array @@ -299,8 +313,6 @@ return buf raise TypeError(init) -POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param - # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: @@ -463,8 +475,6 @@ descr = FormatError(code).strip() return WindowsError(code, descr) -_pointer_type_cache[None] = c_void_p - if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int @@ -550,8 +560,4 @@ elif sizeof(kind) == 8: c_uint64 = kind del(kind) -# XXX for whatever reasons, creating the first instance of a callback -# function is needed for the unittests on Win64 to succeed. This MAY -# be a compiler bug, since the problem occurs only when _ctypes is -# compiled with the MS SDK compiler. Or an uninitialized variable? -CFUNCTYPE(c_int)(lambda: None) +_reset_cache() diff --git a/lib-python/2.7/ctypes/_endian.py b/lib-python/2.7/ctypes/_endian.py --- a/lib-python/2.7/ctypes/_endian.py +++ b/lib-python/2.7/ctypes/_endian.py @@ -4,20 +4,24 @@ import sys from ctypes import * -_array_type = type(c_int * 3) +_array_type = type(Array) def _other_endian(typ): """Return the type with the 'other' byte order. Simple types like c_int and so on already have __ctype_be__ and __ctype_le__ attributes which contain the types, for more complicated types - only arrays are supported. + arrays and structures are supported. """ - try: + # check _OTHER_ENDIAN attribute (present if typ is primitive type) + if hasattr(typ, _OTHER_ENDIAN): return getattr(typ, _OTHER_ENDIAN) - except AttributeError: - if type(typ) == _array_type: - return _other_endian(typ._type_) * typ._length_ - raise TypeError("This type does not support other endian: %s" % typ) + # if typ is array + if isinstance(typ, _array_type): + return _other_endian(typ._type_) * typ._length_ + # if typ is structure + if issubclass(typ, Structure): + return typ + raise TypeError("This type does not support other endian: %s" % typ) class _swapped_meta(type(Structure)): def __setattr__(self, attrname, value): diff --git a/lib-python/2.7/ctypes/test/test_as_parameter.py b/lib-python/2.7/ctypes/test/test_as_parameter.py --- a/lib-python/2.7/ctypes/test/test_as_parameter.py +++ b/lib-python/2.7/ctypes/test/test_as_parameter.py @@ -74,6 +74,7 @@ def test_callbacks(self): f = dll._testfunc_callback_i_if f.restype = c_int + f.argtypes = None MyCallback = CFUNCTYPE(c_int, c_int) diff --git a/lib-python/2.7/ctypes/test/test_buffers.py b/lib-python/2.7/ctypes/test/test_buffers.py --- a/lib-python/2.7/ctypes/test/test_buffers.py +++ b/lib-python/2.7/ctypes/test/test_buffers.py @@ -20,6 +20,10 @@ self.assertEqual(b[::2], "ac") self.assertEqual(b[::5], "a") + def test_buffer_interface(self): + self.assertEqual(len(bytearray(create_string_buffer(0))), 0) + self.assertEqual(len(bytearray(create_string_buffer(1))), 1) + def test_string_conversion(self): b = create_string_buffer(u"abc") self.assertEqual(len(b), 4) # trailing nul char diff --git a/lib-python/2.7/ctypes/test/test_byteswap.py b/lib-python/2.7/ctypes/test/test_byteswap.py --- a/lib-python/2.7/ctypes/test/test_byteswap.py +++ b/lib-python/2.7/ctypes/test/test_byteswap.py @@ -1,4 +1,4 @@ -import sys, unittest, struct, math +import sys, unittest, struct, math, ctypes from binascii import hexlify from ctypes import * @@ -191,19 +191,34 @@ pass self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)]) + @xfail def test_struct_struct(self): - # Nested structures with different byte order not (yet) supported - if sys.byteorder == "little": - base = BigEndianStructure - else: - base = LittleEndianStructure + # nested structures with different byteorders - class T(Structure): - _fields_ = [("a", c_int), - ("b", c_int)] - class S(base): - pass - self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)]) + # create nested structures with given byteorders and set memory to data + + for nested, data in ( + (BigEndianStructure, b'\0\0\0\1\0\0\0\2'), + (LittleEndianStructure, b'\1\0\0\0\2\0\0\0'), + ): + for parent in ( + BigEndianStructure, + LittleEndianStructure, + Structure, + ): + class NestedStructure(nested): + _fields_ = [("x", c_uint32), + ("y", c_uint32)] + + class TestStructure(parent): + _fields_ = [("point", NestedStructure)] + + self.assertEqual(len(data), sizeof(TestStructure)) + ptr = POINTER(TestStructure) + s = cast(data, ptr)[0] + del ctypes._pointer_type_cache[TestStructure] + self.assertEqual(s.point.x, 1) + self.assertEqual(s.point.y, 2) @xfail def test_struct_fields_2(self): diff --git a/lib-python/2.7/ctypes/test/test_callbacks.py b/lib-python/2.7/ctypes/test/test_callbacks.py --- a/lib-python/2.7/ctypes/test/test_callbacks.py +++ b/lib-python/2.7/ctypes/test/test_callbacks.py @@ -142,6 +142,14 @@ if isinstance(x, X)] self.assertEqual(len(live), 0) + def test_issue12483(self): + import gc + class Nasty: + def __del__(self): + gc.collect() + CFUNCTYPE(None)(lambda x=Nasty(): None) + + try: WINFUNCTYPE except NameError: diff --git a/lib-python/2.7/ctypes/test/test_functions.py b/lib-python/2.7/ctypes/test/test_functions.py --- a/lib-python/2.7/ctypes/test/test_functions.py +++ b/lib-python/2.7/ctypes/test/test_functions.py @@ -253,6 +253,7 @@ def test_callbacks(self): f = dll._testfunc_callback_i_if f.restype = c_int + f.argtypes = None MyCallback = CFUNCTYPE(c_int, c_int) diff --git a/lib-python/2.7/ctypes/test/test_structures.py b/lib-python/2.7/ctypes/test/test_structures.py --- a/lib-python/2.7/ctypes/test/test_structures.py +++ b/lib-python/2.7/ctypes/test/test_structures.py @@ -239,6 +239,14 @@ pass self.assertRaises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)]) + def test_invalid_name(self): + # field name must be string + def declare_with_name(name): + class S(Structure): + _fields_ = [(name, c_int)] + + self.assertRaises(TypeError, declare_with_name, u"x\xe9") + def test_intarray_fields(self): class SomeInts(Structure): _fields_ = [("a", c_int * 4)] @@ -324,6 +332,18 @@ else: self.assertEqual(msg, "(Phone) exceptions.TypeError: too many initializers") + def test_huge_field_name(self): + # issue12881: segfault with large structure field names + def create_class(length): + class S(Structure): + _fields_ = [('x' * length, c_int)] + + for length in [10 ** i for i in range(0, 8)]: + try: + create_class(length) + except MemoryError: + # MemoryErrors are OK, we just don't want to segfault + pass def get_except(self, func, *args): try: diff --git a/lib-python/2.7/ctypes/util.py b/lib-python/2.7/ctypes/util.py --- a/lib-python/2.7/ctypes/util.py +++ b/lib-python/2.7/ctypes/util.py @@ -182,28 +182,6 @@ else: - def _findLib_ldconfig(name): - # XXX assuming GLIBC's ldconfig (with option -p) - expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) - f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null') - try: - data = f.read() - finally: - f.close() - res = re.search(expr, data) - if not res: - # Hm, this works only for libs needed by the python executable. - cmd = 'ldd %s 2>/dev/null' % sys.executable - f = os.popen(cmd) - try: - data = f.read() - finally: - f.close() - res = re.search(expr, data) - if not res: - return None - return res.group(0) - def _findSoname_ldconfig(name): import struct if struct.calcsize('l') == 4: @@ -220,8 +198,7 @@ abi_type = mach_map.get(machine, 'libc6') # XXX assuming GLIBC's ldconfig (with option -p) - expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \ - % (abi_type, re.escape(name)) + expr = r'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type) f = os.popen('/sbin/ldconfig -p 2>/dev/null') try: data = f.read() diff --git a/lib-python/2.7/decimal.py b/lib-python/2.7/decimal.py --- a/lib-python/2.7/decimal.py +++ b/lib-python/2.7/decimal.py @@ -21,7 +21,7 @@ This is a Py2.3 implementation of decimal floating point arithmetic based on the General Decimal Arithmetic Specification: - www2.hursley.ibm.com/decimal/decarith.html + http://speleotrove.com/decimal/decarith.html and IEEE standard 854-1987: @@ -1942,9 +1942,9 @@ nonzero. For efficiency, other._exp should not be too large, so that 10**abs(other._exp) is a feasible calculation.""" - # In the comments below, we write x for the value of self and - # y for the value of other. Write x = xc*10**xe and y = - # yc*10**ye. + # In the comments below, we write x for the value of self and y for the + # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc + # and yc positive integers not divisible by 10. # The main purpose of this method is to identify the *failure* # of x**y to be exactly representable with as little effort as @@ -1952,13 +1952,12 @@ # eliminate the possibility of x**y being exact. Only if all # these tests are passed do we go on to actually compute x**y. - # Here's the main idea. First normalize both x and y. We - # express y as a rational m/n, with m and n relatively prime - # and n>0. Then for x**y to be exactly representable (at - # *any* precision), xc must be the nth power of a positive - # integer and xe must be divisible by n. If m is negative - # then additionally xc must be a power of either 2 or 5, hence - # a power of 2**n or 5**n. + # Here's the main idea. Express y as a rational number m/n, with m and + # n relatively prime and n>0. Then for x**y to be exactly + # representable (at *any* precision), xc must be the nth power of a + # positive integer and xe must be divisible by n. If y is negative + # then additionally xc must be a power of either 2 or 5, hence a power + # of 2**n or 5**n. # # There's a limit to how small |y| can be: if y=m/n as above # then: @@ -2030,21 +2029,43 @@ return None # now xc is a power of 2; e is its exponent e = _nbits(xc)-1 - # find e*y and xe*y; both must be integers - if ye >= 0: - y_as_int = yc*10**ye - e = e*y_as_int - xe = xe*y_as_int - else: - ten_pow = 10**-ye - e, remainder = divmod(e*yc, ten_pow) - if remainder: - return None - xe, remainder = divmod(xe*yc, ten_pow) - if remainder: - return None - - if e*65 >= p*93: # 93/65 > log(10)/log(5) + + # We now have: + # + # x = 2**e * 10**xe, e > 0, and y < 0. + # + # The exact result is: + # + # x**y = 5**(-e*y) * 10**(e*y + xe*y) + # + # provided that both e*y and xe*y are integers. Note that if + # 5**(-e*y) >= 10**p, then the result can't be expressed + # exactly with p digits of precision. + # + # Using the above, we can guard against large values of ye. + # 93/65 is an upper bound for log(10)/log(5), so if + # + # ye >= len(str(93*p//65)) + # + # then + # + # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), + # + # so 5**(-e*y) >= 10**p, and the coefficient of the result + # can't be expressed in p digits. + + # emax >= largest e such that 5**e < 10**p. + emax = p*93//65 + if ye >= len(str(emax)): + return None + + # Find -e*y and -xe*y; both must be integers + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: return None xc = 5**e @@ -2058,19 +2079,20 @@ while xc % 5 == 0: xc //= 5 e -= 1 - if ye >= 0: - y_as_integer = yc*10**ye - e = e*y_as_integer - xe = xe*y_as_integer - else: - ten_pow = 10**-ye - e, remainder = divmod(e*yc, ten_pow) - if remainder: - return None - xe, remainder = divmod(xe*yc, ten_pow) - if remainder: - return None - if e*3 >= p*10: # 10/3 > log(10)/log(2) + + # Guard against large values of ye, using the same logic as in + # the 'xc is a power of 2' branch. 10/3 is an upper bound for + # log(10)/log(2). + emax = p*10//3 + if ye >= len(str(emax)): + return None + + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: return None xc = 2**e else: @@ -5463,6 +5485,27 @@ hex_n = "%x" % n return 4*len(hex_n) - correction[hex_n[0]] +def _decimal_lshift_exact(n, e): + """ Given integers n and e, return n * 10**e if it's an integer, else None. + + The computation is designed to avoid computing large powers of 10 + unnecessarily. + + >>> _decimal_lshift_exact(3, 4) + 30000 + >>> _decimal_lshift_exact(300, -999999999) # returns None + + """ + if n == 0: + return 0 + elif e >= 0: + return n * 10**e + else: + # val_n = largest power of 10 dividing n. + str_n = str(abs(n)) + val_n = len(str_n) - len(str_n.rstrip('0')) + return None if val_n < -e else n // 10**-e + def _sqrt_nearest(n, a): """Closest integer to the square root of the positive integer n. a is an initial approximation to the square root. Any positive integer diff --git a/lib-python/2.7/distutils/__init__.py b/lib-python/2.7/distutils/__init__.py --- a/lib-python/2.7/distutils/__init__.py +++ b/lib-python/2.7/distutils/__init__.py @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "2.7.2" +__version__ = "2.7.3" #--end constants-- diff --git a/lib-python/2.7/distutils/ccompiler.py b/lib-python/2.7/distutils/ccompiler.py --- a/lib-python/2.7/distutils/ccompiler.py +++ b/lib-python/2.7/distutils/ccompiler.py @@ -18,58 +18,6 @@ from distutils.util import split_quoted, execute from distutils import log -_sysconfig = __import__('sysconfig') - -def customize_compiler(compiler): - """Do any platform-specific customization of a CCompiler instance. - - Mainly needed on Unix, so we can plug in the information that - varies across Unices and is stored in Python's Makefile. - """ - if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ - _sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO', 'AR', - 'ARFLAGS') - - if 'CC' in os.environ: - cc = os.environ['CC'] - if 'CXX' in os.environ: - cxx = os.environ['CXX'] - if 'LDSHARED' in os.environ: - ldshared = os.environ['LDSHARED'] - if 'CPP' in os.environ: - cpp = os.environ['CPP'] - else: - cpp = cc + " -E" # not always - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: - cflags = opt + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] - cflags = cflags + ' ' + os.environ['CPPFLAGS'] - ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - if 'AR' in os.environ: - ar = os.environ['AR'] - if 'ARFLAGS' in os.environ: - archiver = ar + ' ' + os.environ['ARFLAGS'] - else: - archiver = ar + ' ' + ar_flags - - cc_cmd = cc + ' ' + cflags - compiler.set_executables( - preprocessor=cpp, - compiler=cc_cmd, - compiler_so=cc_cmd + ' ' + ccshared, - compiler_cxx=cxx, - linker_so=ldshared, - linker_exe=cc, - archiver=archiver) - - compiler.shared_lib_extension = so_ext - class CCompiler: """Abstract base class to define the interface that must be implemented by real compiler classes. Also has some utility methods used by diff --git a/lib-python/2.7/distutils/command/bdist_dumb.py b/lib-python/2.7/distutils/command/bdist_dumb.py --- a/lib-python/2.7/distutils/command/bdist_dumb.py +++ b/lib-python/2.7/distutils/command/bdist_dumb.py @@ -58,7 +58,7 @@ self.format = None self.keep_temp = 0 self.dist_dir = None - self.skip_build = 0 + self.skip_build = None self.relative = 0 self.owner = None self.group = None @@ -78,7 +78,8 @@ self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'), - ('plat_name', 'plat_name')) + ('plat_name', 'plat_name'), + ('skip_build', 'skip_build')) def run(self): if not self.skip_build: diff --git a/lib-python/2.7/distutils/command/bdist_msi.py b/lib-python/2.7/distutils/command/bdist_msi.py --- a/lib-python/2.7/distutils/command/bdist_msi.py +++ b/lib-python/2.7/distutils/command/bdist_msi.py @@ -131,18 +131,22 @@ self.no_target_optimize = 0 self.target_version = None self.dist_dir = None - self.skip_build = 0 + self.skip_build = None self.install_script = None self.pre_install_script = None self.versions = None def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'msi') + short_version = get_python_version() if (not self.target_version) and self.distribution.has_ext_modules(): self.target_version = short_version + if self.target_version: self.versions = [self.target_version] if not self.skip_build and self.distribution.has_ext_modules()\ diff --git a/lib-python/2.7/distutils/command/bdist_wininst.py b/lib-python/2.7/distutils/command/bdist_wininst.py --- a/lib-python/2.7/distutils/command/bdist_wininst.py +++ b/lib-python/2.7/distutils/command/bdist_wininst.py @@ -71,7 +71,7 @@ self.dist_dir = None self.bitmap = None self.title = None - self.skip_build = 0 + self.skip_build = None self.install_script = None self.pre_install_script = None self.user_access_control = None @@ -80,6 +80,8 @@ def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + if self.bdist_dir is None: if self.skip_build and self.plat_name: # If build is skipped and plat_name is overridden, bdist will @@ -89,8 +91,10 @@ # next the command will be initialized using that name bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'wininst') + if not self.target_version: self.target_version = "" + if not self.skip_build and self.distribution.has_ext_modules(): short_version = get_python_version() if self.target_version and self.target_version != short_version: diff --git a/lib-python/2.7/distutils/command/build_clib.py b/lib-python/2.7/distutils/command/build_clib.py --- a/lib-python/2.7/distutils/command/build_clib.py +++ b/lib-python/2.7/distutils/command/build_clib.py @@ -19,7 +19,7 @@ import os from distutils.core import Command from distutils.errors import DistutilsSetupError -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler from distutils import log def show_compilers(): diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py --- a/lib-python/2.7/distutils/command/build_ext.py +++ b/lib-python/2.7/distutils/command/build_ext.py @@ -160,8 +160,7 @@ if plat_py_include != py_include: self.include_dirs.append(plat_py_include) - if isinstance(self.libraries, str): - self.libraries = [self.libraries] + self.ensure_string_list('libraries') # Life is easier if we're not forever checking for None, so # simplify these options to empty lists if unset diff --git a/lib-python/2.7/distutils/command/check.py b/lib-python/2.7/distutils/command/check.py --- a/lib-python/2.7/distutils/command/check.py +++ b/lib-python/2.7/distutils/command/check.py @@ -5,6 +5,7 @@ __revision__ = "$Id$" from distutils.core import Command +from distutils.dist import PKG_INFO_ENCODING from distutils.errors import DistutilsSetupError try: @@ -108,6 +109,8 @@ def check_restructuredtext(self): """Checks if the long string fields are reST-compliant.""" data = self.distribution.get_long_description() + if not isinstance(data, unicode): + data = data.decode(PKG_INFO_ENCODING) for warning in self._check_rst_data(data): line = warning[-1].get('line') if line is None: diff --git a/lib-python/2.7/distutils/command/config.py b/lib-python/2.7/distutils/command/config.py --- a/lib-python/2.7/distutils/command/config.py +++ b/lib-python/2.7/distutils/command/config.py @@ -16,7 +16,7 @@ from distutils.core import Command from distutils.errors import DistutilsExecError -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler from distutils import log LANG_EXT = {'c': '.c', 'c++': '.cxx'} diff --git a/lib-python/2.7/distutils/command/register.py b/lib-python/2.7/distutils/command/register.py --- a/lib-python/2.7/distutils/command/register.py +++ b/lib-python/2.7/distutils/command/register.py @@ -10,7 +10,6 @@ import urllib2 import getpass import urlparse -import StringIO from warnings import warn from distutils.core import PyPIRCCommand @@ -260,21 +259,30 @@ boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = '\n--' + boundary end_boundary = sep_boundary + '--' - body = StringIO.StringIO() + chunks = [] for key, value in data.items(): # handle multiple entries for the same name if type(value) not in (type([]), type( () )): value = [value] for value in value: - body.write(sep_boundary) - body.write('\nContent-Disposition: form-data; name="%s"'%key) - body.write("\n\n") - body.write(value) + chunks.append(sep_boundary) + chunks.append('\nContent-Disposition: form-data; name="%s"'%key) + chunks.append("\n\n") + chunks.append(value) if value and value[-1] == '\r': - body.write('\n') # write an extra newline (lurve Macs) - body.write(end_boundary) - body.write("\n") - body = body.getvalue() + chunks.append('\n') # write an extra newline (lurve Macs) + chunks.append(end_boundary) + chunks.append("\n") + + # chunks may be bytes (str) or unicode objects that we need to encode + body = [] + for chunk in chunks: + if isinstance(chunk, unicode): + body.append(chunk.encode('utf-8')) + else: + body.append(chunk) + + body = ''.join(body) # build the Request headers = { diff --git a/lib-python/2.7/distutils/command/sdist.py b/lib-python/2.7/distutils/command/sdist.py --- a/lib-python/2.7/distutils/command/sdist.py +++ b/lib-python/2.7/distutils/command/sdist.py @@ -182,14 +182,20 @@ reading the manifest, or just using the default file set -- it all depends on the user's options. """ - # new behavior: + # new behavior when using a template: # the file list is recalculated everytime because # even if MANIFEST.in or setup.py are not changed # the user might have added some files in the tree that # need to be included. # - # This makes --force the default and only behavior. + # This makes --force the default and only behavior with templates. template_exists = os.path.isfile(self.template) + if not template_exists and self._manifest_is_not_generated(): + self.read_manifest() + self.filelist.sort() + self.filelist.remove_duplicates() + return + if not template_exists: self.warn(("manifest template '%s' does not exist " + "(using default file list)") % @@ -314,7 +320,10 @@ try: self.filelist.process_template_line(line) - except DistutilsTemplateError, msg: + # the call above can raise a DistutilsTemplateError for + # malformed lines, or a ValueError from the lower-level + # convert_path function + except (DistutilsTemplateError, ValueError) as msg: self.warn("%s, line %d: %s" % (template.filename, template.current_line, msg)) @@ -352,23 +361,28 @@ by 'add_defaults()' and 'read_template()') to the manifest file named by 'self.manifest'. """ - if os.path.isfile(self.manifest): - fp = open(self.manifest) - try: - first_line = fp.readline() - finally: - fp.close() - - if first_line != '# file GENERATED by distutils, do NOT edit\n': - log.info("not writing to manually maintained " - "manifest file '%s'" % self.manifest) - return + if self._manifest_is_not_generated(): + log.info("not writing to manually maintained " + "manifest file '%s'" % self.manifest) + return content = self.filelist.files[:] content.insert(0, '# file GENERATED by distutils, do NOT edit') self.execute(file_util.write_file, (self.manifest, content), "writing manifest file '%s'" % self.manifest) + def _manifest_is_not_generated(self): + # check for special comment used in 2.7.1 and higher + if not os.path.isfile(self.manifest): + return False + + fp = open(self.manifest, 'rU') + try: + first_line = fp.readline() + finally: + fp.close() + return first_line != '# file GENERATED by distutils, do NOT edit\n' + def read_manifest(self): """Read the manifest file (named by 'self.manifest') and use it to fill in 'self.filelist', the list of files to include in the source @@ -376,12 +390,11 @@ """ log.info("reading manifest file '%s'", self.manifest) manifest = open(self.manifest) - while 1: - line = manifest.readline() - if line == '': # end of file - break - if line[-1] == '\n': - line = line[0:-1] + for line in manifest: + # ignore comments and blank lines + line = line.strip() + if line.startswith('#') or not line: + continue self.filelist.append(line) manifest.close() diff --git a/lib-python/2.7/distutils/dep_util.py b/lib-python/2.7/distutils/dep_util.py --- a/lib-python/2.7/distutils/dep_util.py +++ b/lib-python/2.7/distutils/dep_util.py @@ -7,6 +7,7 @@ __revision__ = "$Id$" import os +from stat import ST_MTIME from distutils.errors import DistutilsFileError def newer(source, target): @@ -27,7 +28,7 @@ if not os.path.exists(target): return True - return os.stat(source).st_mtime > os.stat(target).st_mtime + return os.stat(source)[ST_MTIME] > os.stat(target)[ST_MTIME] def newer_pairwise(sources, targets): """Walk two filename lists in parallel, testing if each source is newer @@ -71,7 +72,7 @@ # is more recent than 'target', then 'target' is out-of-date and # we can immediately return true. If we fall through to the end # of the loop, then 'target' is up-to-date and we return false. - target_mtime = os.stat(target).st_mtime + target_mtime = os.stat(target)[ST_MTIME] for source in sources: if not os.path.exists(source): @@ -82,7 +83,7 @@ elif missing == 'newer': # missing source means target is return True # out-of-date - if os.stat(source).st_mtime > target_mtime: + if os.stat(source)[ST_MTIME] > target_mtime: return True return False diff --git a/lib-python/2.7/distutils/dist.py b/lib-python/2.7/distutils/dist.py --- a/lib-python/2.7/distutils/dist.py +++ b/lib-python/2.7/distutils/dist.py @@ -1111,7 +1111,8 @@ """Write the PKG-INFO format data to a file object. """ version = '1.0' - if self.provides or self.requires or self.obsoletes: + if (self.provides or self.requires or self.obsoletes or + self.classifiers or self.download_url): version = '1.1' self._write_field(file, 'Metadata-Version', version) diff --git a/lib-python/2.7/distutils/filelist.py b/lib-python/2.7/distutils/filelist.py --- a/lib-python/2.7/distutils/filelist.py +++ b/lib-python/2.7/distutils/filelist.py @@ -210,6 +210,7 @@ Return 1 if files are found. """ + # XXX docstring lying about what the special chars are? files_found = 0 pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) self.debug_print("include_pattern: applying regex r'%s'" % @@ -297,11 +298,14 @@ # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, # and by extension they shouldn't match such "special characters" under # any OS. So change all non-escaped dots in the RE to match any - # character except the special characters. - # XXX currently the "special characters" are just slash -- i.e. this is - # Unix-only. - pattern_re = re.sub(r'((?\s*" manifest_buf = re.sub(pattern, "", manifest_buf) + # Now see if any other assemblies are referenced - if not, we + # don't want a manifest embedded. + pattern = re.compile( + r"""|)""", re.DOTALL) + if re.search(pattern, manifest_buf) is None: + return None + manifest_f = open(manifest_file, 'w') try: manifest_f.write(manifest_buf) + return manifest_file finally: manifest_f.close() except IOError: diff --git a/lib-python/2.7/distutils/spawn.py b/lib-python/2.7/distutils/spawn.py --- a/lib-python/2.7/distutils/spawn.py +++ b/lib-python/2.7/distutils/spawn.py @@ -96,17 +96,43 @@ raise DistutilsExecError, \ "command '%s' failed with exit status %d" % (cmd[0], rc) +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return exec_fn = search_path and os.execvp or os.execv + exec_args = [cmd[0], cmd] + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(cmd[0], cmd) + exec_fn(*exec_args) except OSError, e: sys.stderr.write("unable to execute %s: %s\n" % (cmd[0], e.strerror)) diff --git a/lib-python/2.7/distutils/sysconfig.py b/lib-python/2.7/distutils/sysconfig.py --- a/lib-python/2.7/distutils/sysconfig.py +++ b/lib-python/2.7/distutils/sysconfig.py @@ -26,4 +26,5 @@ from distutils.sysconfig_cpython import _config_vars # needed by setuptools from distutils.sysconfig_cpython import _variable_rx # read_setup_file() +_USE_CLANG = None diff --git a/lib-python/2.7/distutils/sysconfig_cpython.py b/lib-python/2.7/distutils/sysconfig_cpython.py --- a/lib-python/2.7/distutils/sysconfig_cpython.py +++ b/lib-python/2.7/distutils/sysconfig_cpython.py @@ -149,12 +149,43 @@ varies across Unices and is stored in Python's Makefile. """ if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \ + (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO') + 'CCSHARED', 'LDSHARED', 'SO', 'AR', + 'ARFLAGS') + newcc = None if 'CC' in os.environ: - cc = os.environ['CC'] + newcc = os.environ['CC'] + elif sys.platform == 'darwin' and cc == 'gcc-4.2': + # Issue #13590: + # Since Apple removed gcc-4.2 in Xcode 4.2, we can no + # longer assume it is available for extension module builds. + # If Python was built with gcc-4.2, check first to see if + # it is available on this system; if not, try to use clang + # instead unless the caller explicitly set CC. + global _USE_CLANG + if _USE_CLANG is None: + from distutils import log + from subprocess import Popen, PIPE + p = Popen("! type gcc-4.2 && type clang && exit 2", + shell=True, stdout=PIPE, stderr=PIPE) + p.wait() + if p.returncode == 2: + _USE_CLANG = True + log.warn("gcc-4.2 not found, using clang instead") + else: + _USE_CLANG = False + if _USE_CLANG: + newcc = 'clang' + if newcc: + # On OS X, if CC is overridden, use that as the default + # command for LDSHARED as well + if (sys.platform == 'darwin' + and 'LDSHARED' not in os.environ + and ldshared.startswith(cc)): + ldshared = newcc + ldshared[len(cc):] + cc = newcc if 'CXX' in os.environ: cxx = os.environ['CXX'] if 'LDSHARED' in os.environ: @@ -172,6 +203,12 @@ cpp = cpp + ' ' + os.environ['CPPFLAGS'] cflags = cflags + ' ' + os.environ['CPPFLAGS'] ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] + if 'AR' in os.environ: + ar = os.environ['AR'] + if 'ARFLAGS' in os.environ: + archiver = ar + ' ' + os.environ['ARFLAGS'] + else: + archiver = ar + ' ' + ar_flags cc_cmd = cc + ' ' + cflags compiler.set_executables( @@ -180,7 +217,8 @@ compiler_so=cc_cmd + ' ' + ccshared, compiler_cxx=cxx, linker_so=ldshared, - linker_exe=cc) + linker_exe=cc, + archiver=archiver) compiler.shared_lib_extension = so_ext @@ -380,21 +418,6 @@ raise DistutilsPlatformError(my_msg) - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target - elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')): - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. diff --git a/lib-python/2.7/distutils/tests/Setup.sample b/lib-python/2.7/distutils/tests/Setup.sample old mode 100755 new mode 100644 diff --git a/lib-python/2.7/distutils/tests/support.py b/lib-python/2.7/distutils/tests/support.py --- a/lib-python/2.7/distutils/tests/support.py +++ b/lib-python/2.7/distutils/tests/support.py @@ -1,7 +1,10 @@ """Support code for distutils test cases.""" import os +import sys import shutil import tempfile +import unittest +import sysconfig from copy import deepcopy import warnings @@ -9,6 +12,7 @@ from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL from distutils.core import Distribution + def capture_warnings(func): def _capture_warnings(*args, **kw): with warnings.catch_warnings(): @@ -16,6 +20,7 @@ return func(*args, **kw) return _capture_warnings + class LoggingSilencer(object): def setUp(self): @@ -49,6 +54,7 @@ def clear_logs(self): self.logs = [] + class TempdirManager(object): """Mix-in class that handles temporary directories for test cases. @@ -57,9 +63,13 @@ def setUp(self): super(TempdirManager, self).setUp() + self.old_cwd = os.getcwd() self.tempdirs = [] def tearDown(self): + # Restore working dir, for Solaris and derivatives, where rmdir() + # on the current directory fails. + os.chdir(self.old_cwd) super(TempdirManager, self).tearDown() while self.tempdirs: d = self.tempdirs.pop() @@ -105,6 +115,7 @@ return pkg_dir, dist + class DummyCommand: """Class to store options for retrieval via set_undefined_options().""" @@ -115,6 +126,7 @@ def ensure_finalized(self): pass + class EnvironGuard(object): def setUp(self): @@ -131,3 +143,79 @@ del os.environ[key] super(EnvironGuard, self).tearDown() + + +def copy_xxmodule_c(directory): From noreply at buildbot.pypy.org Tue Oct 2 16:37:43 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:43 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Split instrument.h and instrument.c Message-ID: <20121002143743.08D351C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57721:c16499d28e1f Date: 2012-09-30 20:39 +0200 http://bitbucket.org/pypy/pypy/changeset/c16499d28e1f/ Log: Split instrument.h and instrument.c diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py --- a/pypy/translator/c/funcgen.py +++ b/pypy/translator/c/funcgen.py @@ -840,7 +840,7 @@ self.db.instrument_ncounter = max(self.db.instrument_ncounter, counter_label+1) counter_label = self.expr(op.args[1]) - return 'INSTRUMENT_COUNT(%s);' % counter_label + return 'PYPY_INSTRUMENT_COUNT(%s);' % counter_label def OP_IS_EARLY_CONSTANT(self, op): return '%s = 0; /* IS_EARLY_CONSTANT */' % (self.expr(op.result),) diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -252,7 +252,7 @@ else: defines['PYPY_STANDALONE'] = db.get(pf) if self.config.translation.instrument: - defines['INSTRUMENT'] = 1 + defines['PYPY_INSTRUMENT'] = 1 if CBuilder.have___thread: if not self.config.translation.no__thread: defines['USE___THREAD'] = 1 @@ -912,6 +912,7 @@ srcdir / 'debug_print.c', srcdir / 'thread.c', srcdir / 'asm.c', + srcdir / 'instrument.c', ] if _CYGWIN: files.append(srcdir / 'cygwin_wait.c') @@ -961,10 +962,10 @@ gen_startupcode(f, database) f.close() - if 'INSTRUMENT' in defines: + if 'PYPY_INSTRUMENT' in defines: fi = incfilename.open('a') n = database.instrument_ncounter - print >>fi, "#define INSTRUMENT_NCOUNTER %d" % n + print >>fi, "#define PYPY_INSTRUMENT_NCOUNTER %d" % n fi.close() eci = add_extra_files(eci) diff --git a/pypy/translator/c/src/instrument.c b/pypy/translator/c/src/instrument.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/instrument.c @@ -0,0 +1,69 @@ +#include +#include "common_header.h" + +#ifdef PYPY_INSTRUMENT + +#include +#include +#include +#ifndef _WIN32 +#include +#include +#include +#include +#else +#include +#endif + +typedef unsigned long instrument_count_t; + +instrument_count_t *_instrument_counters = NULL; + +void instrument_setup() { + char *fname = getenv("PYPY_INSTRUMENT_COUNTERS"); + if (fname) { + int fd; +#ifdef _WIN32 + HANDLE map_handle; + HANDLE file_handle; +#endif + void *buf; + size_t sz = sizeof(instrument_count_t)*PYPY_INSTRUMENT_NCOUNTER; + fd = open(fname, O_CREAT|O_TRUNC|O_RDWR, 0744); + if (sz > 0) { + lseek(fd, sz-1, SEEK_SET); + write(fd, "", 1); +#ifndef _WIN32 + buf = mmap(NULL, sz, PROT_WRITE|PROT_READ, MAP_SHARED, + fd, 0); + if (buf == MAP_FAILED) { + fprintf(stderr, "mapping instrument counters file failed\n"); + abort(); + } +#else + file_handle = (HANDLE)_get_osfhandle(fd); + map_handle = CreateFileMapping(file_handle, NULL, PAGE_READWRITE, + 0, sz, ""); + buf = MapViewOfFile(map_handle, FILE_MAP_WRITE, 0, 0, 0); + if (buf == 0) { + fprintf(stderr, "mapping instrument counters file failed\n"); + abort(); + } +#endif + _instrument_counters = (instrument_count_t *)buf; + } + } +} + +void instrument_count(long label) { + if(_instrument_counters) { + _instrument_counters[label]++; + } +} + +#else + +void instrument_setup() { +} + +#endif diff --git a/pypy/translator/c/src/instrument.h b/pypy/translator/c/src/instrument.h --- a/pypy/translator/c/src/instrument.h +++ b/pypy/translator/c/src/instrument.h @@ -1,80 +1,13 @@ +#ifndef _PYPY_INSTRUMENT_H +#define _PYPY_INSTRUMENT_H void instrument_setup(); -#ifdef INSTRUMENT - +#ifdef PYPY_INSTRUMENT void instrument_count(long); - -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE -#include -#include -#include -#ifndef _WIN32 -#include -#include -#include -#include +#define PYPY_INSTRUMENT_COUNT(label) instrument_count(label) #else -#include +#define PYPY_INSTRUMENT_COUNT #endif -typedef unsigned long instrument_count_t; - -instrument_count_t *_instrument_counters = NULL; - -void instrument_setup() { - char *fname = getenv("_INSTRUMENT_COUNTERS"); - if (fname) { - int fd; -#ifdef _WIN32 - HANDLE map_handle; - HANDLE file_handle; -#endif - void *buf; - size_t sz = sizeof(instrument_count_t)*INSTRUMENT_NCOUNTER; - fd = open(fname, O_CREAT|O_TRUNC|O_RDWR, 0744); - if (sz > 0) { - lseek(fd, sz-1, SEEK_SET); - write(fd, "", 1); -#ifndef _WIN32 - buf = mmap(NULL, sz, PROT_WRITE|PROT_READ, MAP_SHARED, - fd, 0); - if (buf == MAP_FAILED) { - fprintf(stderr, "mapping instrument counters file failed\n"); - abort(); - } -#else - file_handle = (HANDLE)_get_osfhandle(fd); - map_handle = CreateFileMapping(file_handle, NULL, PAGE_READWRITE, - 0, sz, ""); - buf = MapViewOfFile(map_handle, FILE_MAP_WRITE, 0, 0, 0); - if (buf == 0) { - fprintf(stderr, "mapping instrument counters file failed\n"); - abort(); - } -#endif - _instrument_counters = (instrument_count_t *)buf; - } - } -} - -void instrument_count(long label) { - if(_instrument_counters) { - _instrument_counters[label]++; - } -} -#endif - - -#define INSTRUMENT_COUNT(label) instrument_count(label) - -#else - -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE -void instrument_setup() { -} -#endif - -#define INSTRUMENT_COUNT - -#endif +#endif /* _PYPY_INSTRUMENT_H */ diff --git a/pypy/translator/c/test/test_standalone.py b/pypy/translator/c/test/test_standalone.py --- a/pypy/translator/c/test/test_standalone.py +++ b/pypy/translator/c/test/test_standalone.py @@ -101,11 +101,11 @@ cbuilder.compile() counters_fname = udir.join("_counters_") - os.environ['_INSTRUMENT_COUNTERS'] = str(counters_fname) + os.environ['PYPY_INSTRUMENT_COUNTERS'] = str(counters_fname) try: data = cbuilder.cmdexec() finally: - del os.environ['_INSTRUMENT_COUNTERS'] + del os.environ['PYPY_INSTRUMENT_COUNTERS'] f = counters_fname.open('rb') counters_data = f.read() diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py --- a/pypy/translator/driver.py +++ b/pypy/translator/driver.py @@ -57,7 +57,7 @@ def probe(self, exe, args): env = os.environ.copy() - env['_INSTRUMENT_COUNTERS'] = str(self.datafile) + env['PYPY_INSTRUMENT_COUNTERS'] = str(self.datafile) self.compiler.platform.execute(exe, args, env=env) def after(self): From noreply at buildbot.pypy.org Tue Oct 2 16:37:44 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:44 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Split ll_strtod.h into interface and implementation. Message-ID: <20121002143744.372A11C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57722:72618a227a33 Date: 2012-09-30 20:49 +0200 http://bitbucket.org/pypy/pypy/changeset/72618a227a33/ Log: Split ll_strtod.h into interface and implementation. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -913,6 +913,7 @@ srcdir / 'thread.c', srcdir / 'asm.c', srcdir / 'instrument.c', + srcdir / 'll_strtod.c', ] if _CYGWIN: files.append(srcdir / 'cygwin_wait.c') diff --git a/pypy/translator/c/src/ll_strtod.c b/pypy/translator/c/src/ll_strtod.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/ll_strtod.c @@ -0,0 +1,126 @@ +#include + +#include +#include +#include +#include +#include +#include + + +double LL_strtod_parts_to_float(char *sign, char *beforept, + char *afterpt, char *exponent) +{ + char *fail_pos; + struct lconv *locale_data; + const char *decimal_point; + int decimal_point_len; + double x; + char *last; + char *expo = exponent; + int buf_size; + char *s; + + if (*expo == '\0') { + expo = "0"; + } + + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen(decimal_point); + + buf_size = strlen(sign) + + strlen(beforept) + + decimal_point_len + + strlen(afterpt) + + 1 /* e */ + + strlen(expo) + + 1 /* asciiz */ ; + + s = (char*)malloc(buf_size); + + strcpy(s, sign); + strcat(s, beforept); + strcat(s, decimal_point); + strcat(s, afterpt); + strcat(s, "e"); + strcat(s, expo); + + last = s + (buf_size-1); + x = strtod(s, &fail_pos); + errno = 0; + if (fail_pos > last) + fail_pos = last; + if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { + free(s); + errno = 42; // just because + return -1.0; + } + if (x == 0.0) { /* maybe a denormal value, ask for atof behavior */ + x = strtod(s, NULL); + errno = 0; + } + free(s); + return x; +} + +char buffer[120]; /* this should be enough, from PyString_Format code */ +int buflen = 120; + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +char* LL_strtod_formatd(double x, char code, int precision) +{ + int res; + const char* fmt; + if (code == 'e') fmt = "%.*e"; + else if (code == 'f') fmt = "%.*f"; + else if (code == 'g') fmt = "%.*g"; + else { + strcpy(buffer, "??.?"); /* should not occur */ + return buffer; + } + res = snprintf(buffer, buflen, fmt, precision, x); + if (res <= 0 || res >= buflen) { + strcpy(buffer, "??.?"); /* should not occur */ + } else { + struct lconv *locale_data; + const char *decimal_point; + int decimal_point_len; + char *p; + + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen(decimal_point); + + if (decimal_point[0] != '.' || + decimal_point[1] != 0) + { + p = buffer; + + if (*p == '+' || *p == '-') + p++; + + while (isdigit((unsigned char)*p)) + p++; + + if (strncmp(p, decimal_point, decimal_point_len) == 0) + { + *p = '.'; + p++; + if (decimal_point_len > 1) { + int rest_len; + rest_len = strlen(p + (decimal_point_len - 1)); + memmove(p, p + (decimal_point_len - 1), + rest_len); + p[rest_len] = 0; + } + } + } + + } + + return buffer; +} diff --git a/pypy/translator/c/src/ll_strtod.h b/pypy/translator/c/src/ll_strtod.h --- a/pypy/translator/c/src/ll_strtod.h +++ b/pypy/translator/c/src/ll_strtod.h @@ -1,143 +1,13 @@ -#ifndef LL_STRTOD_H -#define LL_STRTOD_H +/* string <-> float conversions. + Implementation uses sprintf and strtod. + Not used in modern Python, where dtoa.c is preferred. + */ -#include -#include -#include -#include -#include -#include - - -/* prototypes */ +#ifndef _PYPY_LL_STRTOD_H +#define _PYPY_LL_STRTOD_H double LL_strtod_parts_to_float(char *sign, char *beforept, char *afterpt, char *exponent); char *LL_strtod_formatd(double x, char code, int precision); - -/* implementations */ - -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE - -double LL_strtod_parts_to_float( - char *sign, - char *beforept, - char *afterpt, - char *exponent) -{ - char *fail_pos; - struct lconv *locale_data; - const char *decimal_point; - int decimal_point_len; - double x; - char *last; - char *expo = exponent; - int buf_size; - char *s; - - if (*expo == '\0') { - expo = "0"; - } - - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen(decimal_point); - - buf_size = strlen(sign) + - strlen(beforept) + - decimal_point_len + - strlen(afterpt) + - 1 /* e */ + - strlen(expo) + - 1 /* asciiz */ ; - - s = (char*)malloc(buf_size); - - strcpy(s, sign); - strcat(s, beforept); - strcat(s, decimal_point); - strcat(s, afterpt); - strcat(s, "e"); - strcat(s, expo); - - last = s + (buf_size-1); - x = strtod(s, &fail_pos); - errno = 0; - if (fail_pos > last) - fail_pos = last; - if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { - free(s); - errno = 42; // just because - return -1.0; - } - if (x == 0.0) { /* maybe a denormal value, ask for atof behavior */ - x = strtod(s, NULL); - errno = 0; - } - free(s); - return x; -} - -char buffer[120]; /* this should be enough, from PyString_Format code */ -int buflen = 120; - -#ifdef _MSC_VER -#define snprintf _snprintf #endif - -char* LL_strtod_formatd(double x, char code, int precision) { - int res; - const char* fmt; - if (code == 'e') fmt = "%.*e"; - else if (code == 'f') fmt = "%.*f"; - else if (code == 'g') fmt = "%.*g"; - else { - strcpy(buffer, "??.?"); /* should not occur */ - return buffer; - } - res = snprintf(buffer, buflen, fmt, precision, x); - if (res <= 0 || res >= buflen) { - strcpy(buffer, "??.?"); /* should not occur */ - } else { - struct lconv *locale_data; - const char *decimal_point; - int decimal_point_len; - char *p; - - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen(decimal_point); - - if (decimal_point[0] != '.' || - decimal_point[1] != 0) - { - p = buffer; - - if (*p == '+' || *p == '-') - p++; - - while (isdigit((unsigned char)*p)) - p++; - - if (strncmp(p, decimal_point, decimal_point_len) == 0) - { - *p = '.'; - p++; - if (decimal_point_len > 1) { - int rest_len; - rest_len = strlen(p + (decimal_point_len - 1)); - memmove(p, p + (decimal_point_len - 1), - rest_len); - p[rest_len] = 0; - } - } - } - - } - - return buffer; -} - -#endif /* PYPY_MAIN_IMPLEMENTATION_FILE */ -#endif From noreply at buildbot.pypy.org Tue Oct 2 16:37:45 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:45 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Move the "preimpl" lines to their own file preimpl.h Message-ID: <20121002143745.6CA5D1C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57723:ea51e86e4d9d Date: 2012-10-01 23:54 +0200 http://bitbucket.org/pypy/pypy/changeset/ea51e86e4d9d/ Log: Move the "preimpl" lines to their own file preimpl.h (provide well-known aliases to generated objects, e.g. #define RPyExc_TypeError (&pypy_g_exceptions_TypeError.te_super.se_super.e_super) ) diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -649,9 +649,8 @@ class SourceGenerator: one_source_file = True - def __init__(self, database, preimplementationlines=[]): + def __init__(self, database): self.database = database - self.preimpl = preimplementationlines self.extrafiles = [] self.path = None self.namespace = NameManager() @@ -785,6 +784,8 @@ gen_structdef(fi, self.database) with self.write_on_maybe_included_file(f, 'forwarddecl.h') as fi: gen_forwarddecl(fi, self.database) + with self.write_on_maybe_included_file(f, 'preimpl.h') as fi: + gen_preimpl(fi, self.database) # # Implementation of functions and global structures and arrays @@ -795,8 +796,6 @@ print >> f print >> f, '#define PYPY_FILE_NAME "%s"' % os.path.basename(f.name) - for line in self.preimpl: - print >> f, line print >> f, '#include "src/g_include.h"' print >> f @@ -812,6 +811,7 @@ print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' + print >> fc, '#include "preimpl.h"' print >> fc print >> fc, '#include "src/g_include.h"' print >> fc @@ -821,7 +821,7 @@ print >> fc, MARKER print >> fc, '/***********************************************************/' - nextralines = 8 + len(self.preimpl) + 4 + 1 + nextralines = 12 for name, nodeiter in self.splitnodesimpl('implement.c', self.funcnodes, nextralines, 1, @@ -835,10 +835,7 @@ print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' - print >> fc - for line in self.preimpl: - print >> fc, line - print >> fc + print >> fc, '#include "preimpl.h"' print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER @@ -873,6 +870,14 @@ for line in node.forward_declaration(): print >> f, line +def gen_preimpl(f, database): + if database.translator is None or database.translator.rtyper is None: + return + preimplementationlines = pre_include_code_lines( + database, database.translator.rtyper) + for line in preimplementationlines: + print >> f, line + def gen_startupcode(f, database): # generate the start-up code and put it into a function print >> f, 'char *RPython_StartupCode(void) {' @@ -945,17 +950,11 @@ fi.close() - if database.translator is None or database.translator.rtyper is None: - preimplementationlines = [] - else: - preimplementationlines = list( - pre_include_code_lines(database, database.translator.rtyper)) - # # 1) All declarations # 2) Implementation of functions and global structures and arrays # - sg = SourceGenerator(database, preimplementationlines) + sg = SourceGenerator(database) sg.set_strategy(targetdir, split) database.prepare_inline_helpers() sg.gen_readable_parts_of_source(f) From noreply at buildbot.pypy.org Tue Oct 2 16:37:46 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:46 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Always generate separate header files, even for "one_source_file" builds. Message-ID: <20121002143746.8C8BB1C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57724:33ac21ea061d Date: 2012-10-02 14:50 +0200 http://bitbucket.org/pypy/pypy/changeset/33ac21ea061d/ Log: Always generate separate header files, even for "one_source_file" builds. This allows int.c to be compiled separately. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -749,15 +749,11 @@ yield self.uniquecname(basecname), subiter() @contextlib.contextmanager - def write_on_maybe_included_file(self, f, name): - if self.one_source_file: - print >> f - yield f - else: - fi = self.makefile(name) - print >> f, '#include "%s"' % name - yield fi - fi.close() + def write_on_included_file(self, f, name): + fi = self.makefile(name) + print >> f, '#include "%s"' % name + yield fi + fi.close() @contextlib.contextmanager def write_on_maybe_separate_source(self, f, name): @@ -780,11 +776,11 @@ # # All declarations # - with self.write_on_maybe_included_file(f, 'structdef.h') as fi: + with self.write_on_included_file(f, 'structdef.h') as fi: gen_structdef(fi, self.database) - with self.write_on_maybe_included_file(f, 'forwarddecl.h') as fi: + with self.write_on_included_file(f, 'forwarddecl.h') as fi: gen_forwarddecl(fi, self.database) - with self.write_on_maybe_included_file(f, 'preimpl.h') as fi: + with self.write_on_included_file(f, 'preimpl.h') as fi: gen_preimpl(fi, self.database) # @@ -919,6 +915,7 @@ srcdir / 'asm.c', srcdir / 'instrument.c', srcdir / 'll_strtod.c', + srcdir / 'int.c', ] if _CYGWIN: files.append(srcdir / 'cygwin_wait.c') diff --git a/pypy/translator/c/src/int.c b/pypy/translator/c/src/int.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/int.c @@ -0,0 +1,45 @@ +#include "common_header.h" +#include "structdef.h" +#include "forwarddecl.h" +#include "preimpl.h" +#include +#include +#include + +/* adjusted from intobject.c, Python 2.3.3 */ + +long long op_llong_mul_ovf(long long a, long long b) +{ + double doubled_longprod; /* (double)longprod */ + double doubleprod; /* (double)a * (double)b */ + long long longprod; + + longprod = a * b; + doubleprod = (double)a * (double)b; + doubled_longprod = (double)longprod; + + /* Fast path for normal case: small multiplicands, and no info + is lost in either method. */ + if (doubled_longprod == doubleprod) + return longprod; + + /* Somebody somewhere lost info. Close enough, or way off? Note + that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0). + The difference either is or isn't significant compared to the + true value (of which doubleprod is a good approximation). + */ + { + const double diff = doubled_longprod - doubleprod; + const double absdiff = diff >= 0.0 ? diff : -diff; + const double absprod = doubleprod >= 0.0 ? doubleprod : + -doubleprod; + /* absdiff/absprod <= 1/32 iff + 32 * absdiff <= absprod -- 5 good bits is "close enough" */ + if (32.0 * absdiff <= absprod) + return longprod; + + FAIL_OVF("integer multiplication"); + return -1; + } +} + diff --git a/pypy/translator/c/src/int.h b/pypy/translator/c/src/int.h --- a/pypy/translator/c/src/int.h +++ b/pypy/translator/c/src/int.h @@ -1,11 +1,8 @@ +/************************************************************/ +/*** C header subsection: operations between ints ***/ -/************************************************************/ - /*** C header subsection: operations between ints ***/ - -/*** unary operations ***/ - -/************ win64 support: +/* Note for win64: 'Signed' must be defined as @@ -18,6 +15,8 @@ LONG_MIN in all other cases */ +/*** unary operations ***/ + #define OP_INT_IS_TRUE(x,r) r = ((x) != 0) #define OP_INT_INVERT(x,r) r = ~(x) #define OP_INT_NEG(x,r) r = -(x) @@ -237,56 +236,9 @@ #define OP_BOOL_NOT(x, r) r = !(x) -/* _________________ certain implementations __________________ */ - -/* adjusted from intobject.c, Python 2.3.3 */ - -/* prototypes */ - long long op_llong_mul_ovf(long long a, long long b); -/* implementations */ - -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE - -long long op_llong_mul_ovf(long long a, long long b) -{ - double doubled_longprod; /* (double)longprod */ - double doubleprod; /* (double)a * (double)b */ - long long longprod; - - longprod = a * b; - doubleprod = (double)a * (double)b; - doubled_longprod = (double)longprod; - - /* Fast path for normal case: small multiplicands, and no info - is lost in either method. */ - if (doubled_longprod == doubleprod) - return longprod; - - /* Somebody somewhere lost info. Close enough, or way off? Note - that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0). - The difference either is or isn't significant compared to the - true value (of which doubleprod is a good approximation). - */ - { - const double diff = doubled_longprod - doubleprod; - const double absdiff = diff >= 0.0 ? diff : -diff; - const double absprod = doubleprod >= 0.0 ? doubleprod : - -doubleprod; - /* absdiff/absprod <= 1/32 iff - 32 * absdiff <= absprod -- 5 good bits is "close enough" */ - if (32.0 * absdiff <= absprod) - return longprod; - - FAIL_OVF("integer multiplication"); - return -1; - } -} - -#endif /* PYPY_MAIN_IMPLEMENTATION_FILE */ - -/* implementations */ +/* The definitions above can be used with various types */ #define OP_UINT_IS_TRUE OP_INT_IS_TRUE #define OP_UINT_INVERT OP_INT_INVERT From noreply at buildbot.pypy.org Tue Oct 2 16:37:47 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:47 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Split debug_traceback: .h and .c. Message-ID: <20121002143747.B5B361C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57725:6fc70071ea32 Date: 2012-10-02 14:59 +0200 http://bitbucket.org/pypy/pypy/changeset/6fc70071ea32/ Log: Split debug_traceback: .h and .c. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -911,6 +911,7 @@ srcdir / 'mem.c', srcdir / 'profiling.c', srcdir / 'debug_print.c', + srcdir / 'debug_traceback.c', srcdir / 'thread.c', srcdir / 'asm.c', srcdir / 'instrument.c', diff --git a/pypy/translator/c/src/debug_traceback.c b/pypy/translator/c/src/debug_traceback.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/debug_traceback.c @@ -0,0 +1,71 @@ +#include "common_header.h" +#include "structdef.h" +#include "forwarddecl.h" +#include "preimpl.h" +#include "src/debug_traceback.h" +#include + +int pypydtcount = 0; +struct pypydtentry_s pypy_debug_tracebacks[PYPY_DEBUG_TRACEBACK_DEPTH]; + +void pypy_debug_traceback_print(void) +{ + int i; + int skipping; + void *my_etype = RPyFetchExceptionType(); + struct pypydtpos_s *location; + void *etype; + int has_loc; + + /* This code parses the pypy_debug_tracebacks array. See example + at the start of the file. */ + fprintf(stderr, "RPython traceback:\n"); + skipping = 0; + i = pypydtcount; + while (1) + { + i = (i - 1) & (PYPY_DEBUG_TRACEBACK_DEPTH-1); + if (i == pypydtcount) + { + fprintf(stderr, " ...\n"); + break; + } + + location = pypy_debug_tracebacks[i].location; + etype = pypy_debug_tracebacks[i].exctype; + has_loc = location != NULL && location != PYPYDTPOS_RERAISE; + + if (skipping && has_loc && etype == my_etype) + skipping = 0; /* found the matching "f:17, &KeyError */ + + if (!skipping) + { + if (has_loc) + fprintf(stderr, " File \"%s\", line %d, in %s\n", + location->filename, location->lineno, location->funcname); + else + { + /* line "NULL, &KeyError" or "RERAISE, &KeyError" */ + if (!my_etype) + my_etype = etype; + if (etype != my_etype) + { + fprintf(stderr, " Note: this traceback is " + "incomplete or corrupted!\n"); + break; + } + if (location == NULL) /* found the place that raised the exc */ + break; + skipping = 1; /* RERAISE: skip until "f:17, &KeyError" */ + } + } + } +} + +void pypy_debug_catch_fatal_exception(void) +{ + pypy_debug_traceback_print(); + fprintf(stderr, "Fatal RPython error: %s\n", + RPyFetchExceptionType()->ov_name->items); + abort(); +} diff --git a/pypy/translator/c/src/debug_traceback.h b/pypy/translator/c/src/debug_traceback.h --- a/pypy/translator/c/src/debug_traceback.h +++ b/pypy/translator/c/src/debug_traceback.h @@ -65,76 +65,3 @@ void pypy_debug_traceback_print(void); void pypy_debug_catch_fatal_exception(void); - - -/************************************************************/ - - -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE - -int pypydtcount = 0; -struct pypydtentry_s pypy_debug_tracebacks[PYPY_DEBUG_TRACEBACK_DEPTH]; - -void pypy_debug_traceback_print(void) -{ - int i; - int skipping; - void *my_etype = RPyFetchExceptionType(); - struct pypydtpos_s *location; - void *etype; - int has_loc; - - /* This code parses the pypy_debug_tracebacks array. See example - at the start of the file. */ - fprintf(stderr, "RPython traceback:\n"); - skipping = 0; - i = pypydtcount; - while (1) - { - i = (i - 1) & (PYPY_DEBUG_TRACEBACK_DEPTH-1); - if (i == pypydtcount) - { - fprintf(stderr, " ...\n"); - break; - } - - location = pypy_debug_tracebacks[i].location; - etype = pypy_debug_tracebacks[i].exctype; - has_loc = location != NULL && location != PYPYDTPOS_RERAISE; - - if (skipping && has_loc && etype == my_etype) - skipping = 0; /* found the matching "f:17, &KeyError */ - - if (!skipping) - { - if (has_loc) - fprintf(stderr, " File \"%s\", line %d, in %s\n", - location->filename, location->lineno, location->funcname); - else - { - /* line "NULL, &KeyError" or "RERAISE, &KeyError" */ - if (!my_etype) - my_etype = etype; - if (etype != my_etype) - { - fprintf(stderr, " Note: this traceback is " - "incomplete or corrupted!\n"); - break; - } - if (location == NULL) /* found the place that raised the exc */ - break; - skipping = 1; /* RERAISE: skip until "f:17, &KeyError" */ - } - } - } -} - -void pypy_debug_catch_fatal_exception(void) -{ - pypy_debug_traceback_print(); - fprintf(stderr, "Fatal RPython error: %s\n", - RPyFetchExceptionType()->ov_name->items); - abort(); -} - -#endif /* PYPY_MAIN_IMPLEMENTATION_FILE */ From noreply at buildbot.pypy.org Tue Oct 2 16:37:48 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:48 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Fix compilation warning Message-ID: <20121002143748.C61E51C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57726:6c0442c33f2f Date: 2012-10-02 15:00 +0200 http://bitbucket.org/pypy/pypy/changeset/6c0442c33f2f/ Log: Fix compilation warning diff --git a/pypy/translator/c/src/debug_traceback.c b/pypy/translator/c/src/debug_traceback.c --- a/pypy/translator/c/src/debug_traceback.c +++ b/pypy/translator/c/src/debug_traceback.c @@ -4,6 +4,7 @@ #include "preimpl.h" #include "src/debug_traceback.h" #include +#include int pypydtcount = 0; struct pypydtentry_s pypy_debug_tracebacks[PYPY_DEBUG_TRACEBACK_DEPTH]; From noreply at buildbot.pypy.org Tue Oct 2 16:37:50 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:50 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: exception.h: split interface and implementation Message-ID: <20121002143750.0FF3E1C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57727:a96792ef6114 Date: 2012-10-02 15:14 +0200 http://bitbucket.org/pypy/pypy/changeset/a96792ef6114/ Log: exception.h: split interface and implementation diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -909,6 +909,7 @@ files = [ srcdir / 'allocator.c', srcdir / 'mem.c', + srcdir / 'exception.c', srcdir / 'profiling.c', srcdir / 'debug_print.c', srcdir / 'debug_traceback.c', diff --git a/pypy/translator/c/src/exception.c b/pypy/translator/c/src/exception.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/exception.c @@ -0,0 +1,94 @@ +#include "common_header.h" +#include "structdef.h" +#include "forwarddecl.h" +#include "preimpl.h" +#include "src/exception.h" + +#if defined(PYPY_CPYTHON_EXTENSION) + PyObject *RPythonError; +#endif + +/******************************************************************/ +#ifdef HAVE_RTYPER /* RPython version of exceptions */ +/******************************************************************/ + +void RPyDebugReturnShowException(const char *msg, const char *filename, + long lineno, const char *functionname) +{ +#ifdef DO_LOG_EXC + fprintf(stderr, "%s %s: %s:%ld %s\n", msg, + RPyFetchExceptionType()->ov_name->items, + filename, lineno, functionname); +#endif +} + +/* Hint: functions and macros not defined here, like RPyRaiseException, + come from exctransformer via the table in extfunc.py. */ + +#define RPyFetchException(etypevar, evaluevar, type_of_evaluevar) do { \ + etypevar = RPyFetchExceptionType(); \ + evaluevar = (type_of_evaluevar)RPyFetchExceptionValue(); \ + RPyClearException(); \ + } while (0) + +/* implementations */ + +void _RPyRaiseSimpleException(RPYTHON_EXCEPTION rexc) +{ + /* XXX msg is ignored */ + RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc); +} + +#ifdef PYPY_CPYTHON_EXTENSION +void RPyConvertExceptionFromCPython(void) +{ + /* convert the CPython exception to an RPython one */ + PyObject *exc_type, *exc_value, *exc_tb; + RPYTHON_EXCEPTION rexc; + + assert(PyErr_Occurred()); + assert(!RPyExceptionOccurred()); + PyErr_Fetch(&exc_type, &exc_value, &exc_tb); + + /* XXX losing the error message here */ + rexc = RPYTHON_PYEXCCLASS2EXC(exc_type); + RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc); +} + +void RPyConvertExceptionToCPython(void) +{ + /* XXX 1. uses officially bad fishing */ + /* XXX 2. looks for exception classes by name, fragile */ + char* clsname; + PyObject *pycls, *v, *tb; + assert(RPyExceptionOccurred()); + assert(!PyErr_Occurred()); + clsname = RPyFetchExceptionType()->ov_name->items; + v = NULL; + if (strcmp(clsname, "AssertionError") == 0) { + /* workaround against the py lib's BuiltinAssertionError */ + pycls = PyExc_AssertionError; + } + else if (strcmp(clsname, "StackOverflow") == 0) { + pycls = PyExc_RuntimeError; + } + else { + pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); + if (pycls == NULL || !PyExceptionClass_Check(pycls) || + !PyObject_IsSubclass(pycls, PyExc_Exception)) { + pycls = PyExc_Exception; /* XXX RPythonError */ + v = PyString_FromString(clsname); + } + } + Py_INCREF(pycls); + tb = NULL; + RPyClearException(); + + PyErr_NormalizeException(&pycls, &v, &tb); + PyErr_Restore(pycls, v, tb); +} +#endif /* !PYPY_STANDALONE */ + +/******************************************************************/ +#endif /* HAVE_RTYPER */ +/******************************************************************/ diff --git a/pypy/translator/c/src/exception.h b/pypy/translator/c/src/exception.h --- a/pypy/translator/c/src/exception.h +++ b/pypy/translator/c/src/exception.h @@ -1,10 +1,6 @@ /************************************************************/ - /*** C header subsection: exceptions ***/ - -#if defined(PYPY_CPYTHON_EXTENSION) && defined(PYPY_MAIN_IMPLEMENTATION_FILE) - PyObject *RPythonError; -#endif +/*** C header subsection: exceptions ***/ /* just a renaming, unless DO_LOG_EXC is set */ #define RPyExceptionOccurred RPyExceptionOccurred1 @@ -32,28 +28,11 @@ ? (RPyDebugReturnShowException(msg, __FILE__, __LINE__, __FUNCTION__), 1) \ : 0 \ ) +#endif +/* !DO_LOG_EXC: define the function anyway, so that we can shut + off the prints of a debug_exc by remaking only testing_1.o */ void RPyDebugReturnShowException(const char *msg, const char *filename, long lineno, const char *functionname); -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE -void RPyDebugReturnShowException(const char *msg, const char *filename, - long lineno, const char *functionname) -{ - fprintf(stderr, "%s %s: %s:%ld %s\n", msg, - RPyFetchExceptionType()->ov_name->items, - filename, lineno, functionname); -} -#endif -#else /* !DO_LOG_EXC: define the function anyway, so that we can shut - off the prints of a debug_exc by remaking only testing_1.o */ -void RPyDebugReturnShowException(const char *msg, const char *filename, - long lineno, const char *functionname); -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE -void RPyDebugReturnShowException(const char *msg, const char *filename, - long lineno, const char *functionname) -{ -} -#endif -#endif /* DO_LOG_EXC */ /* Hint: functions and macros not defined here, like RPyRaiseException, come from exctransformer via the table in extfunc.py. */ @@ -74,70 +53,6 @@ void RPyConvertExceptionToCPython(void); #endif -/* implementations */ - -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE - -void _RPyRaiseSimpleException(RPYTHON_EXCEPTION rexc) -{ - /* XXX msg is ignored */ - RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc); -} - -#ifdef PYPY_CPYTHON_EXTENSION -void RPyConvertExceptionFromCPython(void) -{ - /* convert the CPython exception to an RPython one */ - PyObject *exc_type, *exc_value, *exc_tb; - RPYTHON_EXCEPTION rexc; - - assert(PyErr_Occurred()); - assert(!RPyExceptionOccurred()); - PyErr_Fetch(&exc_type, &exc_value, &exc_tb); - - /* XXX losing the error message here */ - rexc = RPYTHON_PYEXCCLASS2EXC(exc_type); - RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc); -} - -void RPyConvertExceptionToCPython(void) -{ - /* XXX 1. uses officially bad fishing */ - /* XXX 2. looks for exception classes by name, fragile */ - char* clsname; - PyObject *pycls, *v, *tb; - assert(RPyExceptionOccurred()); - assert(!PyErr_Occurred()); - clsname = RPyFetchExceptionType()->ov_name->items; - v = NULL; - if (strcmp(clsname, "AssertionError") == 0) { - /* workaround against the py lib's BuiltinAssertionError */ - pycls = PyExc_AssertionError; - } - else if (strcmp(clsname, "StackOverflow") == 0) { - pycls = PyExc_RuntimeError; - } - else { - pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); - if (pycls == NULL || !PyExceptionClass_Check(pycls) || - !PyObject_IsSubclass(pycls, PyExc_Exception)) { - pycls = PyExc_Exception; /* XXX RPythonError */ - v = PyString_FromString(clsname); - } - } - Py_INCREF(pycls); - tb = NULL; - RPyClearException(); - - PyErr_NormalizeException(&pycls, &v, &tb); - PyErr_Restore(pycls, v, tb); -} -#endif /* !PYPY_STANDALONE */ - -#endif /* PYPY_MAIN_IMPLEMENTATION_FILE */ - - - /******************************************************************/ #else /* non-RPython version of exceptions, using CPython only */ /******************************************************************/ From noreply at buildbot.pypy.org Tue Oct 2 16:37:51 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:51 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Split support.h into header and implementation. Message-ID: <20121002143751.4C6D71C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57728:58342f3c594d Date: 2012-10-02 15:27 +0200 http://bitbucket.org/pypy/pypy/changeset/58342f3c594d/ Log: Split support.h into header and implementation. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -910,6 +910,7 @@ srcdir / 'allocator.c', srcdir / 'mem.c', srcdir / 'exception.c', + srcdir / 'support.c', srcdir / 'profiling.c', srcdir / 'debug_print.c', srcdir / 'debug_traceback.c', diff --git a/pypy/translator/c/src/debug_print.h b/pypy/translator/c/src/debug_print.h --- a/pypy/translator/c/src/debug_print.h +++ b/pypy/translator/c/src/debug_print.h @@ -1,5 +1,7 @@ /************************************************************/ - /*** C header subsection: debug_print & related tools ***/ +/*** C header subsection: debug_print & related tools ***/ + +#include /* values of the PYPYLOG environment variable: ("top-level" debug_prints means not between debug_start and debug_stop) diff --git a/pypy/translator/c/src/support.c b/pypy/translator/c/src/support.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/support.c @@ -0,0 +1,406 @@ +#include "common_header.h" +#include + +/************************************************************/ +/*** C header subsection: support functions ***/ + +#include +#include + +/*** misc ***/ + +void RPyAssertFailed(const char* filename, long lineno, + const char* function, const char *msg) { + fprintf(stderr, + "PyPy assertion failed at %s:%ld:\n" + "in %s: %s\n", + filename, lineno, function, msg); + abort(); +} + +void RPyAbort(void) { + fprintf(stderr, "Invalid RPython operation (NULL ptr or bad array index)\n"); + abort(); +} + +#ifdef PYPY_CPYTHON_EXTENSION + +/* we need a subclass of 'builtin_function_or_method' which can be used + as methods: builtin function objects that can be bound on instances */ +PyObject * +gencfunc_descr_get(PyObject *func, PyObject *obj, PyObject *type) +{ + if (obj == Py_None) + obj = NULL; + return PyMethod_New(func, obj, type); +} +static PyTypeObject PyGenCFunction_Type = { + PyObject_HEAD_INIT(NULL) + 0, + "pypy_generated_function", + sizeof(PyCFunctionObject), + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + /*&PyCFunction_Type set below*/ 0, /* tp_base */ + 0, /* tp_dict */ + gencfunc_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ +}; + + +/*** misc support functions ***/ + +PyObject* PyList_Pack(int n, ...) +{ + int i; + PyObject *o; + PyObject *result; + va_list vargs; + + va_start(vargs, n); + result = PyList_New(n); + if (result == NULL) { + return NULL; + } + for (i = 0; i < n; i++) { + o = va_arg(vargs, PyObject *); + Py_INCREF(o); + PyList_SET_ITEM(result, i, o); + } + va_end(vargs); + return result; +} + +PyObject* PyDict_Pack(int n, ...) +{ + int i; + PyObject *key, *val; + PyObject *result; + va_list vargs; + + va_start(vargs, n); + result = PyDict_New(); + if (result == NULL) { + return NULL; + } + for (i = 0; i < n; i++) { + key = va_arg(vargs, PyObject *); + val = va_arg(vargs, PyObject *); + if (PyDict_SetItem(result, key, val) < 0) { + Py_DECREF(result); + return NULL; + } + } + va_end(vargs); + return result; +} + +#if PY_VERSION_HEX < 0x02040000 /* 2.4 */ +PyObject* PyTuple_Pack(int n, ...) +{ + int i; + PyObject *o; + PyObject *result; + PyObject **items; + va_list vargs; + + va_start(vargs, n); + result = PyTuple_New(n); + if (result == NULL) { + return NULL; + } + items = ((PyTupleObject *)result)->ob_item; + for (i = 0; i < n; i++) { + o = va_arg(vargs, PyObject *); + Py_INCREF(o); + items[i] = o; + } + va_end(vargs); + return result; +} +#endif + +#if PY_VERSION_HEX < 0x02030000 /* 2.3 */ +/* for Python 2.2 only */ +PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index) +{ + int start, stop, step; + if (!PySlice_Check(index)) { + return PyObject_GetItem(obj, index); + } + if (((PySliceObject*) index)->start == Py_None) { + start = -INT_MAX-1; + } else { + start = PyInt_AsLong(((PySliceObject*) index)->start); + if (start == -1 && PyErr_Occurred()) { + return NULL; + } + } + if (((PySliceObject*) index)->stop == Py_None) { + stop = INT_MAX; + } else { + stop = PyInt_AsLong(((PySliceObject*) index)->stop); + if (stop == -1 && PyErr_Occurred()) { + return NULL; + } + } + if (((PySliceObject*) index)->step != Py_None) { + step = PyInt_AsLong(((PySliceObject*) index)->step); + if (step == -1 && PyErr_Occurred()) { + return NULL; + } + if (step != 1) { + PyErr_SetString(PyExc_ValueError, + "obj[slice]: no step allowed"); + return NULL; + } + } + return PySequence_GetSlice(obj, start, stop); +} + +PyObject* PyObject_SetItem1(PyObject* obj, PyObject* index, PyObject* v) +{ + int start, stop, step; + if (!PySlice_Check(index)) { + return PyObject_SetItem(obj, index, v); + } + if (((PySliceObject*) index)->start == Py_None) { + start = -INT_MAX-1; + } else { + start = PyInt_AsLong(((PySliceObject*) index)->start); + if (start == -1 && PyErr_Occurred()) { + return NULL; + } + } + if (((PySliceObject*) index)->stop == Py_None) { + stop = INT_MAX; + } else { + stop = PyInt_AsLong(((PySliceObject*) index)->stop); + if (stop == -1 && PyErr_Occurred()) { + return NULL; + } + } + if (((PySliceObject*) index)->step != Py_None) { + step = PyInt_AsLong(((PySliceObject*) index)->step); + if (step == -1 && PyErr_Occurred()) { + return NULL; + } + if (step != 1) { + PyErr_SetString(PyExc_ValueError, + "obj[slice]: no step allowed"); + return NULL; + } + } + return PySequence_SetSlice(obj, start, stop, v); +} +#endif + +PyObject* CallWithShape(PyObject* callable, PyObject* shape, ...) +{ + /* XXX the 'shape' argument is a tuple as specified by + XXX pypy.interpreter.argument.fromshape(). This code should + XXX we made independent on the format of the 'shape' later... */ + PyObject* result = NULL; + PyObject* t = NULL; + PyObject* d = NULL; + PyObject* o; + PyObject* key; + PyObject* t2; + int i, nargs, nkwds, starflag, starstarflag; + va_list vargs; + + if (!PyTuple_Check(shape) || + PyTuple_GET_SIZE(shape) != 4 || + !PyInt_Check(PyTuple_GET_ITEM(shape, 0)) || + !PyTuple_Check(PyTuple_GET_ITEM(shape, 1)) || + !PyInt_Check(PyTuple_GET_ITEM(shape, 2)) || + !PyInt_Check(PyTuple_GET_ITEM(shape, 3))) { + Py_FatalError("in genc.h: invalid 'shape' argument"); + } + nargs = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 0)); + nkwds = PyTuple_GET_SIZE(PyTuple_GET_ITEM(shape, 1)); + starflag = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 2)); + starstarflag = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 3)); + + va_start(vargs, shape); + t = PyTuple_New(nargs); + if (t == NULL) + goto finally; + for (i = 0; i < nargs; i++) { + o = va_arg(vargs, PyObject *); + Py_INCREF(o); + PyTuple_SET_ITEM(t, i, o); + } + if (nkwds) { + d = PyDict_New(); + if (d == NULL) + goto finally; + for (i = 0; i < nkwds; i++) { + o = va_arg(vargs, PyObject *); + key = PyTuple_GET_ITEM(PyTuple_GET_ITEM(shape, 1), i); + if (PyDict_SetItem(d, key, o) < 0) + goto finally; + } + } + if (starflag) { + o = va_arg(vargs, PyObject *); + o = PySequence_Tuple(o); + if (o == NULL) + goto finally; + t2 = PySequence_Concat(t, o); + Py_DECREF(o); + Py_DECREF(t); + t = t2; + if (t == NULL) + goto finally; + } + if (starstarflag) { + int len1, len2, len3; + o = va_arg(vargs, PyObject *); + len1 = PyDict_Size(d); + len2 = PyDict_Size(o); + if (len1 < 0 || len2 < 0) + goto finally; + if (PyDict_Update(d, o) < 0) + goto finally; + len3 = PyDict_Size(d); + if (len1 + len2 != len3) { + PyErr_SetString(PyExc_TypeError, + "genc.h: duplicate keyword arguments"); + goto finally; + } + } + va_end(vargs); + + result = PyObject_Call(callable, t, d); + + finally: + Py_XDECREF(d); + Py_XDECREF(t); + return result; +} + +PyObject* decode_arg(PyObject* fname, int position, PyObject* name, + PyObject* vargs, PyObject* vkwds, PyObject* def) +{ + PyObject* result; + int size = PyTuple_Size(vargs); + if (size < 0) + return NULL; + if (vkwds != NULL) { + result = PyDict_GetItem(vkwds, name); + if (result != NULL) { + if (position < size) { + PyErr_Format(PyExc_TypeError, + "%s() got duplicate value for " + "its '%s' argument", + PyString_AS_STRING(fname), + PyString_AS_STRING(name)); + return NULL; + } + Py_INCREF(result); + return result; + } + } + if (position < size) { + /* common case */ + result = PyTuple_GET_ITEM(vargs, position); + Py_INCREF(result); + return result; + } + if (def != NULL) { + Py_INCREF(def); + return def; + } + PyErr_Format(PyExc_TypeError, "%s() got only %d argument(s)", + PyString_AS_STRING(fname), + position); + return NULL; +} + +int check_no_more_arg(PyObject* fname, int n, PyObject* vargs) +{ + int size = PyTuple_Size(vargs); + if (size < 0) + return -1; + if (size > n) { + PyErr_Format(PyExc_TypeError, + "%s() got %d argument(s), expected %d", + PyString_AS_STRING(fname), + size, n); + return -1; + } + return 0; +} + +int check_self_nonzero(PyObject* fname, PyObject* self) +{ + if (!self) { + PyErr_Format(PyExc_TypeError, + "%s() expects instance first arg", + PyString_AS_STRING(fname)); + return -1; + } + return 0; +} + +/************************************************************/ + +PyObject *PyTuple_GetItem_WithIncref(PyObject *tuple, int index) +{ + PyObject *result = PyTuple_GetItem(tuple, index); + Py_XINCREF(result); + return result; +} + +int PyTuple_SetItem_WithIncref(PyObject *tuple, int index, PyObject *o) +{ + Py_INCREF(o); + return PyTuple_SetItem(tuple, index, o); +} + +int PySequence_Contains_with_exc(PyObject *seq, PyObject *ob) +{ + int ret = PySequence_Contains(seq, ob); + + if (ret < 0) + CFAIL(); + return ret; +} + +PyObject* _PyUnicode_FromRPyUnicode(wchar_t *items, long length) +{ + PyObject *u = PyUnicode_FromUnicode(NULL, length); + long i; + for (i=0; i - -/*** misc ***/ - -#if !defined(MIN) -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif /* MIN */ - #define RUNNING_ON_LLINTERP 0 #define OP_JIT_RECORD_KNOWN_CLASS(i, c, r) /* nothing */ @@ -53,20 +45,12 @@ void RPyAssertFailed(const char* filename, long lineno, const char* function, const char *msg); -# ifdef PYPY_MAIN_IMPLEMENTATION_FILE -void RPyAssertFailed(const char* filename, long lineno, - const char* function, const char *msg) { - fprintf(stderr, - "PyPy assertion failed at %s:%ld:\n" - "in %s: %s\n", - filename, lineno, function, msg); - abort(); -} -# endif #else # define RPyAssert(x, msg) /* nothing */ #endif +void RPyAbort(void); + #if defined(RPY_LL_ASSERT) || defined(RPY_SANDBOXED) /* obscure macros that can be used as expressions and lvalues to refer * to a field of a structure or an item in an array in a "safe" way -- @@ -88,14 +72,6 @@ # define RPyBareItem(array, index) \ ((RPyCHECK((array) && (index) >= 0), (array))[index]) -void RPyAbort(void); -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE -void RPyAbort(void) { - fprintf(stderr, "Invalid RPython operation (NULL ptr or bad array index)\n"); - abort(); -} -#endif - #else # define RPyField(ptr, name) ((ptr)->name) # define RPyItem(array, index) ((array)->items[index]) @@ -130,390 +106,4 @@ int PyTuple_SetItem_WithIncref(PyObject *tuple, int index, PyObject *o); int PySequence_Contains_with_exc(PyObject *seq, PyObject *ob); PyObject* _PyUnicode_FromRPyUnicode(wchar_t *items, long length); - -/* implementations */ - -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE - -/* we need a subclass of 'builtin_function_or_method' which can be used - as methods: builtin function objects that can be bound on instances */ -PyObject * -gencfunc_descr_get(PyObject *func, PyObject *obj, PyObject *type) -{ - if (obj == Py_None) - obj = NULL; - return PyMethod_New(func, obj, type); -} -static PyTypeObject PyGenCFunction_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "pypy_generated_function", - sizeof(PyCFunctionObject), - 0, - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - /*&PyCFunction_Type set below*/ 0, /* tp_base */ - 0, /* tp_dict */ - gencfunc_descr_get, /* tp_descr_get */ - 0, /* tp_descr_set */ -}; - - -/*** misc support functions ***/ - -PyObject* PyList_Pack(int n, ...) -{ - int i; - PyObject *o; - PyObject *result; - va_list vargs; - - va_start(vargs, n); - result = PyList_New(n); - if (result == NULL) { - return NULL; - } - for (i = 0; i < n; i++) { - o = va_arg(vargs, PyObject *); - Py_INCREF(o); - PyList_SET_ITEM(result, i, o); - } - va_end(vargs); - return result; -} - -PyObject* PyDict_Pack(int n, ...) -{ - int i; - PyObject *key, *val; - PyObject *result; - va_list vargs; - - va_start(vargs, n); - result = PyDict_New(); - if (result == NULL) { - return NULL; - } - for (i = 0; i < n; i++) { - key = va_arg(vargs, PyObject *); - val = va_arg(vargs, PyObject *); - if (PyDict_SetItem(result, key, val) < 0) { - Py_DECREF(result); - return NULL; - } - } - va_end(vargs); - return result; -} - -#if PY_VERSION_HEX < 0x02040000 /* 2.4 */ -PyObject* PyTuple_Pack(int n, ...) -{ - int i; - PyObject *o; - PyObject *result; - PyObject **items; - va_list vargs; - - va_start(vargs, n); - result = PyTuple_New(n); - if (result == NULL) { - return NULL; - } - items = ((PyTupleObject *)result)->ob_item; - for (i = 0; i < n; i++) { - o = va_arg(vargs, PyObject *); - Py_INCREF(o); - items[i] = o; - } - va_end(vargs); - return result; -} -#endif - -#if PY_VERSION_HEX < 0x02030000 /* 2.3 */ -/* for Python 2.2 only */ -PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index) -{ - int start, stop, step; - if (!PySlice_Check(index)) { - return PyObject_GetItem(obj, index); - } - if (((PySliceObject*) index)->start == Py_None) { - start = -INT_MAX-1; - } else { - start = PyInt_AsLong(((PySliceObject*) index)->start); - if (start == -1 && PyErr_Occurred()) { - return NULL; - } - } - if (((PySliceObject*) index)->stop == Py_None) { - stop = INT_MAX; - } else { - stop = PyInt_AsLong(((PySliceObject*) index)->stop); - if (stop == -1 && PyErr_Occurred()) { - return NULL; - } - } - if (((PySliceObject*) index)->step != Py_None) { - step = PyInt_AsLong(((PySliceObject*) index)->step); - if (step == -1 && PyErr_Occurred()) { - return NULL; - } - if (step != 1) { - PyErr_SetString(PyExc_ValueError, - "obj[slice]: no step allowed"); - return NULL; - } - } - return PySequence_GetSlice(obj, start, stop); -} - -PyObject* PyObject_SetItem1(PyObject* obj, PyObject* index, PyObject* v) -{ - int start, stop, step; - if (!PySlice_Check(index)) { - return PyObject_SetItem(obj, index, v); - } - if (((PySliceObject*) index)->start == Py_None) { - start = -INT_MAX-1; - } else { - start = PyInt_AsLong(((PySliceObject*) index)->start); - if (start == -1 && PyErr_Occurred()) { - return NULL; - } - } - if (((PySliceObject*) index)->stop == Py_None) { - stop = INT_MAX; - } else { - stop = PyInt_AsLong(((PySliceObject*) index)->stop); - if (stop == -1 && PyErr_Occurred()) { - return NULL; - } - } - if (((PySliceObject*) index)->step != Py_None) { - step = PyInt_AsLong(((PySliceObject*) index)->step); - if (step == -1 && PyErr_Occurred()) { - return NULL; - } - if (step != 1) { - PyErr_SetString(PyExc_ValueError, - "obj[slice]: no step allowed"); - return NULL; - } - } - return PySequence_SetSlice(obj, start, stop, v); -} -#endif - -PyObject* CallWithShape(PyObject* callable, PyObject* shape, ...) -{ - /* XXX the 'shape' argument is a tuple as specified by - XXX pypy.interpreter.argument.fromshape(). This code should - XXX we made independent on the format of the 'shape' later... */ - PyObject* result = NULL; - PyObject* t = NULL; - PyObject* d = NULL; - PyObject* o; - PyObject* key; - PyObject* t2; - int i, nargs, nkwds, starflag, starstarflag; - va_list vargs; - - if (!PyTuple_Check(shape) || - PyTuple_GET_SIZE(shape) != 4 || - !PyInt_Check(PyTuple_GET_ITEM(shape, 0)) || - !PyTuple_Check(PyTuple_GET_ITEM(shape, 1)) || - !PyInt_Check(PyTuple_GET_ITEM(shape, 2)) || - !PyInt_Check(PyTuple_GET_ITEM(shape, 3))) { - Py_FatalError("in genc.h: invalid 'shape' argument"); - } - nargs = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 0)); - nkwds = PyTuple_GET_SIZE(PyTuple_GET_ITEM(shape, 1)); - starflag = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 2)); - starstarflag = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 3)); - - va_start(vargs, shape); - t = PyTuple_New(nargs); - if (t == NULL) - goto finally; - for (i = 0; i < nargs; i++) { - o = va_arg(vargs, PyObject *); - Py_INCREF(o); - PyTuple_SET_ITEM(t, i, o); - } - if (nkwds) { - d = PyDict_New(); - if (d == NULL) - goto finally; - for (i = 0; i < nkwds; i++) { - o = va_arg(vargs, PyObject *); - key = PyTuple_GET_ITEM(PyTuple_GET_ITEM(shape, 1), i); - if (PyDict_SetItem(d, key, o) < 0) - goto finally; - } - } - if (starflag) { - o = va_arg(vargs, PyObject *); - o = PySequence_Tuple(o); - if (o == NULL) - goto finally; - t2 = PySequence_Concat(t, o); - Py_DECREF(o); - Py_DECREF(t); - t = t2; - if (t == NULL) - goto finally; - } - if (starstarflag) { - int len1, len2, len3; - o = va_arg(vargs, PyObject *); - len1 = PyDict_Size(d); - len2 = PyDict_Size(o); - if (len1 < 0 || len2 < 0) - goto finally; - if (PyDict_Update(d, o) < 0) - goto finally; - len3 = PyDict_Size(d); - if (len1 + len2 != len3) { - PyErr_SetString(PyExc_TypeError, - "genc.h: duplicate keyword arguments"); - goto finally; - } - } - va_end(vargs); - - result = PyObject_Call(callable, t, d); - - finally: - Py_XDECREF(d); - Py_XDECREF(t); - return result; -} - -PyObject* decode_arg(PyObject* fname, int position, PyObject* name, - PyObject* vargs, PyObject* vkwds, PyObject* def) -{ - PyObject* result; - int size = PyTuple_Size(vargs); - if (size < 0) - return NULL; - if (vkwds != NULL) { - result = PyDict_GetItem(vkwds, name); - if (result != NULL) { - if (position < size) { - PyErr_Format(PyExc_TypeError, - "%s() got duplicate value for " - "its '%s' argument", - PyString_AS_STRING(fname), - PyString_AS_STRING(name)); - return NULL; - } - Py_INCREF(result); - return result; - } - } - if (position < size) { - /* common case */ - result = PyTuple_GET_ITEM(vargs, position); - Py_INCREF(result); - return result; - } - if (def != NULL) { - Py_INCREF(def); - return def; - } - PyErr_Format(PyExc_TypeError, "%s() got only %d argument(s)", - PyString_AS_STRING(fname), - position); - return NULL; -} - -int check_no_more_arg(PyObject* fname, int n, PyObject* vargs) -{ - int size = PyTuple_Size(vargs); - if (size < 0) - return -1; - if (size > n) { - PyErr_Format(PyExc_TypeError, - "%s() got %d argument(s), expected %d", - PyString_AS_STRING(fname), - size, n); - return -1; - } - return 0; -} - -int check_self_nonzero(PyObject* fname, PyObject* self) -{ - if (!self) { - PyErr_Format(PyExc_TypeError, - "%s() expects instance first arg", - PyString_AS_STRING(fname)); - return -1; - } - return 0; -} - -/************************************************************/ - -PyObject *PyTuple_GetItem_WithIncref(PyObject *tuple, int index) -{ - PyObject *result = PyTuple_GetItem(tuple, index); - Py_XINCREF(result); - return result; -} - -int PyTuple_SetItem_WithIncref(PyObject *tuple, int index, PyObject *o) -{ - Py_INCREF(o); - return PyTuple_SetItem(tuple, index, o); -} - -int PySequence_Contains_with_exc(PyObject *seq, PyObject *ob) -{ - int ret = PySequence_Contains(seq, ob); - - if (ret < 0) - CFAIL(); - return ret; -} - -PyObject* _PyUnicode_FromRPyUnicode(wchar_t *items, long length) -{ - PyObject *u = PyUnicode_FromUnicode(NULL, length); - long i; - for (i=0; i Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57729:6519032ac08f Date: 2012-10-02 15:34 +0200 http://bitbucket.org/pypy/pypy/changeset/6519032ac08f/ Log: Split stack.h: header and implementation. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -914,6 +914,7 @@ srcdir / 'profiling.c', srcdir / 'debug_print.c', srcdir / 'debug_traceback.c', + srcdir / 'stack.c', srcdir / 'thread.c', srcdir / 'asm.c', srcdir / 'instrument.c', diff --git a/pypy/translator/c/src/stack.c b/pypy/translator/c/src/stack.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/stack.c @@ -0,0 +1,69 @@ +/* Stack operation */ +#include +#include +#include + + +/* the current stack is in the interval [end-length:end]. We assume a + stack that grows downward here. */ +char *_LLstacktoobig_stack_end = NULL; +long _LLstacktoobig_stack_length = MAX_STACK_SIZE; +char _LLstacktoobig_report_error = 1; +static RPyThreadStaticTLS end_tls_key; + +void LL_stack_set_length_fraction(double fraction) +{ + _LLstacktoobig_stack_length = (long)(MAX_STACK_SIZE * fraction); +} + +char LL_stack_too_big_slowpath(long current) +{ + long diff, max_stack_size; + char *baseptr, *curptr = (char*)current; + + /* The stack_end variable is updated to match the current value + if it is still 0 or if we later find a 'curptr' position + that is above it. The real stack_end pointer is stored in + thread-local storage, but we try to minimize its overhead by + keeping a local copy in _LLstacktoobig_stack_end. */ + + if (_LLstacktoobig_stack_end == NULL) { + /* not initialized */ + /* XXX We assume that initialization is performed early, + when there is still only one thread running. This + allows us to ignore race conditions here */ + char *errmsg = RPyThreadStaticTLS_Create(&end_tls_key); + if (errmsg) { + /* XXX should we exit the process? */ + fprintf(stderr, "Internal PyPy error: %s\n", errmsg); + return 1; + } + } + + baseptr = (char *) RPyThreadStaticTLS_Get(end_tls_key); + max_stack_size = _LLstacktoobig_stack_length; + if (baseptr == NULL) { + /* first time we see this thread */ + } + else { + diff = baseptr - curptr; + if (((unsigned long)diff) <= (unsigned long)max_stack_size) { + /* within bounds, probably just had a thread switch */ + _LLstacktoobig_stack_end = baseptr; + return 0; + } + if (((unsigned long)-diff) <= (unsigned long)max_stack_size) { + /* stack underflowed: the initial estimation of + the stack base must be revised */ + } + else { /* stack overflow (probably) */ + return _LLstacktoobig_report_error; + } + } + + /* update the stack base pointer to the current value */ + baseptr = curptr; + RPyThreadStaticTLS_Set(end_tls_key, baseptr); + _LLstacktoobig_stack_end = baseptr; + return 0; +} diff --git a/pypy/translator/c/src/stack.h b/pypy/translator/c/src/stack.h --- a/pypy/translator/c/src/stack.h +++ b/pypy/translator/c/src/stack.h @@ -35,71 +35,3 @@ #endif -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE -#include - -/* the current stack is in the interval [end-length:end]. We assume a - stack that grows downward here. */ -char *_LLstacktoobig_stack_end = NULL; -long _LLstacktoobig_stack_length = MAX_STACK_SIZE; -char _LLstacktoobig_report_error = 1; -static RPyThreadStaticTLS end_tls_key; - -void LL_stack_set_length_fraction(double fraction) -{ - _LLstacktoobig_stack_length = (long)(MAX_STACK_SIZE * fraction); -} - -char LL_stack_too_big_slowpath(long current) -{ - long diff, max_stack_size; - char *baseptr, *curptr = (char*)current; - - /* The stack_end variable is updated to match the current value - if it is still 0 or if we later find a 'curptr' position - that is above it. The real stack_end pointer is stored in - thread-local storage, but we try to minimize its overhead by - keeping a local copy in _LLstacktoobig_stack_end. */ - - if (_LLstacktoobig_stack_end == NULL) { - /* not initialized */ - /* XXX We assume that initialization is performed early, - when there is still only one thread running. This - allows us to ignore race conditions here */ - char *errmsg = RPyThreadStaticTLS_Create(&end_tls_key); - if (errmsg) { - /* XXX should we exit the process? */ - fprintf(stderr, "Internal PyPy error: %s\n", errmsg); - return 1; - } - } - - baseptr = (char *) RPyThreadStaticTLS_Get(end_tls_key); - max_stack_size = _LLstacktoobig_stack_length; - if (baseptr == NULL) { - /* first time we see this thread */ - } - else { - diff = baseptr - curptr; - if (((unsigned long)diff) <= (unsigned long)max_stack_size) { - /* within bounds, probably just had a thread switch */ - _LLstacktoobig_stack_end = baseptr; - return 0; - } - if (((unsigned long)-diff) <= (unsigned long)max_stack_size) { - /* stack underflowed: the initial estimation of - the stack base must be revised */ - } - else { /* stack overflow (probably) */ - return _LLstacktoobig_report_error; - } - } - - /* update the stack base pointer to the current value */ - baseptr = curptr; - RPyThreadStaticTLS_Set(end_tls_key, baseptr); - _LLstacktoobig_stack_end = baseptr; - return 0; -} - -#endif diff --git a/pypy/translator/c/src/thread.h b/pypy/translator/c/src/thread.h --- a/pypy/translator/c/src/thread.h +++ b/pypy/translator/c/src/thread.h @@ -34,6 +34,7 @@ #define RPyThreadStaticTLS_Create(key) RPyThreadTLS_Create(key) #define RPyThreadStaticTLS_Get(key) RPyThreadTLS_Get(key) #define RPyThreadStaticTLS_Set(key, value) RPyThreadTLS_Set(key, value) +char *RPyThreadTLS_Create(RPyThreadTLS *result); #endif From noreply at buildbot.pypy.org Tue Oct 2 16:37:53 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:53 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Silence a compiler warning. Message-ID: <20121002143753.96ED51C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57730:6c064745905a Date: 2012-10-02 15:35 +0200 http://bitbucket.org/pypy/pypy/changeset/6c064745905a/ Log: Silence a compiler warning. diff --git a/pypy/translator/c/src/instrument.c b/pypy/translator/c/src/instrument.c --- a/pypy/translator/c/src/instrument.c +++ b/pypy/translator/c/src/instrument.c @@ -32,7 +32,7 @@ fd = open(fname, O_CREAT|O_TRUNC|O_RDWR, 0744); if (sz > 0) { lseek(fd, sz-1, SEEK_SET); - write(fd, "", 1); + (void)write(fd, "", 1); #ifndef _WIN32 buf = mmap(NULL, sz, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); From noreply at buildbot.pypy.org Tue Oct 2 16:37:54 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:54 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Split rtyper.h: header and implementation. Message-ID: <20121002143754.AF0BD1C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57731:3eea4e004571 Date: 2012-10-02 15:42 +0200 http://bitbucket.org/pypy/pypy/changeset/3eea4e004571/ Log: Split rtyper.h: header and implementation. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -910,6 +910,7 @@ srcdir / 'allocator.c', srcdir / 'mem.c', srcdir / 'exception.c', + srcdir / 'rtyper.c', srcdir / 'support.c', srcdir / 'profiling.c', srcdir / 'debug_print.c', diff --git a/pypy/translator/c/src/mem.h b/pypy/translator/c/src/mem.h --- a/pypy/translator/c/src/mem.h +++ b/pypy/translator/c/src/mem.h @@ -2,6 +2,8 @@ /************************************************************/ /*** C header subsection: operations on LowLevelTypes ***/ +#include + /* used by pypy.rlib.rstack, but also by asmgcc */ #define OP_STACK_CURRENT(r) r = (Signed)&r diff --git a/pypy/translator/c/src/rtyper.c b/pypy/translator/c/src/rtyper.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/rtyper.c @@ -0,0 +1,46 @@ +/************************************************************/ +/*** C header subsection: tools for RTyper-aware code ***/ +#include "common_header.h" +#include "structdef.h" +#include "forwarddecl.h" +#include "preimpl.h" +#include + +#include +#include + +struct _RPyString_dump_t { + struct _RPyString_dump_t *next; + char data[1]; +} *_RPyString_dump = NULL; + +char *RPyString_AsCharP(RPyString *rps) +{ + Signed len = RPyString_Size(rps); + struct _RPyString_dump_t *dump = \ + malloc(sizeof(struct _RPyString_dump_t) + len); + if (!dump) + return "(out of memory!)"; + dump->next = _RPyString_dump; + _RPyString_dump = dump; + memcpy(dump->data, rps->rs_chars.items, len); + dump->data[len] = 0; + return dump->data; +} + +void RPyString_FreeCache(void) +{ + while (_RPyString_dump) { + struct _RPyString_dump_t *dump = _RPyString_dump; + _RPyString_dump = dump->next; + free(dump); + } +} + +RPyString *RPyString_FromString(char *buf) +{ + int length = strlen(buf); + RPyString *rps = RPyString_New(length); + memcpy(rps->rs_chars.items, buf, length); + return rps; +} diff --git a/pypy/translator/c/src/rtyper.h b/pypy/translator/c/src/rtyper.h --- a/pypy/translator/c/src/rtyper.h +++ b/pypy/translator/c/src/rtyper.h @@ -1,8 +1,5 @@ /************************************************************/ - /*** C header subsection: tools for RTyper-aware code ***/ - -#include - +/*** C header subsection: tools for RTyper-aware code ***/ /* Note that RPython strings are not 0-terminated! For debugging, use PyString_FromRPyString or RPyString_AsCharP */ @@ -12,51 +9,6 @@ #define RPyUnicode_Size(rpu) ((rpu)->ru_chars.length) #define _RPyUnicode_AsUnicode(rpu) ((rpu)->ru_chars.items) -/* prototypes */ - char *RPyString_AsCharP(RPyString *rps); void RPyString_FreeCache(void); RPyString *RPyString_FromString(char *buf); - - -/* implementations */ - -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE - -struct _RPyString_dump_t { - struct _RPyString_dump_t *next; - char data[1]; -} *_RPyString_dump = NULL; - -char *RPyString_AsCharP(RPyString *rps) -{ - Signed len = RPyString_Size(rps); - struct _RPyString_dump_t *dump = \ - malloc(sizeof(struct _RPyString_dump_t) + len); - if (!dump) - return "(out of memory!)"; - dump->next = _RPyString_dump; - _RPyString_dump = dump; - memcpy(dump->data, rps->rs_chars.items, len); - dump->data[len] = 0; - return dump->data; -} - -void RPyString_FreeCache(void) -{ - while (_RPyString_dump) { - struct _RPyString_dump_t *dump = _RPyString_dump; - _RPyString_dump = dump->next; - free(dump); - } -} - -RPyString *RPyString_FromString(char *buf) -{ - int length = strlen(buf); - RPyString *rps = RPyString_New(length); - memcpy(rps->rs_chars.items, buf, length); - return rps; -} - -#endif /* PYPY_MAIN_IMPLEMENTATION_FILE */ From noreply at buildbot.pypy.org Tue Oct 2 16:37:56 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:56 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: pyobj.h: split header and implementation. Message-ID: <20121002143756.0AA411C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57732:5cc488dd7195 Date: 2012-10-02 15:47 +0200 http://bitbucket.org/pypy/pypy/changeset/5cc488dd7195/ Log: pyobj.h: split header and implementation. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -912,6 +912,7 @@ srcdir / 'exception.c', srcdir / 'rtyper.c', srcdir / 'support.c', + srcdir / 'pyobj.c', srcdir / 'profiling.c', srcdir / 'debug_print.c', srcdir / 'debug_traceback.c', diff --git a/pypy/translator/c/src/pyobj.c b/pypy/translator/c/src/pyobj.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/pyobj.c @@ -0,0 +1,45 @@ +#include + +/************************************************************/ +/*** C header subsection: untyped operations ***/ +/*** as OP_XXX() macros calling the CPython API ***/ +#ifdef PYPY_CPYTHON_EXTENSION + +#if (PY_VERSION_HEX < 0x02040000) + +unsigned long RPyLong_AsUnsignedLong(PyObject *v) +{ + if (PyInt_Check(v)) { + long val = PyInt_AsLong(v); + if (val < 0) { + PyErr_SetNone(PyExc_OverflowError); + return (unsigned long)-1; + } + return val; + } else { + return PyLong_AsUnsignedLong(v); + } +} + +#else +#define RPyLong_AsUnsignedLong PyLong_AsUnsignedLong +#endif + + +unsigned long long RPyLong_AsUnsignedLongLong(PyObject *v) +{ + if (PyInt_Check(v)) + return PyInt_AsLong(v); + else + return PyLong_AsUnsignedLongLong(v); +} + +long long RPyLong_AsLongLong(PyObject *v) +{ + if (PyInt_Check(v)) + return PyInt_AsLong(v); + else + return PyLong_AsLongLong(v); +} + +#endif /* PYPY_CPYTHON_EXTENSION */ diff --git a/pypy/translator/c/src/pyobj.h b/pypy/translator/c/src/pyobj.h --- a/pypy/translator/c/src/pyobj.h +++ b/pypy/translator/c/src/pyobj.h @@ -1,7 +1,6 @@ - /************************************************************/ - /*** C header subsection: untyped operations ***/ - /*** as OP_XXX() macros calling the CPython API ***/ +/*** C header subsection: untyped operations ***/ +/*** as OP_XXX() macros calling the CPython API ***/ #ifdef PYPY_CPYTHON_EXTENSION #define op_bool(r,what) { \ @@ -221,45 +220,4 @@ unsigned long long RPyLong_AsUnsignedLongLong(PyObject *v); long long RPyLong_AsLongLong(PyObject *v); -#ifdef PYPY_MAIN_IMPLEMENTATION_FILE - -#if (PY_VERSION_HEX < 0x02040000) - -unsigned long RPyLong_AsUnsignedLong(PyObject *v) -{ - if (PyInt_Check(v)) { - long val = PyInt_AsLong(v); - if (val < 0) { - PyErr_SetNone(PyExc_OverflowError); - return (unsigned long)-1; - } - return val; - } else { - return PyLong_AsUnsignedLong(v); - } -} - -#else -#define RPyLong_AsUnsignedLong PyLong_AsUnsignedLong -#endif - - -unsigned long long RPyLong_AsUnsignedLongLong(PyObject *v) -{ - if (PyInt_Check(v)) - return PyInt_AsLong(v); - else - return PyLong_AsUnsignedLongLong(v); -} - -long long RPyLong_AsLongLong(PyObject *v) -{ - if (PyInt_Check(v)) - return PyInt_AsLong(v); - else - return PyLong_AsLongLong(v); -} - -#endif - #endif /* PYPY_CPYTHON_EXTENSION */ From noreply at buildbot.pypy.org Tue Oct 2 16:37:57 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:37:57 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Split main.h: interface and implementation. Message-ID: <20121002143757.481271C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57733:3387ffeb70aa Date: 2012-10-02 16:23 +0200 http://bitbucket.org/pypy/pypy/changeset/3387ffeb70aa/ Log: Split main.h: interface and implementation. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -907,6 +907,7 @@ def add_extra_files(eci): srcdir = py.path.local(autopath.pypydir).join('translator', 'c', 'src') files = [ + srcdir / 'main.c', srcdir / 'allocator.c', srcdir / 'mem.c', srcdir / 'exception.c', diff --git a/pypy/translator/c/src/main.c b/pypy/translator/c/src/main.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/main.c @@ -0,0 +1,79 @@ +#include "common_header.h" +#ifdef PYPY_STANDALONE +#include "structdef.h" +#include "forwarddecl.h" +#include "preimpl.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef __GNUC__ +/* Hack to prevent this function from being inlined. Helps asmgcc + because the main() function has often a different prologue/epilogue. */ +int pypy_main_function(int argc, char *argv[]) __attribute__((__noinline__)); +#endif + +int pypy_main_function(int argc, char *argv[]) +{ + char *errmsg; + int i, exitcode; + RPyListOfString *list; + + pypy_asm_stack_bottom(); +#ifdef PYPY_X86_CHECK_SSE2_DEFINED + pypy_x86_check_sse2(); +#endif + instrument_setup(); + +#ifndef MS_WINDOWS + /* this message does no longer apply to win64 :-) */ + if (sizeof(void*) != SIZEOF_LONG) { + errmsg = "only support platforms where sizeof(void*) == sizeof(long)," + " for now"; + goto error; + } +#endif + + errmsg = RPython_StartupCode(); + if (errmsg) goto error; + + list = _RPyListOfString_New(argc); + if (RPyExceptionOccurred()) goto memory_out; + for (i=0; i Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57734:8144ea8e6de4 Date: 2012-10-02 16:37 +0200 http://bitbucket.org/pypy/pypy/changeset/8144ea8e6de4/ Log: Some #ifdef and documentation. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -907,21 +907,21 @@ def add_extra_files(eci): srcdir = py.path.local(autopath.pypydir).join('translator', 'c', 'src') files = [ - srcdir / 'main.c', - srcdir / 'allocator.c', + srcdir / 'main.c', # ifdef PYPY_STANDALONE + srcdir / 'allocator.c', # ifdef PYPY_STANDALONE srcdir / 'mem.c', srcdir / 'exception.c', - srcdir / 'rtyper.c', + srcdir / 'rtyper.c', # ifdef HAVE_RTYPER srcdir / 'support.c', srcdir / 'pyobj.c', srcdir / 'profiling.c', srcdir / 'debug_print.c', - srcdir / 'debug_traceback.c', + srcdir / 'debug_traceback.c', # ifdef HAVE_RTYPER srcdir / 'stack.c', srcdir / 'thread.c', srcdir / 'asm.c', srcdir / 'instrument.c', - srcdir / 'll_strtod.c', + srcdir / 'll_strtod.c', # ifdef HAVE_RTYPER srcdir / 'int.c', ] if _CYGWIN: diff --git a/pypy/translator/c/src/allocator.c b/pypy/translator/c/src/allocator.c --- a/pypy/translator/c/src/allocator.c +++ b/pypy/translator/c/src/allocator.c @@ -1,5 +1,6 @@ /* allocation functions */ #include "common_header.h" +#ifdef PYPY_STANDALONE #include #include @@ -24,3 +25,5 @@ # include "src/obmalloc.c" #endif + +#endif /* PYPY_STANDALONE */ diff --git a/pypy/translator/c/src/allocator.h b/pypy/translator/c/src/allocator.h --- a/pypy/translator/c/src/allocator.h +++ b/pypy/translator/c/src/allocator.h @@ -1,5 +1,7 @@ +#ifdef PYPY_STANDALONE /* allocation functions prototypes */ void *PyObject_Malloc(size_t n); void *PyObject_Realloc(void *p, size_t n); void PyObject_Free(void *p); +#endif /* PYPY_STANDALONE */ From noreply at buildbot.pypy.org Tue Oct 2 16:41:55 2012 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Tue, 2 Oct 2012 16:41:55 +0200 (CEST) Subject: [pypy-commit] pypy pytest: merge from default Message-ID: <20121002144155.3B6561C00EC@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r57735:ec16c2890fc7 Date: 2012-10-02 16:41 +0200 http://bitbucket.org/pypy/pypy/changeset/ec16c2890fc7/ Log: merge from default diff too long, truncating to 2000 out of 2491 lines diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -23,7 +23,7 @@ The tools required to cross translate from a Linux based host to an ARM based Linux target are: -- A checkout of PyPy's arm-backend-2 branch. +- A checkout of PyPy (default branch). - The GCC ARM cross compiler (on Ubuntu it is the ``gcc-arm-linux-gnueabi package``) but other toolchains should also work. - Scratchbox 2, a cross-compilation engine (``scratchbox2`` Ubuntu package). - A 32-bit PyPy or Python. @@ -147,4 +147,4 @@ return 0 def target(*args): - return main, None \ No newline at end of file + return main, None diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -115,13 +115,16 @@ which data structures would be more appropriate? For example, a dict implemented as a hash table will suffer "stm collisions" in all threads whenever one thread writes anything to it; but there could be other - implementations. + implementations. Maybe alternate strategies can be implemented at the + level of the Python interpreter (see list/dict strategies, + ``pypy/objspace/std/{list,dict}object.py``). * More generally, there is the idea that we would need some kind of "debugger"-like tool to "debug" things that are not bugs, but stm conflicts. How would this tool look like to the end Python programmers? Like a profiler? Or like a debugger with breakpoints - on aborted transactions? + on aborted transactions? It would probably be all app-level, with + a few hooks e.g. for transaction conflicts. * Find good ways to have libraries using internally threads and atomics, but not exposing threads to the user. Right now there is a rough draft 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 @@ -18,6 +18,7 @@ .. branch: numpypy_count_nonzero .. branch: numpy-refactor Remove numpy lazy evaluation and simplify everything +.. branch: numpy-reintroduce-jit-drivers .. branch: numpy-fancy-indexing Support for array[array-of-ints] in numpy .. branch: even-more-jit-hooks 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 @@ -474,7 +474,7 @@ if f_type == F_BLOCK_LOOP: self.emit_jump(ops.CONTINUE_LOOP, block, True) break - if self.frame_blocks[i][0] == F_BLOCK_FINALLY_END: + if f_type == F_BLOCK_FINALLY_END: self.error("'continue' not supported inside 'finally' " \ "clause", cont) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -208,11 +208,11 @@ def int_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def bigint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -292,8 +292,6 @@ """Base class for the interpreter-level implementations of object spaces. http://pypy.readthedocs.org/en/latest/objspace.html""" - full_exceptions = True # full support for exceptions (normalization & more) - def __init__(self, config=None): "NOT_RPYTHON: Basic initialization of objects." self.fromcache = InternalSpaceCache(self).getorbuild @@ -1124,13 +1122,9 @@ def exception_is_valid_obj_as_class_w(self, w_obj): if not self.isinstance_w(w_obj, self.w_type): return False - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_obj, self.w_BaseException)) def exception_is_valid_class_w(self, w_cls): - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_cls, self.w_BaseException)) def exception_getclass(self, w_obj): @@ -1381,7 +1375,7 @@ if not self.is_true(self.isinstance(w_obj, self.w_str)): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) - return self.str_w(w_obj) + return self.str_w(w_obj) def unicode_w(self, w_obj): return w_obj.unicode_w(self) @@ -1702,7 +1696,7 @@ 'ValueError', 'ZeroDivisionError', ] - + if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -45,11 +45,6 @@ def async(self, space): "Check if this is an exception that should better not be caught." - if not space.full_exceptions: - # flow objspace does not support such exceptions and more - # importantly, raises KeyboardInterrupt if you try to access - # space.w_KeyboardInterrupt - return False return (self.match(space, space.w_SystemExit) or self.match(space, space.w_KeyboardInterrupt)) @@ -166,9 +161,7 @@ # Or 'Class' can also be an old-style class and 'inst' an old-style # instance of it. # - # Note that 'space.full_exceptions' is set to False by the flow - # object space; in this case we must assume that we are in a - # non-advanced case, and ignore the advanced cases. Old-style + # The flow object space only deals with non-advanced case. Old-style # classes and instances *are* advanced. # # input (w_type, w_value)... becomes... advanced case? @@ -183,9 +176,8 @@ # w_type = self.w_type w_value = self.get_w_value(space) - if space.full_exceptions: - while space.is_true(space.isinstance(w_type, space.w_tuple)): - w_type = space.getitem(w_type, space.wrap(0)) + while space.is_true(space.isinstance(w_type, space.w_tuple)): + w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): # this is for all cases of the form (Class, something) @@ -199,8 +191,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.full_exceptions and space.is_true( - space.isinstance(w_value, space.w_tuple)): + if space.is_true(space.isinstance(w_value, space.w_tuple)): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -944,14 +944,6 @@ def appcaller(space, *args_w): if not isinstance(space, ObjSpace): raise TypeError("first argument must be a space instance.") - # redirect if the space handles this specially - # XXX can this be factored a bit less flow space dependently? - if hasattr(space, 'specialcases'): - sc = space.specialcases - if ApplevelClass in sc: - ret_w = sc[ApplevelClass](space, self, name, args_w) - if ret_w is not None: # it was RPython - return ret_w # the last argument can be an Arguments w_func = self.wget(space, name) if not args_w: diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -223,7 +223,7 @@ return next_instr if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: - return self.jump_absolute(oparg, next_instr, ec) + return self.jump_absolute(oparg, ec) if we_are_translated(): for opdesc in unrolling_all_opcode_descs: @@ -557,7 +557,7 @@ w_type = self.popvalue() operror = OperationError(w_type, w_value) operror.normalize_exception(space) - if not space.full_exceptions or space.is_w(w_traceback, space.w_None): + if space.is_w(w_traceback, space.w_None): # common case raise operror else: @@ -858,7 +858,8 @@ def YIELD_VALUE(self, oparg, next_instr): raise Yield - def jump_absolute(self, jumpto, next_instr, ec): + def jump_absolute(self, jumpto, ec): + # this function is overridden by pypy.module.pypyjit.interp_jit check_nonneg(jumpto) return jumpto @@ -944,21 +945,9 @@ def WITH_CLEANUP(self, oparg, next_instr): # see comment in END_FINALLY for stack state - # This opcode changed a lot between CPython versions - if (self.pycode.magic >= 0xa0df2ef - # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) - or self.pycode.magic >= 0xa0df2d1): - # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) - w_unroller = self.popvalue() - w_exitfunc = self.popvalue() - self.pushvalue(w_unroller) - elif self.pycode.magic >= 0xa0df28c: - # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) - w_exitfunc = self.popvalue() - w_unroller = self.peekvalue(0) - else: - raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") - + w_unroller = self.popvalue() + w_exitfunc = self.popvalue() + self.pushvalue(w_unroller) unroller = self.space.interpclass_w(w_unroller) is_app_exc = (unroller is not None and isinstance(unroller, SApplicationException)) @@ -1192,10 +1181,6 @@ 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): """Signals a 'return' statement. Argument is the wrapped object to return.""" @@ -1206,12 +1191,6 @@ def nomoreblocks(self): return self.w_returnvalue - def state_unpack_variables(self, space): - return [self.w_returnvalue] - def state_pack_variables(space, w_returnvalue): - return SReturnValue(w_returnvalue) - state_pack_variables = staticmethod(state_pack_variables) - class SApplicationException(SuspendedUnroller): """Signals an application-level exception (i.e. an OperationException).""" @@ -1226,13 +1205,6 @@ """Signals a 'break' statement.""" _immutable_ = True kind = 0x04 - - def state_unpack_variables(self, space): - return [] - def state_pack_variables(space): - return SBreakLoop.singleton - state_pack_variables = staticmethod(state_pack_variables) - SBreakLoop.singleton = SBreakLoop() class SContinueLoop(SuspendedUnroller): @@ -1243,12 +1215,6 @@ def __init__(self, jump_to): self.jump_to = jump_to - def state_unpack_variables(self, space): - return [space.wrap(self.jump_to)] - def state_pack_variables(space, w_jump_to): - return SContinueLoop(space.int_w(w_jump_to)) - state_pack_variables = staticmethod(state_pack_variables) - class FrameBlock(object): """Abstract base class for frame blocks from the blockstack, @@ -1303,7 +1269,9 @@ # and jump to the beginning of the loop, stored in the # exception's argument frame.append_block(self) - return r_uint(unroller.jump_to) + jumpto = unroller.jump_to + ec = frame.space.getexecutioncontext() + return r_uint(frame.jump_absolute(jumpto, ec)) else: # jump to the end of the loop self.cleanupstack(frame) @@ -1323,8 +1291,7 @@ self.cleanupstack(frame) assert isinstance(unroller, SApplicationException) operationerr = unroller.operr - if frame.space.full_exceptions: - operationerr.normalize_exception(frame.space) + operationerr.normalize_exception(frame.space) # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. @@ -1356,8 +1323,7 @@ _immutable_ = True def handle(self, frame, unroller): - if (frame.space.full_exceptions and - isinstance(unroller, SApplicationException)): + if isinstance(unroller, SApplicationException): unroller.operr.normalize_exception(frame.space) return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -131,13 +131,13 @@ def get_latest_value_float(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a float.""" + or from 'args' if it was a FINISH). Returns a FLOATSTORAGE.""" raise NotImplementedError def get_latest_value_ref(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a ptr or an obj.""" + or from 'args' if it was a FINISH). Returns a GCREF.""" raise NotImplementedError def get_latest_value_count(self): diff --git a/pypy/jit/metainterp/optimizeopt/util.py b/pypy/jit/metainterp/optimizeopt/util.py --- a/pypy/jit/metainterp/optimizeopt/util.py +++ b/pypy/jit/metainterp/optimizeopt/util.py @@ -2,9 +2,10 @@ from pypy.rlib.objectmodel import r_dict, compute_identity_hash from pypy.rlib.rarithmetic import intmask from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp import resoperation, history +from pypy.jit.metainterp import resoperation from pypy.rlib.debug import make_sure_not_resized from pypy.jit.metainterp.resoperation import rop +from pypy.rlib.objectmodel import we_are_translated # ____________________________________________________________ # Misc. utilities @@ -28,13 +29,20 @@ def make_dispatcher_method(Class, name_prefix, op_prefix=None, default=None): ops = _findall(Class, name_prefix, op_prefix) def dispatch(self, op, *args): - opnum = op.getopnum() - for value, cls, func in ops: - if opnum == value: - assert isinstance(op, cls) + if we_are_translated(): + opnum = op.getopnum() + for value, cls, func in ops: + if opnum == value: + assert isinstance(op, cls) + return func(self, op, *args) + if default: + return default(self, op, *args) + else: + func = getattr(Class, name_prefix + op.getopname().upper(), None) + if func is not None: return func(self, op, *args) - if default: - return default(self, op, *args) + if default: + return default(self, op, *args) dispatch.func_name = "dispatch_" + name_prefix return dispatch 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 @@ -981,7 +981,7 @@ assert strlenaddr == cast(BVoidP, strlen) def test_read_variable(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BVoidP = new_pointer_type(new_void_type()) ll = find_and_load_library('c') @@ -989,7 +989,7 @@ assert stderr == cast(BVoidP, _testfunc(8)) def test_read_variable_as_unknown_length_array(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BCharP = new_pointer_type(new_primitive_type("char")) BArray = new_array_type(BCharP, None) @@ -999,7 +999,7 @@ # ^^ and not 'char[]', which is basically not allowed and would crash def test_write_variable(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BVoidP = new_pointer_type(new_void_type()) ll = find_and_load_library('c') 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 @@ -244,6 +244,7 @@ def setitem_index(self, space, index, value): self.setitem(self._lookup_by_unwrapped_index(space, index), value) + @jit.unroll_safe def _single_item_index(self, space, w_idx): """ Return an index of single item if possible, otherwise raises IndexError 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 @@ -9,8 +9,8 @@ from pypy.interpreter.error import OperationError from pypy.module.micronumpy import interp_boxes from pypy.module.micronumpy.interp_dtype import get_dtype_cache -from pypy.module.micronumpy.interp_numarray import (Scalar, BaseArray, - scalar_w, W_NDimArray, array) +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.interp_numarray import array from pypy.module.micronumpy.interp_arrayops import where from pypy.module.micronumpy import interp_ufuncs from pypy.rlib.objectmodel import specialize, instantiate @@ -147,7 +147,8 @@ def is_true(self, w_obj): assert isinstance(w_obj, BoolObject) - return w_obj.boolval + return False + #return w_obj.boolval def is_w(self, w_obj, w_what): return w_obj is w_what @@ -274,7 +275,7 @@ if isinstance(w_index, FloatObject): w_index = IntObject(int(w_index.floatval)) w_val = self.expr.execute(interp) - assert isinstance(arr, BaseArray) + assert isinstance(arr, W_NDimArray) arr.descr_setitem(interp.space, w_index, w_val) def __repr__(self): @@ -302,11 +303,11 @@ w_rhs = self.rhs.wrap(interp.space) else: w_rhs = self.rhs.execute(interp) - if not isinstance(w_lhs, BaseArray): + if not isinstance(w_lhs, W_NDimArray): # scalar dtype = get_dtype_cache(interp.space).w_float64dtype - w_lhs = scalar_w(interp.space, dtype, w_lhs) - assert isinstance(w_lhs, BaseArray) + w_lhs = W_NDimArray.new_scalar(interp.space, dtype, w_lhs) + assert isinstance(w_lhs, W_NDimArray) if self.name == '+': w_res = w_lhs.descr_add(interp.space, w_rhs) elif self.name == '*': @@ -314,17 +315,16 @@ elif self.name == '-': w_res = w_lhs.descr_sub(interp.space, w_rhs) elif self.name == '->': - assert not isinstance(w_rhs, Scalar) if isinstance(w_rhs, FloatObject): w_rhs = IntObject(int(w_rhs.floatval)) - assert isinstance(w_lhs, BaseArray) + assert isinstance(w_lhs, W_NDimArray) w_res = w_lhs.descr_getitem(interp.space, w_rhs) else: raise NotImplementedError - if (not isinstance(w_res, BaseArray) and + if (not isinstance(w_res, W_NDimArray) and not isinstance(w_res, interp_boxes.W_GenericBox)): dtype = get_dtype_cache(interp.space).w_float64dtype - w_res = scalar_w(interp.space, dtype, w_res) + w_res = W_NDimArray.new_scalar(interp.space, dtype, w_res) return w_res def __repr__(self): @@ -416,7 +416,7 @@ def execute(self, interp): arr = self.args[0].execute(interp) - if not isinstance(arr, BaseArray): + if not isinstance(arr, W_NDimArray): raise ArgumentNotAnArray if self.name in SINGLE_ARG_FUNCTIONS: if len(self.args) != 1 and self.name != 'sum': @@ -440,20 +440,21 @@ elif self.name == "unegative": neg = interp_ufuncs.get(interp.space).negative w_res = neg.call(interp.space, [arr]) + elif self.name == "cos": + cos = interp_ufuncs.get(interp.space).cos + w_res = cos.call(interp.space, [arr]) elif self.name == "flat": w_res = arr.descr_get_flatiter(interp.space) elif self.name == "tostring": arr.descr_tostring(interp.space) w_res = None - elif self.name == "count_nonzero": - w_res = arr.descr_count_nonzero(interp.space) else: assert False # unreachable code elif self.name in TWO_ARG_FUNCTIONS: if len(self.args) != 2: raise ArgumentMismatch arg = self.args[1].execute(interp) - if not isinstance(arg, BaseArray): + if not isinstance(arg, W_NDimArray): raise ArgumentNotAnArray if self.name == "dot": w_res = arr.descr_dot(interp.space, arg) @@ -466,9 +467,9 @@ raise ArgumentMismatch arg1 = self.args[1].execute(interp) arg2 = self.args[2].execute(interp) - if not isinstance(arg1, BaseArray): + if not isinstance(arg1, W_NDimArray): raise ArgumentNotAnArray - if not isinstance(arg2, BaseArray): + if not isinstance(arg2, W_NDimArray): raise ArgumentNotAnArray if self.name == "where": w_res = where(interp.space, arr, arg1, arg2) @@ -476,7 +477,7 @@ assert False else: raise WrongFunctionName - if isinstance(w_res, BaseArray): + if isinstance(w_res, W_NDimArray): return w_res if isinstance(w_res, FloatObject): dtype = get_dtype_cache(interp.space).w_float64dtype @@ -488,7 +489,7 @@ dtype = w_res.get_dtype(interp.space) else: dtype = None - return scalar_w(interp.space, dtype, w_res) + return W_NDimArray.new_scalar(interp.space, dtype, w_res) _REGEXES = [ ('-?[\d\.]+', 'number'), 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 @@ -129,6 +129,8 @@ self._prepare_array_index(space, w_index) shape = res_shape + self.get_shape()[len(indexes):] res = W_NDimArray.from_shape(shape, self.get_dtype(), self.get_order()) + if not res.get_size(): + return res return loop.getitem_array_int(space, self, res, iter_shape, indexes, prefix) @@ -514,7 +516,7 @@ if self.get_size() == 0: raise OperationError(space.w_ValueError, space.wrap("Can't call %s on zero-size arrays" % op_name)) - return space.wrap(loop.argmin_argmax(op_name, self)) + return space.wrap(getattr(loop, 'arg' + op_name)(self)) return func_with_new_name(impl, "reduce_arg%s_impl" % op_name) descr_argmax = _reduce_argmax_argmin_impl("max") 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 @@ -258,7 +258,7 @@ return out shape = shape_agreement(space, w_obj.get_shape(), out, broadcast_down=False) - return loop.call1(shape, self.func, self.name, calc_dtype, res_dtype, + return loop.call1(shape, self.func, calc_dtype, res_dtype, w_obj, out) @@ -322,7 +322,7 @@ return out 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(new_shape, self.func, self.name, calc_dtype, + return loop.call2(new_shape, self.func, calc_dtype, res_dtype, w_lhs, w_rhs, out) 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 @@ -1,21 +1,34 @@ """ This file is the main run loop as well as evaluation loops for various -signatures +operations. This is the place to look for all the computations that iterate +over all the array elements. """ -from pypy.rlib.objectmodel import specialize from pypy.rlib.rstring import StringBuilder from pypy.rlib import jit from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy.base import W_NDimArray -def call2(shape, func, name, calc_dtype, res_dtype, w_lhs, w_rhs, out): +call2_driver = jit.JitDriver(name='numpy_call2', + greens = ['shapelen', 'func', 'calc_dtype', + 'res_dtype'], + reds = ['shape', 'w_lhs', 'w_rhs', 'out', + 'left_iter', 'right_iter', 'out_iter']) + +def call2(shape, func, calc_dtype, res_dtype, w_lhs, w_rhs, out): if out is None: out = W_NDimArray.from_shape(shape, res_dtype) left_iter = w_lhs.create_iter(shape) right_iter = w_rhs.create_iter(shape) out_iter = out.create_iter(shape) + shapelen = len(shape) while not out_iter.done(): + call2_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, res_dtype=res_dtype, + shape=shape, w_lhs=w_lhs, w_rhs=w_rhs, + out=out, + left_iter=left_iter, right_iter=right_iter, + out_iter=out_iter) w_left = left_iter.getitem().convert_to(calc_dtype) w_right = right_iter.getitem().convert_to(calc_dtype) out_iter.setitem(func(calc_dtype, w_left, w_right).convert_to( @@ -25,30 +38,56 @@ out_iter.next() return out -def call1(shape, func, name, calc_dtype, res_dtype, w_obj, out): +call1_driver = jit.JitDriver(name='numpy_call1', + greens = ['shapelen', 'func', 'calc_dtype', + 'res_dtype'], + reds = ['shape', 'w_obj', 'out', 'obj_iter', + 'out_iter']) + +def call1(shape, func, calc_dtype, res_dtype, w_obj, out): if out is None: out = W_NDimArray.from_shape(shape, res_dtype) obj_iter = w_obj.create_iter(shape) out_iter = out.create_iter(shape) + shapelen = len(shape) while not out_iter.done(): + call1_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, res_dtype=res_dtype, + shape=shape, w_obj=w_obj, out=out, + obj_iter=obj_iter, out_iter=out_iter) elem = obj_iter.getitem().convert_to(calc_dtype) out_iter.setitem(func(calc_dtype, elem).convert_to(res_dtype)) out_iter.next() obj_iter.next() return out +setslice_driver = jit.JitDriver(name='numpy_setslice', + greens = ['shapelen', 'dtype'], + reds = ['target', 'source', 'target_iter', + 'source_iter']) + def setslice(shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) source_iter = source.create_iter(shape) dtype = target.dtype + shapelen = len(shape) while not target_iter.done(): + setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + target=target, source=source, + target_iter=target_iter, + source_iter=source_iter) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target +reduce_driver = jit.JitDriver(name='numpy_reduce', + greens = ['shapelen', 'func', 'done_func', + 'calc_dtype', 'identity'], + reds = ['obj', 'obj_iter', 'cur_value']) + def compute_reduce(obj, calc_dtype, func, done_func, identity): obj_iter = obj.create_iter(obj.get_shape()) if identity is None: @@ -56,7 +95,12 @@ obj_iter.next() else: cur_value = identity.convert_to(calc_dtype) + shapelen = len(obj.get_shape()) while not obj_iter.done(): + reduce_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, identity=identity, + done_func=done_func, obj=obj, + obj_iter=obj_iter, cur_value=cur_value) rval = obj_iter.getitem().convert_to(calc_dtype) if done_func is not None and done_func(calc_dtype, rval): return rval @@ -70,6 +114,11 @@ arr_iter.setitem(box) arr_iter.next() +where_driver = jit.JitDriver(name='numpy_where', + greens = ['shapelen', 'dtype', 'arr_dtype'], + reds = ['shape', 'arr', 'x', 'y','arr_iter', 'out', + 'x_iter', 'y_iter', 'iter', 'out_iter']) + def where(out, shape, arr, x, y, dtype): out_iter = out.create_iter(shape) arr_iter = arr.create_iter(shape) @@ -83,7 +132,13 @@ iter = y_iter else: iter = x_iter + shapelen = len(shape) while not iter.done(): + where_driver.jit_merge_point(shapelen=shapelen, shape=shape, + dtype=dtype, iter=iter, x_iter=x_iter, + y_iter=y_iter, arr_iter=arr_iter, + arr=arr, x=x, y=y, arr_dtype=arr_dtype, + out_iter=out_iter, out=out) w_cond = arr_iter.getitem() if arr_dtype.itemtype.bool(w_cond): w_val = x_iter.getitem().convert_to(dtype) @@ -96,12 +151,24 @@ y_iter.next() return out +axis_reduce__driver = jit.JitDriver(name='numpy_axis_reduce', + greens=['shapelen', 'func', 'dtype', + 'identity'], + reds=['axis', 'arr', 'out', 'shape', + 'out_iter', 'arr_iter']) + def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): out_iter = out.create_axis_iter(arr.get_shape(), axis) arr_iter = arr.create_iter(arr.get_shape()) if identity is not None: identity = identity.convert_to(dtype) + shapelen = len(shape) while not out_iter.done(): + axis_reduce__driver.jit_merge_point(shapelen=shapelen, func=func, + dtype=dtype, identity=identity, + axis=axis, arr=arr, out=out, + shape=shape, out_iter=out_iter, + arr_iter=arr_iter) w_val = arr_iter.getitem().convert_to(dtype) if out_iter.first_line: if identity is not None: @@ -114,23 +181,41 @@ out_iter.next() return out - at specialize.arg(0) -def argmin_argmax(op_name, arr): - result = 0 - idx = 1 - dtype = arr.get_dtype() - iter = arr.create_iter(arr.get_shape()) - cur_best = iter.getitem() - iter.next() - while not iter.done(): - w_val = iter.getitem() - new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) - if dtype.itemtype.ne(new_best, cur_best): - result = idx - cur_best = new_best + +def _new_argmin_argmax(op_name): + arg_driver = jit.JitDriver(name='numpy_' + op_name, + greens = ['shapelen', 'dtype'], + reds = ['result', 'idx', 'cur_best', 'arr', + 'iter']) + + def argmin_argmax(arr): + result = 0 + idx = 1 + dtype = arr.get_dtype() + iter = arr.create_iter(arr.get_shape()) + cur_best = iter.getitem() iter.next() - idx += 1 - return result + shapelen = len(arr.get_shape()) + while not iter.done(): + arg_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + result=result, idx=idx, + cur_best=cur_best, arr=arr, iter=iter) + w_val = iter.getitem() + new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) + if dtype.itemtype.ne(new_best, cur_best): + result = idx + cur_best = new_best + iter.next() + idx += 1 + return result + return argmin_argmax +argmin = _new_argmin_argmax('min') +argmax = _new_argmin_argmax('max') + +# note that shapelen == 2 always +dot_driver = jit.JitDriver(name = 'numpy_dot', + greens = ['dtype'], + reds = ['outi', 'lefti', 'righti', 'result']) def multidim_dot(space, left, right, result, dtype, right_critical_dim): ''' assumes left, right are concrete arrays @@ -157,6 +242,8 @@ lefti = left.create_dot_iter(broadcast_shape, left_skip) righti = right.create_dot_iter(broadcast_shape, right_skip) while not outi.done(): + dot_driver.jit_merge_point(dtype=dtype, outi=outi, lefti=lefti, + righti=righti, result=result) lval = lefti.getitem().convert_to(dtype) rval = righti.getitem().convert_to(dtype) outval = outi.getitem().convert_to(dtype) @@ -168,21 +255,45 @@ lefti.next() return result +count_all_true_driver = jit.JitDriver(name = 'numpy_count', + greens = ['shapelen', 'dtype'], + reds = ['s', 'iter']) + 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() while not iter.done(): + count_all_true_driver.jit_merge_point(shapelen=shapelen, iter=iter, + s=s, 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'], + reds = ['res', 'index_iter', 'res_iter', + 'arr_iter']) + def getitem_filter(res, arr, index): res_iter = res.create_iter() index_iter = index.create_iter() arr_iter = arr.create_iter() + shapelen = len(arr.get_shape()) + arr_dtype = arr.get_dtype() + index_dtype = index.get_dtype() + # XXX length of shape of index as well? while not index_iter.done(): + getitem_filter_driver.jit_merge_point(shapelen=shapelen, + index_dtype=index_dtype, + arr_dtype=arr_dtype, + res=res, index_iter=index_iter, + res_iter=res_iter, + arr_iter=arr_iter) if index_iter.getitem_bool(): res_iter.setitem(arr_iter.getitem()) res_iter.next() @@ -190,31 +301,63 @@ arr_iter.next() return res +setitem_filter_driver = jit.JitDriver(name = 'numpy_setitem_bool', + greens = ['shapelen', 'arr_dtype', + 'index_dtype'], + reds = ['index_iter', 'value_iter', + 'arr_iter']) + def setitem_filter(arr, index, value): arr_iter = arr.create_iter() index_iter = index.create_iter() value_iter = value.create_iter() + shapelen = len(arr.get_shape()) + index_dtype = index.get_dtype() + arr_dtype = arr.get_dtype() while not index_iter.done(): + setitem_filter_driver.jit_merge_point(shapelen=shapelen, + index_dtype=index_dtype, + arr_dtype=arr_dtype, + index_iter=index_iter, + value_iter=value_iter, + arr_iter=arr_iter) if index_iter.getitem_bool(): arr_iter.setitem(value_iter.getitem()) value_iter.next() arr_iter.next() index_iter.next() +flatiter_getitem_driver = jit.JitDriver(name = 'numpy_flatiter_getitem', + greens = ['dtype'], + reds = ['step', 'ri', 'res', + 'base_iter']) + def flatiter_getitem(res, base_iter, step): ri = res.create_iter() + dtype = res.get_dtype() while not ri.done(): + flatiter_getitem_driver.jit_merge_point(dtype=dtype, + base_iter=base_iter, + ri=ri, res=res, step=step) ri.setitem(base_iter.getitem()) base_iter.next_skip_x(step) ri.next() return res +flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', + greens = ['dtype'], + reds = ['length', 'step', 'arr_iter', + 'val_iter']) + def flatiter_setitem(arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: + flatiter_setitem_driver.jit_merge_point(dtype=dtype, length=length, + step=step, arr_iter=arr_iter, + val_iter=val_iter) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -223,10 +366,16 @@ # WTF numpy? val_iter.reset() +fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', + greens = ['itemsize', 'dtype'], + reds = ['i', 's', 'ai']) + def fromstring_loop(a, dtype, itemsize, s): i = 0 ai = a.create_iter() while not ai.done(): + fromstring_driver.jit_merge_point(dtype=dtype, s=s, ai=ai, i=i, + itemsize=itemsize) val = dtype.itemtype.runpack_str(s[i*itemsize:i*itemsize + itemsize]) ai.setitem(val) ai.next() @@ -274,12 +423,25 @@ else: self._done = True + @jit.unroll_safe def get_index(self, space): return [space.wrap(i) for i in self.indexes] +getitem_int_driver = jit.JitDriver(name = 'numpy_getitem_int', + greens = ['shapelen', 'indexlen', 'dtype'], + reds = ['arr', 'res', 'iter', 'indexes_w', + 'prefix_w']) + def getitem_array_int(space, arr, res, iter_shape, indexes_w, prefix_w): + shapelen = len(iter_shape) + indexlen = len(indexes_w) + dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): + getitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, + dtype=dtype, arr=arr, res=res, + iter=iter, indexes_w=indexes_w, + prefix_w=prefix_w) # prepare the index index_w = [None] * len(indexes_w) for i in range(len(indexes_w)): @@ -293,10 +455,22 @@ iter.next() return res +setitem_int_driver = jit.JitDriver(name = 'numpy_setitem_int', + greens = ['shapelen', 'indexlen', 'dtype'], + reds = ['arr', 'iter', 'indexes_w', + 'prefix_w', 'val_arr']) + def setitem_array_int(space, arr, iter_shape, indexes_w, val_arr, prefix_w): + shapelen = len(iter_shape) + indexlen = len(indexes_w) + dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): + setitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, + dtype=dtype, arr=arr, + iter=iter, indexes_w=indexes_w, + prefix_w=prefix_w, val_arr=val_arr) # prepare the index index_w = [None] * len(indexes_w) for i in range(len(indexes_w)): diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py --- a/pypy/module/micronumpy/test/test_compile.py +++ b/pypy/module/micronumpy/test/test_compile.py @@ -1,6 +1,5 @@ + import py -py.test.skip("this is going away") - from pypy.module.micronumpy.compile import (numpy_compile, Assignment, ArrayConstant, FloatConstant, Operator, Variable, RangeConstant, Execute, FunctionCall, FakeSpace) @@ -136,7 +135,7 @@ r """ interp = self.run(code) - assert interp.results[0].value.value == 15 + assert interp.results[0].get_scalar_value().value == 15 def test_sum2(self): code = """ @@ -145,7 +144,7 @@ sum(b) """ interp = self.run(code) - assert interp.results[0].value.value == 30 * (30 - 1) + assert interp.results[0].get_scalar_value().value == 30 * (30 - 1) def test_array_write(self): @@ -164,7 +163,7 @@ b = a + a min(b) """) - assert interp.results[0].value.value == -24 + assert interp.results[0].get_scalar_value().value == -24 def test_max(self): interp = self.run(""" @@ -173,7 +172,7 @@ b = a + a max(b) """) - assert interp.results[0].value.value == 256 + assert interp.results[0].get_scalar_value().value == 256 def test_slice(self): interp = self.run(""" @@ -265,6 +264,7 @@ assert interp.results[0].value == 3 def test_take(self): + py.test.skip("unsupported") interp = self.run(""" a = |10| b = take(a, [1, 1, 3, 2]) 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 @@ -1519,7 +1519,7 @@ assert (a == [1, 1]).all() def test_int_array_index(self): - from numpypy import array, arange + from numpypy import array, arange, zeros b = arange(10)[array([3, 2, 1, 5])] assert (b == [3, 2, 1, 5]).all() raises(IndexError, "arange(10)[array([10])]") @@ -1528,6 +1528,7 @@ a = arange(1) a[[0, 0]] += 1 assert a[0] == 1 + assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): from numpypy import array, arange, zeros @@ -1999,6 +2000,7 @@ def test_int_array_index(self): from _numpypy import array + assert (array([])[[]] == []).all() a = array([[1, 2], [3, 4], [5, 6]]) assert (a[slice(0, 3), [0, 0]] == [[1, 1], [3, 3], [5, 5]]).all() assert (a[array([0, 2]), slice(0, 2)] == [[1, 2], [5, 6]]).all() 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 @@ -4,18 +4,12 @@ """ import py -py.test.skip("this is going away") - from pypy.jit.metainterp import pyjitpl from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp.warmspot import reset_stats from pypy.module.micronumpy import interp_boxes -from pypy.module.micronumpy.compile import (FakeSpace, - IntObject, Parser, InterpreterState) -from pypy.module.micronumpy.interp_numarray import (W_NDimArray, - BaseArray, W_FlatIterator) -from pypy.rlib.nonconst import NonConstant - +from pypy.module.micronumpy.compile import FakeSpace, Parser, InterpreterState +from pypy.module.micronumpy.base import W_NDimArray class TestNumpyJIt(LLJitMixin): graph = None @@ -51,11 +45,8 @@ if not len(interp.results): raise Exception("need results") w_res = interp.results[-1] - if isinstance(w_res, BaseArray): - concr = w_res.get_concrete_or_scalar() - sig = concr.find_sig() - frame = sig.create_frame(concr) - w_res = sig.eval(frame, concr) + if isinstance(w_res, W_NDimArray): + w_res = w_res.create_iter().getitem() if isinstance(w_res, interp_boxes.W_Float64Box): return w_res.value if isinstance(w_res, interp_boxes.W_Int64Box): @@ -73,6 +64,7 @@ self.__class__.graph = graph reset_stats() pyjitpl._warmrunnerdesc.memory_manager.alive_loops.clear() + py.test.skip("don't run for now") return self.interp.eval_graph(self.graph, [i]) def define_add(): 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 @@ -79,7 +79,7 @@ except ExitFrame: return self.popvalue() - def jump_absolute(self, jumpto, _, ec=None): + def jump_absolute(self, jumpto, ec): if we_are_jitted(): # # assume that only threads are using the bytecode counter diff --git a/pypy/module/pypyjit/test_pypy_c/test_exception.py b/pypy/module/pypyjit/test_pypy_c/test_exception.py --- a/pypy/module/pypyjit/test_pypy_c/test_exception.py +++ b/pypy/module/pypyjit/test_pypy_c/test_exception.py @@ -95,7 +95,6 @@ def test_continue_in_finally(self): # check that 'continue' inside a try:finally: block is correctly # detected as closing a loop - py.test.skip("is this case important?") def f(n): i = 0 while 1: @@ -110,10 +109,9 @@ assert log.result == 2001 loop, = log.loops_by_filename(self.filepath) assert loop.match(""" - i40 = int_add_ovf(i31, 1) - guard_no_overflow(descr=...) - i41 = int_lt(i40, i33) - guard_true(i41, descr=...) + i3 = int_lt(i1, i2) + guard_true(i3, descr=...) + i4 = int_add(i1, 1) --TICK-- jump(..., descr=...) """) diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,7 +1,8 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import PyCode, BytecodeCorruption +from pypy.interpreter.pycode import (PyCode, BytecodeCorruption, cpython_magic, + cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) from pypy.interpreter.astcompiler.consts import CO_GENERATOR @@ -12,6 +13,57 @@ """ opnames = host_bytecode_spec.method_names + def __init__(self, space, argcount, nlocals, stacksize, flags, + code, consts, names, varnames, filename, + name, firstlineno, lnotab, freevars, cellvars, + hidden_applevel=False, magic=cpython_magic): + """Initialize a new code object""" + self.space = space + self.co_name = name + assert nlocals >= 0 + self.co_argcount = argcount + self.co_nlocals = nlocals + self.co_stacksize = stacksize + self.co_flags = flags + self.co_code = code + self.co_consts_w = consts + self.co_names_w = [space.wrap(aname) for aname in names] + self.co_varnames = varnames + self.co_freevars = freevars + self.co_cellvars = cellvars + self.co_filename = filename + self.co_name = name + self.co_firstlineno = firstlineno + self.co_lnotab = lnotab + self.hidden_applevel = hidden_applevel + self.magic = magic + self._signature = cpython_code_signature(self) + self._initialize() + + def _initialize(self): + # Precompute what arguments need to be copied into cellvars + self._args_as_cellvars = [] + + if self.co_cellvars: + argcount = self.co_argcount + assert argcount >= 0 # annotator hint + if self.co_flags & CO_VARARGS: + argcount += 1 + if self.co_flags & CO_VARKEYWORDS: + argcount += 1 + # Cell vars could shadow already-set arguments. + # See comment in PyCode._initialize() + argvars = self.co_varnames + cellvars = self.co_cellvars + for i in range(len(cellvars)): + cellname = cellvars[i] + for j in range(argcount): + if cellname == argvars[j]: + # argument j has the same name as the cell var i + while len(self._args_as_cellvars) <= i: + self._args_as_cellvars.append(-1) # pad + self._args_as_cellvars[i] = j + def read(self, pos): """ Decode the instruction starting at position ``next_instr``. diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -1,19 +1,17 @@ import collections -import sys from pypy.tool.error import source_lines -from pypy.interpreter.error import OperationError -from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter import pyframe from pypy.interpreter.nestedscope import Cell -from pypy.interpreter.pycode import CO_OPTIMIZED, CO_NEWLOCALS +from pypy.interpreter.pycode import CO_NEWLOCALS from pypy.interpreter.argument import ArgumentsForTranslation -from pypy.interpreter.pyopcode import (Return, Yield, SuspendedUnroller, - SReturnValue, SApplicationException, BytecodeCorruption, - RaiseWithExplicitTraceback) -from pypy.objspace.flow.model import * +from pypy.interpreter.pyopcode import Return, BytecodeCorruption +from pypy.objspace.flow.model import (Constant, Variable, Block, Link, + UnwrapException, SpaceOperation, FunctionGraph, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, recursively_flatten) from pypy.objspace.flow.bytecode import HostCode +from pypy.objspace.flow.specialcase import (rpython_print_item, + rpython_print_newline) class FlowingError(Exception): """ Signals invalid RPython in the function being analysed""" @@ -27,16 +25,14 @@ msg += source_lines(self.frame.graph, None, offset=self.frame.last_instr) return "\n".join(msg) - class StopFlowing(Exception): pass -class FSException(OperationError): - def __init__(self, w_type, w_value, tb=None): +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 - self._application_traceback = tb def get_w_value(self, _): return self.w_value @@ -44,45 +40,6 @@ def __str__(self): return '[%s: %s]' % (self.w_type, self.w_value) - def normalize_exception(self, space): - """Normalize the OperationError. In other words, fix w_type and/or - w_value to make sure that the __class__ of w_value is exactly w_type. - """ - w_type = self.w_type - w_value = self.w_value - if space.exception_is_valid_obj_as_class_w(w_type): - # this is for all cases of the form (Class, something) - if space.is_w(w_value, space.w_None): - # raise Type: we assume we have to instantiate Type - w_value = space.call_function(w_type) - w_type = self._exception_getclass(space, w_value) - else: - w_valuetype = space.exception_getclass(w_value) - if space.exception_issubclass_w(w_valuetype, w_type): - # raise Type, Instance: let etype be the exact type of value - w_type = w_valuetype - else: - # raise Type, X: assume X is the constructor argument - w_value = space.call_function(w_type, w_value) - w_type = self._exception_getclass(space, w_value) - - else: - # the only case left here is (inst, None), from a 'raise inst'. - w_inst = w_type - w_instclass = self._exception_getclass(space, w_inst) - if not space.is_w(w_value, space.w_None): - raise FSException(space.w_TypeError, - space.wrap("instance exception may not " - "have a separate value")) - w_value = w_inst - w_type = w_instclass - - self.w_type = w_type - self.w_value = w_value - -class OperationThatShouldNotBePropagatedError(FSException): - pass - class ImplicitOperationError(FSException): pass @@ -262,6 +219,20 @@ # ____________________________________________________________ +compare_method = [ + "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", + ] + class FlowSpaceFrame(pyframe.CPythonFrame): def __init__(self, space, func, constargs=None): @@ -497,38 +468,68 @@ res = getattr(self, methodname)(oparg, next_instr) if res is not None: next_instr = res - except OperationThatShouldNotBePropagatedError, e: - raise Exception( - 'found an operation that always raises %s: %s' % ( - self.space.unwrap(e.w_type).__name__, - self.space.unwrap(e.w_value))) except FSException, operr: - self.attach_traceback(operr) next_instr = self.handle_operation_error(operr) - except RaiseWithExplicitTraceback, e: - next_instr = self.handle_operation_error(e.operr) return next_instr - def attach_traceback(self, operr): - if self.pycode.hidden_applevel: - return - tb = operr.get_traceback() - tb = PyTraceback(self.space, self, self.last_instr, tb) - operr.set_traceback(tb) - def handle_operation_error(self, operr): - block = self.unrollstack(SFlowException.kind) + block = self.unrollstack(SApplicationException.kind) if block is None: - # no handler found for the exception - # try to preserve the CPython-level traceback - import sys - tb = sys.exc_info()[2] - raise operr, None, tb + raise operr else: - unroller = SFlowException(operr) + unroller = SApplicationException(operr) next_instr = block.handle(self, unroller) return next_instr + def BAD_OPCODE(self, _, next_instr): + raise FlowingError(self, "This operation is not RPython") + + def BREAK_LOOP(self, oparg, next_instr): + return self.unrollstack_and_jump(SBreakLoop.singleton) + + def CONTINUE_LOOP(self, startofloop, next_instr): + unroller = SContinueLoop(startofloop) + return self.unrollstack_and_jump(unroller) + + 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)) + + def cmp_exc_match(self, w_1, w_2): + return self.space.newbool(self.space.exception_match(w_1, w_2)) + + def COMPARE_OP(self, testnum, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = getattr(self, compare_method[testnum])(w_1, w_2) + self.pushvalue(w_result) + def RAISE_VARARGS(self, nbargs, next_instr): space = self.space if nbargs == 0: @@ -538,7 +539,7 @@ # re-raising an implicit operation makes it an explicit one operr = FSException(operr.w_type, operr.w_value) self.last_exception = operr - raise RaiseWithExplicitTraceback(operr) + raise operr else: raise FSException(space.w_TypeError, space.wrap("raise: no active exception to re-raise")) @@ -550,8 +551,7 @@ w_value = self.popvalue() if 1: w_type = self.popvalue() - operror = FSException(w_type, w_value) - operror.normalize_exception(space) + operror = space.exc_from_raise(w_type, w_value) raise operror def IMPORT_NAME(self, nameindex, next_instr): @@ -580,17 +580,45 @@ return next_instr # now inside a 'finally' block def END_FINALLY(self, oparg, next_instr): - unroller = self.end_finally() - if isinstance(unroller, SuspendedUnroller): - # go on unrolling the stack - block = self.unrollstack(unroller.kind) - if block is None: - w_result = unroller.nomoreblocks() - self.pushvalue(w_result) - raise Return - else: - next_instr = block.handle(self, unroller) - return next_instr + # unlike CPython, there are two statically distinct cases: the + # END_FINALLY might be closing an 'except' block or a 'finally' + # block. In the first case, the stack contains three items: + # [exception type we are now handling] + # [exception value we are now handling] + # [wrapped 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] + w_top = self.popvalue() + if w_top == self.space.w_None: + # finally: block with no unroller active + return + try: + unroller = self.space.unwrap(w_top) + except UnwrapException: + pass + else: + if isinstance(unroller, SuspendedUnroller): + # case of a finally: block + return self.unroll_finally(unroller) + # case of an except: block. We popped the exception type + self.popvalue() # Now we pop the exception value + unroller = self.space.unwrap(self.popvalue()) + return self.unroll_finally(unroller) + + def unroll_finally(self, unroller): + # go on unrolling the stack + block = self.unrollstack(unroller.kind) + if block is None: + w_result = unroller.nomoreblocks() + self.pushvalue(w_result) + raise Return + else: + return block.handle(self, unroller) + + def POP_BLOCK(self, oparg, next_instr): + block = self.pop_block() + block.cleanupstack(self) # the block knows how to clean up the value stack def JUMP_ABSOLUTE(self, jumpto, next_instr): return jumpto @@ -603,11 +631,48 @@ # isn't popped straightaway. self.pushvalue(None) + PRINT_EXPR = BAD_OPCODE + PRINT_ITEM_TO = BAD_OPCODE + PRINT_NEWLINE_TO = BAD_OPCODE + + def PRINT_ITEM(self, oparg, next_instr): + w_item = self.popvalue() + w_s = self.space.do_operation('str', w_item) + self.space.appcall(rpython_print_item, w_s) + + def PRINT_NEWLINE(self, oparg, next_instr): + self.space.appcall(rpython_print_newline) + + def FOR_ITER(self, jumpby, next_instr): + w_iterator = self.peekvalue() + try: + w_nextitem = self.space.next(w_iterator) + except FSException, e: + if not self.space.exception_match(e.w_type, self.space.w_StopIteration): + raise + # iterator exhausted + self.popvalue() + next_instr += jumpby + else: + self.pushvalue(w_nextitem) + return next_instr + + def SETUP_LOOP(self, offsettoend, next_instr): + block = LoopBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + + def SETUP_EXCEPT(self, offsettoend, next_instr): + block = ExceptBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + + def SETUP_FINALLY(self, offsettoend, next_instr): + block = FinallyBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + def SETUP_WITH(self, offsettoend, next_instr): # A simpler version than the 'real' 2.7 one: # directly call manager.__enter__(), don't use special lookup functions # which don't make sense on the RPython type system. - from pypy.interpreter.pyopcode import WithBlock w_manager = self.peekvalue() w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__")) self.settopvalue(w_exit) @@ -616,10 +681,47 @@ self.lastblock = block self.pushvalue(w_result) + def WITH_CLEANUP(self, oparg, next_instr): + # Note: RPython context managers receive None in lieu of tracebacks + # and cannot suppress the exception. + # This opcode changed a lot between CPython versions + if (self.pycode.magic >= 0xa0df2ef + # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) + or self.pycode.magic >= 0xa0df2d1): + # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) + w_unroller = self.popvalue() + w_exitfunc = self.popvalue() + self.pushvalue(w_unroller) + elif self.pycode.magic >= 0xa0df28c: + # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) + w_exitfunc = self.popvalue() + w_unroller = self.peekvalue(0) + else: + raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") + + unroller = self.space.unwrap(w_unroller) + w_None = self.space.w_None + if isinstance(unroller, SApplicationException): + operr = unroller.operr + # 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) + else: + self.space.call_function(w_exitfunc, w_None, w_None, w_None) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) + def LOAD_ATTR(self, nameindex, next_instr): + "obj.attributename" + w_obj = self.popvalue() + w_attributename = self.getname_w(nameindex) + w_value = self.space.getattr(w_obj, w_attributename) + self.pushvalue(w_value) + LOOKUP_METHOD = LOAD_ATTR + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. @@ -647,23 +749,173 @@ def argument_factory(self, *args): return ArgumentsForTranslation(self.space, *args) - def call_contextmanager_exit_function(self, w_func, w_typ, w_val, w_tb): - if w_typ is not self.space.w_None: - # The annotator won't allow to merge exception types with None. - # Replace it with the exception value... - w_typ = w_val - self.space.call_function(w_func, w_typ, w_val, w_tb) - # Return None so that the flow space statically knows that we didn't - # swallow the exception - return self.space.w_None - ### Frame blocks ### -class SFlowException(SApplicationException): - """Flowspace override for SApplicationException""" +class SuspendedUnroller(object): + """Abstract base class for interpreter-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: + + WHY_NOT, OK, not this one :-) + WHY_EXCEPTION, SApplicationException + WHY_RERAISE, implemented differently, see Reraise + WHY_RETURN, SReturnValue + WHY_BREAK, SBreakLoop + WHY_CONTINUE, SContinueLoop + WHY_YIELD not needed + """ + 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): + """Signals a 'return' statement. + Argument is the wrapped object to return.""" + kind = 0x01 + def __init__(self, w_returnvalue): + self.w_returnvalue = w_returnvalue + + def nomoreblocks(self): + return self.w_returnvalue + + def state_unpack_variables(self, space): + return [self.w_returnvalue] + + @staticmethod + def state_pack_variables(space, w_returnvalue): + return SReturnValue(w_returnvalue) + +class SApplicationException(SuspendedUnroller): + """Signals an application-level exception + (i.e. an OperationException).""" + kind = 0x02 + def __init__(self, operr): + self.operr = operr + + def nomoreblocks(self): + raise self.operr + def state_unpack_variables(self, space): return [self.operr.w_type, self.operr.w_value] @staticmethod def state_pack_variables(space, w_type, w_value): - return SFlowException(FSException(w_type, w_value)) + return SApplicationException(FSException(w_type, w_value)) + +class SBreakLoop(SuspendedUnroller): + """Signals a 'break' statement.""" + kind = 0x04 + + def state_unpack_variables(self, space): + return [] + + @staticmethod + def state_pack_variables(space): + return SBreakLoop.singleton + +SBreakLoop.singleton = SBreakLoop() + +class SContinueLoop(SuspendedUnroller): + """Signals a 'continue' statement. + Argument is the bytecode position of the beginning of the loop.""" + kind = 0x08 + def __init__(self, jump_to): + self.jump_to = jump_to + + def state_unpack_variables(self, space): + return [space.wrap(self.jump_to)] + + @staticmethod + def state_pack_variables(space, w_jump_to): + return SContinueLoop(space.int_w(w_jump_to)) + + +class FrameBlock(object): + """Abstract base class for frame blocks from the blockstack, + used by the SETUP_XXX and POP_BLOCK opcodes.""" + + def __init__(self, frame, handlerposition, previous): + self.handlerposition = handlerposition + self.valuestackdepth = frame.valuestackdepth + self.previous = previous # this makes a linked list of blocks + + def __eq__(self, other): + return (self.__class__ is other.__class__ and + self.handlerposition == other.handlerposition and + self.valuestackdepth == other.valuestackdepth) + + def __ne__(self, other): + return not (self == other) + + def __hash__(self): + return hash((self.handlerposition, self.valuestackdepth)) + + def cleanupstack(self, frame): + frame.dropvaluesuntil(self.valuestackdepth) + + def handle(self, frame, unroller): + raise NotImplementedError + +class LoopBlock(FrameBlock): + """A loop block. Stores the end-of-loop pointer in case of 'break'.""" + + _opname = 'SETUP_LOOP' + handling_mask = SBreakLoop.kind | SContinueLoop.kind + + def handle(self, frame, unroller): + if isinstance(unroller, SContinueLoop): + # 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 + frame.append_block(self) + return unroller.jump_to + else: + # jump to the end of the loop + self.cleanupstack(frame) + return self.handlerposition + +class ExceptBlock(FrameBlock): + """An try:except: block. Stores the position of the exception handler.""" + + _opname = 'SETUP_EXCEPT' + handling_mask = SApplicationException.kind + + 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) + operationerr = unroller.operr + # the stack setup is slightly different than in CPython: + # instead of the traceback, we store the unroller object, + # wrapped. + frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(operationerr.get_w_value(frame.space)) + frame.pushvalue(operationerr.w_type) + frame.last_exception = operationerr + return self.handlerposition # jump to the handler + +class FinallyBlock(FrameBlock): + """A try:finally: block. Stores the position of the exception handler.""" + + _opname = 'SETUP_FINALLY' + handling_mask = -1 # handles every kind of SuspendedUnroller + + def handle(self, frame, unroller): + # any abnormal reason for unrolling a finally: triggers the end of + # the block unrolling and the entering the finally: handler. + self.cleanupstack(frame) + frame.pushvalue(frame.space.wrap(unroller)) + return self.handlerposition # jump to the handler + + +class WithBlock(FinallyBlock): + + def handle(self, frame, unroller): + return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -1,4 +1,3 @@ -from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.rlib.unroll import SpecTag from pypy.objspace.flow.model import * @@ -106,6 +105,7 @@ UNPICKLE_TAGS = {} def recursively_flatten(space, lst): + from pypy.objspace.flow.flowcontext import SuspendedUnroller i = 0 while i < len(lst): item = lst[i] diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -1,14 +1,14 @@ # ______________________________________________________________________ import __builtin__ import sys -import operator import types -from pypy.interpreter.baseobjspace import ObjSpace, Wrappable -from pypy.interpreter import pyframe, argument -from pypy.objspace.flow.model import * +from pypy.interpreter.baseobjspace import ObjSpace +from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.model import (Constant, Variable, WrapException, + UnwrapException, checkgraph, SpaceOperation) from pypy.objspace.flow import operation from pypy.objspace.flow.flowcontext import (FlowSpaceFrame, fixeggblocks, - OperationThatShouldNotBePropagatedError, FSException, FlowingError) + FSException, FlowingError) from pypy.objspace.flow.specialcase import SPECIAL_CASES from pypy.rlib.unroll import unrolling_iterable, _unroller from pypy.rlib import rstackovf, rarithmetic @@ -38,47 +38,32 @@ } # ______________________________________________________________________ -class FlowObjSpace(ObjSpace): +class FlowObjSpace(object): """NOT_RPYTHON. The flow objspace space is used to produce a flow graph by recording the space operations that the interpreter generates when it interprets (the bytecode of) some function. """ + w_None = Constant(None) + builtin = Constant(__builtin__) + sys = Constant(sys) + w_False = Constant(False) + w_True = Constant(True) + w_type = Constant(type) + w_tuple = Constant(tuple) + for exc in [KeyError, ValueError, IndexError, StopIteration, + AssertionError, TypeError, AttributeError, ImportError]: + clsname = exc.__name__ + locals()['w_' + clsname] = Constant(exc) - full_exceptions = False - FrameClass = FlowSpaceFrame + # the following exceptions should not show up + # during flow graph construction + w_NameError = None + w_UnboundLocalError = None - def initialize(self): - self.w_None = Constant(None) - self.builtin = Constant(__builtin__) - self.sys = Constant(sys) - self.w_False = Constant(False) - self.w_True = Constant(True) - self.w_type = Constant(type) - self.w_tuple = Constant(tuple) - for exc in [KeyError, ValueError, IndexError, StopIteration, - AssertionError, TypeError, AttributeError, ImportError]: - clsname = exc.__name__ - setattr(self, 'w_'+clsname, Constant(exc)) - # the following exceptions are the ones that should not show up - # during flow graph construction; they are triggered by - # non-R-Pythonic constructs or real bugs like typos. - for exc in [NameError, UnboundLocalError]: - clsname = exc.__name__ - setattr(self, 'w_'+clsname, None) - self.specialcases = SPECIAL_CASES.copy() - #self.make_builtins() - #self.make_sys() - # w_str is needed because cmp_exc_match of frames checks against it, - # as string exceptions are deprecated - self.w_str = Constant(str) - # objects which should keep their SomeObjectness - self.not_really_const = NOT_REALLY_CONST - - # disable superclass methods - enter_cache_building_mode = None - leave_cache_building_mode = None - createcompiler = None + specialcases = SPECIAL_CASES + # objects which should keep their SomeObjectness + not_really_const = NOT_REALLY_CONST def is_w(self, w_one, w_two): return self.is_true(self.is_(w_one, w_two)) @@ -103,6 +88,12 @@ def newslice(self, w_start, w_stop, w_step): return self.do_operation('newslice', w_start, w_stop, w_step) + def newbool(self, b): + if b: + return self.w_True + else: + return self.w_False + def wrap(self, obj): if isinstance(obj, (Variable, Constant)): raise TypeError("already wrapped: " + repr(obj)) @@ -167,53 +158,77 @@ raise UnwrapException return obj - def interpclass_w(self, w_obj): - obj = self.unwrap(w_obj) - if isinstance(obj, Wrappable): - return obj - return None + def exception_issubclass_w(self, w_cls1, w_cls2): + return self.is_true(self.issubtype(w_cls1, w_cls2)) - def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj): + def _exception_match(self, w_exc_type, w_check_class): + """Helper for exception_match + + Handles the base case where w_check_class is a constant exception + type. """ - WARNING: this implementation is not complete at all. It's just enough - to be used by end_finally() inside pyopcode.py. - """ - return w_obj == self.w_None or (isinstance(w_obj, Constant) and - isinstance(w_obj.value, RequiredClass)) - - def getexecutioncontext(self): - return self.frame + if self.is_w(w_exc_type, w_check_class): + return True # fast path (also here to handle string exceptions) + try: + return self.exception_issubclass_w(w_exc_type, w_check_class) + except FSException, e: + if e.match(self, self.w_TypeError): # string exceptions maybe + return False + raise def exception_match(self, w_exc_type, w_check_class): + """Checks if the given exception type matches 'w_check_class'.""" try: check_class = self.unwrap(w_check_class) except UnwrapException: - raise Exception, "non-constant except guard" + raise FlowingError(self.frame, "Non-constant except guard.") if check_class in (NotImplementedError, AssertionError): raise FlowingError(self.frame, "Catching %s is not valid in RPython" % check_class.__name__) if not isinstance(check_class, tuple): # the simple case - return ObjSpace.exception_match(self, w_exc_type, w_check_class) + return self._exception_match(w_exc_type, w_check_class) # special case for StackOverflow (see rlib/rstackovf.py) if check_class == rstackovf.StackOverflow: w_real_class = self.wrap(rstackovf._StackOverflow) - return ObjSpace.exception_match(self, w_exc_type, w_real_class) + return self._exception_match(w_exc_type, w_real_class) # checking a tuple of classes for w_klass in self.fixedview(w_check_class): if self.exception_match(w_exc_type, w_klass): return True return False - def getconstclass(space, w_cls): - try: - ecls = space.unwrap(w_cls) - except UnwrapException: - pass + def exc_from_raise(self, w_type, w_value): + """ From noreply at buildbot.pypy.org Tue Oct 2 16:45:15 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 16:45:15 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: This hack is not needed anymore :-) Message-ID: <20121002144515.A6B891C00EC@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57736:3d4fb2de6119 Date: 2012-10-02 16:44 +0200 http://bitbucket.org/pypy/pypy/changeset/3d4fb2de6119/ Log: This hack is not needed anymore :-) diff --git a/pypy/rpython/tool/rffi_platform.py b/pypy/rpython/tool/rffi_platform.py --- a/pypy/rpython/tool/rffi_platform.py +++ b/pypy/rpython/tool/rffi_platform.py @@ -718,7 +718,7 @@ """ def run_example_code(filepath, eci, ignore_errors=False): - eci = eci.convert_sources_to_files(being_main=True) + eci = eci.convert_sources_to_files() files = [filepath] output = build_executable_cache(files, eci, ignore_errors=ignore_errors) section = None diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -942,7 +942,6 @@ # # Header # - print >> f, '#define PYPY_MAIN_IMPLEMENTATION_FILE' print >> f, '#include "common_header.h"' print >> f commondefs(defines) @@ -973,6 +972,6 @@ fi.close() eci = add_extra_files(eci) - eci = eci.convert_sources_to_files(being_main=True) + eci = eci.convert_sources_to_files() files, eci = eci.get_module_files() return eci, filename, sg.getextrafiles() + list(files) diff --git a/pypy/translator/tool/cbuild.py b/pypy/translator/tool/cbuild.py --- a/pypy/translator/tool/cbuild.py +++ b/pypy/translator/tool/cbuild.py @@ -238,7 +238,7 @@ d[attr] = getattr(self, attr) return d - def convert_sources_to_files(self, cache_dir=None, being_main=False): + def convert_sources_to_files(self, cache_dir=None): if not self.separate_module_sources: return self if cache_dir is None: @@ -252,11 +252,6 @@ if not filename.check(): break f = filename.open("w") - if not being_main: - # This eci is being built independently from a larger - # target, so it has to include a copy of the C RPython - # helper functions when needed. - f.write("#define PYPY_MAIN_IMPLEMENTATION_FILE\n") self.write_c_header(f) source = str(source) f.write(source) From noreply at buildbot.pypy.org Tue Oct 2 16:59:01 2012 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Tue, 2 Oct 2012 16:59:01 +0200 (CEST) Subject: [pypy-commit] pypy pytest: move the test jit/translation graph viewing options to a own plugin to external code can use it Message-ID: <20121002145901.4E18A1C00EC@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r57737:263956ca5435 Date: 2012-10-02 16:58 +0200 http://bitbucket.org/pypy/pypy/changeset/263956ca5435/ Log: move the test jit/translation graph viewing options to a own plugin to external code can use it diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -46,8 +46,6 @@ def pytest_addoption(parser): group = parser.getgroup("pypy options") - group.addoption('--view', action="store_true", dest="view", default=False, - help="view translation tests' flow graphs with Pygame") group.addoption('-A', '--runappdirect', action="store_true", default=False, dest="runappdirect", help="run applevel tests directly on python interpreter (not through PyPy)") @@ -57,10 +55,6 @@ group.addoption('-P', '--platform', action="callback", type="string", default="host", callback=_set_platform, help="set up tests to use specified platform as compile/run target") - group = parser.getgroup("JIT options") - group.addoption('--viewloops', action="store_true", - default=False, dest="viewloops", - help="show only the compiled loops") def pytest_sessionstart(): # have python subprocesses avoid startup customizations by default diff --git a/pypy/tool/pytest/viewerplugin.py b/pypy/tool/pytest/viewerplugin.py new file mode 100644 --- /dev/null +++ b/pypy/tool/pytest/viewerplugin.py @@ -0,0 +1,26 @@ +""" + pypy.tool.pytest.viewerplugin + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + this pytest plugin is support code for + testsuites using translation flowgraphs + or jit loop graphs. + + it can be enabled by + + * adding the module name to pytest_plugins in a conftest + * putting "-p pypy.tool.pytest.viewerplugin" + into pytest.ini +""" + + +def pytest_addoption(parser): + + group = parser.getgroup("pypy options") + group.addoption('--view', action="store_true", dest="view", default=False, + help="view translation tests' flow graphs with Pygame") + + group = parser.getgroup("JIT options") + group.addoption('--viewloops', action="store_true", + default=False, dest="viewloops", + help="show only the compiled loops") diff --git a/pytest.ini b/pytest.ini --- a/pytest.ini +++ b/pytest.ini @@ -1,2 +1,4 @@ [pytest] -addopts = --assert=reinterp -rf +addopts = + --assert=reinterp -rf + -p pypy.tool.pytest.viewerplugin From noreply at buildbot.pypy.org Tue Oct 2 17:06:39 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 2 Oct 2012 17:06:39 +0200 (CEST) Subject: [pypy-commit] pypy py3k: try to fix what was broken after the merge because of the translation-cleanup branch Message-ID: <20121002150639.451E71C00EC@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57738:f123c1cfc55b Date: 2012-10-02 17:06 +0200 http://bitbucket.org/pypy/pypy/changeset/f123c1cfc55b/ Log: try to fix what was broken after the merge because of the translation-cleanup branch diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -13,7 +13,7 @@ """ opnames = host_bytecode_spec.method_names - def __init__(self, space, argcount, nlocals, stacksize, flags, + def __init__(self, space, argcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, hidden_applevel=False, magic=cpython_magic): @@ -22,6 +22,8 @@ self.co_name = name assert nlocals >= 0 self.co_argcount = argcount + # note that this is ignored, as HostCode represents a python2 bytecode + self.co_kwonlyargcount = kwonlyargcount self.co_nlocals = nlocals self.co_stacksize = stacksize self.co_flags = flags diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -678,7 +678,7 @@ w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__")) self.settopvalue(w_exit) w_result = self.space.call_method(w_manager, "__enter__") - block = WithBlock(self.valuestackdepth, + block = WithBlock(self, next_instr + offsettoend, self.lastblock) self.lastblock = block self.pushvalue(w_result) From noreply at buildbot.pypy.org Tue Oct 2 17:29:59 2012 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Tue, 2 Oct 2012 17:29:59 +0200 (CEST) Subject: [pypy-commit] pypy pytest: use the applymarker api Message-ID: <20121002152959.1CD3A1C00EC@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r57739:e76c004973a7 Date: 2012-10-02 17:15 +0200 http://bitbucket.org/pypy/pypy/changeset/e76c004973a7/ Log: use the applymarker api diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -365,7 +365,7 @@ class IntTestFunction(py.test.collect.Function): def __init__(self, *args, **kwargs): super(IntTestFunction, self).__init__(*args, **kwargs) - self.keywords['interplevel'] = True + self.applymarker(pytest.mark.interplevel) def runtest(self): try: @@ -386,7 +386,7 @@ class AppTestFunction(py.test.collect.Function): def __init__(self, *args, **kwargs): super(AppTestFunction, self).__init__(*args, **kwargs) - self.keywords['applevel'] = True + self.applymarker(pytest.mark.applevel) def _prunetraceback(self, traceback): return traceback From noreply at buildbot.pypy.org Tue Oct 2 17:30:00 2012 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Tue, 2 Oct 2012 17:30:00 +0200 (CEST) Subject: [pypy-commit] pypy pytest: move the pygame check to the viewer plugin, add a test for it Message-ID: <20121002153000.4409F1C00EC@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r57740:3a8ee8860fee Date: 2012-10-02 17:29 +0200 http://bitbucket.org/pypy/pypy/changeset/3a8ee8860fee/ Log: move the pygame check to the viewer plugin, add a test for it diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -356,12 +356,6 @@ if getattr(item, '_success', False) and item._pypytest_leaks: raise leakfinder.MallocMismatch(item._pypytest_leaks) - if 'pygame' in sys.modules: - assert option.view, ("should not invoke Pygame " - "if conftest.option.view is False") - -_pygame_imported = False - class IntTestFunction(py.test.collect.Function): def __init__(self, *args, **kwargs): super(IntTestFunction, self).__init__(*args, **kwargs) diff --git a/pypy/tool/pytest/test/test_viewerplugin.py b/pypy/tool/pytest/test/test_viewerplugin.py new file mode 100644 --- /dev/null +++ b/pypy/tool/pytest/test/test_viewerplugin.py @@ -0,0 +1,28 @@ +import sys +import pytest +from pypy.tool.pytest import viewerplugin + +class mock: + view = False + + @staticmethod + def execute(): + pass + +mock.config = mock +mock.option = mock + + +def test_pygame_teardown_check(monkeypatch): + monkeypatch.delitem(sys.modules, 'pygame', raising=False) + viewerplugin.pytest_runtest_teardown(mock, mock) + + monkeypatch.setitem(sys.modules, 'pygame', None) + with pytest.raises(AssertionError) as exc_info: + viewerplugin.pytest_runtest_teardown(mock, mock) + + monkeypatch.setattr(mock, 'view', True) + viewerplugin.pytest_runtest_teardown(mock, mock) + + + diff --git a/pypy/tool/pytest/viewerplugin.py b/pypy/tool/pytest/viewerplugin.py --- a/pypy/tool/pytest/viewerplugin.py +++ b/pypy/tool/pytest/viewerplugin.py @@ -12,7 +12,8 @@ * putting "-p pypy.tool.pytest.viewerplugin" into pytest.ini """ - +import sys +import pytest def pytest_addoption(parser): @@ -24,3 +25,13 @@ group.addoption('--viewloops', action="store_true", default=False, dest="viewloops", help="show only the compiled loops") + + + at pytest.mark.tryfirst +def pytest_runtest_teardown(__multicall__, item): + __multicall__.execute() + + if 'pygame' in sys.modules: + assert item.config.option.view, ("should not invoke Pygame " + "if view option is False") + From noreply at buildbot.pypy.org Tue Oct 2 18:20:08 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 2 Oct 2012 18:20:08 +0200 (CEST) Subject: [pypy-commit] pypy py3k: the _csv module now expects unicode to read, not strings Message-ID: <20121002162008.C00DA1C00EC@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57741:4193517439a8 Date: 2012-10-02 17:54 +0200 http://bitbucket.org/pypy/pypy/changeset/4193517439a8/ Log: the _csv module now expects unicode to read, not strings diff --git a/pypy/module/_csv/interp_reader.py b/pypy/module/_csv/interp_reader.py --- a/pypy/module/_csv/interp_reader.py +++ b/pypy/module/_csv/interp_reader.py @@ -1,4 +1,4 @@ -from pypy.rlib.rstring import StringBuilder +from pypy.rlib.rstring import UnicodeBuilder from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import NoneNotWrapped, unwrap_spec @@ -78,13 +78,13 @@ break raise self.line_num += 1 - line = space.str_w(w_line) + line = space.unicode_w(w_line) for c in line: - if c == '\0': + if c == u'\0': raise self.error("line contains NULL byte") if state == START_RECORD: - if c == '\n' or c == '\r': + if c == u'\n' or c == u'\r': state = EAT_CRNL continue # normal character - handle as START_FIELD @@ -92,9 +92,9 @@ # fall-through to the next case if state == START_FIELD: - field_builder = StringBuilder(64) + field_builder = UnicodeBuilder(64) # expecting field - if c == '\n' or c == '\r': + if c == u'\n' or c == u'\r': # save empty field self.save_field(field_builder) state = EAT_CRNL @@ -105,7 +105,7 @@ elif c == dialect.escapechar: # possible escaped character state = ESCAPED_CHAR - elif c == ' ' and dialect.skipinitialspace: + elif c == u' ' and dialect.skipinitialspace: # ignore space at start of field pass elif c == dialect.delimiter: @@ -124,7 +124,7 @@ elif state == IN_FIELD: # in unquoted field - if c == '\n' or c == '\r': + if c == u'\n' or c == u'\r': # end of line self.save_field(field_builder) state = EAT_CRNL @@ -171,7 +171,7 @@ # save field - wait for new field self.save_field(field_builder) state = START_FIELD - elif c == '\n' or c == '\r': + elif c == u'\n' or c == u'\r': # end of line self.save_field(field_builder) state = EAT_CRNL @@ -184,7 +184,7 @@ dialect.delimiter, dialect.quotechar)) elif state == EAT_CRNL: - if not (c == '\n' or c == '\r'): + if not (c == u'\n' or c == u'\r'): raise self.error("new-line character seen in unquoted " "field - do you need to open the file " "in universal-newline mode?") @@ -193,16 +193,16 @@ self.save_field(field_builder) break elif state == ESCAPED_CHAR: - self.add_char(field_builder, '\n') + self.add_char(field_builder, u'\n') state = IN_FIELD elif state == IN_QUOTED_FIELD: pass elif state == ESCAPE_IN_QUOTED_FIELD: - self.add_char(field_builder, '\n') + self.add_char(field_builder, u'\n') state = IN_QUOTED_FIELD elif state == START_FIELD: # save empty field - field_builder = StringBuilder(1) + field_builder = UnicodeBuilder(1) self.save_field(field_builder) break else: @@ -249,7 +249,7 @@ dialect = interp_attrproperty_w('dialect', W_Reader), line_num = interp_attrproperty('line_num', W_Reader), __iter__ = interp2app(W_Reader.iter_w), - next = interp2app(W_Reader.next_w), + __next__ = interp2app(W_Reader.next_w), __doc__ = """CSV reader Reader objects are responsible for reading and parsing tabular data diff --git a/pypy/module/_csv/test/test_reader.py b/pypy/module/_csv/test/test_reader.py --- a/pypy/module/_csv/test/test_reader.py +++ b/pypy/module/_csv/test/test_reader.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals from pypy.conftest import gettestobjspace @@ -24,6 +25,11 @@ def test_simple_reader(self): self._read_test(['foo:bar\n'], [['foo', 'bar']], delimiter=':') + def test_cannot_read_bytes(self): + import _csv + reader = _csv.reader([b'foo']) + raises(TypeError, "next(reader)") + def test_read_oddinputs(self): self._read_test([], []) self._read_test([''], [[]]) @@ -88,13 +94,13 @@ import _csv as csv r = csv.reader(['line,1', 'line,2', 'line,3']) assert r.line_num == 0 - r.next() + next(r) assert r.line_num == 1 - r.next() + next(r) assert r.line_num == 2 - r.next() + next(r) assert r.line_num == 3 - raises(StopIteration, r.next) + raises(StopIteration, "next(r)") assert r.line_num == 3 def test_dubious_quote(self): From noreply at buildbot.pypy.org Tue Oct 2 18:20:10 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 2 Oct 2012 18:20:10 +0200 (CEST) Subject: [pypy-commit] pypy py3k: bytes->unicode conversion for all of _csv Message-ID: <20121002162010.137441C00EC@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57742:eb67e48a3a84 Date: 2012-10-02 18:19 +0200 http://bitbucket.org/pypy/pypy/changeset/eb67e48a3a84/ Log: bytes->unicode conversion for all of _csv diff --git a/pypy/module/_csv/app_csv.py b/pypy/module/_csv/app_csv.py --- a/pypy/module/_csv/app_csv.py +++ b/pypy/module/_csv/app_csv.py @@ -8,7 +8,7 @@ def register_dialect(name, dialect=None, **kwargs): """Create a mapping from a string name to a dialect class.""" - if not isinstance(name, basestring): + if not isinstance(name, str): raise TypeError("dialect name must be a string or unicode") dialect = _csv.Dialect(dialect, **kwargs) diff --git a/pypy/module/_csv/interp_csv.py b/pypy/module/_csv/interp_csv.py --- a/pypy/module/_csv/interp_csv.py +++ b/pypy/module/_csv/interp_csv.py @@ -37,18 +37,18 @@ def _get_str(space, w_src, default): if w_src is None: return default - return space.str_w(w_src) + return space.unicode_w(w_src) def _get_char(space, w_src, default, name): if w_src is None: return default if space.is_w(w_src, space.w_None): - return '\0' - src = space.str_w(w_src) + return u'\0' + src = space.unicode_w(w_src) if len(src) == 1: return src[0] if len(src) == 0: - return '\0' + return u'\0' raise operationerrfmt(space.w_TypeError, '"%s" must be a 1-character string', name) @@ -56,7 +56,7 @@ w_escapechar, w_lineterminator, w_quotechar, w_quoting, w_skipinitialspace, w_strict): if w_dialect is not None: - if space.isinstance_w(w_dialect, space.w_basestring): + if space.isinstance_w(w_dialect, space.w_unicode): w_module = space.getbuiltinmodule('_csv') w_dialect = space.call_method(w_module, 'get_dialect', w_dialect) @@ -90,11 +90,11 @@ w_strict = _fetch(space, w_dialect, 'strict') dialect = W_Dialect() - dialect.delimiter = _get_char(space, w_delimiter, ',', 'delimiter') + dialect.delimiter = _get_char(space, w_delimiter, u',', 'delimiter') dialect.doublequote = _get_bool(space, w_doublequote, True) - dialect.escapechar = _get_char(space, w_escapechar, '\0', 'escapechar') - dialect.lineterminator = _get_str(space, w_lineterminator, '\r\n') - dialect.quotechar = _get_char(space, w_quotechar, '"', 'quotechar') + dialect.escapechar = _get_char(space, w_escapechar, u'\0', 'escapechar') + dialect.lineterminator = _get_str(space, w_lineterminator, u'\r\n') + dialect.quotechar = _get_char(space, w_quotechar, u'"', 'quotechar') tmp_quoting = _get_int(space, w_quoting, QUOTE_MINIMAL) dialect.skipinitialspace = _get_bool(space, w_skipinitialspace, False) dialect.strict = _get_bool(space, w_strict, False) @@ -104,13 +104,13 @@ raise OperationError(space.w_TypeError, space.wrap('bad "quoting" value')) - if dialect.delimiter == '\0': + if dialect.delimiter == u'\0': raise OperationError(space.w_TypeError, space.wrap('delimiter must be set')) if space.is_w(w_quotechar, space.w_None) and w_quoting is None: tmp_quoting = QUOTE_NONE - if tmp_quoting != QUOTE_NONE and dialect.quotechar == '\0': + if tmp_quoting != QUOTE_NONE and dialect.quotechar == u'\0': raise OperationError(space.w_TypeError, space.wrap('quotechar must be set if quoting enabled')) dialect.quoting = tmp_quoting @@ -145,12 +145,12 @@ def _get_escapechar(space, dialect): - if dialect.escapechar == '\0': + if dialect.escapechar == u'\0': return space.w_None return space.wrap(dialect.escapechar) def _get_quotechar(space, dialect): - if dialect.quotechar == '\0': + if dialect.quotechar == u'\0': return space.w_None return space.wrap(dialect.quotechar) diff --git a/pypy/module/_csv/interp_writer.py b/pypy/module/_csv/interp_writer.py --- a/pypy/module/_csv/interp_writer.py +++ b/pypy/module/_csv/interp_writer.py @@ -1,4 +1,4 @@ -from pypy.rlib.rstring import StringBuilder +from pypy.rlib.rstring import UnicodeBuilder from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import NoneNotWrapped @@ -34,16 +34,16 @@ space = self.space fields_w = space.listview(w_fields) dialect = self.dialect - rec = StringBuilder(80) + rec = UnicodeBuilder(80) # for field_index in range(len(fields_w)): w_field = fields_w[field_index] if space.is_w(w_field, space.w_None): field = "" elif space.isinstance_w(w_field, space.w_float): - field = space.str_w(space.repr(w_field)) + field = space.unicode_w(space.repr(w_field)) else: - field = space.str_w(space.str(w_field)) + field = space.unicode_w(space.str(w_field)) # if dialect.quoting == QUOTE_NONNUMERIC: try: @@ -97,7 +97,7 @@ else: want_escape = True if want_escape: - if dialect.escapechar == '\0': + if dialect.escapechar == u'\0': raise self.error("need to escape, " "but no escapechar set") rec.append(dialect.escapechar) From noreply at buildbot.pypy.org Tue Oct 2 18:25:11 2012 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 2 Oct 2012 18:25:11 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: do not trust tranlating platform's power() for tests Message-ID: <20121002162511.CFE501C00EC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-complex2 Changeset: r57743:5c72f033e952 Date: 2012-10-02 00:05 +0200 http://bitbucket.org/pypy/pypy/changeset/5c72f033e952/ Log: do not trust tranlating platform's power() for tests 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 @@ -304,7 +304,7 @@ ], dtype=c) got_err = False for p in (3, -1, 10000, 2.3, -10000, 10+3j): - b = power(a, p) + b = self.c_pow(a, p) for i in range(len(a)): r = a[i]**p msg = 'result of %r(%r)**%r got %r expected %r\n ' % \ From noreply at buildbot.pypy.org Tue Oct 2 18:25:13 2012 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 2 Oct 2012 18:25:13 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: add failing test for pow ( ** ) for interpreter, Message-ID: <20121002162513.184EF1C00EC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-complex2 Changeset: r57744:bfe960db6801 Date: 2012-10-02 06:07 +0200 http://bitbucket.org/pypy/pypy/changeset/bfe960db6801/ Log: add failing test for pow ( ** ) for interpreter, start to fix for interpreter, rcomplex, and numpypy disallow arctan2 for complex diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -153,6 +153,11 @@ yield self.simple_test, "x = 17 %s 5" % operator, "x", expected expected = eval("0 %s 11" % operator) yield self.simple_test, "x = 0 %s 11" % operator, "x", expected + + def test_pow(self): + expected = eval("complex(float('inf'), 0.) ** complex(10., 3.0)") + yield self.simple_test, \ + "x = complex(float('inf'), 0.) ** complex(10., 3.0)", "x", expected def test_compare(self): yield self.st, "x = 2; y = 5; y; h = 1 < x >= 3 < x", "h", False 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 @@ -547,7 +547,8 @@ "allow_complex": False}), ("fmax", "fmax", 2, {"promote_to_float": True}), ("fmin", "fmin", 2, {"promote_to_float": True}), - ("fmod", "fmod", 2, {"promote_to_float": True, 'allow_complex': False}), + ("fmod", "fmod", 2, {"promote_to_float": True, + 'allow_complex': False}), ("floor", "floor", 1, {"promote_to_float": True, "allow_complex": False}), ("ceil", "ceil", 1, {"promote_to_float": True, @@ -567,7 +568,8 @@ ("arcsin", "arcsin", 1, {"promote_to_float": True}), ("arccos", "arccos", 1, {"promote_to_float": True}), ("arctan", "arctan", 1, {"promote_to_float": True}), - ("arctan2", "arctan2", 2, {"promote_to_float": True}), + ("arctan2", "arctan2", 2, {"promote_to_float": True, + "allow_complex": False}), ("sinh", "sinh", 1, {"promote_to_float": True}), ("cosh", "cosh", 1, {"promote_to_float": True}), ("tanh", "tanh", 1, {"promote_to_float": True}), 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 @@ -263,7 +263,7 @@ def test_not_complex(self): from _numpypy import (radians, deg2rad, degrees, rad2deg, isneginf, isposinf, logaddexp, logaddexp2, fmod, - max, min) + arctan2) raises(TypeError, radians, complex(90,90)) raises(TypeError, deg2rad, complex(90,90)) raises(TypeError, degrees, complex(90,90)) @@ -272,6 +272,7 @@ raises(TypeError, isposinf, complex(1, 1)) raises(TypeError, logaddexp, complex(1, 1), complex(3, 3)) raises(TypeError, logaddexp2, complex(1, 1), complex(3, 3)) + raises(TypeError, arctan2, complex(1, 1), complex(3, 3)) raises (TypeError, fmod, complex(90,90), 3) def test_isnan_isinf(self): @@ -291,6 +292,7 @@ ninf = -float('inf') nan = float('nan') cmpl = complex + from math import copysign from _numpypy import power, array, complex128, complex64 for c,rel_err in ((complex128, 5e-323), (complex64, 1e-7)): a = array([cmpl(-5., 0), cmpl(-5., -5.), cmpl(-5., 5.), @@ -304,17 +306,24 @@ ], dtype=c) got_err = False for p in (3, -1, 10000, 2.3, -10000, 10+3j): - b = self.c_pow(a, p) + b = power(a, p) for i in range(len(a)): - r = a[i]**p + print a[i],p,p.real,p.imag + try: + r = self.c_pow((float(a[i].real), float(a[i].imag)), + (float(p.real), float(p.imag))) + except ZeroDivisionError: + r = (nan, nan) + except OverflowError: + r = (inf, -copysign(inf, a[i].imag)) msg = 'result of %r(%r)**%r got %r expected %r\n ' % \ (c,a[i], p, b[i], r) try: - t1 = float(r.real) + t1 = float(r[0]) t2 = float(b[i].real) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(r.imag) - t2 = float(b[i].imag) + t1 = float(r[1]) + t2 = float(b[i].imag) self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) except AssertionError as e: print e.message 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 @@ -1156,14 +1156,16 @@ @complex_binary_op def pow(self, v1, v2): - if not isfinite(v1[0]) or not isfinite(v1[1]): - return rfloat.NAN, rfloat.NAN + if v1[1] == 0 and v2[1] == 0 and v1[0] > 0: + return math.pow(v1[0], v2[0]), 0 + #if not isfinite(v1[0]) or not isfinite(v1[1]): + # return rfloat.NAN, rfloat.NAN try: return rcomplex.c_pow(v1, v2) except ZeroDivisionError: return rfloat.NAN, rfloat.NAN except OverflowError: - return rfloat.INFINITY, rfloat.INFINITY + return rfloat.INFINITY, -math.copysign(rfloat.INFINITY, v1[1]) #complex copysign does not exist in numpy @@ -1332,9 +1334,9 @@ return rfloat.NAN, math.copysign(rfloat.INFINITY, v[1]) return rcomplex.c_atan(*v) - @complex_binary_op - def arctan2(self, v1, v2): - return rcomplex.c_atan2(v1, v2) + #@complex_binary_op + #def arctan2(self, v1, v2): + # return rcomplex.c_atan2(v1, v2) @complex_unary_op def sinh(self, v): diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -229,6 +229,8 @@ raise OperationError(space.w_ZeroDivisionError, space.wrap("0.0 to a negative or complex power")) except OverflowError: raise OperationError(space.w_OverflowError, space.wrap("complex exponentiation")) + except ValueError as e: + raise OperationError(space.w_ValueError, space.wrap(e.message)) return w_p def neg__Complex(space, w_complex): diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py --- a/pypy/rlib/rcomplex.py +++ b/pypy/rlib/rcomplex.py @@ -67,7 +67,7 @@ def c_pow(x, y): (r1, i1), (r2, i2) = x, y - if i1 == 0 and i2 == 0 and r1>=0: + if i1 == 0 and i2 == 0 and r1 > 0: rr = math.pow(r1, r2) ir = 0. elif r2 == 0.0 and i2 == 0.0: From noreply at buildbot.pypy.org Tue Oct 2 18:25:14 2012 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 2 Oct 2012 18:25:14 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: test, implement square Message-ID: <20121002162514.50E231C00EC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-complex2 Changeset: r57745:aa838974e5f4 Date: 2012-10-02 08:59 +0200 http://bitbucket.org/pypy/pypy/changeset/aa838974e5f4/ Log: test, implement square 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 @@ -287,6 +287,11 @@ complex(float('nan'), 0)], dtype=complex)) == \ [False, True, True, False, False]).all() + + def test_square(self): + from _numpypy import square + assert square(complex(3, 4)) == complex(3,4) * complex(3, 4) + def test_power_complex(self): inf = float('inf') ninf = -float('inf') 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 @@ -1380,32 +1380,14 @@ return (math.copysign(rfloat.INFINITY, v[0]), math.copysign(0., v[1])) return rcomplex.c_atanh(*v) - - @complex_unary_op def sqrt(self, v): return rcomplex.c_sqrt(*v) - @simple_unary_op + @complex_unary_op def square(self, v): - return v*v - - @raw_unary_op - def isnan(self, v): - return rfloat.isnan(v[0]) or rfloat.isnan(v[1]) - - @raw_unary_op - def isinf(self, v): - return rfloat.isinf(v[0]) or rfloat.isinf(v[1]) - - #@raw_unary_op - #def isneginf(self, v): - # return rfloat.isinf(v) and v < 0 - - #@raw_unary_op - #def isposinf(self, v): - # return rfloat.isinf(v) and v > 0 + return rcomplex.c_mul(v,v) @raw_unary_op def isfinite(self, v): From noreply at buildbot.pypy.org Tue Oct 2 18:25:15 2012 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 2 Oct 2012 18:25:15 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: pass power tests Message-ID: <20121002162515.6E5251C00EC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-complex2 Changeset: r57746:cbb6be7ebe82 Date: 2012-10-02 18:18 +0200 http://bitbucket.org/pypy/pypy/changeset/cbb6be7ebe82/ Log: pass power tests 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 @@ -2,6 +2,7 @@ from math import isnan, isinf, copysign from sys import version_info, builtin_module_names from pypy.rlib.rcomplex import c_pow +from pypy.interpreter.error import OperationError from pypy.conftest import option @@ -65,7 +66,12 @@ cls.w_testcases128 = cls.space.wrap(fname128) cls.w_testcases64 = cls.space.wrap(fname64) def cls_c_pow(self, *args): - return c_pow(*args) + try: + retVal = c_pow(*args) + return retVal + except ValueError as e: + raise OperationError(cls.space.w_ValueError, + cls.space.wrap(e.message)) cls.w_c_pow = cls.space.wrap(cls_c_pow) cls.w_runAppDirect = cls.space.wrap(option.runappdirect) cls.w_isWindows = cls.space.wrap(os.name == 'nt') @@ -299,7 +305,7 @@ cmpl = complex from math import copysign from _numpypy import power, array, complex128, complex64 - for c,rel_err in ((complex128, 5e-323), (complex64, 1e-7)): + for c,rel_err in ((complex128, 5e-323), (complex64, 4e-7)): a = array([cmpl(-5., 0), cmpl(-5., -5.), cmpl(-5., 5.), cmpl(0., -5.), cmpl(0., 0.), cmpl(0., 5.), cmpl(-0., -5.), cmpl(-0., 0.), cmpl(-0., 5.), @@ -313,7 +319,6 @@ for p in (3, -1, 10000, 2.3, -10000, 10+3j): b = power(a, p) for i in range(len(a)): - print a[i],p,p.real,p.imag try: r = self.c_pow((float(a[i].real), float(a[i].imag)), (float(p.real), float(p.imag))) @@ -321,6 +326,8 @@ r = (nan, nan) except OverflowError: r = (inf, -copysign(inf, a[i].imag)) + except ValueError: + r = (nan, nan) msg = 'result of %r(%r)**%r got %r expected %r\n ' % \ (c,a[i], p, b[i], r) try: 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 @@ -1166,6 +1166,8 @@ return rfloat.NAN, rfloat.NAN except OverflowError: return rfloat.INFINITY, -math.copysign(rfloat.INFINITY, v1[1]) + except ValueError: + return rfloat.NAN, rfloat.NAN #complex copysign does not exist in numpy From noreply at buildbot.pypy.org Tue Oct 2 20:53:11 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 2 Oct 2012 20:53:11 +0200 (CEST) Subject: [pypy-commit] pypy length-hint: hook length_hinting into map/filter/zip Message-ID: <20121002185311.CFA991C03F2@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: length-hint Changeset: r57747:117775ce3778 Date: 2012-10-02 11:46 -0700 http://bitbucket.org/pypy/pypy/changeset/117775ce3778/ Log: hook length_hinting into map/filter/zip diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py --- a/pypy/module/__builtin__/app_functional.py +++ b/pypy/module/__builtin__/app_functional.py @@ -2,6 +2,9 @@ Plain Python definition of the builtin functions oriented towards functional programming. """ +from __future__ import with_statement +import operator +from __pypy__ import resizelist_hint # ____________________________________________________________ @@ -66,38 +69,69 @@ if num_collections == 1: if none_func: return list(collections[0]) - else: - # Special case for the really common case of a single collection, - # this can be eliminated if we could unroll that loop that creates - # `args` based on whether or not len(collections) was constant - result = [] - for item in collections[0]: + # Special case for the really common case of a single collection, + # this can be eliminated if we could unroll that loop that creates + # `args` based on whether or not len(collections) was constant + seq = collections[0] + with _managed_newlist_hint(operator._length_hint(seq, 0)) as result: + for item in seq: result.append(func(item)) return result + + # Gather the iterators (pair of (iter, has_finished)) and guess the + # result length (the max of the input lengths) + iterators = [] + max_hint = 0 + for seq in collections: + iterators.append((iter(seq), False)) + max_hint = max(max_hint, operator._length_hint(seq, 0)) + + with _managed_newlist_hint(max_hint) as result: + while True: + cont = False + args = [] + for idx, (iterator, has_finished) in enumerate(iterators): + val = None + if not has_finished: + try: + val = next(iterator) + except StopIteration: + iterators[idx] = (None, True) + else: + cont = True + args.append(val) + args = tuple(args) + if cont: + if none_func: + result.append(args) + else: + result.append(func(*args)) + else: + return result + +def _newlist_hint(length_hint): + """Return an empty list with an underlying capacity of length_hint""" result = [] - # Pair of (iterator, has_finished) - iterators = [(iter(seq), False) for seq in collections] - while True: - cont = False - args = [] - for idx, (iterator, has_finished) in enumerate(iterators): - val = None - if not has_finished: - try: - val = next(iterator) - except StopIteration: - iterators[idx] = (None, True) - else: - cont = True - args.append(val) - args = tuple(args) - if cont: - if none_func: - result.append(args) - else: - result.append(func(*args)) - else: - return result + resizelist_hint(result, length_hint) + return result + +def _managed_newlist_hint(length_hint): + """Context manager returning a _newlist_hint upon entry. + + Upon exit the list's underlying capacity will be cut back to match + its length if necessary (incase the initial length_hint was too + large). + """ + # hack: can't import contextlib.contextmanager at the global level + from contextlib import contextmanager + @contextmanager + def _do_managed_newlist_hint(length_hint): + result = _newlist_hint(length_hint) + yield result + extended = len(result) + if extended < length_hint: + resizelist_hint(result, extended) + return _do_managed_newlist_hint(length_hint) sentinel = object() @@ -135,17 +169,18 @@ return _filter_string(func, seq, unicode) elif isinstance(seq, tuple): return _filter_tuple(func, seq) - result = [] - for item in seq: - if func(item): - result.append(item) + with _managed_newlist_hint(operator._length_hint(seq, 0)) as result: + for item in seq: + if func(item): + result.append(item) return result def _filter_string(func, string, str_type): if func is bool and type(string) is str_type: return string - result = [] - for i in range(len(string)): + length = len(string) + result = _newlist_hint(length) + for i in range(length): # You must call __getitem__ on the strings, simply iterating doesn't # work :/ item = string[i] @@ -156,8 +191,9 @@ return str_type().join(result) def _filter_tuple(func, seq): - result = [] - for i in range(len(seq)): + length = len(seq) + result = _newlist_hint(length) + for i in range(length): # Again, must call __getitem__, at least there are tests. item = seq[i] if func(item): @@ -172,11 +208,21 @@ in length to the length of the shortest argument sequence.""" if not sequences: return [] - result = [] - iterators = [iter(seq) for seq in sequences] - while True: - try: - items = [next(it) for it in iterators] - except StopIteration: - return result - result.append(tuple(items)) + + # Gather the iterators and guess the result length (the min of the + # input lengths) + iterators = [] + min_hint = -1 + for seq in sequences: + iterators.append(iter(seq)) + hint = operator._length_hint(seq, min_hint) + if min_hint == -1 or hint < min_hint: + min_hint = hint + + with _managed_newlist_hint(min_hint) as result: + while True: + try: + items = [next(it) for it in iterators] + except StopIteration: + return result + result.append(tuple(items)) diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -43,6 +43,7 @@ 'do_what_I_mean' : 'interp_magic.do_what_I_mean', 'list_strategy' : 'interp_magic.list_strategy', 'validate_fd' : 'interp_magic.validate_fd', + 'resizelist_hint' : 'interp_magic.resizelist_hint', 'newdict' : 'interp_dict.newdict', 'dictstrategy' : 'interp_dict.dictstrategy', } diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -1,7 +1,8 @@ from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError, wrap_oserror from pypy.interpreter.gateway import unwrap_spec -from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.objectmodel import resizelist_hint, we_are_translated +from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.typeobject import MethodCache from pypy.objspace.std.mapdict import IndexCache from pypy.rlib import rposix @@ -75,7 +76,6 @@ return space.wrap(42) def list_strategy(space, w_list): - from pypy.objspace.std.listobject import W_ListObject if isinstance(w_list, W_ListObject): return space.wrap(w_list.strategy._applevel_repr) else: @@ -95,3 +95,10 @@ space.wrap('cp%d' % rwin32.GetConsoleCP()), space.wrap('cp%d' % rwin32.GetConsoleOutputCP()), ]) + + at unwrap_spec(sizehint=int) +def resizelist_hint(space, w_iterable, sizehint): + if not isinstance(w_iterable, W_ListObject): + raise OperationError(space.w_TypeError, + space.wrap("arg 1 must be a 'list'")) + w_iterable._resize_hint(sizehint) 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 @@ -37,7 +37,7 @@ 'sub', 'truediv', 'truth', 'xor', 'iadd', 'iand', 'iconcat', 'idiv', 'ifloordiv', 'ilshift', 'imod', 'imul', 'ior', 'ipow', 'irepeat', - 'irshift', 'isub', 'itruediv', 'ixor'] + 'irshift', 'isub', 'itruediv', 'ixor', '_length_hint'] interpleveldefs = {} diff --git a/pypy/module/operator/interp_operator.py b/pypy/module/operator/interp_operator.py --- a/pypy/module/operator/interp_operator.py +++ b/pypy/module/operator/interp_operator.py @@ -1,4 +1,5 @@ from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import unwrap_spec def index(space, w_a): return space.index(w_a) @@ -240,3 +241,8 @@ return space.inplace_mul(w_obj1, w_obj2) +# _length_hint (to be length_hint in 3.4) + + at unwrap_spec(default=int) +def _length_hint(space, w_iterable, default): + return space.wrap(space.length_hint(w_iterable, default)) From noreply at buildbot.pypy.org Tue Oct 2 21:11:03 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 2 Oct 2012 21:11:03 +0200 (CEST) Subject: [pypy-commit] pypy length-hint: merge default Message-ID: <20121002191103.590BB1C00EC@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: length-hint Changeset: r57748:529ad8ffd831 Date: 2012-10-02 12:10 -0700 http://bitbucket.org/pypy/pypy/changeset/529ad8ffd831/ Log: merge default diff too long, truncating to 2000 out of 2395 lines diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -23,7 +23,7 @@ The tools required to cross translate from a Linux based host to an ARM based Linux target are: -- A checkout of PyPy's arm-backend-2 branch. +- A checkout of PyPy (default branch). - The GCC ARM cross compiler (on Ubuntu it is the ``gcc-arm-linux-gnueabi package``) but other toolchains should also work. - Scratchbox 2, a cross-compilation engine (``scratchbox2`` Ubuntu package). - A 32-bit PyPy or Python. @@ -147,4 +147,4 @@ return 0 def target(*args): - return main, None \ No newline at end of file + return main, None diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -115,13 +115,16 @@ which data structures would be more appropriate? For example, a dict implemented as a hash table will suffer "stm collisions" in all threads whenever one thread writes anything to it; but there could be other - implementations. + implementations. Maybe alternate strategies can be implemented at the + level of the Python interpreter (see list/dict strategies, + ``pypy/objspace/std/{list,dict}object.py``). * More generally, there is the idea that we would need some kind of "debugger"-like tool to "debug" things that are not bugs, but stm conflicts. How would this tool look like to the end Python programmers? Like a profiler? Or like a debugger with breakpoints - on aborted transactions? + on aborted transactions? It would probably be all app-level, with + a few hooks e.g. for transaction conflicts. * Find good ways to have libraries using internally threads and atomics, but not exposing threads to the user. Right now there is a rough draft 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 @@ -18,6 +18,7 @@ .. branch: numpypy_count_nonzero .. branch: numpy-refactor Remove numpy lazy evaluation and simplify everything +.. branch: numpy-reintroduce-jit-drivers .. branch: numpy-fancy-indexing Support for array[array-of-ints] in numpy .. branch: even-more-jit-hooks 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 @@ -474,7 +474,7 @@ if f_type == F_BLOCK_LOOP: self.emit_jump(ops.CONTINUE_LOOP, block, True) break - if self.frame_blocks[i][0] == F_BLOCK_FINALLY_END: + if f_type == F_BLOCK_FINALLY_END: self.error("'continue' not supported inside 'finally' " \ "clause", cont) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -208,11 +208,11 @@ def int_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def bigint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -292,8 +292,6 @@ """Base class for the interpreter-level implementations of object spaces. http://pypy.readthedocs.org/en/latest/objspace.html""" - full_exceptions = True # full support for exceptions (normalization & more) - def __init__(self, config=None): "NOT_RPYTHON: Basic initialization of objects." self.fromcache = InternalSpaceCache(self).getorbuild @@ -1142,13 +1140,9 @@ def exception_is_valid_obj_as_class_w(self, w_obj): if not self.isinstance_w(w_obj, self.w_type): return False - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_obj, self.w_BaseException)) def exception_is_valid_class_w(self, w_cls): - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_cls, self.w_BaseException)) def exception_getclass(self, w_obj): @@ -1399,7 +1393,7 @@ if not self.is_true(self.isinstance(w_obj, self.w_str)): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) - return self.str_w(w_obj) + return self.str_w(w_obj) def unicode_w(self, w_obj): return w_obj.unicode_w(self) @@ -1720,7 +1714,7 @@ 'ValueError', 'ZeroDivisionError', ] - + if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -45,11 +45,6 @@ def async(self, space): "Check if this is an exception that should better not be caught." - if not space.full_exceptions: - # flow objspace does not support such exceptions and more - # importantly, raises KeyboardInterrupt if you try to access - # space.w_KeyboardInterrupt - return False return (self.match(space, space.w_SystemExit) or self.match(space, space.w_KeyboardInterrupt)) @@ -166,9 +161,7 @@ # Or 'Class' can also be an old-style class and 'inst' an old-style # instance of it. # - # Note that 'space.full_exceptions' is set to False by the flow - # object space; in this case we must assume that we are in a - # non-advanced case, and ignore the advanced cases. Old-style + # The flow object space only deals with non-advanced case. Old-style # classes and instances *are* advanced. # # input (w_type, w_value)... becomes... advanced case? @@ -183,9 +176,8 @@ # w_type = self.w_type w_value = self.get_w_value(space) - if space.full_exceptions: - while space.is_true(space.isinstance(w_type, space.w_tuple)): - w_type = space.getitem(w_type, space.wrap(0)) + while space.is_true(space.isinstance(w_type, space.w_tuple)): + w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): # this is for all cases of the form (Class, something) @@ -199,8 +191,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.full_exceptions and space.is_true( - space.isinstance(w_value, space.w_tuple)): + if space.is_true(space.isinstance(w_value, space.w_tuple)): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -944,14 +944,6 @@ def appcaller(space, *args_w): if not isinstance(space, ObjSpace): raise TypeError("first argument must be a space instance.") - # redirect if the space handles this specially - # XXX can this be factored a bit less flow space dependently? - if hasattr(space, 'specialcases'): - sc = space.specialcases - if ApplevelClass in sc: - ret_w = sc[ApplevelClass](space, self, name, args_w) - if ret_w is not None: # it was RPython - return ret_w # the last argument can be an Arguments w_func = self.wget(space, name) if not args_w: diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -223,7 +223,7 @@ return next_instr if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: - return self.jump_absolute(oparg, next_instr, ec) + return self.jump_absolute(oparg, ec) if we_are_translated(): for opdesc in unrolling_all_opcode_descs: @@ -557,7 +557,7 @@ w_type = self.popvalue() operror = OperationError(w_type, w_value) operror.normalize_exception(space) - if not space.full_exceptions or space.is_w(w_traceback, space.w_None): + if space.is_w(w_traceback, space.w_None): # common case raise operror else: @@ -858,7 +858,8 @@ def YIELD_VALUE(self, oparg, next_instr): raise Yield - def jump_absolute(self, jumpto, next_instr, ec): + def jump_absolute(self, jumpto, ec): + # this function is overridden by pypy.module.pypyjit.interp_jit check_nonneg(jumpto) return jumpto @@ -944,21 +945,9 @@ def WITH_CLEANUP(self, oparg, next_instr): # see comment in END_FINALLY for stack state - # This opcode changed a lot between CPython versions - if (self.pycode.magic >= 0xa0df2ef - # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) - or self.pycode.magic >= 0xa0df2d1): - # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) - w_unroller = self.popvalue() - w_exitfunc = self.popvalue() - self.pushvalue(w_unroller) - elif self.pycode.magic >= 0xa0df28c: - # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) - w_exitfunc = self.popvalue() - w_unroller = self.peekvalue(0) - else: - raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") - + w_unroller = self.popvalue() + w_exitfunc = self.popvalue() + self.pushvalue(w_unroller) unroller = self.space.interpclass_w(w_unroller) is_app_exc = (unroller is not None and isinstance(unroller, SApplicationException)) @@ -1192,10 +1181,6 @@ 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): """Signals a 'return' statement. Argument is the wrapped object to return.""" @@ -1206,12 +1191,6 @@ def nomoreblocks(self): return self.w_returnvalue - def state_unpack_variables(self, space): - return [self.w_returnvalue] - def state_pack_variables(space, w_returnvalue): - return SReturnValue(w_returnvalue) - state_pack_variables = staticmethod(state_pack_variables) - class SApplicationException(SuspendedUnroller): """Signals an application-level exception (i.e. an OperationException).""" @@ -1226,13 +1205,6 @@ """Signals a 'break' statement.""" _immutable_ = True kind = 0x04 - - def state_unpack_variables(self, space): - return [] - def state_pack_variables(space): - return SBreakLoop.singleton - state_pack_variables = staticmethod(state_pack_variables) - SBreakLoop.singleton = SBreakLoop() class SContinueLoop(SuspendedUnroller): @@ -1243,12 +1215,6 @@ def __init__(self, jump_to): self.jump_to = jump_to - def state_unpack_variables(self, space): - return [space.wrap(self.jump_to)] - def state_pack_variables(space, w_jump_to): - return SContinueLoop(space.int_w(w_jump_to)) - state_pack_variables = staticmethod(state_pack_variables) - class FrameBlock(object): """Abstract base class for frame blocks from the blockstack, @@ -1303,7 +1269,9 @@ # and jump to the beginning of the loop, stored in the # exception's argument frame.append_block(self) - return r_uint(unroller.jump_to) + jumpto = unroller.jump_to + ec = frame.space.getexecutioncontext() + return r_uint(frame.jump_absolute(jumpto, ec)) else: # jump to the end of the loop self.cleanupstack(frame) @@ -1323,8 +1291,7 @@ self.cleanupstack(frame) assert isinstance(unroller, SApplicationException) operationerr = unroller.operr - if frame.space.full_exceptions: - operationerr.normalize_exception(frame.space) + operationerr.normalize_exception(frame.space) # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. @@ -1356,8 +1323,7 @@ _immutable_ = True def handle(self, frame, unroller): - if (frame.space.full_exceptions and - isinstance(unroller, SApplicationException)): + if isinstance(unroller, SApplicationException): unroller.operr.normalize_exception(frame.space) return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -131,13 +131,13 @@ def get_latest_value_float(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a float.""" + or from 'args' if it was a FINISH). Returns a FLOATSTORAGE.""" raise NotImplementedError def get_latest_value_ref(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a ptr or an obj.""" + or from 'args' if it was a FINISH). Returns a GCREF.""" raise NotImplementedError def get_latest_value_count(self): 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 @@ -981,7 +981,7 @@ assert strlenaddr == cast(BVoidP, strlen) def test_read_variable(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BVoidP = new_pointer_type(new_void_type()) ll = find_and_load_library('c') @@ -989,7 +989,7 @@ assert stderr == cast(BVoidP, _testfunc(8)) def test_read_variable_as_unknown_length_array(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BCharP = new_pointer_type(new_primitive_type("char")) BArray = new_array_type(BCharP, None) @@ -999,7 +999,7 @@ # ^^ and not 'char[]', which is basically not allowed and would crash def test_write_variable(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BVoidP = new_pointer_type(new_void_type()) ll = find_and_load_library('c') 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 @@ -244,6 +244,7 @@ def setitem_index(self, space, index, value): self.setitem(self._lookup_by_unwrapped_index(space, index), value) + @jit.unroll_safe def _single_item_index(self, space, w_idx): """ Return an index of single item if possible, otherwise raises IndexError 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 @@ -9,8 +9,8 @@ from pypy.interpreter.error import OperationError from pypy.module.micronumpy import interp_boxes from pypy.module.micronumpy.interp_dtype import get_dtype_cache -from pypy.module.micronumpy.interp_numarray import (Scalar, BaseArray, - scalar_w, W_NDimArray, array) +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.interp_numarray import array from pypy.module.micronumpy.interp_arrayops import where from pypy.module.micronumpy import interp_ufuncs from pypy.rlib.objectmodel import specialize, instantiate @@ -147,7 +147,8 @@ def is_true(self, w_obj): assert isinstance(w_obj, BoolObject) - return w_obj.boolval + return False + #return w_obj.boolval def is_w(self, w_obj, w_what): return w_obj is w_what @@ -274,7 +275,7 @@ if isinstance(w_index, FloatObject): w_index = IntObject(int(w_index.floatval)) w_val = self.expr.execute(interp) - assert isinstance(arr, BaseArray) + assert isinstance(arr, W_NDimArray) arr.descr_setitem(interp.space, w_index, w_val) def __repr__(self): @@ -302,11 +303,11 @@ w_rhs = self.rhs.wrap(interp.space) else: w_rhs = self.rhs.execute(interp) - if not isinstance(w_lhs, BaseArray): + if not isinstance(w_lhs, W_NDimArray): # scalar dtype = get_dtype_cache(interp.space).w_float64dtype - w_lhs = scalar_w(interp.space, dtype, w_lhs) - assert isinstance(w_lhs, BaseArray) + w_lhs = W_NDimArray.new_scalar(interp.space, dtype, w_lhs) + assert isinstance(w_lhs, W_NDimArray) if self.name == '+': w_res = w_lhs.descr_add(interp.space, w_rhs) elif self.name == '*': @@ -314,17 +315,16 @@ elif self.name == '-': w_res = w_lhs.descr_sub(interp.space, w_rhs) elif self.name == '->': - assert not isinstance(w_rhs, Scalar) if isinstance(w_rhs, FloatObject): w_rhs = IntObject(int(w_rhs.floatval)) - assert isinstance(w_lhs, BaseArray) + assert isinstance(w_lhs, W_NDimArray) w_res = w_lhs.descr_getitem(interp.space, w_rhs) else: raise NotImplementedError - if (not isinstance(w_res, BaseArray) and + if (not isinstance(w_res, W_NDimArray) and not isinstance(w_res, interp_boxes.W_GenericBox)): dtype = get_dtype_cache(interp.space).w_float64dtype - w_res = scalar_w(interp.space, dtype, w_res) + w_res = W_NDimArray.new_scalar(interp.space, dtype, w_res) return w_res def __repr__(self): @@ -416,7 +416,7 @@ def execute(self, interp): arr = self.args[0].execute(interp) - if not isinstance(arr, BaseArray): + if not isinstance(arr, W_NDimArray): raise ArgumentNotAnArray if self.name in SINGLE_ARG_FUNCTIONS: if len(self.args) != 1 and self.name != 'sum': @@ -440,20 +440,21 @@ elif self.name == "unegative": neg = interp_ufuncs.get(interp.space).negative w_res = neg.call(interp.space, [arr]) + elif self.name == "cos": + cos = interp_ufuncs.get(interp.space).cos + w_res = cos.call(interp.space, [arr]) elif self.name == "flat": w_res = arr.descr_get_flatiter(interp.space) elif self.name == "tostring": arr.descr_tostring(interp.space) w_res = None - elif self.name == "count_nonzero": - w_res = arr.descr_count_nonzero(interp.space) else: assert False # unreachable code elif self.name in TWO_ARG_FUNCTIONS: if len(self.args) != 2: raise ArgumentMismatch arg = self.args[1].execute(interp) - if not isinstance(arg, BaseArray): + if not isinstance(arg, W_NDimArray): raise ArgumentNotAnArray if self.name == "dot": w_res = arr.descr_dot(interp.space, arg) @@ -466,9 +467,9 @@ raise ArgumentMismatch arg1 = self.args[1].execute(interp) arg2 = self.args[2].execute(interp) - if not isinstance(arg1, BaseArray): + if not isinstance(arg1, W_NDimArray): raise ArgumentNotAnArray - if not isinstance(arg2, BaseArray): + if not isinstance(arg2, W_NDimArray): raise ArgumentNotAnArray if self.name == "where": w_res = where(interp.space, arr, arg1, arg2) @@ -476,7 +477,7 @@ assert False else: raise WrongFunctionName - if isinstance(w_res, BaseArray): + if isinstance(w_res, W_NDimArray): return w_res if isinstance(w_res, FloatObject): dtype = get_dtype_cache(interp.space).w_float64dtype @@ -488,7 +489,7 @@ dtype = w_res.get_dtype(interp.space) else: dtype = None - return scalar_w(interp.space, dtype, w_res) + return W_NDimArray.new_scalar(interp.space, dtype, w_res) _REGEXES = [ ('-?[\d\.]+', 'number'), 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 @@ -129,6 +129,8 @@ self._prepare_array_index(space, w_index) shape = res_shape + self.get_shape()[len(indexes):] res = W_NDimArray.from_shape(shape, self.get_dtype(), self.get_order()) + if not res.get_size(): + return res return loop.getitem_array_int(space, self, res, iter_shape, indexes, prefix) @@ -514,7 +516,7 @@ if self.get_size() == 0: raise OperationError(space.w_ValueError, space.wrap("Can't call %s on zero-size arrays" % op_name)) - return space.wrap(loop.argmin_argmax(op_name, self)) + return space.wrap(getattr(loop, 'arg' + op_name)(self)) return func_with_new_name(impl, "reduce_arg%s_impl" % op_name) descr_argmax = _reduce_argmax_argmin_impl("max") 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 @@ -258,7 +258,7 @@ return out shape = shape_agreement(space, w_obj.get_shape(), out, broadcast_down=False) - return loop.call1(shape, self.func, self.name, calc_dtype, res_dtype, + return loop.call1(shape, self.func, calc_dtype, res_dtype, w_obj, out) @@ -322,7 +322,7 @@ return out 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(new_shape, self.func, self.name, calc_dtype, + return loop.call2(new_shape, self.func, calc_dtype, res_dtype, w_lhs, w_rhs, out) 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 @@ -1,21 +1,34 @@ """ This file is the main run loop as well as evaluation loops for various -signatures +operations. This is the place to look for all the computations that iterate +over all the array elements. """ -from pypy.rlib.objectmodel import specialize from pypy.rlib.rstring import StringBuilder from pypy.rlib import jit from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy.base import W_NDimArray -def call2(shape, func, name, calc_dtype, res_dtype, w_lhs, w_rhs, out): +call2_driver = jit.JitDriver(name='numpy_call2', + greens = ['shapelen', 'func', 'calc_dtype', + 'res_dtype'], + reds = ['shape', 'w_lhs', 'w_rhs', 'out', + 'left_iter', 'right_iter', 'out_iter']) + +def call2(shape, func, calc_dtype, res_dtype, w_lhs, w_rhs, out): if out is None: out = W_NDimArray.from_shape(shape, res_dtype) left_iter = w_lhs.create_iter(shape) right_iter = w_rhs.create_iter(shape) out_iter = out.create_iter(shape) + shapelen = len(shape) while not out_iter.done(): + call2_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, res_dtype=res_dtype, + shape=shape, w_lhs=w_lhs, w_rhs=w_rhs, + out=out, + left_iter=left_iter, right_iter=right_iter, + out_iter=out_iter) w_left = left_iter.getitem().convert_to(calc_dtype) w_right = right_iter.getitem().convert_to(calc_dtype) out_iter.setitem(func(calc_dtype, w_left, w_right).convert_to( @@ -25,30 +38,56 @@ out_iter.next() return out -def call1(shape, func, name, calc_dtype, res_dtype, w_obj, out): +call1_driver = jit.JitDriver(name='numpy_call1', + greens = ['shapelen', 'func', 'calc_dtype', + 'res_dtype'], + reds = ['shape', 'w_obj', 'out', 'obj_iter', + 'out_iter']) + +def call1(shape, func, calc_dtype, res_dtype, w_obj, out): if out is None: out = W_NDimArray.from_shape(shape, res_dtype) obj_iter = w_obj.create_iter(shape) out_iter = out.create_iter(shape) + shapelen = len(shape) while not out_iter.done(): + call1_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, res_dtype=res_dtype, + shape=shape, w_obj=w_obj, out=out, + obj_iter=obj_iter, out_iter=out_iter) elem = obj_iter.getitem().convert_to(calc_dtype) out_iter.setitem(func(calc_dtype, elem).convert_to(res_dtype)) out_iter.next() obj_iter.next() return out +setslice_driver = jit.JitDriver(name='numpy_setslice', + greens = ['shapelen', 'dtype'], + reds = ['target', 'source', 'target_iter', + 'source_iter']) + def setslice(shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) source_iter = source.create_iter(shape) dtype = target.dtype + shapelen = len(shape) while not target_iter.done(): + setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + target=target, source=source, + target_iter=target_iter, + source_iter=source_iter) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target +reduce_driver = jit.JitDriver(name='numpy_reduce', + greens = ['shapelen', 'func', 'done_func', + 'calc_dtype', 'identity'], + reds = ['obj', 'obj_iter', 'cur_value']) + def compute_reduce(obj, calc_dtype, func, done_func, identity): obj_iter = obj.create_iter(obj.get_shape()) if identity is None: @@ -56,7 +95,12 @@ obj_iter.next() else: cur_value = identity.convert_to(calc_dtype) + shapelen = len(obj.get_shape()) while not obj_iter.done(): + reduce_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, identity=identity, + done_func=done_func, obj=obj, + obj_iter=obj_iter, cur_value=cur_value) rval = obj_iter.getitem().convert_to(calc_dtype) if done_func is not None and done_func(calc_dtype, rval): return rval @@ -70,6 +114,11 @@ arr_iter.setitem(box) arr_iter.next() +where_driver = jit.JitDriver(name='numpy_where', + greens = ['shapelen', 'dtype', 'arr_dtype'], + reds = ['shape', 'arr', 'x', 'y','arr_iter', 'out', + 'x_iter', 'y_iter', 'iter', 'out_iter']) + def where(out, shape, arr, x, y, dtype): out_iter = out.create_iter(shape) arr_iter = arr.create_iter(shape) @@ -83,7 +132,13 @@ iter = y_iter else: iter = x_iter + shapelen = len(shape) while not iter.done(): + where_driver.jit_merge_point(shapelen=shapelen, shape=shape, + dtype=dtype, iter=iter, x_iter=x_iter, + y_iter=y_iter, arr_iter=arr_iter, + arr=arr, x=x, y=y, arr_dtype=arr_dtype, + out_iter=out_iter, out=out) w_cond = arr_iter.getitem() if arr_dtype.itemtype.bool(w_cond): w_val = x_iter.getitem().convert_to(dtype) @@ -96,12 +151,24 @@ y_iter.next() return out +axis_reduce__driver = jit.JitDriver(name='numpy_axis_reduce', + greens=['shapelen', 'func', 'dtype', + 'identity'], + reds=['axis', 'arr', 'out', 'shape', + 'out_iter', 'arr_iter']) + def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): out_iter = out.create_axis_iter(arr.get_shape(), axis) arr_iter = arr.create_iter(arr.get_shape()) if identity is not None: identity = identity.convert_to(dtype) + shapelen = len(shape) while not out_iter.done(): + axis_reduce__driver.jit_merge_point(shapelen=shapelen, func=func, + dtype=dtype, identity=identity, + axis=axis, arr=arr, out=out, + shape=shape, out_iter=out_iter, + arr_iter=arr_iter) w_val = arr_iter.getitem().convert_to(dtype) if out_iter.first_line: if identity is not None: @@ -114,23 +181,41 @@ out_iter.next() return out - at specialize.arg(0) -def argmin_argmax(op_name, arr): - result = 0 - idx = 1 - dtype = arr.get_dtype() - iter = arr.create_iter(arr.get_shape()) - cur_best = iter.getitem() - iter.next() - while not iter.done(): - w_val = iter.getitem() - new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) - if dtype.itemtype.ne(new_best, cur_best): - result = idx - cur_best = new_best + +def _new_argmin_argmax(op_name): + arg_driver = jit.JitDriver(name='numpy_' + op_name, + greens = ['shapelen', 'dtype'], + reds = ['result', 'idx', 'cur_best', 'arr', + 'iter']) + + def argmin_argmax(arr): + result = 0 + idx = 1 + dtype = arr.get_dtype() + iter = arr.create_iter(arr.get_shape()) + cur_best = iter.getitem() iter.next() - idx += 1 - return result + shapelen = len(arr.get_shape()) + while not iter.done(): + arg_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + result=result, idx=idx, + cur_best=cur_best, arr=arr, iter=iter) + w_val = iter.getitem() + new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) + if dtype.itemtype.ne(new_best, cur_best): + result = idx + cur_best = new_best + iter.next() + idx += 1 + return result + return argmin_argmax +argmin = _new_argmin_argmax('min') +argmax = _new_argmin_argmax('max') + +# note that shapelen == 2 always +dot_driver = jit.JitDriver(name = 'numpy_dot', + greens = ['dtype'], + reds = ['outi', 'lefti', 'righti', 'result']) def multidim_dot(space, left, right, result, dtype, right_critical_dim): ''' assumes left, right are concrete arrays @@ -157,6 +242,8 @@ lefti = left.create_dot_iter(broadcast_shape, left_skip) righti = right.create_dot_iter(broadcast_shape, right_skip) while not outi.done(): + dot_driver.jit_merge_point(dtype=dtype, outi=outi, lefti=lefti, + righti=righti, result=result) lval = lefti.getitem().convert_to(dtype) rval = righti.getitem().convert_to(dtype) outval = outi.getitem().convert_to(dtype) @@ -168,21 +255,45 @@ lefti.next() return result +count_all_true_driver = jit.JitDriver(name = 'numpy_count', + greens = ['shapelen', 'dtype'], + reds = ['s', 'iter']) + 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() while not iter.done(): + count_all_true_driver.jit_merge_point(shapelen=shapelen, iter=iter, + s=s, 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'], + reds = ['res', 'index_iter', 'res_iter', + 'arr_iter']) + def getitem_filter(res, arr, index): res_iter = res.create_iter() index_iter = index.create_iter() arr_iter = arr.create_iter() + shapelen = len(arr.get_shape()) + arr_dtype = arr.get_dtype() + index_dtype = index.get_dtype() + # XXX length of shape of index as well? while not index_iter.done(): + getitem_filter_driver.jit_merge_point(shapelen=shapelen, + index_dtype=index_dtype, + arr_dtype=arr_dtype, + res=res, index_iter=index_iter, + res_iter=res_iter, + arr_iter=arr_iter) if index_iter.getitem_bool(): res_iter.setitem(arr_iter.getitem()) res_iter.next() @@ -190,31 +301,63 @@ arr_iter.next() return res +setitem_filter_driver = jit.JitDriver(name = 'numpy_setitem_bool', + greens = ['shapelen', 'arr_dtype', + 'index_dtype'], + reds = ['index_iter', 'value_iter', + 'arr_iter']) + def setitem_filter(arr, index, value): arr_iter = arr.create_iter() index_iter = index.create_iter() value_iter = value.create_iter() + shapelen = len(arr.get_shape()) + index_dtype = index.get_dtype() + arr_dtype = arr.get_dtype() while not index_iter.done(): + setitem_filter_driver.jit_merge_point(shapelen=shapelen, + index_dtype=index_dtype, + arr_dtype=arr_dtype, + index_iter=index_iter, + value_iter=value_iter, + arr_iter=arr_iter) if index_iter.getitem_bool(): arr_iter.setitem(value_iter.getitem()) value_iter.next() arr_iter.next() index_iter.next() +flatiter_getitem_driver = jit.JitDriver(name = 'numpy_flatiter_getitem', + greens = ['dtype'], + reds = ['step', 'ri', 'res', + 'base_iter']) + def flatiter_getitem(res, base_iter, step): ri = res.create_iter() + dtype = res.get_dtype() while not ri.done(): + flatiter_getitem_driver.jit_merge_point(dtype=dtype, + base_iter=base_iter, + ri=ri, res=res, step=step) ri.setitem(base_iter.getitem()) base_iter.next_skip_x(step) ri.next() return res +flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', + greens = ['dtype'], + reds = ['length', 'step', 'arr_iter', + 'val_iter']) + def flatiter_setitem(arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: + flatiter_setitem_driver.jit_merge_point(dtype=dtype, length=length, + step=step, arr_iter=arr_iter, + val_iter=val_iter) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -223,10 +366,16 @@ # WTF numpy? val_iter.reset() +fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', + greens = ['itemsize', 'dtype'], + reds = ['i', 's', 'ai']) + def fromstring_loop(a, dtype, itemsize, s): i = 0 ai = a.create_iter() while not ai.done(): + fromstring_driver.jit_merge_point(dtype=dtype, s=s, ai=ai, i=i, + itemsize=itemsize) val = dtype.itemtype.runpack_str(s[i*itemsize:i*itemsize + itemsize]) ai.setitem(val) ai.next() @@ -274,12 +423,25 @@ else: self._done = True + @jit.unroll_safe def get_index(self, space): return [space.wrap(i) for i in self.indexes] +getitem_int_driver = jit.JitDriver(name = 'numpy_getitem_int', + greens = ['shapelen', 'indexlen', 'dtype'], + reds = ['arr', 'res', 'iter', 'indexes_w', + 'prefix_w']) + def getitem_array_int(space, arr, res, iter_shape, indexes_w, prefix_w): + shapelen = len(iter_shape) + indexlen = len(indexes_w) + dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): + getitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, + dtype=dtype, arr=arr, res=res, + iter=iter, indexes_w=indexes_w, + prefix_w=prefix_w) # prepare the index index_w = [None] * len(indexes_w) for i in range(len(indexes_w)): @@ -293,10 +455,22 @@ iter.next() return res +setitem_int_driver = jit.JitDriver(name = 'numpy_setitem_int', + greens = ['shapelen', 'indexlen', 'dtype'], + reds = ['arr', 'iter', 'indexes_w', + 'prefix_w', 'val_arr']) + def setitem_array_int(space, arr, iter_shape, indexes_w, val_arr, prefix_w): + shapelen = len(iter_shape) + indexlen = len(indexes_w) + dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): + setitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, + dtype=dtype, arr=arr, + iter=iter, indexes_w=indexes_w, + prefix_w=prefix_w, val_arr=val_arr) # prepare the index index_w = [None] * len(indexes_w) for i in range(len(indexes_w)): diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py --- a/pypy/module/micronumpy/test/test_compile.py +++ b/pypy/module/micronumpy/test/test_compile.py @@ -1,6 +1,5 @@ + import py -py.test.skip("this is going away") - from pypy.module.micronumpy.compile import (numpy_compile, Assignment, ArrayConstant, FloatConstant, Operator, Variable, RangeConstant, Execute, FunctionCall, FakeSpace) @@ -136,7 +135,7 @@ r """ interp = self.run(code) - assert interp.results[0].value.value == 15 + assert interp.results[0].get_scalar_value().value == 15 def test_sum2(self): code = """ @@ -145,7 +144,7 @@ sum(b) """ interp = self.run(code) - assert interp.results[0].value.value == 30 * (30 - 1) + assert interp.results[0].get_scalar_value().value == 30 * (30 - 1) def test_array_write(self): @@ -164,7 +163,7 @@ b = a + a min(b) """) - assert interp.results[0].value.value == -24 + assert interp.results[0].get_scalar_value().value == -24 def test_max(self): interp = self.run(""" @@ -173,7 +172,7 @@ b = a + a max(b) """) - assert interp.results[0].value.value == 256 + assert interp.results[0].get_scalar_value().value == 256 def test_slice(self): interp = self.run(""" @@ -265,6 +264,7 @@ assert interp.results[0].value == 3 def test_take(self): + py.test.skip("unsupported") interp = self.run(""" a = |10| b = take(a, [1, 1, 3, 2]) 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 @@ -1519,7 +1519,7 @@ assert (a == [1, 1]).all() def test_int_array_index(self): - from numpypy import array, arange + from numpypy import array, arange, zeros b = arange(10)[array([3, 2, 1, 5])] assert (b == [3, 2, 1, 5]).all() raises(IndexError, "arange(10)[array([10])]") @@ -1528,6 +1528,7 @@ a = arange(1) a[[0, 0]] += 1 assert a[0] == 1 + assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): from numpypy import array, arange, zeros @@ -1999,6 +2000,7 @@ def test_int_array_index(self): from _numpypy import array + assert (array([])[[]] == []).all() a = array([[1, 2], [3, 4], [5, 6]]) assert (a[slice(0, 3), [0, 0]] == [[1, 1], [3, 3], [5, 5]]).all() assert (a[array([0, 2]), slice(0, 2)] == [[1, 2], [5, 6]]).all() 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 @@ -4,18 +4,12 @@ """ import py -py.test.skip("this is going away") - from pypy.jit.metainterp import pyjitpl from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp.warmspot import reset_stats from pypy.module.micronumpy import interp_boxes -from pypy.module.micronumpy.compile import (FakeSpace, - IntObject, Parser, InterpreterState) -from pypy.module.micronumpy.interp_numarray import (W_NDimArray, - BaseArray, W_FlatIterator) -from pypy.rlib.nonconst import NonConstant - +from pypy.module.micronumpy.compile import FakeSpace, Parser, InterpreterState +from pypy.module.micronumpy.base import W_NDimArray class TestNumpyJIt(LLJitMixin): graph = None @@ -51,11 +45,8 @@ if not len(interp.results): raise Exception("need results") w_res = interp.results[-1] - if isinstance(w_res, BaseArray): - concr = w_res.get_concrete_or_scalar() - sig = concr.find_sig() - frame = sig.create_frame(concr) - w_res = sig.eval(frame, concr) + if isinstance(w_res, W_NDimArray): + w_res = w_res.create_iter().getitem() if isinstance(w_res, interp_boxes.W_Float64Box): return w_res.value if isinstance(w_res, interp_boxes.W_Int64Box): @@ -73,6 +64,7 @@ self.__class__.graph = graph reset_stats() pyjitpl._warmrunnerdesc.memory_manager.alive_loops.clear() + py.test.skip("don't run for now") return self.interp.eval_graph(self.graph, [i]) def define_add(): 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 @@ -79,7 +79,7 @@ except ExitFrame: return self.popvalue() - def jump_absolute(self, jumpto, _, ec=None): + def jump_absolute(self, jumpto, ec): if we_are_jitted(): # # assume that only threads are using the bytecode counter diff --git a/pypy/module/pypyjit/test_pypy_c/test_exception.py b/pypy/module/pypyjit/test_pypy_c/test_exception.py --- a/pypy/module/pypyjit/test_pypy_c/test_exception.py +++ b/pypy/module/pypyjit/test_pypy_c/test_exception.py @@ -95,7 +95,6 @@ def test_continue_in_finally(self): # check that 'continue' inside a try:finally: block is correctly # detected as closing a loop - py.test.skip("is this case important?") def f(n): i = 0 while 1: @@ -110,10 +109,9 @@ assert log.result == 2001 loop, = log.loops_by_filename(self.filepath) assert loop.match(""" - i40 = int_add_ovf(i31, 1) - guard_no_overflow(descr=...) - i41 = int_lt(i40, i33) - guard_true(i41, descr=...) + i3 = int_lt(i1, i2) + guard_true(i3, descr=...) + i4 = int_add(i1, 1) --TICK-- jump(..., descr=...) """) diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,7 +1,8 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import PyCode, BytecodeCorruption +from pypy.interpreter.pycode import (PyCode, BytecodeCorruption, cpython_magic, + cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) from pypy.interpreter.astcompiler.consts import CO_GENERATOR @@ -12,6 +13,57 @@ """ opnames = host_bytecode_spec.method_names + def __init__(self, space, argcount, nlocals, stacksize, flags, + code, consts, names, varnames, filename, + name, firstlineno, lnotab, freevars, cellvars, + hidden_applevel=False, magic=cpython_magic): + """Initialize a new code object""" + self.space = space + self.co_name = name + assert nlocals >= 0 + self.co_argcount = argcount + self.co_nlocals = nlocals + self.co_stacksize = stacksize + self.co_flags = flags + self.co_code = code + self.co_consts_w = consts + self.co_names_w = [space.wrap(aname) for aname in names] + self.co_varnames = varnames + self.co_freevars = freevars + self.co_cellvars = cellvars + self.co_filename = filename + self.co_name = name + self.co_firstlineno = firstlineno + self.co_lnotab = lnotab + self.hidden_applevel = hidden_applevel + self.magic = magic + self._signature = cpython_code_signature(self) + self._initialize() + + def _initialize(self): + # Precompute what arguments need to be copied into cellvars + self._args_as_cellvars = [] + + if self.co_cellvars: + argcount = self.co_argcount + assert argcount >= 0 # annotator hint + if self.co_flags & CO_VARARGS: + argcount += 1 + if self.co_flags & CO_VARKEYWORDS: + argcount += 1 + # Cell vars could shadow already-set arguments. + # See comment in PyCode._initialize() + argvars = self.co_varnames + cellvars = self.co_cellvars + for i in range(len(cellvars)): + cellname = cellvars[i] + for j in range(argcount): + if cellname == argvars[j]: + # argument j has the same name as the cell var i + while len(self._args_as_cellvars) <= i: + self._args_as_cellvars.append(-1) # pad + self._args_as_cellvars[i] = j + def read(self, pos): """ Decode the instruction starting at position ``next_instr``. diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -1,19 +1,17 @@ import collections -import sys from pypy.tool.error import source_lines -from pypy.interpreter.error import OperationError -from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter import pyframe from pypy.interpreter.nestedscope import Cell -from pypy.interpreter.pycode import CO_OPTIMIZED, CO_NEWLOCALS +from pypy.interpreter.pycode import CO_NEWLOCALS from pypy.interpreter.argument import ArgumentsForTranslation -from pypy.interpreter.pyopcode import (Return, Yield, SuspendedUnroller, - SReturnValue, SApplicationException, BytecodeCorruption, - RaiseWithExplicitTraceback) -from pypy.objspace.flow.model import * +from pypy.interpreter.pyopcode import Return, BytecodeCorruption +from pypy.objspace.flow.model import (Constant, Variable, Block, Link, + UnwrapException, SpaceOperation, FunctionGraph, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, recursively_flatten) from pypy.objspace.flow.bytecode import HostCode +from pypy.objspace.flow.specialcase import (rpython_print_item, + rpython_print_newline) class FlowingError(Exception): """ Signals invalid RPython in the function being analysed""" @@ -27,16 +25,14 @@ msg += source_lines(self.frame.graph, None, offset=self.frame.last_instr) return "\n".join(msg) - class StopFlowing(Exception): pass -class FSException(OperationError): - def __init__(self, w_type, w_value, tb=None): +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 - self._application_traceback = tb def get_w_value(self, _): return self.w_value @@ -44,45 +40,6 @@ def __str__(self): return '[%s: %s]' % (self.w_type, self.w_value) - def normalize_exception(self, space): - """Normalize the OperationError. In other words, fix w_type and/or - w_value to make sure that the __class__ of w_value is exactly w_type. - """ - w_type = self.w_type - w_value = self.w_value - if space.exception_is_valid_obj_as_class_w(w_type): - # this is for all cases of the form (Class, something) - if space.is_w(w_value, space.w_None): - # raise Type: we assume we have to instantiate Type - w_value = space.call_function(w_type) - w_type = self._exception_getclass(space, w_value) - else: - w_valuetype = space.exception_getclass(w_value) - if space.exception_issubclass_w(w_valuetype, w_type): - # raise Type, Instance: let etype be the exact type of value - w_type = w_valuetype - else: - # raise Type, X: assume X is the constructor argument - w_value = space.call_function(w_type, w_value) - w_type = self._exception_getclass(space, w_value) - - else: - # the only case left here is (inst, None), from a 'raise inst'. - w_inst = w_type - w_instclass = self._exception_getclass(space, w_inst) - if not space.is_w(w_value, space.w_None): - raise FSException(space.w_TypeError, - space.wrap("instance exception may not " - "have a separate value")) - w_value = w_inst - w_type = w_instclass - - self.w_type = w_type - self.w_value = w_value - -class OperationThatShouldNotBePropagatedError(FSException): - pass - class ImplicitOperationError(FSException): pass @@ -262,6 +219,20 @@ # ____________________________________________________________ +compare_method = [ + "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", + ] + class FlowSpaceFrame(pyframe.CPythonFrame): def __init__(self, space, func, constargs=None): @@ -497,38 +468,68 @@ res = getattr(self, methodname)(oparg, next_instr) if res is not None: next_instr = res - except OperationThatShouldNotBePropagatedError, e: - raise Exception( - 'found an operation that always raises %s: %s' % ( - self.space.unwrap(e.w_type).__name__, - self.space.unwrap(e.w_value))) except FSException, operr: - self.attach_traceback(operr) next_instr = self.handle_operation_error(operr) - except RaiseWithExplicitTraceback, e: - next_instr = self.handle_operation_error(e.operr) return next_instr - def attach_traceback(self, operr): - if self.pycode.hidden_applevel: - return - tb = operr.get_traceback() - tb = PyTraceback(self.space, self, self.last_instr, tb) - operr.set_traceback(tb) - def handle_operation_error(self, operr): - block = self.unrollstack(SFlowException.kind) + block = self.unrollstack(SApplicationException.kind) if block is None: - # no handler found for the exception - # try to preserve the CPython-level traceback - import sys - tb = sys.exc_info()[2] - raise operr, None, tb + raise operr else: - unroller = SFlowException(operr) + unroller = SApplicationException(operr) next_instr = block.handle(self, unroller) return next_instr + def BAD_OPCODE(self, _, next_instr): + raise FlowingError(self, "This operation is not RPython") + + def BREAK_LOOP(self, oparg, next_instr): + return self.unrollstack_and_jump(SBreakLoop.singleton) + + def CONTINUE_LOOP(self, startofloop, next_instr): + unroller = SContinueLoop(startofloop) + return self.unrollstack_and_jump(unroller) + + 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)) + + def cmp_exc_match(self, w_1, w_2): + return self.space.newbool(self.space.exception_match(w_1, w_2)) + + def COMPARE_OP(self, testnum, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = getattr(self, compare_method[testnum])(w_1, w_2) + self.pushvalue(w_result) + def RAISE_VARARGS(self, nbargs, next_instr): space = self.space if nbargs == 0: @@ -538,7 +539,7 @@ # re-raising an implicit operation makes it an explicit one operr = FSException(operr.w_type, operr.w_value) self.last_exception = operr - raise RaiseWithExplicitTraceback(operr) + raise operr else: raise FSException(space.w_TypeError, space.wrap("raise: no active exception to re-raise")) @@ -550,8 +551,7 @@ w_value = self.popvalue() if 1: w_type = self.popvalue() - operror = FSException(w_type, w_value) - operror.normalize_exception(space) + operror = space.exc_from_raise(w_type, w_value) raise operror def IMPORT_NAME(self, nameindex, next_instr): @@ -580,17 +580,45 @@ return next_instr # now inside a 'finally' block def END_FINALLY(self, oparg, next_instr): - unroller = self.end_finally() - if isinstance(unroller, SuspendedUnroller): - # go on unrolling the stack - block = self.unrollstack(unroller.kind) - if block is None: - w_result = unroller.nomoreblocks() - self.pushvalue(w_result) - raise Return - else: - next_instr = block.handle(self, unroller) - return next_instr + # unlike CPython, there are two statically distinct cases: the + # END_FINALLY might be closing an 'except' block or a 'finally' + # block. In the first case, the stack contains three items: + # [exception type we are now handling] + # [exception value we are now handling] + # [wrapped 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] + w_top = self.popvalue() + if w_top == self.space.w_None: + # finally: block with no unroller active + return + try: + unroller = self.space.unwrap(w_top) + except UnwrapException: + pass + else: + if isinstance(unroller, SuspendedUnroller): + # case of a finally: block + return self.unroll_finally(unroller) + # case of an except: block. We popped the exception type + self.popvalue() # Now we pop the exception value + unroller = self.space.unwrap(self.popvalue()) + return self.unroll_finally(unroller) + + def unroll_finally(self, unroller): + # go on unrolling the stack + block = self.unrollstack(unroller.kind) + if block is None: + w_result = unroller.nomoreblocks() + self.pushvalue(w_result) + raise Return + else: + return block.handle(self, unroller) + + def POP_BLOCK(self, oparg, next_instr): + block = self.pop_block() + block.cleanupstack(self) # the block knows how to clean up the value stack def JUMP_ABSOLUTE(self, jumpto, next_instr): return jumpto @@ -603,11 +631,48 @@ # isn't popped straightaway. self.pushvalue(None) + PRINT_EXPR = BAD_OPCODE + PRINT_ITEM_TO = BAD_OPCODE + PRINT_NEWLINE_TO = BAD_OPCODE + + def PRINT_ITEM(self, oparg, next_instr): + w_item = self.popvalue() + w_s = self.space.do_operation('str', w_item) + self.space.appcall(rpython_print_item, w_s) + + def PRINT_NEWLINE(self, oparg, next_instr): + self.space.appcall(rpython_print_newline) + + def FOR_ITER(self, jumpby, next_instr): + w_iterator = self.peekvalue() + try: + w_nextitem = self.space.next(w_iterator) + except FSException, e: + if not self.space.exception_match(e.w_type, self.space.w_StopIteration): + raise + # iterator exhausted + self.popvalue() + next_instr += jumpby + else: + self.pushvalue(w_nextitem) + return next_instr + + def SETUP_LOOP(self, offsettoend, next_instr): + block = LoopBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + + def SETUP_EXCEPT(self, offsettoend, next_instr): + block = ExceptBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + + def SETUP_FINALLY(self, offsettoend, next_instr): + block = FinallyBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + def SETUP_WITH(self, offsettoend, next_instr): # A simpler version than the 'real' 2.7 one: # directly call manager.__enter__(), don't use special lookup functions # which don't make sense on the RPython type system. - from pypy.interpreter.pyopcode import WithBlock w_manager = self.peekvalue() w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__")) self.settopvalue(w_exit) @@ -616,10 +681,47 @@ self.lastblock = block self.pushvalue(w_result) + def WITH_CLEANUP(self, oparg, next_instr): + # Note: RPython context managers receive None in lieu of tracebacks + # and cannot suppress the exception. + # This opcode changed a lot between CPython versions + if (self.pycode.magic >= 0xa0df2ef + # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) + or self.pycode.magic >= 0xa0df2d1): + # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) + w_unroller = self.popvalue() + w_exitfunc = self.popvalue() + self.pushvalue(w_unroller) + elif self.pycode.magic >= 0xa0df28c: + # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) + w_exitfunc = self.popvalue() + w_unroller = self.peekvalue(0) + else: + raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") + + unroller = self.space.unwrap(w_unroller) + w_None = self.space.w_None + if isinstance(unroller, SApplicationException): + operr = unroller.operr + # 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) + else: + self.space.call_function(w_exitfunc, w_None, w_None, w_None) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) + def LOAD_ATTR(self, nameindex, next_instr): + "obj.attributename" + w_obj = self.popvalue() + w_attributename = self.getname_w(nameindex) + w_value = self.space.getattr(w_obj, w_attributename) + self.pushvalue(w_value) + LOOKUP_METHOD = LOAD_ATTR + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. @@ -647,23 +749,173 @@ def argument_factory(self, *args): return ArgumentsForTranslation(self.space, *args) - def call_contextmanager_exit_function(self, w_func, w_typ, w_val, w_tb): - if w_typ is not self.space.w_None: - # The annotator won't allow to merge exception types with None. - # Replace it with the exception value... - w_typ = w_val - self.space.call_function(w_func, w_typ, w_val, w_tb) - # Return None so that the flow space statically knows that we didn't - # swallow the exception - return self.space.w_None - ### Frame blocks ### -class SFlowException(SApplicationException): - """Flowspace override for SApplicationException""" +class SuspendedUnroller(object): + """Abstract base class for interpreter-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: + + WHY_NOT, OK, not this one :-) + WHY_EXCEPTION, SApplicationException + WHY_RERAISE, implemented differently, see Reraise + WHY_RETURN, SReturnValue + WHY_BREAK, SBreakLoop + WHY_CONTINUE, SContinueLoop + WHY_YIELD not needed + """ + 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): + """Signals a 'return' statement. + Argument is the wrapped object to return.""" + kind = 0x01 + def __init__(self, w_returnvalue): + self.w_returnvalue = w_returnvalue + + def nomoreblocks(self): + return self.w_returnvalue + + def state_unpack_variables(self, space): + return [self.w_returnvalue] + + @staticmethod + def state_pack_variables(space, w_returnvalue): + return SReturnValue(w_returnvalue) + +class SApplicationException(SuspendedUnroller): + """Signals an application-level exception + (i.e. an OperationException).""" + kind = 0x02 + def __init__(self, operr): + self.operr = operr + + def nomoreblocks(self): + raise self.operr + def state_unpack_variables(self, space): return [self.operr.w_type, self.operr.w_value] @staticmethod def state_pack_variables(space, w_type, w_value): - return SFlowException(FSException(w_type, w_value)) + return SApplicationException(FSException(w_type, w_value)) + +class SBreakLoop(SuspendedUnroller): + """Signals a 'break' statement.""" + kind = 0x04 + + def state_unpack_variables(self, space): + return [] + + @staticmethod + def state_pack_variables(space): + return SBreakLoop.singleton + +SBreakLoop.singleton = SBreakLoop() + +class SContinueLoop(SuspendedUnroller): + """Signals a 'continue' statement. + Argument is the bytecode position of the beginning of the loop.""" + kind = 0x08 + def __init__(self, jump_to): + self.jump_to = jump_to + + def state_unpack_variables(self, space): + return [space.wrap(self.jump_to)] + + @staticmethod + def state_pack_variables(space, w_jump_to): + return SContinueLoop(space.int_w(w_jump_to)) + + +class FrameBlock(object): + """Abstract base class for frame blocks from the blockstack, + used by the SETUP_XXX and POP_BLOCK opcodes.""" + + def __init__(self, frame, handlerposition, previous): + self.handlerposition = handlerposition + self.valuestackdepth = frame.valuestackdepth + self.previous = previous # this makes a linked list of blocks + + def __eq__(self, other): + return (self.__class__ is other.__class__ and + self.handlerposition == other.handlerposition and + self.valuestackdepth == other.valuestackdepth) + + def __ne__(self, other): + return not (self == other) + + def __hash__(self): + return hash((self.handlerposition, self.valuestackdepth)) + + def cleanupstack(self, frame): + frame.dropvaluesuntil(self.valuestackdepth) + + def handle(self, frame, unroller): + raise NotImplementedError + +class LoopBlock(FrameBlock): + """A loop block. Stores the end-of-loop pointer in case of 'break'.""" + + _opname = 'SETUP_LOOP' + handling_mask = SBreakLoop.kind | SContinueLoop.kind + + def handle(self, frame, unroller): + if isinstance(unroller, SContinueLoop): + # 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 + frame.append_block(self) + return unroller.jump_to + else: + # jump to the end of the loop + self.cleanupstack(frame) + return self.handlerposition + +class ExceptBlock(FrameBlock): + """An try:except: block. Stores the position of the exception handler.""" + + _opname = 'SETUP_EXCEPT' + handling_mask = SApplicationException.kind + + 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) + operationerr = unroller.operr + # the stack setup is slightly different than in CPython: + # instead of the traceback, we store the unroller object, + # wrapped. + frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(operationerr.get_w_value(frame.space)) + frame.pushvalue(operationerr.w_type) + frame.last_exception = operationerr + return self.handlerposition # jump to the handler + +class FinallyBlock(FrameBlock): + """A try:finally: block. Stores the position of the exception handler.""" + + _opname = 'SETUP_FINALLY' + handling_mask = -1 # handles every kind of SuspendedUnroller + + def handle(self, frame, unroller): + # any abnormal reason for unrolling a finally: triggers the end of + # the block unrolling and the entering the finally: handler. + self.cleanupstack(frame) + frame.pushvalue(frame.space.wrap(unroller)) + return self.handlerposition # jump to the handler + + +class WithBlock(FinallyBlock): + + def handle(self, frame, unroller): + return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -1,4 +1,3 @@ -from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.rlib.unroll import SpecTag from pypy.objspace.flow.model import * @@ -106,6 +105,7 @@ UNPICKLE_TAGS = {} def recursively_flatten(space, lst): + from pypy.objspace.flow.flowcontext import SuspendedUnroller i = 0 while i < len(lst): item = lst[i] diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -1,14 +1,14 @@ # ______________________________________________________________________ import __builtin__ import sys -import operator import types -from pypy.interpreter.baseobjspace import ObjSpace, Wrappable -from pypy.interpreter import pyframe, argument -from pypy.objspace.flow.model import * +from pypy.interpreter.baseobjspace import ObjSpace +from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.model import (Constant, Variable, WrapException, + UnwrapException, checkgraph, SpaceOperation) from pypy.objspace.flow import operation from pypy.objspace.flow.flowcontext import (FlowSpaceFrame, fixeggblocks, - OperationThatShouldNotBePropagatedError, FSException, FlowingError) + FSException, FlowingError) from pypy.objspace.flow.specialcase import SPECIAL_CASES from pypy.rlib.unroll import unrolling_iterable, _unroller from pypy.rlib import rstackovf, rarithmetic @@ -38,47 +38,32 @@ } # ______________________________________________________________________ -class FlowObjSpace(ObjSpace): +class FlowObjSpace(object): """NOT_RPYTHON. The flow objspace space is used to produce a flow graph by recording the space operations that the interpreter generates when it interprets (the bytecode of) some function. """ + w_None = Constant(None) + builtin = Constant(__builtin__) + sys = Constant(sys) + w_False = Constant(False) + w_True = Constant(True) + w_type = Constant(type) + w_tuple = Constant(tuple) + for exc in [KeyError, ValueError, IndexError, StopIteration, + AssertionError, TypeError, AttributeError, ImportError]: + clsname = exc.__name__ + locals()['w_' + clsname] = Constant(exc) - full_exceptions = False - FrameClass = FlowSpaceFrame + # the following exceptions should not show up + # during flow graph construction + w_NameError = None + w_UnboundLocalError = None - def initialize(self): - self.w_None = Constant(None) - self.builtin = Constant(__builtin__) - self.sys = Constant(sys) - self.w_False = Constant(False) - self.w_True = Constant(True) - self.w_type = Constant(type) - self.w_tuple = Constant(tuple) - for exc in [KeyError, ValueError, IndexError, StopIteration, - AssertionError, TypeError, AttributeError, ImportError]: - clsname = exc.__name__ - setattr(self, 'w_'+clsname, Constant(exc)) - # the following exceptions are the ones that should not show up - # during flow graph construction; they are triggered by - # non-R-Pythonic constructs or real bugs like typos. - for exc in [NameError, UnboundLocalError]: - clsname = exc.__name__ - setattr(self, 'w_'+clsname, None) - self.specialcases = SPECIAL_CASES.copy() - #self.make_builtins() - #self.make_sys() - # w_str is needed because cmp_exc_match of frames checks against it, - # as string exceptions are deprecated - self.w_str = Constant(str) - # objects which should keep their SomeObjectness - self.not_really_const = NOT_REALLY_CONST - - # disable superclass methods - enter_cache_building_mode = None - leave_cache_building_mode = None - createcompiler = None + specialcases = SPECIAL_CASES + # objects which should keep their SomeObjectness + not_really_const = NOT_REALLY_CONST def is_w(self, w_one, w_two): return self.is_true(self.is_(w_one, w_two)) @@ -103,6 +88,12 @@ def newslice(self, w_start, w_stop, w_step): return self.do_operation('newslice', w_start, w_stop, w_step) + def newbool(self, b): + if b: + return self.w_True + else: + return self.w_False + def wrap(self, obj): if isinstance(obj, (Variable, Constant)): raise TypeError("already wrapped: " + repr(obj)) @@ -167,53 +158,77 @@ raise UnwrapException return obj - def interpclass_w(self, w_obj): - obj = self.unwrap(w_obj) - if isinstance(obj, Wrappable): - return obj - return None + def exception_issubclass_w(self, w_cls1, w_cls2): + return self.is_true(self.issubtype(w_cls1, w_cls2)) - def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj): + def _exception_match(self, w_exc_type, w_check_class): + """Helper for exception_match + + Handles the base case where w_check_class is a constant exception + type. """ - WARNING: this implementation is not complete at all. It's just enough - to be used by end_finally() inside pyopcode.py. - """ - return w_obj == self.w_None or (isinstance(w_obj, Constant) and - isinstance(w_obj.value, RequiredClass)) - - def getexecutioncontext(self): - return self.frame + if self.is_w(w_exc_type, w_check_class): + return True # fast path (also here to handle string exceptions) + try: + return self.exception_issubclass_w(w_exc_type, w_check_class) + except FSException, e: + if e.match(self, self.w_TypeError): # string exceptions maybe + return False + raise def exception_match(self, w_exc_type, w_check_class): + """Checks if the given exception type matches 'w_check_class'.""" try: check_class = self.unwrap(w_check_class) except UnwrapException: - raise Exception, "non-constant except guard" + raise FlowingError(self.frame, "Non-constant except guard.") if check_class in (NotImplementedError, AssertionError): raise FlowingError(self.frame, "Catching %s is not valid in RPython" % check_class.__name__) if not isinstance(check_class, tuple): # the simple case - return ObjSpace.exception_match(self, w_exc_type, w_check_class) + return self._exception_match(w_exc_type, w_check_class) # special case for StackOverflow (see rlib/rstackovf.py) if check_class == rstackovf.StackOverflow: w_real_class = self.wrap(rstackovf._StackOverflow) - return ObjSpace.exception_match(self, w_exc_type, w_real_class) + return self._exception_match(w_exc_type, w_real_class) # checking a tuple of classes for w_klass in self.fixedview(w_check_class): if self.exception_match(w_exc_type, w_klass): return True return False - def getconstclass(space, w_cls): - try: - ecls = space.unwrap(w_cls) - except UnwrapException: - pass + def exc_from_raise(self, w_type, w_value): + """ + Create a wrapped exception from the arguments of a raise statement. + + Returns an FSException object whose w_value is an instance of w_type. + """ + if self.isinstance_w(w_type, self.w_type): + # this is for all cases of the form (Class, something) + if self.is_w(w_value, self.w_None): + # raise Type: we assume we have to instantiate Type + w_value = self.call_function(w_type) + w_type = self.type(w_value) + else: + w_valuetype = self.type(w_value) + if self.exception_issubclass_w(w_valuetype, w_type): + # raise Type, Instance: let etype be the exact type of value + w_type = w_valuetype + else: + # raise Type, X: assume X is the constructor argument + w_value = self.call_function(w_type, w_value) + w_type = self.type(w_value) else: - if isinstance(ecls, (type, types.ClassType)): - return ecls - return None + # the only case left here is (inst, None), from a 'raise inst'. + w_inst = w_type + w_instclass = self.type(w_inst) + if not self.is_w(w_value, self.w_None): + raise FSException(self.w_TypeError, self.wrap( + "instance exception may not have a separate value")) + w_value = w_inst + w_type = w_instclass + return FSException(w_type, w_value) def build_flow(self, func, constargs={}, tweak_for_generator=True): """ @@ -232,7 +247,7 @@ def fixedview(self, w_tuple, expected_length=None): return self.unpackiterable(w_tuple, expected_length) - listview = fixedview + listview = fixedview_unroll = fixedview From noreply at buildbot.pypy.org Tue Oct 2 21:55:38 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 2 Oct 2012 21:55:38 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Kill option tweak_for_generator Message-ID: <20121002195538.A46281C0EA4@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57749:07cb024bd3aa Date: 2012-10-01 18:14 +0100 http://bitbucket.org/pypy/pypy/changeset/07cb024bd3aa/ Log: Kill option tweak_for_generator diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -233,7 +233,7 @@ w_type = w_instclass return FSException(w_type, w_value) - def build_flow(self, func, tweak_for_generator=True): + def build_flow(self, func): """ """ if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): @@ -244,7 +244,7 @@ frame.build_flow() fixeggblocks(graph) checkgraph(graph) - if graph.is_generator and tweak_for_generator: + if graph.is_generator: tweak_generator_graph(graph) return graph diff --git a/pypy/objspace/flow/test/test_generator.py b/pypy/objspace/flow/test/test_generator.py --- a/pypy/objspace/flow/test/test_generator.py +++ b/pypy/objspace/flow/test/test_generator.py @@ -69,11 +69,7 @@ yield n yield n # - space = FlowObjSpace() - graph = space.build_flow(func, tweak_for_generator=False) - assert graph.startblock.operations[0].opname == 'generator_mark' - GeneratorIterator = make_generatoriterator_class(graph) - replace_graph_with_bootstrap(GeneratorIterator, graph) + graph = FlowObjSpace().build_flow(func) if option.view: graph.show() block = graph.startblock @@ -93,24 +89,6 @@ assert len(block.exits) == 1 assert block.exits[0].target is graph.returnblock - def test_tweak_generator_body_graph(self): - def f(n, x, y, z=3): - z *= 10 - yield n + 1 - z -= 10 - # - space = FlowObjSpace() - graph = space.build_flow(f, tweak_for_generator=False) - class Entry: - varnames = ['g_n', 'g_x', 'g_y', 'g_z'] - tweak_generator_body_graph(Entry, graph) - if option.view: - graph.show() - # XXX how to test directly that the graph is correct? :-( - assert len(graph.startblock.inputargs) == 1 - assert graph.signature == Signature(['entry']) - assert graph.defaults == () - def test_tweak_generator_graph(self): def f(n, x, y, z): z *= 10 @@ -118,7 +96,7 @@ z -= 10 # space = FlowObjSpace() - graph = space.build_flow(f, tweak_for_generator=False) + graph = space.build_flow(f) GeneratorIterator = make_generatoriterator_class(graph) replace_graph_with_bootstrap(GeneratorIterator, graph) func1 = attach_next_method(GeneratorIterator, graph) @@ -133,8 +111,7 @@ if option.view: graph_next.show() # - graph1 = space.build_flow(func1, tweak_for_generator=False) - tweak_generator_body_graph(GeneratorIterator.Entry, graph1) + graph1 = space.build_flow(func1) if option.view: graph1.show() @@ -144,8 +121,7 @@ yield n + 1 z -= 10 # - space = FlowObjSpace() - graph = space.build_flow(f) # tweak_for_generator=True + graph = FlowObjSpace().build_flow(f) if option.view: graph.show() block = graph.startblock From noreply at buildbot.pypy.org Tue Oct 2 21:55:39 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 2 Oct 2012 21:55:39 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Don't build the flow graph when bootstrapping generator graphs Message-ID: <20121002195539.CC2E21C0EA4@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57750:eab196c1b02f Date: 2012-10-02 20:55 +0100 http://bitbucket.org/pypy/pypy/changeset/eab196c1b02f/ Log: Don't build the flow graph when bootstrapping generator graphs + Split tweak_generator_graph() diff --git a/pypy/objspace/flow/generator.py b/pypy/objspace/flow/generator.py --- a/pypy/objspace/flow/generator.py +++ b/pypy/objspace/flow/generator.py @@ -11,21 +11,21 @@ _immutable_ = True _attrs_ = () +def bootstrap_generator(graph): + # This is the first copy of the graph. We replace it with + # a small bootstrap graph. + GeneratorIterator = make_generatoriterator_class(graph) + replace_graph_with_bootstrap(GeneratorIterator, graph) + # We attach a 'next' method to the GeneratorIterator class + # that will invoke the real function, based on a second + # copy of the graph. + attach_next_method(GeneratorIterator, graph) + return graph def tweak_generator_graph(graph): - if not hasattr(graph.func, '_generator_next_method_of_'): - # This is the first copy of the graph. We replace it with - # a small bootstrap graph. - GeneratorIterator = make_generatoriterator_class(graph) - replace_graph_with_bootstrap(GeneratorIterator, graph) - # We attach a 'next' method to the GeneratorIterator class - # that will invoke the real function, based on a second - # copy of the graph. - attach_next_method(GeneratorIterator, graph) - else: - # This is the second copy of the graph. Tweak it. - GeneratorIterator = graph.func._generator_next_method_of_ - tweak_generator_body_graph(GeneratorIterator.Entry, graph) + # This is the second copy of the graph. Tweak it. + GeneratorIterator = graph.func._generator_next_method_of_ + tweak_generator_body_graph(GeneratorIterator.Entry, graph) def make_generatoriterator_class(graph): diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -10,7 +10,8 @@ from pypy.objspace.flow import operation from pypy.objspace.flow.flowcontext import (FlowSpaceFrame, fixeggblocks, FSException, FlowingError) -from pypy.objspace.flow.generator import tweak_generator_graph +from pypy.objspace.flow.generator import (tweak_generator_graph, + bootstrap_generator) from pypy.objspace.flow.pygraph import PyGraph from pypy.objspace.flow.specialcase import SPECIAL_CASES from pypy.rlib.unroll import unrolling_iterable, _unroller @@ -239,6 +240,14 @@ if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): raise Exception, "%r is tagged as NOT_RPYTHON" % (func,) code = HostCode._from_code(self, func.func_code) + if (code.is_generator and + not hasattr(func, '_generator_next_method_of_')): + graph = PyGraph(func, code) + block = graph.startblock + for name, w_value in zip(code.co_varnames, block.framestate.mergeable): + if isinstance(w_value, Variable): + w_value.rename(name) + return bootstrap_generator(graph) graph = PyGraph(func, code) frame = self.frame = FlowSpaceFrame(self, graph, code) frame.build_flow() From noreply at buildbot.pypy.org Tue Oct 2 23:07:32 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 23:07:32 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Fix fix fix. Message-ID: <20121002210732.66E441C0EA4@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57751:b7aba3fd9ad8 Date: 2012-10-02 22:58 +0200 http://bitbucket.org/pypy/pypy/changeset/b7aba3fd9ad8/ Log: Fix fix fix. Also rename main.c into entrypoint.c, to avoid collision in case of --shared build. diff --git a/pypy/rpython/module/ll_strtod.py b/pypy/rpython/module/ll_strtod.py --- a/pypy/rpython/module/ll_strtod.py +++ b/pypy/rpython/module/ll_strtod.py @@ -14,7 +14,7 @@ _compilation_info_ = ExternalCompilationInfo( includes = ['src/ll_strtod.h'], include_dirs = [str(py.path.local(pypydir).join('translator', 'c'))], - separate_module_sources = ['#include '], + separate_module_sources = ['#include '], export_symbols = ['LL_strtod_formatd', 'LL_strtod_parts_to_float'], ) diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -907,7 +907,7 @@ def add_extra_files(eci): srcdir = py.path.local(autopath.pypydir).join('translator', 'c', 'src') files = [ - srcdir / 'main.c', # ifdef PYPY_STANDALONE + srcdir / 'entrypoint.c', # ifdef PYPY_STANDALONE srcdir / 'allocator.c', # ifdef PYPY_STANDALONE srcdir / 'mem.c', srcdir / 'exception.c', diff --git a/pypy/translator/c/src/main.c b/pypy/translator/c/src/entrypoint.c rename from pypy/translator/c/src/main.c rename to pypy/translator/c/src/entrypoint.c --- a/pypy/translator/c/src/main.c +++ b/pypy/translator/c/src/entrypoint.c @@ -3,7 +3,7 @@ #include "structdef.h" #include "forwarddecl.h" #include "preimpl.h" -#include +#include #include #include #include diff --git a/pypy/translator/c/src/main.h b/pypy/translator/c/src/entrypoint.h rename from pypy/translator/c/src/main.h rename to pypy/translator/c/src/entrypoint.h diff --git a/pypy/translator/c/src/g_include.h b/pypy/translator/c/src/g_include.h --- a/pypy/translator/c/src/g_include.h +++ b/pypy/translator/c/src/g_include.h @@ -50,7 +50,7 @@ #ifdef PYPY_STANDALONE # include "src/allocator.h" -# include "src/main.h" +# include "src/entrypoint.h" #endif /* suppress a few warnings in the generated code */ diff --git a/pypy/translator/c/src/mem.c b/pypy/translator/c/src/mem.c --- a/pypy/translator/c/src/mem.c +++ b/pypy/translator/c/src/mem.c @@ -1,6 +1,7 @@ #include "common_header.h" #include "src/support.h" #include +#include /*** tracking raw mallocs and frees for debugging ***/ diff --git a/pypy/translator/c/src/pyobj.c b/pypy/translator/c/src/pyobj.c --- a/pypy/translator/c/src/pyobj.c +++ b/pypy/translator/c/src/pyobj.c @@ -1,3 +1,4 @@ +#include "common_header.h" #include /************************************************************/ diff --git a/pypy/translator/c/src/pyobj.h b/pypy/translator/c/src/pyobj.h --- a/pypy/translator/c/src/pyobj.h +++ b/pypy/translator/c/src/pyobj.h @@ -217,6 +217,12 @@ #define OP_NEWDICT(args,r) if (!(r=PyDict_Pack args)) CFAIL() #define OP_NEWTUPLE(args,r) if (!(r=PyTuple_Pack args)) CFAIL() +#if (PY_VERSION_HEX < 0x02040000) +unsigned long RPyLong_AsUnsignedLong(PyObject *v); +#else +#define RPyLong_AsUnsignedLong PyLong_AsUnsignedLong +#endif + unsigned long long RPyLong_AsUnsignedLongLong(PyObject *v); long long RPyLong_AsLongLong(PyObject *v); From noreply at buildbot.pypy.org Tue Oct 2 23:07:33 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 2 Oct 2012 23:07:33 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: hg merge default Message-ID: <20121002210733.E90691C0EA4@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57752:403594295483 Date: 2012-10-02 23:07 +0200 http://bitbucket.org/pypy/pypy/changeset/403594295483/ Log: hg merge default diff too long, truncating to 2000 out of 2395 lines diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -23,7 +23,7 @@ The tools required to cross translate from a Linux based host to an ARM based Linux target are: -- A checkout of PyPy's arm-backend-2 branch. +- A checkout of PyPy (default branch). - The GCC ARM cross compiler (on Ubuntu it is the ``gcc-arm-linux-gnueabi package``) but other toolchains should also work. - Scratchbox 2, a cross-compilation engine (``scratchbox2`` Ubuntu package). - A 32-bit PyPy or Python. @@ -147,4 +147,4 @@ return 0 def target(*args): - return main, None \ No newline at end of file + return main, None diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -115,13 +115,16 @@ which data structures would be more appropriate? For example, a dict implemented as a hash table will suffer "stm collisions" in all threads whenever one thread writes anything to it; but there could be other - implementations. + implementations. Maybe alternate strategies can be implemented at the + level of the Python interpreter (see list/dict strategies, + ``pypy/objspace/std/{list,dict}object.py``). * More generally, there is the idea that we would need some kind of "debugger"-like tool to "debug" things that are not bugs, but stm conflicts. How would this tool look like to the end Python programmers? Like a profiler? Or like a debugger with breakpoints - on aborted transactions? + on aborted transactions? It would probably be all app-level, with + a few hooks e.g. for transaction conflicts. * Find good ways to have libraries using internally threads and atomics, but not exposing threads to the user. Right now there is a rough draft 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 @@ -18,6 +18,7 @@ .. branch: numpypy_count_nonzero .. branch: numpy-refactor Remove numpy lazy evaluation and simplify everything +.. branch: numpy-reintroduce-jit-drivers .. branch: numpy-fancy-indexing Support for array[array-of-ints] in numpy .. branch: even-more-jit-hooks 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 @@ -474,7 +474,7 @@ if f_type == F_BLOCK_LOOP: self.emit_jump(ops.CONTINUE_LOOP, block, True) break - if self.frame_blocks[i][0] == F_BLOCK_FINALLY_END: + if f_type == F_BLOCK_FINALLY_END: self.error("'continue' not supported inside 'finally' " \ "clause", cont) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -208,11 +208,11 @@ def int_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def bigint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -292,8 +292,6 @@ """Base class for the interpreter-level implementations of object spaces. http://pypy.readthedocs.org/en/latest/objspace.html""" - full_exceptions = True # full support for exceptions (normalization & more) - def __init__(self, config=None): "NOT_RPYTHON: Basic initialization of objects." self.fromcache = InternalSpaceCache(self).getorbuild @@ -1124,13 +1122,9 @@ def exception_is_valid_obj_as_class_w(self, w_obj): if not self.isinstance_w(w_obj, self.w_type): return False - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_obj, self.w_BaseException)) def exception_is_valid_class_w(self, w_cls): - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_cls, self.w_BaseException)) def exception_getclass(self, w_obj): @@ -1381,7 +1375,7 @@ if not self.is_true(self.isinstance(w_obj, self.w_str)): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) - return self.str_w(w_obj) + return self.str_w(w_obj) def unicode_w(self, w_obj): return w_obj.unicode_w(self) @@ -1702,7 +1696,7 @@ 'ValueError', 'ZeroDivisionError', ] - + if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -45,11 +45,6 @@ def async(self, space): "Check if this is an exception that should better not be caught." - if not space.full_exceptions: - # flow objspace does not support such exceptions and more - # importantly, raises KeyboardInterrupt if you try to access - # space.w_KeyboardInterrupt - return False return (self.match(space, space.w_SystemExit) or self.match(space, space.w_KeyboardInterrupt)) @@ -166,9 +161,7 @@ # Or 'Class' can also be an old-style class and 'inst' an old-style # instance of it. # - # Note that 'space.full_exceptions' is set to False by the flow - # object space; in this case we must assume that we are in a - # non-advanced case, and ignore the advanced cases. Old-style + # The flow object space only deals with non-advanced case. Old-style # classes and instances *are* advanced. # # input (w_type, w_value)... becomes... advanced case? @@ -183,9 +176,8 @@ # w_type = self.w_type w_value = self.get_w_value(space) - if space.full_exceptions: - while space.is_true(space.isinstance(w_type, space.w_tuple)): - w_type = space.getitem(w_type, space.wrap(0)) + while space.is_true(space.isinstance(w_type, space.w_tuple)): + w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): # this is for all cases of the form (Class, something) @@ -199,8 +191,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.full_exceptions and space.is_true( - space.isinstance(w_value, space.w_tuple)): + if space.is_true(space.isinstance(w_value, space.w_tuple)): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -944,14 +944,6 @@ def appcaller(space, *args_w): if not isinstance(space, ObjSpace): raise TypeError("first argument must be a space instance.") - # redirect if the space handles this specially - # XXX can this be factored a bit less flow space dependently? - if hasattr(space, 'specialcases'): - sc = space.specialcases - if ApplevelClass in sc: - ret_w = sc[ApplevelClass](space, self, name, args_w) - if ret_w is not None: # it was RPython - return ret_w # the last argument can be an Arguments w_func = self.wget(space, name) if not args_w: diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -223,7 +223,7 @@ return next_instr if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: - return self.jump_absolute(oparg, next_instr, ec) + return self.jump_absolute(oparg, ec) if we_are_translated(): for opdesc in unrolling_all_opcode_descs: @@ -557,7 +557,7 @@ w_type = self.popvalue() operror = OperationError(w_type, w_value) operror.normalize_exception(space) - if not space.full_exceptions or space.is_w(w_traceback, space.w_None): + if space.is_w(w_traceback, space.w_None): # common case raise operror else: @@ -858,7 +858,8 @@ def YIELD_VALUE(self, oparg, next_instr): raise Yield - def jump_absolute(self, jumpto, next_instr, ec): + def jump_absolute(self, jumpto, ec): + # this function is overridden by pypy.module.pypyjit.interp_jit check_nonneg(jumpto) return jumpto @@ -944,21 +945,9 @@ def WITH_CLEANUP(self, oparg, next_instr): # see comment in END_FINALLY for stack state - # This opcode changed a lot between CPython versions - if (self.pycode.magic >= 0xa0df2ef - # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) - or self.pycode.magic >= 0xa0df2d1): - # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) - w_unroller = self.popvalue() - w_exitfunc = self.popvalue() - self.pushvalue(w_unroller) - elif self.pycode.magic >= 0xa0df28c: - # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) - w_exitfunc = self.popvalue() - w_unroller = self.peekvalue(0) - else: - raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") - + w_unroller = self.popvalue() + w_exitfunc = self.popvalue() + self.pushvalue(w_unroller) unroller = self.space.interpclass_w(w_unroller) is_app_exc = (unroller is not None and isinstance(unroller, SApplicationException)) @@ -1192,10 +1181,6 @@ 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): """Signals a 'return' statement. Argument is the wrapped object to return.""" @@ -1206,12 +1191,6 @@ def nomoreblocks(self): return self.w_returnvalue - def state_unpack_variables(self, space): - return [self.w_returnvalue] - def state_pack_variables(space, w_returnvalue): - return SReturnValue(w_returnvalue) - state_pack_variables = staticmethod(state_pack_variables) - class SApplicationException(SuspendedUnroller): """Signals an application-level exception (i.e. an OperationException).""" @@ -1226,13 +1205,6 @@ """Signals a 'break' statement.""" _immutable_ = True kind = 0x04 - - def state_unpack_variables(self, space): - return [] - def state_pack_variables(space): - return SBreakLoop.singleton - state_pack_variables = staticmethod(state_pack_variables) - SBreakLoop.singleton = SBreakLoop() class SContinueLoop(SuspendedUnroller): @@ -1243,12 +1215,6 @@ def __init__(self, jump_to): self.jump_to = jump_to - def state_unpack_variables(self, space): - return [space.wrap(self.jump_to)] - def state_pack_variables(space, w_jump_to): - return SContinueLoop(space.int_w(w_jump_to)) - state_pack_variables = staticmethod(state_pack_variables) - class FrameBlock(object): """Abstract base class for frame blocks from the blockstack, @@ -1303,7 +1269,9 @@ # and jump to the beginning of the loop, stored in the # exception's argument frame.append_block(self) - return r_uint(unroller.jump_to) + jumpto = unroller.jump_to + ec = frame.space.getexecutioncontext() + return r_uint(frame.jump_absolute(jumpto, ec)) else: # jump to the end of the loop self.cleanupstack(frame) @@ -1323,8 +1291,7 @@ self.cleanupstack(frame) assert isinstance(unroller, SApplicationException) operationerr = unroller.operr - if frame.space.full_exceptions: - operationerr.normalize_exception(frame.space) + operationerr.normalize_exception(frame.space) # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. @@ -1356,8 +1323,7 @@ _immutable_ = True def handle(self, frame, unroller): - if (frame.space.full_exceptions and - isinstance(unroller, SApplicationException)): + if isinstance(unroller, SApplicationException): unroller.operr.normalize_exception(frame.space) return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -131,13 +131,13 @@ def get_latest_value_float(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a float.""" + or from 'args' if it was a FINISH). Returns a FLOATSTORAGE.""" raise NotImplementedError def get_latest_value_ref(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a ptr or an obj.""" + or from 'args' if it was a FINISH). Returns a GCREF.""" raise NotImplementedError def get_latest_value_count(self): 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 @@ -981,7 +981,7 @@ assert strlenaddr == cast(BVoidP, strlen) def test_read_variable(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BVoidP = new_pointer_type(new_void_type()) ll = find_and_load_library('c') @@ -989,7 +989,7 @@ assert stderr == cast(BVoidP, _testfunc(8)) def test_read_variable_as_unknown_length_array(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BCharP = new_pointer_type(new_primitive_type("char")) BArray = new_array_type(BCharP, None) @@ -999,7 +999,7 @@ # ^^ and not 'char[]', which is basically not allowed and would crash def test_write_variable(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BVoidP = new_pointer_type(new_void_type()) ll = find_and_load_library('c') 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 @@ -244,6 +244,7 @@ def setitem_index(self, space, index, value): self.setitem(self._lookup_by_unwrapped_index(space, index), value) + @jit.unroll_safe def _single_item_index(self, space, w_idx): """ Return an index of single item if possible, otherwise raises IndexError 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 @@ -9,8 +9,8 @@ from pypy.interpreter.error import OperationError from pypy.module.micronumpy import interp_boxes from pypy.module.micronumpy.interp_dtype import get_dtype_cache -from pypy.module.micronumpy.interp_numarray import (Scalar, BaseArray, - scalar_w, W_NDimArray, array) +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.interp_numarray import array from pypy.module.micronumpy.interp_arrayops import where from pypy.module.micronumpy import interp_ufuncs from pypy.rlib.objectmodel import specialize, instantiate @@ -147,7 +147,8 @@ def is_true(self, w_obj): assert isinstance(w_obj, BoolObject) - return w_obj.boolval + return False + #return w_obj.boolval def is_w(self, w_obj, w_what): return w_obj is w_what @@ -274,7 +275,7 @@ if isinstance(w_index, FloatObject): w_index = IntObject(int(w_index.floatval)) w_val = self.expr.execute(interp) - assert isinstance(arr, BaseArray) + assert isinstance(arr, W_NDimArray) arr.descr_setitem(interp.space, w_index, w_val) def __repr__(self): @@ -302,11 +303,11 @@ w_rhs = self.rhs.wrap(interp.space) else: w_rhs = self.rhs.execute(interp) - if not isinstance(w_lhs, BaseArray): + if not isinstance(w_lhs, W_NDimArray): # scalar dtype = get_dtype_cache(interp.space).w_float64dtype - w_lhs = scalar_w(interp.space, dtype, w_lhs) - assert isinstance(w_lhs, BaseArray) + w_lhs = W_NDimArray.new_scalar(interp.space, dtype, w_lhs) + assert isinstance(w_lhs, W_NDimArray) if self.name == '+': w_res = w_lhs.descr_add(interp.space, w_rhs) elif self.name == '*': @@ -314,17 +315,16 @@ elif self.name == '-': w_res = w_lhs.descr_sub(interp.space, w_rhs) elif self.name == '->': - assert not isinstance(w_rhs, Scalar) if isinstance(w_rhs, FloatObject): w_rhs = IntObject(int(w_rhs.floatval)) - assert isinstance(w_lhs, BaseArray) + assert isinstance(w_lhs, W_NDimArray) w_res = w_lhs.descr_getitem(interp.space, w_rhs) else: raise NotImplementedError - if (not isinstance(w_res, BaseArray) and + if (not isinstance(w_res, W_NDimArray) and not isinstance(w_res, interp_boxes.W_GenericBox)): dtype = get_dtype_cache(interp.space).w_float64dtype - w_res = scalar_w(interp.space, dtype, w_res) + w_res = W_NDimArray.new_scalar(interp.space, dtype, w_res) return w_res def __repr__(self): @@ -416,7 +416,7 @@ def execute(self, interp): arr = self.args[0].execute(interp) - if not isinstance(arr, BaseArray): + if not isinstance(arr, W_NDimArray): raise ArgumentNotAnArray if self.name in SINGLE_ARG_FUNCTIONS: if len(self.args) != 1 and self.name != 'sum': @@ -440,20 +440,21 @@ elif self.name == "unegative": neg = interp_ufuncs.get(interp.space).negative w_res = neg.call(interp.space, [arr]) + elif self.name == "cos": + cos = interp_ufuncs.get(interp.space).cos + w_res = cos.call(interp.space, [arr]) elif self.name == "flat": w_res = arr.descr_get_flatiter(interp.space) elif self.name == "tostring": arr.descr_tostring(interp.space) w_res = None - elif self.name == "count_nonzero": - w_res = arr.descr_count_nonzero(interp.space) else: assert False # unreachable code elif self.name in TWO_ARG_FUNCTIONS: if len(self.args) != 2: raise ArgumentMismatch arg = self.args[1].execute(interp) - if not isinstance(arg, BaseArray): + if not isinstance(arg, W_NDimArray): raise ArgumentNotAnArray if self.name == "dot": w_res = arr.descr_dot(interp.space, arg) @@ -466,9 +467,9 @@ raise ArgumentMismatch arg1 = self.args[1].execute(interp) arg2 = self.args[2].execute(interp) - if not isinstance(arg1, BaseArray): + if not isinstance(arg1, W_NDimArray): raise ArgumentNotAnArray - if not isinstance(arg2, BaseArray): + if not isinstance(arg2, W_NDimArray): raise ArgumentNotAnArray if self.name == "where": w_res = where(interp.space, arr, arg1, arg2) @@ -476,7 +477,7 @@ assert False else: raise WrongFunctionName - if isinstance(w_res, BaseArray): + if isinstance(w_res, W_NDimArray): return w_res if isinstance(w_res, FloatObject): dtype = get_dtype_cache(interp.space).w_float64dtype @@ -488,7 +489,7 @@ dtype = w_res.get_dtype(interp.space) else: dtype = None - return scalar_w(interp.space, dtype, w_res) + return W_NDimArray.new_scalar(interp.space, dtype, w_res) _REGEXES = [ ('-?[\d\.]+', 'number'), 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 @@ -129,6 +129,8 @@ self._prepare_array_index(space, w_index) shape = res_shape + self.get_shape()[len(indexes):] res = W_NDimArray.from_shape(shape, self.get_dtype(), self.get_order()) + if not res.get_size(): + return res return loop.getitem_array_int(space, self, res, iter_shape, indexes, prefix) @@ -514,7 +516,7 @@ if self.get_size() == 0: raise OperationError(space.w_ValueError, space.wrap("Can't call %s on zero-size arrays" % op_name)) - return space.wrap(loop.argmin_argmax(op_name, self)) + return space.wrap(getattr(loop, 'arg' + op_name)(self)) return func_with_new_name(impl, "reduce_arg%s_impl" % op_name) descr_argmax = _reduce_argmax_argmin_impl("max") 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 @@ -258,7 +258,7 @@ return out shape = shape_agreement(space, w_obj.get_shape(), out, broadcast_down=False) - return loop.call1(shape, self.func, self.name, calc_dtype, res_dtype, + return loop.call1(shape, self.func, calc_dtype, res_dtype, w_obj, out) @@ -322,7 +322,7 @@ return out 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(new_shape, self.func, self.name, calc_dtype, + return loop.call2(new_shape, self.func, calc_dtype, res_dtype, w_lhs, w_rhs, out) 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 @@ -1,21 +1,34 @@ """ This file is the main run loop as well as evaluation loops for various -signatures +operations. This is the place to look for all the computations that iterate +over all the array elements. """ -from pypy.rlib.objectmodel import specialize from pypy.rlib.rstring import StringBuilder from pypy.rlib import jit from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy.base import W_NDimArray -def call2(shape, func, name, calc_dtype, res_dtype, w_lhs, w_rhs, out): +call2_driver = jit.JitDriver(name='numpy_call2', + greens = ['shapelen', 'func', 'calc_dtype', + 'res_dtype'], + reds = ['shape', 'w_lhs', 'w_rhs', 'out', + 'left_iter', 'right_iter', 'out_iter']) + +def call2(shape, func, calc_dtype, res_dtype, w_lhs, w_rhs, out): if out is None: out = W_NDimArray.from_shape(shape, res_dtype) left_iter = w_lhs.create_iter(shape) right_iter = w_rhs.create_iter(shape) out_iter = out.create_iter(shape) + shapelen = len(shape) while not out_iter.done(): + call2_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, res_dtype=res_dtype, + shape=shape, w_lhs=w_lhs, w_rhs=w_rhs, + out=out, + left_iter=left_iter, right_iter=right_iter, + out_iter=out_iter) w_left = left_iter.getitem().convert_to(calc_dtype) w_right = right_iter.getitem().convert_to(calc_dtype) out_iter.setitem(func(calc_dtype, w_left, w_right).convert_to( @@ -25,30 +38,56 @@ out_iter.next() return out -def call1(shape, func, name, calc_dtype, res_dtype, w_obj, out): +call1_driver = jit.JitDriver(name='numpy_call1', + greens = ['shapelen', 'func', 'calc_dtype', + 'res_dtype'], + reds = ['shape', 'w_obj', 'out', 'obj_iter', + 'out_iter']) + +def call1(shape, func, calc_dtype, res_dtype, w_obj, out): if out is None: out = W_NDimArray.from_shape(shape, res_dtype) obj_iter = w_obj.create_iter(shape) out_iter = out.create_iter(shape) + shapelen = len(shape) while not out_iter.done(): + call1_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, res_dtype=res_dtype, + shape=shape, w_obj=w_obj, out=out, + obj_iter=obj_iter, out_iter=out_iter) elem = obj_iter.getitem().convert_to(calc_dtype) out_iter.setitem(func(calc_dtype, elem).convert_to(res_dtype)) out_iter.next() obj_iter.next() return out +setslice_driver = jit.JitDriver(name='numpy_setslice', + greens = ['shapelen', 'dtype'], + reds = ['target', 'source', 'target_iter', + 'source_iter']) + def setslice(shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) source_iter = source.create_iter(shape) dtype = target.dtype + shapelen = len(shape) while not target_iter.done(): + setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + target=target, source=source, + target_iter=target_iter, + source_iter=source_iter) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target +reduce_driver = jit.JitDriver(name='numpy_reduce', + greens = ['shapelen', 'func', 'done_func', + 'calc_dtype', 'identity'], + reds = ['obj', 'obj_iter', 'cur_value']) + def compute_reduce(obj, calc_dtype, func, done_func, identity): obj_iter = obj.create_iter(obj.get_shape()) if identity is None: @@ -56,7 +95,12 @@ obj_iter.next() else: cur_value = identity.convert_to(calc_dtype) + shapelen = len(obj.get_shape()) while not obj_iter.done(): + reduce_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, identity=identity, + done_func=done_func, obj=obj, + obj_iter=obj_iter, cur_value=cur_value) rval = obj_iter.getitem().convert_to(calc_dtype) if done_func is not None and done_func(calc_dtype, rval): return rval @@ -70,6 +114,11 @@ arr_iter.setitem(box) arr_iter.next() +where_driver = jit.JitDriver(name='numpy_where', + greens = ['shapelen', 'dtype', 'arr_dtype'], + reds = ['shape', 'arr', 'x', 'y','arr_iter', 'out', + 'x_iter', 'y_iter', 'iter', 'out_iter']) + def where(out, shape, arr, x, y, dtype): out_iter = out.create_iter(shape) arr_iter = arr.create_iter(shape) @@ -83,7 +132,13 @@ iter = y_iter else: iter = x_iter + shapelen = len(shape) while not iter.done(): + where_driver.jit_merge_point(shapelen=shapelen, shape=shape, + dtype=dtype, iter=iter, x_iter=x_iter, + y_iter=y_iter, arr_iter=arr_iter, + arr=arr, x=x, y=y, arr_dtype=arr_dtype, + out_iter=out_iter, out=out) w_cond = arr_iter.getitem() if arr_dtype.itemtype.bool(w_cond): w_val = x_iter.getitem().convert_to(dtype) @@ -96,12 +151,24 @@ y_iter.next() return out +axis_reduce__driver = jit.JitDriver(name='numpy_axis_reduce', + greens=['shapelen', 'func', 'dtype', + 'identity'], + reds=['axis', 'arr', 'out', 'shape', + 'out_iter', 'arr_iter']) + def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): out_iter = out.create_axis_iter(arr.get_shape(), axis) arr_iter = arr.create_iter(arr.get_shape()) if identity is not None: identity = identity.convert_to(dtype) + shapelen = len(shape) while not out_iter.done(): + axis_reduce__driver.jit_merge_point(shapelen=shapelen, func=func, + dtype=dtype, identity=identity, + axis=axis, arr=arr, out=out, + shape=shape, out_iter=out_iter, + arr_iter=arr_iter) w_val = arr_iter.getitem().convert_to(dtype) if out_iter.first_line: if identity is not None: @@ -114,23 +181,41 @@ out_iter.next() return out - at specialize.arg(0) -def argmin_argmax(op_name, arr): - result = 0 - idx = 1 - dtype = arr.get_dtype() - iter = arr.create_iter(arr.get_shape()) - cur_best = iter.getitem() - iter.next() - while not iter.done(): - w_val = iter.getitem() - new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) - if dtype.itemtype.ne(new_best, cur_best): - result = idx - cur_best = new_best + +def _new_argmin_argmax(op_name): + arg_driver = jit.JitDriver(name='numpy_' + op_name, + greens = ['shapelen', 'dtype'], + reds = ['result', 'idx', 'cur_best', 'arr', + 'iter']) + + def argmin_argmax(arr): + result = 0 + idx = 1 + dtype = arr.get_dtype() + iter = arr.create_iter(arr.get_shape()) + cur_best = iter.getitem() iter.next() - idx += 1 - return result + shapelen = len(arr.get_shape()) + while not iter.done(): + arg_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + result=result, idx=idx, + cur_best=cur_best, arr=arr, iter=iter) + w_val = iter.getitem() + new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) + if dtype.itemtype.ne(new_best, cur_best): + result = idx + cur_best = new_best + iter.next() + idx += 1 + return result + return argmin_argmax +argmin = _new_argmin_argmax('min') +argmax = _new_argmin_argmax('max') + +# note that shapelen == 2 always +dot_driver = jit.JitDriver(name = 'numpy_dot', + greens = ['dtype'], + reds = ['outi', 'lefti', 'righti', 'result']) def multidim_dot(space, left, right, result, dtype, right_critical_dim): ''' assumes left, right are concrete arrays @@ -157,6 +242,8 @@ lefti = left.create_dot_iter(broadcast_shape, left_skip) righti = right.create_dot_iter(broadcast_shape, right_skip) while not outi.done(): + dot_driver.jit_merge_point(dtype=dtype, outi=outi, lefti=lefti, + righti=righti, result=result) lval = lefti.getitem().convert_to(dtype) rval = righti.getitem().convert_to(dtype) outval = outi.getitem().convert_to(dtype) @@ -168,21 +255,45 @@ lefti.next() return result +count_all_true_driver = jit.JitDriver(name = 'numpy_count', + greens = ['shapelen', 'dtype'], + reds = ['s', 'iter']) + 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() while not iter.done(): + count_all_true_driver.jit_merge_point(shapelen=shapelen, iter=iter, + s=s, 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'], + reds = ['res', 'index_iter', 'res_iter', + 'arr_iter']) + def getitem_filter(res, arr, index): res_iter = res.create_iter() index_iter = index.create_iter() arr_iter = arr.create_iter() + shapelen = len(arr.get_shape()) + arr_dtype = arr.get_dtype() + index_dtype = index.get_dtype() + # XXX length of shape of index as well? while not index_iter.done(): + getitem_filter_driver.jit_merge_point(shapelen=shapelen, + index_dtype=index_dtype, + arr_dtype=arr_dtype, + res=res, index_iter=index_iter, + res_iter=res_iter, + arr_iter=arr_iter) if index_iter.getitem_bool(): res_iter.setitem(arr_iter.getitem()) res_iter.next() @@ -190,31 +301,63 @@ arr_iter.next() return res +setitem_filter_driver = jit.JitDriver(name = 'numpy_setitem_bool', + greens = ['shapelen', 'arr_dtype', + 'index_dtype'], + reds = ['index_iter', 'value_iter', + 'arr_iter']) + def setitem_filter(arr, index, value): arr_iter = arr.create_iter() index_iter = index.create_iter() value_iter = value.create_iter() + shapelen = len(arr.get_shape()) + index_dtype = index.get_dtype() + arr_dtype = arr.get_dtype() while not index_iter.done(): + setitem_filter_driver.jit_merge_point(shapelen=shapelen, + index_dtype=index_dtype, + arr_dtype=arr_dtype, + index_iter=index_iter, + value_iter=value_iter, + arr_iter=arr_iter) if index_iter.getitem_bool(): arr_iter.setitem(value_iter.getitem()) value_iter.next() arr_iter.next() index_iter.next() +flatiter_getitem_driver = jit.JitDriver(name = 'numpy_flatiter_getitem', + greens = ['dtype'], + reds = ['step', 'ri', 'res', + 'base_iter']) + def flatiter_getitem(res, base_iter, step): ri = res.create_iter() + dtype = res.get_dtype() while not ri.done(): + flatiter_getitem_driver.jit_merge_point(dtype=dtype, + base_iter=base_iter, + ri=ri, res=res, step=step) ri.setitem(base_iter.getitem()) base_iter.next_skip_x(step) ri.next() return res +flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', + greens = ['dtype'], + reds = ['length', 'step', 'arr_iter', + 'val_iter']) + def flatiter_setitem(arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: + flatiter_setitem_driver.jit_merge_point(dtype=dtype, length=length, + step=step, arr_iter=arr_iter, + val_iter=val_iter) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -223,10 +366,16 @@ # WTF numpy? val_iter.reset() +fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', + greens = ['itemsize', 'dtype'], + reds = ['i', 's', 'ai']) + def fromstring_loop(a, dtype, itemsize, s): i = 0 ai = a.create_iter() while not ai.done(): + fromstring_driver.jit_merge_point(dtype=dtype, s=s, ai=ai, i=i, + itemsize=itemsize) val = dtype.itemtype.runpack_str(s[i*itemsize:i*itemsize + itemsize]) ai.setitem(val) ai.next() @@ -274,12 +423,25 @@ else: self._done = True + @jit.unroll_safe def get_index(self, space): return [space.wrap(i) for i in self.indexes] +getitem_int_driver = jit.JitDriver(name = 'numpy_getitem_int', + greens = ['shapelen', 'indexlen', 'dtype'], + reds = ['arr', 'res', 'iter', 'indexes_w', + 'prefix_w']) + def getitem_array_int(space, arr, res, iter_shape, indexes_w, prefix_w): + shapelen = len(iter_shape) + indexlen = len(indexes_w) + dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): + getitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, + dtype=dtype, arr=arr, res=res, + iter=iter, indexes_w=indexes_w, + prefix_w=prefix_w) # prepare the index index_w = [None] * len(indexes_w) for i in range(len(indexes_w)): @@ -293,10 +455,22 @@ iter.next() return res +setitem_int_driver = jit.JitDriver(name = 'numpy_setitem_int', + greens = ['shapelen', 'indexlen', 'dtype'], + reds = ['arr', 'iter', 'indexes_w', + 'prefix_w', 'val_arr']) + def setitem_array_int(space, arr, iter_shape, indexes_w, val_arr, prefix_w): + shapelen = len(iter_shape) + indexlen = len(indexes_w) + dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): + setitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, + dtype=dtype, arr=arr, + iter=iter, indexes_w=indexes_w, + prefix_w=prefix_w, val_arr=val_arr) # prepare the index index_w = [None] * len(indexes_w) for i in range(len(indexes_w)): diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py --- a/pypy/module/micronumpy/test/test_compile.py +++ b/pypy/module/micronumpy/test/test_compile.py @@ -1,6 +1,5 @@ + import py -py.test.skip("this is going away") - from pypy.module.micronumpy.compile import (numpy_compile, Assignment, ArrayConstant, FloatConstant, Operator, Variable, RangeConstant, Execute, FunctionCall, FakeSpace) @@ -136,7 +135,7 @@ r """ interp = self.run(code) - assert interp.results[0].value.value == 15 + assert interp.results[0].get_scalar_value().value == 15 def test_sum2(self): code = """ @@ -145,7 +144,7 @@ sum(b) """ interp = self.run(code) - assert interp.results[0].value.value == 30 * (30 - 1) + assert interp.results[0].get_scalar_value().value == 30 * (30 - 1) def test_array_write(self): @@ -164,7 +163,7 @@ b = a + a min(b) """) - assert interp.results[0].value.value == -24 + assert interp.results[0].get_scalar_value().value == -24 def test_max(self): interp = self.run(""" @@ -173,7 +172,7 @@ b = a + a max(b) """) - assert interp.results[0].value.value == 256 + assert interp.results[0].get_scalar_value().value == 256 def test_slice(self): interp = self.run(""" @@ -265,6 +264,7 @@ assert interp.results[0].value == 3 def test_take(self): + py.test.skip("unsupported") interp = self.run(""" a = |10| b = take(a, [1, 1, 3, 2]) 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 @@ -1519,7 +1519,7 @@ assert (a == [1, 1]).all() def test_int_array_index(self): - from numpypy import array, arange + from numpypy import array, arange, zeros b = arange(10)[array([3, 2, 1, 5])] assert (b == [3, 2, 1, 5]).all() raises(IndexError, "arange(10)[array([10])]") @@ -1528,6 +1528,7 @@ a = arange(1) a[[0, 0]] += 1 assert a[0] == 1 + assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): from numpypy import array, arange, zeros @@ -1999,6 +2000,7 @@ def test_int_array_index(self): from _numpypy import array + assert (array([])[[]] == []).all() a = array([[1, 2], [3, 4], [5, 6]]) assert (a[slice(0, 3), [0, 0]] == [[1, 1], [3, 3], [5, 5]]).all() assert (a[array([0, 2]), slice(0, 2)] == [[1, 2], [5, 6]]).all() 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 @@ -4,18 +4,12 @@ """ import py -py.test.skip("this is going away") - from pypy.jit.metainterp import pyjitpl from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp.warmspot import reset_stats from pypy.module.micronumpy import interp_boxes -from pypy.module.micronumpy.compile import (FakeSpace, - IntObject, Parser, InterpreterState) -from pypy.module.micronumpy.interp_numarray import (W_NDimArray, - BaseArray, W_FlatIterator) -from pypy.rlib.nonconst import NonConstant - +from pypy.module.micronumpy.compile import FakeSpace, Parser, InterpreterState +from pypy.module.micronumpy.base import W_NDimArray class TestNumpyJIt(LLJitMixin): graph = None @@ -51,11 +45,8 @@ if not len(interp.results): raise Exception("need results") w_res = interp.results[-1] - if isinstance(w_res, BaseArray): - concr = w_res.get_concrete_or_scalar() - sig = concr.find_sig() - frame = sig.create_frame(concr) - w_res = sig.eval(frame, concr) + if isinstance(w_res, W_NDimArray): + w_res = w_res.create_iter().getitem() if isinstance(w_res, interp_boxes.W_Float64Box): return w_res.value if isinstance(w_res, interp_boxes.W_Int64Box): @@ -73,6 +64,7 @@ self.__class__.graph = graph reset_stats() pyjitpl._warmrunnerdesc.memory_manager.alive_loops.clear() + py.test.skip("don't run for now") return self.interp.eval_graph(self.graph, [i]) def define_add(): 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 @@ -79,7 +79,7 @@ except ExitFrame: return self.popvalue() - def jump_absolute(self, jumpto, _, ec=None): + def jump_absolute(self, jumpto, ec): if we_are_jitted(): # # assume that only threads are using the bytecode counter diff --git a/pypy/module/pypyjit/test_pypy_c/test_exception.py b/pypy/module/pypyjit/test_pypy_c/test_exception.py --- a/pypy/module/pypyjit/test_pypy_c/test_exception.py +++ b/pypy/module/pypyjit/test_pypy_c/test_exception.py @@ -95,7 +95,6 @@ def test_continue_in_finally(self): # check that 'continue' inside a try:finally: block is correctly # detected as closing a loop - py.test.skip("is this case important?") def f(n): i = 0 while 1: @@ -110,10 +109,9 @@ assert log.result == 2001 loop, = log.loops_by_filename(self.filepath) assert loop.match(""" - i40 = int_add_ovf(i31, 1) - guard_no_overflow(descr=...) - i41 = int_lt(i40, i33) - guard_true(i41, descr=...) + i3 = int_lt(i1, i2) + guard_true(i3, descr=...) + i4 = int_add(i1, 1) --TICK-- jump(..., descr=...) """) diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,7 +1,8 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import PyCode, BytecodeCorruption +from pypy.interpreter.pycode import (PyCode, BytecodeCorruption, cpython_magic, + cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) from pypy.interpreter.astcompiler.consts import CO_GENERATOR @@ -12,6 +13,57 @@ """ opnames = host_bytecode_spec.method_names + def __init__(self, space, argcount, nlocals, stacksize, flags, + code, consts, names, varnames, filename, + name, firstlineno, lnotab, freevars, cellvars, + hidden_applevel=False, magic=cpython_magic): + """Initialize a new code object""" + self.space = space + self.co_name = name + assert nlocals >= 0 + self.co_argcount = argcount + self.co_nlocals = nlocals + self.co_stacksize = stacksize + self.co_flags = flags + self.co_code = code + self.co_consts_w = consts + self.co_names_w = [space.wrap(aname) for aname in names] + self.co_varnames = varnames + self.co_freevars = freevars + self.co_cellvars = cellvars + self.co_filename = filename + self.co_name = name + self.co_firstlineno = firstlineno + self.co_lnotab = lnotab + self.hidden_applevel = hidden_applevel + self.magic = magic + self._signature = cpython_code_signature(self) + self._initialize() + + def _initialize(self): + # Precompute what arguments need to be copied into cellvars + self._args_as_cellvars = [] + + if self.co_cellvars: + argcount = self.co_argcount + assert argcount >= 0 # annotator hint + if self.co_flags & CO_VARARGS: + argcount += 1 + if self.co_flags & CO_VARKEYWORDS: + argcount += 1 + # Cell vars could shadow already-set arguments. + # See comment in PyCode._initialize() + argvars = self.co_varnames + cellvars = self.co_cellvars + for i in range(len(cellvars)): + cellname = cellvars[i] + for j in range(argcount): + if cellname == argvars[j]: + # argument j has the same name as the cell var i + while len(self._args_as_cellvars) <= i: + self._args_as_cellvars.append(-1) # pad + self._args_as_cellvars[i] = j + def read(self, pos): """ Decode the instruction starting at position ``next_instr``. diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -1,19 +1,17 @@ import collections -import sys from pypy.tool.error import source_lines -from pypy.interpreter.error import OperationError -from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter import pyframe from pypy.interpreter.nestedscope import Cell -from pypy.interpreter.pycode import CO_OPTIMIZED, CO_NEWLOCALS +from pypy.interpreter.pycode import CO_NEWLOCALS from pypy.interpreter.argument import ArgumentsForTranslation -from pypy.interpreter.pyopcode import (Return, Yield, SuspendedUnroller, - SReturnValue, SApplicationException, BytecodeCorruption, - RaiseWithExplicitTraceback) -from pypy.objspace.flow.model import * +from pypy.interpreter.pyopcode import Return, BytecodeCorruption +from pypy.objspace.flow.model import (Constant, Variable, Block, Link, + UnwrapException, SpaceOperation, FunctionGraph, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, recursively_flatten) from pypy.objspace.flow.bytecode import HostCode +from pypy.objspace.flow.specialcase import (rpython_print_item, + rpython_print_newline) class FlowingError(Exception): """ Signals invalid RPython in the function being analysed""" @@ -27,16 +25,14 @@ msg += source_lines(self.frame.graph, None, offset=self.frame.last_instr) return "\n".join(msg) - class StopFlowing(Exception): pass -class FSException(OperationError): - def __init__(self, w_type, w_value, tb=None): +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 - self._application_traceback = tb def get_w_value(self, _): return self.w_value @@ -44,45 +40,6 @@ def __str__(self): return '[%s: %s]' % (self.w_type, self.w_value) - def normalize_exception(self, space): - """Normalize the OperationError. In other words, fix w_type and/or - w_value to make sure that the __class__ of w_value is exactly w_type. - """ - w_type = self.w_type - w_value = self.w_value - if space.exception_is_valid_obj_as_class_w(w_type): - # this is for all cases of the form (Class, something) - if space.is_w(w_value, space.w_None): - # raise Type: we assume we have to instantiate Type - w_value = space.call_function(w_type) - w_type = self._exception_getclass(space, w_value) - else: - w_valuetype = space.exception_getclass(w_value) - if space.exception_issubclass_w(w_valuetype, w_type): - # raise Type, Instance: let etype be the exact type of value - w_type = w_valuetype - else: - # raise Type, X: assume X is the constructor argument - w_value = space.call_function(w_type, w_value) - w_type = self._exception_getclass(space, w_value) - - else: - # the only case left here is (inst, None), from a 'raise inst'. - w_inst = w_type - w_instclass = self._exception_getclass(space, w_inst) - if not space.is_w(w_value, space.w_None): - raise FSException(space.w_TypeError, - space.wrap("instance exception may not " - "have a separate value")) - w_value = w_inst - w_type = w_instclass - - self.w_type = w_type - self.w_value = w_value - -class OperationThatShouldNotBePropagatedError(FSException): - pass - class ImplicitOperationError(FSException): pass @@ -262,6 +219,20 @@ # ____________________________________________________________ +compare_method = [ + "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", + ] + class FlowSpaceFrame(pyframe.CPythonFrame): def __init__(self, space, func, constargs=None): @@ -497,38 +468,68 @@ res = getattr(self, methodname)(oparg, next_instr) if res is not None: next_instr = res - except OperationThatShouldNotBePropagatedError, e: - raise Exception( - 'found an operation that always raises %s: %s' % ( - self.space.unwrap(e.w_type).__name__, - self.space.unwrap(e.w_value))) except FSException, operr: - self.attach_traceback(operr) next_instr = self.handle_operation_error(operr) - except RaiseWithExplicitTraceback, e: - next_instr = self.handle_operation_error(e.operr) return next_instr - def attach_traceback(self, operr): - if self.pycode.hidden_applevel: - return - tb = operr.get_traceback() - tb = PyTraceback(self.space, self, self.last_instr, tb) - operr.set_traceback(tb) - def handle_operation_error(self, operr): - block = self.unrollstack(SFlowException.kind) + block = self.unrollstack(SApplicationException.kind) if block is None: - # no handler found for the exception - # try to preserve the CPython-level traceback - import sys - tb = sys.exc_info()[2] - raise operr, None, tb + raise operr else: - unroller = SFlowException(operr) + unroller = SApplicationException(operr) next_instr = block.handle(self, unroller) return next_instr + def BAD_OPCODE(self, _, next_instr): + raise FlowingError(self, "This operation is not RPython") + + def BREAK_LOOP(self, oparg, next_instr): + return self.unrollstack_and_jump(SBreakLoop.singleton) + + def CONTINUE_LOOP(self, startofloop, next_instr): + unroller = SContinueLoop(startofloop) + return self.unrollstack_and_jump(unroller) + + 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)) + + def cmp_exc_match(self, w_1, w_2): + return self.space.newbool(self.space.exception_match(w_1, w_2)) + + def COMPARE_OP(self, testnum, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = getattr(self, compare_method[testnum])(w_1, w_2) + self.pushvalue(w_result) + def RAISE_VARARGS(self, nbargs, next_instr): space = self.space if nbargs == 0: @@ -538,7 +539,7 @@ # re-raising an implicit operation makes it an explicit one operr = FSException(operr.w_type, operr.w_value) self.last_exception = operr - raise RaiseWithExplicitTraceback(operr) + raise operr else: raise FSException(space.w_TypeError, space.wrap("raise: no active exception to re-raise")) @@ -550,8 +551,7 @@ w_value = self.popvalue() if 1: w_type = self.popvalue() - operror = FSException(w_type, w_value) - operror.normalize_exception(space) + operror = space.exc_from_raise(w_type, w_value) raise operror def IMPORT_NAME(self, nameindex, next_instr): @@ -580,17 +580,45 @@ return next_instr # now inside a 'finally' block def END_FINALLY(self, oparg, next_instr): - unroller = self.end_finally() - if isinstance(unroller, SuspendedUnroller): - # go on unrolling the stack - block = self.unrollstack(unroller.kind) - if block is None: - w_result = unroller.nomoreblocks() - self.pushvalue(w_result) - raise Return - else: - next_instr = block.handle(self, unroller) - return next_instr + # unlike CPython, there are two statically distinct cases: the + # END_FINALLY might be closing an 'except' block or a 'finally' + # block. In the first case, the stack contains three items: + # [exception type we are now handling] + # [exception value we are now handling] + # [wrapped 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] + w_top = self.popvalue() + if w_top == self.space.w_None: + # finally: block with no unroller active + return + try: + unroller = self.space.unwrap(w_top) + except UnwrapException: + pass + else: + if isinstance(unroller, SuspendedUnroller): + # case of a finally: block + return self.unroll_finally(unroller) + # case of an except: block. We popped the exception type + self.popvalue() # Now we pop the exception value + unroller = self.space.unwrap(self.popvalue()) + return self.unroll_finally(unroller) + + def unroll_finally(self, unroller): + # go on unrolling the stack + block = self.unrollstack(unroller.kind) + if block is None: + w_result = unroller.nomoreblocks() + self.pushvalue(w_result) + raise Return + else: + return block.handle(self, unroller) + + def POP_BLOCK(self, oparg, next_instr): + block = self.pop_block() + block.cleanupstack(self) # the block knows how to clean up the value stack def JUMP_ABSOLUTE(self, jumpto, next_instr): return jumpto @@ -603,11 +631,48 @@ # isn't popped straightaway. self.pushvalue(None) + PRINT_EXPR = BAD_OPCODE + PRINT_ITEM_TO = BAD_OPCODE + PRINT_NEWLINE_TO = BAD_OPCODE + + def PRINT_ITEM(self, oparg, next_instr): + w_item = self.popvalue() + w_s = self.space.do_operation('str', w_item) + self.space.appcall(rpython_print_item, w_s) + + def PRINT_NEWLINE(self, oparg, next_instr): + self.space.appcall(rpython_print_newline) + + def FOR_ITER(self, jumpby, next_instr): + w_iterator = self.peekvalue() + try: + w_nextitem = self.space.next(w_iterator) + except FSException, e: + if not self.space.exception_match(e.w_type, self.space.w_StopIteration): + raise + # iterator exhausted + self.popvalue() + next_instr += jumpby + else: + self.pushvalue(w_nextitem) + return next_instr + + def SETUP_LOOP(self, offsettoend, next_instr): + block = LoopBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + + def SETUP_EXCEPT(self, offsettoend, next_instr): + block = ExceptBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + + def SETUP_FINALLY(self, offsettoend, next_instr): + block = FinallyBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + def SETUP_WITH(self, offsettoend, next_instr): # A simpler version than the 'real' 2.7 one: # directly call manager.__enter__(), don't use special lookup functions # which don't make sense on the RPython type system. - from pypy.interpreter.pyopcode import WithBlock w_manager = self.peekvalue() w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__")) self.settopvalue(w_exit) @@ -616,10 +681,47 @@ self.lastblock = block self.pushvalue(w_result) + def WITH_CLEANUP(self, oparg, next_instr): + # Note: RPython context managers receive None in lieu of tracebacks + # and cannot suppress the exception. + # This opcode changed a lot between CPython versions + if (self.pycode.magic >= 0xa0df2ef + # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) + or self.pycode.magic >= 0xa0df2d1): + # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) + w_unroller = self.popvalue() + w_exitfunc = self.popvalue() + self.pushvalue(w_unroller) + elif self.pycode.magic >= 0xa0df28c: + # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) + w_exitfunc = self.popvalue() + w_unroller = self.peekvalue(0) + else: + raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") + + unroller = self.space.unwrap(w_unroller) + w_None = self.space.w_None + if isinstance(unroller, SApplicationException): + operr = unroller.operr + # 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) + else: + self.space.call_function(w_exitfunc, w_None, w_None, w_None) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) + def LOAD_ATTR(self, nameindex, next_instr): + "obj.attributename" + w_obj = self.popvalue() + w_attributename = self.getname_w(nameindex) + w_value = self.space.getattr(w_obj, w_attributename) + self.pushvalue(w_value) + LOOKUP_METHOD = LOAD_ATTR + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. @@ -647,23 +749,173 @@ def argument_factory(self, *args): return ArgumentsForTranslation(self.space, *args) - def call_contextmanager_exit_function(self, w_func, w_typ, w_val, w_tb): - if w_typ is not self.space.w_None: - # The annotator won't allow to merge exception types with None. - # Replace it with the exception value... - w_typ = w_val - self.space.call_function(w_func, w_typ, w_val, w_tb) - # Return None so that the flow space statically knows that we didn't - # swallow the exception - return self.space.w_None - ### Frame blocks ### -class SFlowException(SApplicationException): - """Flowspace override for SApplicationException""" +class SuspendedUnroller(object): + """Abstract base class for interpreter-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: + + WHY_NOT, OK, not this one :-) + WHY_EXCEPTION, SApplicationException + WHY_RERAISE, implemented differently, see Reraise + WHY_RETURN, SReturnValue + WHY_BREAK, SBreakLoop + WHY_CONTINUE, SContinueLoop + WHY_YIELD not needed + """ + 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): + """Signals a 'return' statement. + Argument is the wrapped object to return.""" + kind = 0x01 + def __init__(self, w_returnvalue): + self.w_returnvalue = w_returnvalue + + def nomoreblocks(self): + return self.w_returnvalue + + def state_unpack_variables(self, space): + return [self.w_returnvalue] + + @staticmethod + def state_pack_variables(space, w_returnvalue): + return SReturnValue(w_returnvalue) + +class SApplicationException(SuspendedUnroller): + """Signals an application-level exception + (i.e. an OperationException).""" + kind = 0x02 + def __init__(self, operr): + self.operr = operr + + def nomoreblocks(self): + raise self.operr + def state_unpack_variables(self, space): return [self.operr.w_type, self.operr.w_value] @staticmethod def state_pack_variables(space, w_type, w_value): - return SFlowException(FSException(w_type, w_value)) + return SApplicationException(FSException(w_type, w_value)) + +class SBreakLoop(SuspendedUnroller): + """Signals a 'break' statement.""" + kind = 0x04 + + def state_unpack_variables(self, space): + return [] + + @staticmethod + def state_pack_variables(space): + return SBreakLoop.singleton + +SBreakLoop.singleton = SBreakLoop() + +class SContinueLoop(SuspendedUnroller): + """Signals a 'continue' statement. + Argument is the bytecode position of the beginning of the loop.""" + kind = 0x08 + def __init__(self, jump_to): + self.jump_to = jump_to + + def state_unpack_variables(self, space): + return [space.wrap(self.jump_to)] + + @staticmethod + def state_pack_variables(space, w_jump_to): + return SContinueLoop(space.int_w(w_jump_to)) + + +class FrameBlock(object): + """Abstract base class for frame blocks from the blockstack, + used by the SETUP_XXX and POP_BLOCK opcodes.""" + + def __init__(self, frame, handlerposition, previous): + self.handlerposition = handlerposition + self.valuestackdepth = frame.valuestackdepth + self.previous = previous # this makes a linked list of blocks + + def __eq__(self, other): + return (self.__class__ is other.__class__ and + self.handlerposition == other.handlerposition and + self.valuestackdepth == other.valuestackdepth) + + def __ne__(self, other): + return not (self == other) + + def __hash__(self): + return hash((self.handlerposition, self.valuestackdepth)) + + def cleanupstack(self, frame): + frame.dropvaluesuntil(self.valuestackdepth) + + def handle(self, frame, unroller): + raise NotImplementedError + +class LoopBlock(FrameBlock): + """A loop block. Stores the end-of-loop pointer in case of 'break'.""" + + _opname = 'SETUP_LOOP' + handling_mask = SBreakLoop.kind | SContinueLoop.kind + + def handle(self, frame, unroller): + if isinstance(unroller, SContinueLoop): + # 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 + frame.append_block(self) + return unroller.jump_to + else: + # jump to the end of the loop + self.cleanupstack(frame) + return self.handlerposition + +class ExceptBlock(FrameBlock): + """An try:except: block. Stores the position of the exception handler.""" + + _opname = 'SETUP_EXCEPT' + handling_mask = SApplicationException.kind + + 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) + operationerr = unroller.operr + # the stack setup is slightly different than in CPython: + # instead of the traceback, we store the unroller object, + # wrapped. + frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(operationerr.get_w_value(frame.space)) + frame.pushvalue(operationerr.w_type) + frame.last_exception = operationerr + return self.handlerposition # jump to the handler + +class FinallyBlock(FrameBlock): + """A try:finally: block. Stores the position of the exception handler.""" + + _opname = 'SETUP_FINALLY' + handling_mask = -1 # handles every kind of SuspendedUnroller + + def handle(self, frame, unroller): + # any abnormal reason for unrolling a finally: triggers the end of + # the block unrolling and the entering the finally: handler. + self.cleanupstack(frame) + frame.pushvalue(frame.space.wrap(unroller)) + return self.handlerposition # jump to the handler + + +class WithBlock(FinallyBlock): + + def handle(self, frame, unroller): + return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -1,4 +1,3 @@ -from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.rlib.unroll import SpecTag from pypy.objspace.flow.model import * @@ -106,6 +105,7 @@ UNPICKLE_TAGS = {} def recursively_flatten(space, lst): + from pypy.objspace.flow.flowcontext import SuspendedUnroller i = 0 while i < len(lst): item = lst[i] diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -1,14 +1,14 @@ # ______________________________________________________________________ import __builtin__ import sys -import operator import types -from pypy.interpreter.baseobjspace import ObjSpace, Wrappable -from pypy.interpreter import pyframe, argument -from pypy.objspace.flow.model import * +from pypy.interpreter.baseobjspace import ObjSpace +from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.model import (Constant, Variable, WrapException, + UnwrapException, checkgraph, SpaceOperation) from pypy.objspace.flow import operation from pypy.objspace.flow.flowcontext import (FlowSpaceFrame, fixeggblocks, - OperationThatShouldNotBePropagatedError, FSException, FlowingError) + FSException, FlowingError) from pypy.objspace.flow.specialcase import SPECIAL_CASES from pypy.rlib.unroll import unrolling_iterable, _unroller from pypy.rlib import rstackovf, rarithmetic @@ -38,47 +38,32 @@ } # ______________________________________________________________________ -class FlowObjSpace(ObjSpace): +class FlowObjSpace(object): """NOT_RPYTHON. The flow objspace space is used to produce a flow graph by recording the space operations that the interpreter generates when it interprets (the bytecode of) some function. """ + w_None = Constant(None) + builtin = Constant(__builtin__) + sys = Constant(sys) + w_False = Constant(False) + w_True = Constant(True) + w_type = Constant(type) + w_tuple = Constant(tuple) + for exc in [KeyError, ValueError, IndexError, StopIteration, + AssertionError, TypeError, AttributeError, ImportError]: + clsname = exc.__name__ + locals()['w_' + clsname] = Constant(exc) - full_exceptions = False - FrameClass = FlowSpaceFrame + # the following exceptions should not show up + # during flow graph construction + w_NameError = None + w_UnboundLocalError = None - def initialize(self): - self.w_None = Constant(None) - self.builtin = Constant(__builtin__) - self.sys = Constant(sys) - self.w_False = Constant(False) - self.w_True = Constant(True) - self.w_type = Constant(type) - self.w_tuple = Constant(tuple) - for exc in [KeyError, ValueError, IndexError, StopIteration, - AssertionError, TypeError, AttributeError, ImportError]: - clsname = exc.__name__ - setattr(self, 'w_'+clsname, Constant(exc)) - # the following exceptions are the ones that should not show up - # during flow graph construction; they are triggered by - # non-R-Pythonic constructs or real bugs like typos. - for exc in [NameError, UnboundLocalError]: - clsname = exc.__name__ - setattr(self, 'w_'+clsname, None) - self.specialcases = SPECIAL_CASES.copy() - #self.make_builtins() - #self.make_sys() - # w_str is needed because cmp_exc_match of frames checks against it, - # as string exceptions are deprecated - self.w_str = Constant(str) - # objects which should keep their SomeObjectness - self.not_really_const = NOT_REALLY_CONST - - # disable superclass methods - enter_cache_building_mode = None - leave_cache_building_mode = None - createcompiler = None + specialcases = SPECIAL_CASES + # objects which should keep their SomeObjectness + not_really_const = NOT_REALLY_CONST def is_w(self, w_one, w_two): return self.is_true(self.is_(w_one, w_two)) @@ -103,6 +88,12 @@ def newslice(self, w_start, w_stop, w_step): return self.do_operation('newslice', w_start, w_stop, w_step) + def newbool(self, b): + if b: + return self.w_True + else: + return self.w_False + def wrap(self, obj): if isinstance(obj, (Variable, Constant)): raise TypeError("already wrapped: " + repr(obj)) @@ -167,53 +158,77 @@ raise UnwrapException return obj - def interpclass_w(self, w_obj): - obj = self.unwrap(w_obj) - if isinstance(obj, Wrappable): - return obj - return None + def exception_issubclass_w(self, w_cls1, w_cls2): + return self.is_true(self.issubtype(w_cls1, w_cls2)) - def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj): + def _exception_match(self, w_exc_type, w_check_class): + """Helper for exception_match + + Handles the base case where w_check_class is a constant exception + type. """ - WARNING: this implementation is not complete at all. It's just enough - to be used by end_finally() inside pyopcode.py. - """ - return w_obj == self.w_None or (isinstance(w_obj, Constant) and - isinstance(w_obj.value, RequiredClass)) - - def getexecutioncontext(self): - return self.frame + if self.is_w(w_exc_type, w_check_class): + return True # fast path (also here to handle string exceptions) + try: + return self.exception_issubclass_w(w_exc_type, w_check_class) + except FSException, e: + if e.match(self, self.w_TypeError): # string exceptions maybe + return False + raise def exception_match(self, w_exc_type, w_check_class): + """Checks if the given exception type matches 'w_check_class'.""" try: check_class = self.unwrap(w_check_class) except UnwrapException: - raise Exception, "non-constant except guard" + raise FlowingError(self.frame, "Non-constant except guard.") if check_class in (NotImplementedError, AssertionError): raise FlowingError(self.frame, "Catching %s is not valid in RPython" % check_class.__name__) if not isinstance(check_class, tuple): # the simple case - return ObjSpace.exception_match(self, w_exc_type, w_check_class) + return self._exception_match(w_exc_type, w_check_class) # special case for StackOverflow (see rlib/rstackovf.py) if check_class == rstackovf.StackOverflow: w_real_class = self.wrap(rstackovf._StackOverflow) - return ObjSpace.exception_match(self, w_exc_type, w_real_class) + return self._exception_match(w_exc_type, w_real_class) # checking a tuple of classes for w_klass in self.fixedview(w_check_class): if self.exception_match(w_exc_type, w_klass): return True return False - def getconstclass(space, w_cls): - try: - ecls = space.unwrap(w_cls) - except UnwrapException: - pass + def exc_from_raise(self, w_type, w_value): + """ + Create a wrapped exception from the arguments of a raise statement. + + Returns an FSException object whose w_value is an instance of w_type. + """ + if self.isinstance_w(w_type, self.w_type): + # this is for all cases of the form (Class, something) + if self.is_w(w_value, self.w_None): + # raise Type: we assume we have to instantiate Type + w_value = self.call_function(w_type) + w_type = self.type(w_value) + else: + w_valuetype = self.type(w_value) + if self.exception_issubclass_w(w_valuetype, w_type): + # raise Type, Instance: let etype be the exact type of value + w_type = w_valuetype + else: + # raise Type, X: assume X is the constructor argument + w_value = self.call_function(w_type, w_value) + w_type = self.type(w_value) else: - if isinstance(ecls, (type, types.ClassType)): - return ecls - return None + # the only case left here is (inst, None), from a 'raise inst'. + w_inst = w_type + w_instclass = self.type(w_inst) + if not self.is_w(w_value, self.w_None): + raise FSException(self.w_TypeError, self.wrap( + "instance exception may not have a separate value")) + w_value = w_inst + w_type = w_instclass + return FSException(w_type, w_value) def build_flow(self, func, constargs={}, tweak_for_generator=True): """ @@ -232,7 +247,7 @@ def fixedview(self, w_tuple, expected_length=None): return self.unpackiterable(w_tuple, expected_length) - listview = fixedview + listview = fixedview_unroll = fixedview From noreply at buildbot.pypy.org Wed Oct 3 00:44:02 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 3 Oct 2012 00:44:02 +0200 (CEST) Subject: [pypy-commit] pypy py3k: rpython fix Message-ID: <20121002224402.13EE21C00EC@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57753:046240dc8f86 Date: 2012-10-03 00:39 +0200 http://bitbucket.org/pypy/pypy/changeset/046240dc8f86/ Log: rpython fix diff --git a/pypy/module/_csv/interp_writer.py b/pypy/module/_csv/interp_writer.py --- a/pypy/module/_csv/interp_writer.py +++ b/pypy/module/_csv/interp_writer.py @@ -39,7 +39,7 @@ for field_index in range(len(fields_w)): w_field = fields_w[field_index] if space.is_w(w_field, space.w_None): - field = "" + field = u"" elif space.isinstance_w(w_field, space.w_float): field = space.unicode_w(space.repr(w_field)) else: From noreply at buildbot.pypy.org Wed Oct 3 00:44:03 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 3 Oct 2012 00:44:03 +0200 (CEST) Subject: [pypy-commit] pypy py3k: rpython fix: use unicode strings for error messages, because we need to use %s on unicode args Message-ID: <20121002224403.6CD361C00EC@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57754:c8036c0dd50b Date: 2012-10-03 00:43 +0200 http://bitbucket.org/pypy/pypy/changeset/c8036c0dd50b/ Log: rpython fix: use unicode strings for error messages, because we need to use %s on unicode args diff --git a/pypy/module/_csv/interp_reader.py b/pypy/module/_csv/interp_reader.py --- a/pypy/module/_csv/interp_reader.py +++ b/pypy/module/_csv/interp_reader.py @@ -26,7 +26,7 @@ def error(self, msg): space = self.space - msg = 'line %d: %s' % (self.line_num, msg) + msg = u'line %d: %s' % (self.line_num, msg) w_module = space.getbuiltinmodule('_csv') w_error = space.getattr(w_module, space.wrap('Error')) raise OperationError(w_error, space.wrap(msg)) @@ -35,7 +35,7 @@ def add_char(self, field_builder, c): assert field_builder is not None if field_builder.getlength() >= field_limit.limit: - raise self.error("field larger than field limit") + raise self.error(u"field larger than field limit") field_builder.append(c) def save_field(self, field_builder): @@ -72,7 +72,7 @@ (len(field_builder.build()) > 0 or state == IN_QUOTED_FIELD)): if dialect.strict: - raise self.error("newline inside string") + raise self.error(u"newline inside string") else: self.save_field(field_builder) break @@ -81,7 +81,7 @@ line = space.unicode_w(w_line) for c in line: if c == u'\0': - raise self.error("line contains NULL byte") + raise self.error(u"line contains NULL byte") if state == START_RECORD: if c == u'\n' or c == u'\r': @@ -180,14 +180,14 @@ state = IN_FIELD else: # illegal - raise self.error("'%s' expected after '%s'" % ( + raise self.error(u"'%s' expected after '%s'" % ( dialect.delimiter, dialect.quotechar)) elif state == EAT_CRNL: if not (c == u'\n' or c == u'\r'): - raise self.error("new-line character seen in unquoted " - "field - do you need to open the file " - "in universal-newline mode?") + raise self.error(u"new-line character seen in unquoted " + u"field - do you need to open the file " + u"in universal-newline mode?") if state == IN_FIELD or state == QUOTE_IN_QUOTED_FIELD: self.save_field(field_builder) From noreply at buildbot.pypy.org Wed Oct 3 01:11:39 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 3 Oct 2012 01:11:39 +0200 (CEST) Subject: [pypy-commit] pypy length-hint: restore iadd__List_List, it's still needed to override add__List_List Message-ID: <20121002231139.6B3771C03F2@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: length-hint Changeset: r57755:3eea894217c9 Date: 2012-10-02 16:11 -0700 http://bitbucket.org/pypy/pypy/changeset/3eea894217c9/ Log: restore iadd__List_List, it's still needed to override add__List_List 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 @@ -1189,6 +1189,10 @@ raise return w_list1 +def inplace_add__List_List(space, w_list1, w_list2): + list_extend__List_ANY(space, w_list1, w_list2) + return w_list1 + def mul_list_times(space, w_list, w_times): try: times = space.getindex_w(w_times, space.w_OverflowError) From noreply at buildbot.pypy.org Wed Oct 3 01:59:47 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 3 Oct 2012 01:59:47 +0200 (CEST) Subject: [pypy-commit] pypy length-hint: avoid the contextlib import here entirely as it complicates a few tests Message-ID: <20121002235947.5EE081C00EC@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: length-hint Changeset: r57756:270bd0593d3f Date: 2012-10-02 16:58 -0700 http://bitbucket.org/pypy/pypy/changeset/270bd0593d3f/ Log: avoid the contextlib import here entirely as it complicates a few tests diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py --- a/pypy/module/__builtin__/app_functional.py +++ b/pypy/module/__builtin__/app_functional.py @@ -73,7 +73,7 @@ # this can be eliminated if we could unroll that loop that creates # `args` based on whether or not len(collections) was constant seq = collections[0] - with _managed_newlist_hint(operator._length_hint(seq, 0)) as result: + with _ManagedNewlistHint(operator._length_hint(seq, 0)) as result: for item in seq: result.append(func(item)) return result @@ -86,7 +86,7 @@ iterators.append((iter(seq), False)) max_hint = max(max_hint, operator._length_hint(seq, 0)) - with _managed_newlist_hint(max_hint) as result: + with _ManagedNewlistHint(max_hint) as result: while True: cont = False args = [] @@ -115,23 +115,27 @@ resizelist_hint(result, length_hint) return result -def _managed_newlist_hint(length_hint): +class _ManagedNewlistHint(object): + """Context manager returning a _newlist_hint upon entry. Upon exit the list's underlying capacity will be cut back to match its length if necessary (incase the initial length_hint was too large). """ - # hack: can't import contextlib.contextmanager at the global level - from contextlib import contextmanager - @contextmanager - def _do_managed_newlist_hint(length_hint): - result = _newlist_hint(length_hint) - yield result - extended = len(result) - if extended < length_hint: - resizelist_hint(result, extended) - return _do_managed_newlist_hint(length_hint) + + def __init__(self, length_hint): + self.length_hint = length_hint + self.list = _newlist_hint(length_hint) + + def __enter__(self): + return self.list + + def __exit__(self, type, value, tb): + if type is None: + extended = len(self.list) + if extended < self.length_hint: + resizelist_hint(self.list, extended) sentinel = object() @@ -169,7 +173,7 @@ return _filter_string(func, seq, unicode) elif isinstance(seq, tuple): return _filter_tuple(func, seq) - with _managed_newlist_hint(operator._length_hint(seq, 0)) as result: + with _ManagedNewlistHint(operator._length_hint(seq, 0)) as result: for item in seq: if func(item): result.append(item) @@ -219,7 +223,7 @@ if min_hint == -1 or hint < min_hint: min_hint = hint - with _managed_newlist_hint(min_hint) as result: + with _ManagedNewlistHint(min_hint) as result: while True: try: items = [next(it) for it in iterators] From noreply at buildbot.pypy.org Wed Oct 3 08:15:06 2012 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 3 Oct 2012 08:15:06 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: revert attempt to fix, test issue1275 - test was bogus Message-ID: <20121003061506.5F6CF1C00EE@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-complex2 Changeset: r57757:8a750e1d53b2 Date: 2012-10-03 08:14 +0200 http://bitbucket.org/pypy/pypy/changeset/8a750e1d53b2/ Log: revert attempt to fix, test issue1275 - test was bogus diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -154,11 +154,6 @@ expected = eval("0 %s 11" % operator) yield self.simple_test, "x = 0 %s 11" % operator, "x", expected - def test_pow(self): - expected = eval("complex(float('inf'), 0.) ** complex(10., 3.0)") - yield self.simple_test, \ - "x = complex(float('inf'), 0.) ** complex(10., 3.0)", "x", expected - def test_compare(self): yield self.st, "x = 2; y = 5; y; h = 1 < x >= 3 < x", "h", False diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -229,8 +229,6 @@ raise OperationError(space.w_ZeroDivisionError, space.wrap("0.0 to a negative or complex power")) except OverflowError: raise OperationError(space.w_OverflowError, space.wrap("complex exponentiation")) - except ValueError as e: - raise OperationError(space.w_ValueError, space.wrap(e.message)) return w_p def neg__Complex(space, w_complex): From noreply at buildbot.pypy.org Wed Oct 3 08:19:21 2012 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 3 Oct 2012 08:19:21 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: merge default into branch Message-ID: <20121003061921.742F61C00EE@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-complex2 Changeset: r57758:e10e0328f0f5 Date: 2012-10-03 08:18 +0200 http://bitbucket.org/pypy/pypy/changeset/e10e0328f0f5/ Log: merge default into branch diff too long, truncating to 2000 out of 2776 lines diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -23,7 +23,7 @@ The tools required to cross translate from a Linux based host to an ARM based Linux target are: -- A checkout of PyPy's arm-backend-2 branch. +- A checkout of PyPy (default branch). - The GCC ARM cross compiler (on Ubuntu it is the ``gcc-arm-linux-gnueabi package``) but other toolchains should also work. - Scratchbox 2, a cross-compilation engine (``scratchbox2`` Ubuntu package). - A 32-bit PyPy or Python. @@ -147,4 +147,4 @@ return 0 def target(*args): - return main, None \ No newline at end of file + return main, None diff --git a/pypy/doc/config/objspace.usemodules._csv.txt b/pypy/doc/config/objspace.usemodules._csv.txt new file mode 100644 --- /dev/null +++ b/pypy/doc/config/objspace.usemodules._csv.txt @@ -0,0 +1,2 @@ +Implementation in RPython for the core of the 'csv' module + diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -115,13 +115,16 @@ which data structures would be more appropriate? For example, a dict implemented as a hash table will suffer "stm collisions" in all threads whenever one thread writes anything to it; but there could be other - implementations. + implementations. Maybe alternate strategies can be implemented at the + level of the Python interpreter (see list/dict strategies, + ``pypy/objspace/std/{list,dict}object.py``). * More generally, there is the idea that we would need some kind of "debugger"-like tool to "debug" things that are not bugs, but stm conflicts. How would this tool look like to the end Python programmers? Like a profiler? Or like a debugger with breakpoints - on aborted transactions? + on aborted transactions? It would probably be all app-level, with + a few hooks e.g. for transaction conflicts. * Find good ways to have libraries using internally threads and atomics, but not exposing threads to the user. Right now there is a rough draft 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 @@ -18,6 +18,7 @@ .. branch: numpypy_count_nonzero .. branch: numpy-refactor Remove numpy lazy evaluation and simplify everything +.. branch: numpy-reintroduce-jit-drivers .. branch: numpy-fancy-indexing Support for array[array-of-ints] in numpy .. branch: even-more-jit-hooks 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 @@ -474,7 +474,7 @@ if f_type == F_BLOCK_LOOP: self.emit_jump(ops.CONTINUE_LOOP, block, True) break - if self.frame_blocks[i][0] == F_BLOCK_FINALLY_END: + if f_type == F_BLOCK_FINALLY_END: self.error("'continue' not supported inside 'finally' " \ "clause", cont) diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -153,7 +153,7 @@ yield self.simple_test, "x = 17 %s 5" % operator, "x", expected expected = eval("0 %s 11" % operator) yield self.simple_test, "x = 0 %s 11" % operator, "x", expected - + def test_compare(self): yield self.st, "x = 2; y = 5; y; h = 1 < x >= 3 < x", "h", False diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -208,11 +208,11 @@ def int_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def bigint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -292,8 +292,6 @@ """Base class for the interpreter-level implementations of object spaces. http://pypy.readthedocs.org/en/latest/objspace.html""" - full_exceptions = True # full support for exceptions (normalization & more) - def __init__(self, config=None): "NOT_RPYTHON: Basic initialization of objects." self.fromcache = InternalSpaceCache(self).getorbuild @@ -1124,13 +1122,9 @@ def exception_is_valid_obj_as_class_w(self, w_obj): if not self.isinstance_w(w_obj, self.w_type): return False - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_obj, self.w_BaseException)) def exception_is_valid_class_w(self, w_cls): - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_cls, self.w_BaseException)) def exception_getclass(self, w_obj): @@ -1381,7 +1375,7 @@ if not self.is_true(self.isinstance(w_obj, self.w_str)): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) - return self.str_w(w_obj) + return self.str_w(w_obj) def unicode_w(self, w_obj): return w_obj.unicode_w(self) @@ -1702,7 +1696,7 @@ 'ValueError', 'ZeroDivisionError', ] - + if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -45,11 +45,6 @@ def async(self, space): "Check if this is an exception that should better not be caught." - if not space.full_exceptions: - # flow objspace does not support such exceptions and more - # importantly, raises KeyboardInterrupt if you try to access - # space.w_KeyboardInterrupt - return False return (self.match(space, space.w_SystemExit) or self.match(space, space.w_KeyboardInterrupt)) @@ -166,9 +161,7 @@ # Or 'Class' can also be an old-style class and 'inst' an old-style # instance of it. # - # Note that 'space.full_exceptions' is set to False by the flow - # object space; in this case we must assume that we are in a - # non-advanced case, and ignore the advanced cases. Old-style + # The flow object space only deals with non-advanced case. Old-style # classes and instances *are* advanced. # # input (w_type, w_value)... becomes... advanced case? @@ -183,9 +176,8 @@ # w_type = self.w_type w_value = self.get_w_value(space) - if space.full_exceptions: - while space.is_true(space.isinstance(w_type, space.w_tuple)): - w_type = space.getitem(w_type, space.wrap(0)) + while space.is_true(space.isinstance(w_type, space.w_tuple)): + w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): # this is for all cases of the form (Class, something) @@ -199,8 +191,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.full_exceptions and space.is_true( - space.isinstance(w_value, space.w_tuple)): + if space.is_true(space.isinstance(w_value, space.w_tuple)): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -944,14 +944,6 @@ def appcaller(space, *args_w): if not isinstance(space, ObjSpace): raise TypeError("first argument must be a space instance.") - # redirect if the space handles this specially - # XXX can this be factored a bit less flow space dependently? - if hasattr(space, 'specialcases'): - sc = space.specialcases - if ApplevelClass in sc: - ret_w = sc[ApplevelClass](space, self, name, args_w) - if ret_w is not None: # it was RPython - return ret_w # the last argument can be an Arguments w_func = self.wget(space, name) if not args_w: diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -223,7 +223,7 @@ return next_instr if opcode == self.opcodedesc.JUMP_ABSOLUTE.index: - return self.jump_absolute(oparg, next_instr, ec) + return self.jump_absolute(oparg, ec) if we_are_translated(): for opdesc in unrolling_all_opcode_descs: @@ -557,7 +557,7 @@ w_type = self.popvalue() operror = OperationError(w_type, w_value) operror.normalize_exception(space) - if not space.full_exceptions or space.is_w(w_traceback, space.w_None): + if space.is_w(w_traceback, space.w_None): # common case raise operror else: @@ -858,7 +858,8 @@ def YIELD_VALUE(self, oparg, next_instr): raise Yield - def jump_absolute(self, jumpto, next_instr, ec): + def jump_absolute(self, jumpto, ec): + # this function is overridden by pypy.module.pypyjit.interp_jit check_nonneg(jumpto) return jumpto @@ -944,21 +945,9 @@ def WITH_CLEANUP(self, oparg, next_instr): # see comment in END_FINALLY for stack state - # This opcode changed a lot between CPython versions - if (self.pycode.magic >= 0xa0df2ef - # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) - or self.pycode.magic >= 0xa0df2d1): - # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) - w_unroller = self.popvalue() - w_exitfunc = self.popvalue() - self.pushvalue(w_unroller) - elif self.pycode.magic >= 0xa0df28c: - # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) - w_exitfunc = self.popvalue() - w_unroller = self.peekvalue(0) - else: - raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") - + w_unroller = self.popvalue() + w_exitfunc = self.popvalue() + self.pushvalue(w_unroller) unroller = self.space.interpclass_w(w_unroller) is_app_exc = (unroller is not None and isinstance(unroller, SApplicationException)) @@ -1192,10 +1181,6 @@ 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): """Signals a 'return' statement. Argument is the wrapped object to return.""" @@ -1206,12 +1191,6 @@ def nomoreblocks(self): return self.w_returnvalue - def state_unpack_variables(self, space): - return [self.w_returnvalue] - def state_pack_variables(space, w_returnvalue): - return SReturnValue(w_returnvalue) - state_pack_variables = staticmethod(state_pack_variables) - class SApplicationException(SuspendedUnroller): """Signals an application-level exception (i.e. an OperationException).""" @@ -1226,13 +1205,6 @@ """Signals a 'break' statement.""" _immutable_ = True kind = 0x04 - - def state_unpack_variables(self, space): - return [] - def state_pack_variables(space): - return SBreakLoop.singleton - state_pack_variables = staticmethod(state_pack_variables) - SBreakLoop.singleton = SBreakLoop() class SContinueLoop(SuspendedUnroller): @@ -1243,12 +1215,6 @@ def __init__(self, jump_to): self.jump_to = jump_to - def state_unpack_variables(self, space): - return [space.wrap(self.jump_to)] - def state_pack_variables(space, w_jump_to): - return SContinueLoop(space.int_w(w_jump_to)) - state_pack_variables = staticmethod(state_pack_variables) - class FrameBlock(object): """Abstract base class for frame blocks from the blockstack, @@ -1303,7 +1269,9 @@ # and jump to the beginning of the loop, stored in the # exception's argument frame.append_block(self) - return r_uint(unroller.jump_to) + jumpto = unroller.jump_to + ec = frame.space.getexecutioncontext() + return r_uint(frame.jump_absolute(jumpto, ec)) else: # jump to the end of the loop self.cleanupstack(frame) @@ -1323,8 +1291,7 @@ self.cleanupstack(frame) assert isinstance(unroller, SApplicationException) operationerr = unroller.operr - if frame.space.full_exceptions: - operationerr.normalize_exception(frame.space) + operationerr.normalize_exception(frame.space) # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. @@ -1356,8 +1323,7 @@ _immutable_ = True def handle(self, frame, unroller): - if (frame.space.full_exceptions and - isinstance(unroller, SApplicationException)): + if isinstance(unroller, SApplicationException): unroller.operr.normalize_exception(frame.space) return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -131,13 +131,13 @@ def get_latest_value_float(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a float.""" + or from 'args' if it was a FINISH). Returns a FLOATSTORAGE.""" raise NotImplementedError def get_latest_value_ref(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a ptr or an obj.""" + or from 'args' if it was a FINISH). Returns a GCREF.""" raise NotImplementedError def get_latest_value_count(self): diff --git a/pypy/jit/metainterp/optimizeopt/util.py b/pypy/jit/metainterp/optimizeopt/util.py --- a/pypy/jit/metainterp/optimizeopt/util.py +++ b/pypy/jit/metainterp/optimizeopt/util.py @@ -2,9 +2,10 @@ from pypy.rlib.objectmodel import r_dict, compute_identity_hash from pypy.rlib.rarithmetic import intmask from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp import resoperation, history +from pypy.jit.metainterp import resoperation from pypy.rlib.debug import make_sure_not_resized from pypy.jit.metainterp.resoperation import rop +from pypy.rlib.objectmodel import we_are_translated # ____________________________________________________________ # Misc. utilities @@ -28,13 +29,20 @@ def make_dispatcher_method(Class, name_prefix, op_prefix=None, default=None): ops = _findall(Class, name_prefix, op_prefix) def dispatch(self, op, *args): - opnum = op.getopnum() - for value, cls, func in ops: - if opnum == value: - assert isinstance(op, cls) + if we_are_translated(): + opnum = op.getopnum() + for value, cls, func in ops: + if opnum == value: + assert isinstance(op, cls) + return func(self, op, *args) + if default: + return default(self, op, *args) + else: + func = getattr(Class, name_prefix + op.getopname().upper(), None) + if func is not None: return func(self, op, *args) - if default: - return default(self, op, *args) + if default: + return default(self, op, *args) dispatch.func_name = "dispatch_" + name_prefix return dispatch diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py --- a/pypy/jit/metainterp/test/test_ajit.py +++ b/pypy/jit/metainterp/test/test_ajit.py @@ -2028,6 +2028,7 @@ y -= 1 return res def g(x, y): + set_param(myjitdriver, 'max_unroll_loops', 5) a1 = f(A(x), y) a2 = f(A(x), y) b1 = f(B(x), y) diff --git a/pypy/jit/metainterp/test/test_send.py b/pypy/jit/metainterp/test/test_send.py --- a/pypy/jit/metainterp/test/test_send.py +++ b/pypy/jit/metainterp/test/test_send.py @@ -1,5 +1,5 @@ import py -from pypy.rlib.jit import JitDriver, promote, elidable +from pypy.rlib.jit import JitDriver, promote, elidable, set_param from pypy.jit.codewriter.policy import StopAtXPolicy from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin @@ -181,6 +181,7 @@ def getvalue(self): return self.y def f(x, y): + set_param(myjitdriver, 'max_unroll_loops', 5) if x & 1: w = W1(x) else: @@ -226,6 +227,7 @@ w2 = W2(20) def f(x, y): + set_param(myjitdriver, 'max_unroll_loops', 5) if x & 1: w = w1 else: diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -286,8 +286,8 @@ for i, cf in enumerate(ctype.fields_list): if cf.is_bitfield(): raise OperationError(space.w_NotImplementedError, - space.wrap("cannot pass as argument a struct " - "with bit fields")) + space.wrap("cannot pass as argument or return value " + "a struct with bit fields")) ffi_subtype = self.fb_fill_type(cf.ctype, False) if elements: elements[i] = ffi_subtype 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 @@ -981,7 +981,7 @@ assert strlenaddr == cast(BVoidP, strlen) def test_read_variable(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BVoidP = new_pointer_type(new_void_type()) ll = find_and_load_library('c') @@ -989,7 +989,7 @@ assert stderr == cast(BVoidP, _testfunc(8)) def test_read_variable_as_unknown_length_array(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BCharP = new_pointer_type(new_primitive_type("char")) BArray = new_array_type(BCharP, None) @@ -999,7 +999,7 @@ # ^^ and not 'char[]', which is basically not allowed and would crash def test_write_variable(): - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': py.test.skip("untested") BVoidP = new_pointer_type(new_void_type()) ll = find_and_load_library('c') diff --git a/pypy/module/_csv/interp_reader.py b/pypy/module/_csv/interp_reader.py --- a/pypy/module/_csv/interp_reader.py +++ b/pypy/module/_csv/interp_reader.py @@ -67,8 +67,15 @@ w_line = space.next(self.w_iter) except OperationError, e: if e.match(space, space.w_StopIteration): - if field_builder is not None: - raise self.error("newline inside string") + if (field_builder is not None and + state != START_RECORD and state != EAT_CRNL and + (len(field_builder.build()) > 0 or + state == IN_QUOTED_FIELD)): + if dialect.strict: + raise self.error("newline inside string") + else: + self.save_field(field_builder) + break raise self.line_num += 1 line = space.str_w(w_line) diff --git a/pypy/module/_csv/test/test_reader.py b/pypy/module/_csv/test/test_reader.py --- a/pypy/module/_csv/test/test_reader.py +++ b/pypy/module/_csv/test/test_reader.py @@ -99,3 +99,11 @@ def test_dubious_quote(self): self._read_test(['12,12,1",'], [['12', '12', '1"', '']]) + + def test_read_eof(self): + self._read_test(['a,"'], [['a', '']]) + self._read_test(['"a'], [['a']]) + self._read_test(['^'], [['\n']], escapechar='^') + self._read_test(['a,"'], 'Error', strict=True) + self._read_test(['"a'], 'Error', strict=True) + self._read_test(['^'], 'Error', escapechar='^', strict=True) diff --git a/pypy/module/_ffi/interp_funcptr.py b/pypy/module/_ffi/interp_funcptr.py --- a/pypy/module/_ffi/interp_funcptr.py +++ b/pypy/module/_ffi/interp_funcptr.py @@ -287,7 +287,11 @@ w_restype) addr = rffi.cast(rffi.VOIDP, addr) func = libffi.Func(name, argtypes, restype, addr, flags) - return W_FuncPtr(func, argtypes_w, w_restype) + try: + return W_FuncPtr(func, argtypes_w, w_restype) + except OSError: + raise OperationError(space.w_SystemError, + space.wrap("internal error building the Func object")) W_FuncPtr.typedef = TypeDef( 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 @@ -244,6 +244,7 @@ def setitem_index(self, space, index, value): self.setitem(self._lookup_by_unwrapped_index(space, index), value) + @jit.unroll_safe def _single_item_index(self, space, w_idx): """ Return an index of single item if possible, otherwise raises IndexError 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 @@ -9,8 +9,8 @@ from pypy.interpreter.error import OperationError from pypy.module.micronumpy import interp_boxes from pypy.module.micronumpy.interp_dtype import get_dtype_cache -from pypy.module.micronumpy.interp_numarray import (Scalar, BaseArray, - scalar_w, W_NDimArray, array) +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.interp_numarray import array from pypy.module.micronumpy.interp_arrayops import where from pypy.module.micronumpy import interp_ufuncs from pypy.rlib.objectmodel import specialize, instantiate @@ -148,7 +148,8 @@ def is_true(self, w_obj): assert isinstance(w_obj, BoolObject) - return w_obj.boolval + return False + #return w_obj.boolval def is_w(self, w_obj, w_what): return w_obj is w_what @@ -275,7 +276,7 @@ if isinstance(w_index, FloatObject): w_index = IntObject(int(w_index.floatval)) w_val = self.expr.execute(interp) - assert isinstance(arr, BaseArray) + assert isinstance(arr, W_NDimArray) arr.descr_setitem(interp.space, w_index, w_val) def __repr__(self): @@ -303,11 +304,11 @@ w_rhs = self.rhs.wrap(interp.space) else: w_rhs = self.rhs.execute(interp) - if not isinstance(w_lhs, BaseArray): + if not isinstance(w_lhs, W_NDimArray): # scalar dtype = get_dtype_cache(interp.space).w_float64dtype - w_lhs = scalar_w(interp.space, dtype, w_lhs) - assert isinstance(w_lhs, BaseArray) + w_lhs = W_NDimArray.new_scalar(interp.space, dtype, w_lhs) + assert isinstance(w_lhs, W_NDimArray) if self.name == '+': w_res = w_lhs.descr_add(interp.space, w_rhs) elif self.name == '*': @@ -315,17 +316,16 @@ elif self.name == '-': w_res = w_lhs.descr_sub(interp.space, w_rhs) elif self.name == '->': - assert not isinstance(w_rhs, Scalar) if isinstance(w_rhs, FloatObject): w_rhs = IntObject(int(w_rhs.floatval)) - assert isinstance(w_lhs, BaseArray) + assert isinstance(w_lhs, W_NDimArray) w_res = w_lhs.descr_getitem(interp.space, w_rhs) else: raise NotImplementedError - if (not isinstance(w_res, BaseArray) and + if (not isinstance(w_res, W_NDimArray) and not isinstance(w_res, interp_boxes.W_GenericBox)): dtype = get_dtype_cache(interp.space).w_float64dtype - w_res = scalar_w(interp.space, dtype, w_res) + w_res = W_NDimArray.new_scalar(interp.space, dtype, w_res) return w_res def __repr__(self): @@ -417,7 +417,7 @@ def execute(self, interp): arr = self.args[0].execute(interp) - if not isinstance(arr, BaseArray): + if not isinstance(arr, W_NDimArray): raise ArgumentNotAnArray if self.name in SINGLE_ARG_FUNCTIONS: if len(self.args) != 1 and self.name != 'sum': @@ -441,20 +441,21 @@ elif self.name == "unegative": neg = interp_ufuncs.get(interp.space).negative w_res = neg.call(interp.space, [arr]) + elif self.name == "cos": + cos = interp_ufuncs.get(interp.space).cos + w_res = cos.call(interp.space, [arr]) elif self.name == "flat": w_res = arr.descr_get_flatiter(interp.space) elif self.name == "tostring": arr.descr_tostring(interp.space) w_res = None - elif self.name == "count_nonzero": - w_res = arr.descr_count_nonzero(interp.space) else: assert False # unreachable code elif self.name in TWO_ARG_FUNCTIONS: if len(self.args) != 2: raise ArgumentMismatch arg = self.args[1].execute(interp) - if not isinstance(arg, BaseArray): + if not isinstance(arg, W_NDimArray): raise ArgumentNotAnArray if self.name == "dot": w_res = arr.descr_dot(interp.space, arg) @@ -467,9 +468,9 @@ raise ArgumentMismatch arg1 = self.args[1].execute(interp) arg2 = self.args[2].execute(interp) - if not isinstance(arg1, BaseArray): + if not isinstance(arg1, W_NDimArray): raise ArgumentNotAnArray - if not isinstance(arg2, BaseArray): + if not isinstance(arg2, W_NDimArray): raise ArgumentNotAnArray if self.name == "where": w_res = where(interp.space, arr, arg1, arg2) @@ -477,7 +478,7 @@ assert False else: raise WrongFunctionName - if isinstance(w_res, BaseArray): + if isinstance(w_res, W_NDimArray): return w_res if isinstance(w_res, FloatObject): dtype = get_dtype_cache(interp.space).w_float64dtype @@ -489,7 +490,7 @@ dtype = w_res.get_dtype(interp.space) else: dtype = None - return scalar_w(interp.space, dtype, w_res) + return W_NDimArray.new_scalar(interp.space, dtype, w_res) _REGEXES = [ ('-?[\d\.]+', 'number'), 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 @@ -129,6 +129,8 @@ self._prepare_array_index(space, w_index) shape = res_shape + self.get_shape()[len(indexes):] res = W_NDimArray.from_shape(shape, self.get_dtype(), self.get_order()) + if not res.get_size(): + return res return loop.getitem_array_int(space, self, res, iter_shape, indexes, prefix) @@ -516,7 +518,7 @@ if self.get_size() == 0: raise OperationError(space.w_ValueError, space.wrap("Can't call %s on zero-size arrays" % op_name)) - return space.wrap(loop.argmin_argmax(op_name, self)) + return space.wrap(getattr(loop, 'arg' + op_name)(self)) return func_with_new_name(impl, "reduce_arg%s_impl" % op_name) descr_argmax = _reduce_argmax_argmin_impl("max") 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 @@ -260,7 +260,7 @@ return out shape = shape_agreement(space, w_obj.get_shape(), out, broadcast_down=False) - return loop.call1(shape, self.func, self.name, calc_dtype, res_dtype, + return loop.call1(shape, self.func, calc_dtype, res_dtype, w_obj, out) @@ -325,7 +325,7 @@ return out 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(new_shape, self.func, self.name, calc_dtype, + return loop.call2(new_shape, self.func, calc_dtype, res_dtype, w_lhs, w_rhs, out) 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 @@ -1,21 +1,34 @@ """ This file is the main run loop as well as evaluation loops for various -signatures +operations. This is the place to look for all the computations that iterate +over all the array elements. """ -from pypy.rlib.objectmodel import specialize from pypy.rlib.rstring import StringBuilder from pypy.rlib import jit from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy.base import W_NDimArray -def call2(shape, func, name, calc_dtype, res_dtype, w_lhs, w_rhs, out): +call2_driver = jit.JitDriver(name='numpy_call2', + greens = ['shapelen', 'func', 'calc_dtype', + 'res_dtype'], + reds = ['shape', 'w_lhs', 'w_rhs', 'out', + 'left_iter', 'right_iter', 'out_iter']) + +def call2(shape, func, calc_dtype, res_dtype, w_lhs, w_rhs, out): if out is None: out = W_NDimArray.from_shape(shape, res_dtype) left_iter = w_lhs.create_iter(shape) right_iter = w_rhs.create_iter(shape) out_iter = out.create_iter(shape) + shapelen = len(shape) while not out_iter.done(): + call2_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, res_dtype=res_dtype, + shape=shape, w_lhs=w_lhs, w_rhs=w_rhs, + out=out, + left_iter=left_iter, right_iter=right_iter, + out_iter=out_iter) w_left = left_iter.getitem().convert_to(calc_dtype) w_right = right_iter.getitem().convert_to(calc_dtype) out_iter.setitem(func(calc_dtype, w_left, w_right).convert_to( @@ -25,30 +38,56 @@ out_iter.next() return out -def call1(shape, func, name, calc_dtype, res_dtype, w_obj, out): +call1_driver = jit.JitDriver(name='numpy_call1', + greens = ['shapelen', 'func', 'calc_dtype', + 'res_dtype'], + reds = ['shape', 'w_obj', 'out', 'obj_iter', + 'out_iter']) + +def call1(shape, func, calc_dtype, res_dtype, w_obj, out): if out is None: out = W_NDimArray.from_shape(shape, res_dtype) obj_iter = w_obj.create_iter(shape) out_iter = out.create_iter(shape) + shapelen = len(shape) while not out_iter.done(): + call1_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, res_dtype=res_dtype, + shape=shape, w_obj=w_obj, out=out, + obj_iter=obj_iter, out_iter=out_iter) elem = obj_iter.getitem().convert_to(calc_dtype) out_iter.setitem(func(calc_dtype, elem).convert_to(res_dtype)) out_iter.next() obj_iter.next() return out +setslice_driver = jit.JitDriver(name='numpy_setslice', + greens = ['shapelen', 'dtype'], + reds = ['target', 'source', 'target_iter', + 'source_iter']) + def setslice(shape, target, source): # note that unlike everything else, target and source here are # array implementations, not arrays target_iter = target.create_iter(shape) source_iter = source.create_iter(shape) dtype = target.dtype + shapelen = len(shape) while not target_iter.done(): + setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + target=target, source=source, + target_iter=target_iter, + source_iter=source_iter) target_iter.setitem(source_iter.getitem().convert_to(dtype)) target_iter.next() source_iter.next() return target +reduce_driver = jit.JitDriver(name='numpy_reduce', + greens = ['shapelen', 'func', 'done_func', + 'calc_dtype', 'identity'], + reds = ['obj', 'obj_iter', 'cur_value']) + def compute_reduce(obj, calc_dtype, func, done_func, identity): obj_iter = obj.create_iter(obj.get_shape()) if identity is None: @@ -56,7 +95,12 @@ obj_iter.next() else: cur_value = identity.convert_to(calc_dtype) + shapelen = len(obj.get_shape()) while not obj_iter.done(): + reduce_driver.jit_merge_point(shapelen=shapelen, func=func, + calc_dtype=calc_dtype, identity=identity, + done_func=done_func, obj=obj, + obj_iter=obj_iter, cur_value=cur_value) rval = obj_iter.getitem().convert_to(calc_dtype) if done_func is not None and done_func(calc_dtype, rval): return rval @@ -70,6 +114,11 @@ arr_iter.setitem(box) arr_iter.next() +where_driver = jit.JitDriver(name='numpy_where', + greens = ['shapelen', 'dtype', 'arr_dtype'], + reds = ['shape', 'arr', 'x', 'y','arr_iter', 'out', + 'x_iter', 'y_iter', 'iter', 'out_iter']) + def where(out, shape, arr, x, y, dtype): out_iter = out.create_iter(shape) arr_iter = arr.create_iter(shape) @@ -83,7 +132,13 @@ iter = y_iter else: iter = x_iter + shapelen = len(shape) while not iter.done(): + where_driver.jit_merge_point(shapelen=shapelen, shape=shape, + dtype=dtype, iter=iter, x_iter=x_iter, + y_iter=y_iter, arr_iter=arr_iter, + arr=arr, x=x, y=y, arr_dtype=arr_dtype, + out_iter=out_iter, out=out) w_cond = arr_iter.getitem() if arr_dtype.itemtype.bool(w_cond): w_val = x_iter.getitem().convert_to(dtype) @@ -96,12 +151,24 @@ y_iter.next() return out +axis_reduce__driver = jit.JitDriver(name='numpy_axis_reduce', + greens=['shapelen', 'func', 'dtype', + 'identity'], + reds=['axis', 'arr', 'out', 'shape', + 'out_iter', 'arr_iter']) + def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): out_iter = out.create_axis_iter(arr.get_shape(), axis) arr_iter = arr.create_iter(arr.get_shape()) if identity is not None: identity = identity.convert_to(dtype) + shapelen = len(shape) while not out_iter.done(): + axis_reduce__driver.jit_merge_point(shapelen=shapelen, func=func, + dtype=dtype, identity=identity, + axis=axis, arr=arr, out=out, + shape=shape, out_iter=out_iter, + arr_iter=arr_iter) w_val = arr_iter.getitem().convert_to(dtype) if out_iter.first_line: if identity is not None: @@ -114,23 +181,41 @@ out_iter.next() return out - at specialize.arg(0) -def argmin_argmax(op_name, arr): - result = 0 - idx = 1 - dtype = arr.get_dtype() - iter = arr.create_iter(arr.get_shape()) - cur_best = iter.getitem() - iter.next() - while not iter.done(): - w_val = iter.getitem() - new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) - if dtype.itemtype.ne(new_best, cur_best): - result = idx - cur_best = new_best + +def _new_argmin_argmax(op_name): + arg_driver = jit.JitDriver(name='numpy_' + op_name, + greens = ['shapelen', 'dtype'], + reds = ['result', 'idx', 'cur_best', 'arr', + 'iter']) + + def argmin_argmax(arr): + result = 0 + idx = 1 + dtype = arr.get_dtype() + iter = arr.create_iter(arr.get_shape()) + cur_best = iter.getitem() iter.next() - idx += 1 - return result + shapelen = len(arr.get_shape()) + while not iter.done(): + arg_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + result=result, idx=idx, + cur_best=cur_best, arr=arr, iter=iter) + w_val = iter.getitem() + new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) + if dtype.itemtype.ne(new_best, cur_best): + result = idx + cur_best = new_best + iter.next() + idx += 1 + return result + return argmin_argmax +argmin = _new_argmin_argmax('min') +argmax = _new_argmin_argmax('max') + +# note that shapelen == 2 always +dot_driver = jit.JitDriver(name = 'numpy_dot', + greens = ['dtype'], + reds = ['outi', 'lefti', 'righti', 'result']) def multidim_dot(space, left, right, result, dtype, right_critical_dim): ''' assumes left, right are concrete arrays @@ -157,6 +242,8 @@ lefti = left.create_dot_iter(broadcast_shape, left_skip) righti = right.create_dot_iter(broadcast_shape, right_skip) while not outi.done(): + dot_driver.jit_merge_point(dtype=dtype, outi=outi, lefti=lefti, + righti=righti, result=result) lval = lefti.getitem().convert_to(dtype) rval = righti.getitem().convert_to(dtype) outval = outi.getitem().convert_to(dtype) @@ -168,21 +255,45 @@ lefti.next() return result +count_all_true_driver = jit.JitDriver(name = 'numpy_count', + greens = ['shapelen', 'dtype'], + reds = ['s', 'iter']) + 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() while not iter.done(): + count_all_true_driver.jit_merge_point(shapelen=shapelen, iter=iter, + s=s, 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'], + reds = ['res', 'index_iter', 'res_iter', + 'arr_iter']) + def getitem_filter(res, arr, index): res_iter = res.create_iter() index_iter = index.create_iter() arr_iter = arr.create_iter() + shapelen = len(arr.get_shape()) + arr_dtype = arr.get_dtype() + index_dtype = index.get_dtype() + # XXX length of shape of index as well? while not index_iter.done(): + getitem_filter_driver.jit_merge_point(shapelen=shapelen, + index_dtype=index_dtype, + arr_dtype=arr_dtype, + res=res, index_iter=index_iter, + res_iter=res_iter, + arr_iter=arr_iter) if index_iter.getitem_bool(): res_iter.setitem(arr_iter.getitem()) res_iter.next() @@ -190,31 +301,63 @@ arr_iter.next() return res +setitem_filter_driver = jit.JitDriver(name = 'numpy_setitem_bool', + greens = ['shapelen', 'arr_dtype', + 'index_dtype'], + reds = ['index_iter', 'value_iter', + 'arr_iter']) + def setitem_filter(arr, index, value): arr_iter = arr.create_iter() index_iter = index.create_iter() value_iter = value.create_iter() + shapelen = len(arr.get_shape()) + index_dtype = index.get_dtype() + arr_dtype = arr.get_dtype() while not index_iter.done(): + setitem_filter_driver.jit_merge_point(shapelen=shapelen, + index_dtype=index_dtype, + arr_dtype=arr_dtype, + index_iter=index_iter, + value_iter=value_iter, + arr_iter=arr_iter) if index_iter.getitem_bool(): arr_iter.setitem(value_iter.getitem()) value_iter.next() arr_iter.next() index_iter.next() +flatiter_getitem_driver = jit.JitDriver(name = 'numpy_flatiter_getitem', + greens = ['dtype'], + reds = ['step', 'ri', 'res', + 'base_iter']) + def flatiter_getitem(res, base_iter, step): ri = res.create_iter() + dtype = res.get_dtype() while not ri.done(): + flatiter_getitem_driver.jit_merge_point(dtype=dtype, + base_iter=base_iter, + ri=ri, res=res, step=step) ri.setitem(base_iter.getitem()) base_iter.next_skip_x(step) ri.next() return res +flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', + greens = ['dtype'], + reds = ['length', 'step', 'arr_iter', + 'val_iter']) + def flatiter_setitem(arr, val, start, step, length): dtype = arr.get_dtype() arr_iter = arr.create_iter() val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: + flatiter_setitem_driver.jit_merge_point(dtype=dtype, length=length, + step=step, arr_iter=arr_iter, + val_iter=val_iter) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -223,10 +366,16 @@ # WTF numpy? val_iter.reset() +fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', + greens = ['itemsize', 'dtype'], + reds = ['i', 's', 'ai']) + def fromstring_loop(a, dtype, itemsize, s): i = 0 ai = a.create_iter() while not ai.done(): + fromstring_driver.jit_merge_point(dtype=dtype, s=s, ai=ai, i=i, + itemsize=itemsize) val = dtype.itemtype.runpack_str(s[i*itemsize:i*itemsize + itemsize]) ai.setitem(val) ai.next() @@ -274,12 +423,25 @@ else: self._done = True + @jit.unroll_safe def get_index(self, space): return [space.wrap(i) for i in self.indexes] +getitem_int_driver = jit.JitDriver(name = 'numpy_getitem_int', + greens = ['shapelen', 'indexlen', 'dtype'], + reds = ['arr', 'res', 'iter', 'indexes_w', + 'prefix_w']) + def getitem_array_int(space, arr, res, iter_shape, indexes_w, prefix_w): + shapelen = len(iter_shape) + indexlen = len(indexes_w) + dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): + getitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, + dtype=dtype, arr=arr, res=res, + iter=iter, indexes_w=indexes_w, + prefix_w=prefix_w) # prepare the index index_w = [None] * len(indexes_w) for i in range(len(indexes_w)): @@ -293,10 +455,22 @@ iter.next() return res +setitem_int_driver = jit.JitDriver(name = 'numpy_setitem_int', + greens = ['shapelen', 'indexlen', 'dtype'], + reds = ['arr', 'iter', 'indexes_w', + 'prefix_w', 'val_arr']) + def setitem_array_int(space, arr, iter_shape, indexes_w, val_arr, prefix_w): + shapelen = len(iter_shape) + indexlen = len(indexes_w) + dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): + setitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, + dtype=dtype, arr=arr, + iter=iter, indexes_w=indexes_w, + prefix_w=prefix_w, val_arr=val_arr) # prepare the index index_w = [None] * len(indexes_w) for i in range(len(indexes_w)): diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py --- a/pypy/module/micronumpy/test/test_compile.py +++ b/pypy/module/micronumpy/test/test_compile.py @@ -1,6 +1,5 @@ + import py -py.test.skip("this is going away") - from pypy.module.micronumpy.compile import (numpy_compile, Assignment, ArrayConstant, FloatConstant, Operator, Variable, RangeConstant, Execute, FunctionCall, FakeSpace) @@ -136,7 +135,7 @@ r """ interp = self.run(code) - assert interp.results[0].value.value == 15 + assert interp.results[0].get_scalar_value().value == 15 def test_sum2(self): code = """ @@ -145,7 +144,7 @@ sum(b) """ interp = self.run(code) - assert interp.results[0].value.value == 30 * (30 - 1) + assert interp.results[0].get_scalar_value().value == 30 * (30 - 1) def test_array_write(self): @@ -164,7 +163,7 @@ b = a + a min(b) """) - assert interp.results[0].value.value == -24 + assert interp.results[0].get_scalar_value().value == -24 def test_max(self): interp = self.run(""" @@ -173,7 +172,7 @@ b = a + a max(b) """) - assert interp.results[0].value.value == 256 + assert interp.results[0].get_scalar_value().value == 256 def test_slice(self): interp = self.run(""" @@ -265,6 +264,7 @@ assert interp.results[0].value == 3 def test_take(self): + py.test.skip("unsupported") interp = self.run(""" a = |10| b = take(a, [1, 1, 3, 2]) 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 @@ -1519,7 +1519,7 @@ assert (a == [1, 1]).all() def test_int_array_index(self): - from numpypy import array, arange + from numpypy import array, arange, zeros b = arange(10)[array([3, 2, 1, 5])] assert (b == [3, 2, 1, 5]).all() raises(IndexError, "arange(10)[array([10])]") @@ -1528,6 +1528,7 @@ a = arange(1) a[[0, 0]] += 1 assert a[0] == 1 + assert (zeros(1)[[]] == []).all() def test_int_array_index_setitem(self): from numpypy import array, arange, zeros @@ -1999,6 +2000,7 @@ def test_int_array_index(self): from _numpypy import array + assert (array([])[[]] == []).all() a = array([[1, 2], [3, 4], [5, 6]]) assert (a[slice(0, 3), [0, 0]] == [[1, 1], [3, 3], [5, 5]]).all() assert (a[array([0, 2]), slice(0, 2)] == [[1, 2], [5, 6]]).all() 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 @@ -4,18 +4,12 @@ """ import py -py.test.skip("this is going away") - from pypy.jit.metainterp import pyjitpl from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp.warmspot import reset_stats from pypy.module.micronumpy import interp_boxes -from pypy.module.micronumpy.compile import (FakeSpace, - IntObject, Parser, InterpreterState) -from pypy.module.micronumpy.interp_numarray import (W_NDimArray, - BaseArray, W_FlatIterator) -from pypy.rlib.nonconst import NonConstant - +from pypy.module.micronumpy.compile import FakeSpace, Parser, InterpreterState +from pypy.module.micronumpy.base import W_NDimArray class TestNumpyJIt(LLJitMixin): graph = None @@ -51,11 +45,8 @@ if not len(interp.results): raise Exception("need results") w_res = interp.results[-1] - if isinstance(w_res, BaseArray): - concr = w_res.get_concrete_or_scalar() - sig = concr.find_sig() - frame = sig.create_frame(concr) - w_res = sig.eval(frame, concr) + if isinstance(w_res, W_NDimArray): + w_res = w_res.create_iter().getitem() if isinstance(w_res, interp_boxes.W_Float64Box): return w_res.value if isinstance(w_res, interp_boxes.W_Int64Box): @@ -73,6 +64,7 @@ self.__class__.graph = graph reset_stats() pyjitpl._warmrunnerdesc.memory_manager.alive_loops.clear() + py.test.skip("don't run for now") return self.interp.eval_graph(self.graph, [i]) def define_add(): 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 @@ -79,7 +79,7 @@ except ExitFrame: return self.popvalue() - def jump_absolute(self, jumpto, _, ec=None): + def jump_absolute(self, jumpto, ec): if we_are_jitted(): # # assume that only threads are using the bytecode counter diff --git a/pypy/module/pypyjit/test_pypy_c/test_exception.py b/pypy/module/pypyjit/test_pypy_c/test_exception.py --- a/pypy/module/pypyjit/test_pypy_c/test_exception.py +++ b/pypy/module/pypyjit/test_pypy_c/test_exception.py @@ -95,7 +95,6 @@ def test_continue_in_finally(self): # check that 'continue' inside a try:finally: block is correctly # detected as closing a loop - py.test.skip("is this case important?") def f(n): i = 0 while 1: @@ -110,10 +109,9 @@ assert log.result == 2001 loop, = log.loops_by_filename(self.filepath) assert loop.match(""" - i40 = int_add_ovf(i31, 1) - guard_no_overflow(descr=...) - i41 = int_lt(i40, i33) - guard_true(i41, descr=...) + i3 = int_lt(i1, i2) + guard_true(i3, descr=...) + i4 = int_add(i1, 1) --TICK-- jump(..., descr=...) """) diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,7 +1,8 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import PyCode, BytecodeCorruption +from pypy.interpreter.pycode import (PyCode, BytecodeCorruption, cpython_magic, + cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) from pypy.interpreter.astcompiler.consts import CO_GENERATOR @@ -12,6 +13,57 @@ """ opnames = host_bytecode_spec.method_names + def __init__(self, space, argcount, nlocals, stacksize, flags, + code, consts, names, varnames, filename, + name, firstlineno, lnotab, freevars, cellvars, + hidden_applevel=False, magic=cpython_magic): + """Initialize a new code object""" + self.space = space + self.co_name = name + assert nlocals >= 0 + self.co_argcount = argcount + self.co_nlocals = nlocals + self.co_stacksize = stacksize + self.co_flags = flags + self.co_code = code + self.co_consts_w = consts + self.co_names_w = [space.wrap(aname) for aname in names] + self.co_varnames = varnames + self.co_freevars = freevars + self.co_cellvars = cellvars + self.co_filename = filename + self.co_name = name + self.co_firstlineno = firstlineno + self.co_lnotab = lnotab + self.hidden_applevel = hidden_applevel + self.magic = magic + self._signature = cpython_code_signature(self) + self._initialize() + + def _initialize(self): + # Precompute what arguments need to be copied into cellvars + self._args_as_cellvars = [] + + if self.co_cellvars: + argcount = self.co_argcount + assert argcount >= 0 # annotator hint + if self.co_flags & CO_VARARGS: + argcount += 1 + if self.co_flags & CO_VARKEYWORDS: + argcount += 1 + # Cell vars could shadow already-set arguments. + # See comment in PyCode._initialize() + argvars = self.co_varnames + cellvars = self.co_cellvars + for i in range(len(cellvars)): + cellname = cellvars[i] + for j in range(argcount): + if cellname == argvars[j]: + # argument j has the same name as the cell var i + while len(self._args_as_cellvars) <= i: + self._args_as_cellvars.append(-1) # pad + self._args_as_cellvars[i] = j + def read(self, pos): """ Decode the instruction starting at position ``next_instr``. diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -1,19 +1,17 @@ import collections -import sys from pypy.tool.error import source_lines -from pypy.interpreter.error import OperationError -from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter import pyframe from pypy.interpreter.nestedscope import Cell -from pypy.interpreter.pycode import CO_OPTIMIZED, CO_NEWLOCALS +from pypy.interpreter.pycode import CO_NEWLOCALS from pypy.interpreter.argument import ArgumentsForTranslation -from pypy.interpreter.pyopcode import (Return, Yield, SuspendedUnroller, - SReturnValue, SApplicationException, BytecodeCorruption, - RaiseWithExplicitTraceback) -from pypy.objspace.flow.model import * +from pypy.interpreter.pyopcode import Return, BytecodeCorruption +from pypy.objspace.flow.model import (Constant, Variable, Block, Link, + UnwrapException, SpaceOperation, FunctionGraph, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, recursively_flatten) from pypy.objspace.flow.bytecode import HostCode +from pypy.objspace.flow.specialcase import (rpython_print_item, + rpython_print_newline) class FlowingError(Exception): """ Signals invalid RPython in the function being analysed""" @@ -27,16 +25,14 @@ msg += source_lines(self.frame.graph, None, offset=self.frame.last_instr) return "\n".join(msg) - class StopFlowing(Exception): pass -class FSException(OperationError): - def __init__(self, w_type, w_value, tb=None): +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 - self._application_traceback = tb def get_w_value(self, _): return self.w_value @@ -44,45 +40,6 @@ def __str__(self): return '[%s: %s]' % (self.w_type, self.w_value) - def normalize_exception(self, space): - """Normalize the OperationError. In other words, fix w_type and/or - w_value to make sure that the __class__ of w_value is exactly w_type. - """ - w_type = self.w_type - w_value = self.w_value - if space.exception_is_valid_obj_as_class_w(w_type): - # this is for all cases of the form (Class, something) - if space.is_w(w_value, space.w_None): - # raise Type: we assume we have to instantiate Type - w_value = space.call_function(w_type) - w_type = self._exception_getclass(space, w_value) - else: - w_valuetype = space.exception_getclass(w_value) - if space.exception_issubclass_w(w_valuetype, w_type): - # raise Type, Instance: let etype be the exact type of value - w_type = w_valuetype - else: - # raise Type, X: assume X is the constructor argument - w_value = space.call_function(w_type, w_value) - w_type = self._exception_getclass(space, w_value) - - else: - # the only case left here is (inst, None), from a 'raise inst'. - w_inst = w_type - w_instclass = self._exception_getclass(space, w_inst) - if not space.is_w(w_value, space.w_None): - raise FSException(space.w_TypeError, - space.wrap("instance exception may not " - "have a separate value")) - w_value = w_inst - w_type = w_instclass - - self.w_type = w_type - self.w_value = w_value - -class OperationThatShouldNotBePropagatedError(FSException): - pass - class ImplicitOperationError(FSException): pass @@ -262,6 +219,20 @@ # ____________________________________________________________ +compare_method = [ + "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", + ] + class FlowSpaceFrame(pyframe.CPythonFrame): def __init__(self, space, func, constargs=None): @@ -497,38 +468,68 @@ res = getattr(self, methodname)(oparg, next_instr) if res is not None: next_instr = res - except OperationThatShouldNotBePropagatedError, e: - raise Exception( - 'found an operation that always raises %s: %s' % ( - self.space.unwrap(e.w_type).__name__, - self.space.unwrap(e.w_value))) except FSException, operr: - self.attach_traceback(operr) next_instr = self.handle_operation_error(operr) - except RaiseWithExplicitTraceback, e: - next_instr = self.handle_operation_error(e.operr) return next_instr - def attach_traceback(self, operr): - if self.pycode.hidden_applevel: - return - tb = operr.get_traceback() - tb = PyTraceback(self.space, self, self.last_instr, tb) - operr.set_traceback(tb) - def handle_operation_error(self, operr): - block = self.unrollstack(SFlowException.kind) + block = self.unrollstack(SApplicationException.kind) if block is None: - # no handler found for the exception - # try to preserve the CPython-level traceback - import sys - tb = sys.exc_info()[2] - raise operr, None, tb + raise operr else: - unroller = SFlowException(operr) + unroller = SApplicationException(operr) next_instr = block.handle(self, unroller) return next_instr + def BAD_OPCODE(self, _, next_instr): + raise FlowingError(self, "This operation is not RPython") + + def BREAK_LOOP(self, oparg, next_instr): + return self.unrollstack_and_jump(SBreakLoop.singleton) + + def CONTINUE_LOOP(self, startofloop, next_instr): + unroller = SContinueLoop(startofloop) + return self.unrollstack_and_jump(unroller) + + 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)) + + def cmp_exc_match(self, w_1, w_2): + return self.space.newbool(self.space.exception_match(w_1, w_2)) + + def COMPARE_OP(self, testnum, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = getattr(self, compare_method[testnum])(w_1, w_2) + self.pushvalue(w_result) + def RAISE_VARARGS(self, nbargs, next_instr): space = self.space if nbargs == 0: @@ -538,7 +539,7 @@ # re-raising an implicit operation makes it an explicit one operr = FSException(operr.w_type, operr.w_value) self.last_exception = operr - raise RaiseWithExplicitTraceback(operr) + raise operr else: raise FSException(space.w_TypeError, space.wrap("raise: no active exception to re-raise")) @@ -550,8 +551,7 @@ w_value = self.popvalue() if 1: w_type = self.popvalue() - operror = FSException(w_type, w_value) - operror.normalize_exception(space) + operror = space.exc_from_raise(w_type, w_value) raise operror def IMPORT_NAME(self, nameindex, next_instr): @@ -580,17 +580,45 @@ return next_instr # now inside a 'finally' block def END_FINALLY(self, oparg, next_instr): - unroller = self.end_finally() - if isinstance(unroller, SuspendedUnroller): - # go on unrolling the stack - block = self.unrollstack(unroller.kind) - if block is None: - w_result = unroller.nomoreblocks() - self.pushvalue(w_result) - raise Return - else: - next_instr = block.handle(self, unroller) - return next_instr + # unlike CPython, there are two statically distinct cases: the + # END_FINALLY might be closing an 'except' block or a 'finally' + # block. In the first case, the stack contains three items: + # [exception type we are now handling] + # [exception value we are now handling] + # [wrapped 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] + w_top = self.popvalue() + if w_top == self.space.w_None: + # finally: block with no unroller active + return + try: + unroller = self.space.unwrap(w_top) + except UnwrapException: + pass + else: + if isinstance(unroller, SuspendedUnroller): + # case of a finally: block + return self.unroll_finally(unroller) + # case of an except: block. We popped the exception type + self.popvalue() # Now we pop the exception value + unroller = self.space.unwrap(self.popvalue()) + return self.unroll_finally(unroller) + + def unroll_finally(self, unroller): + # go on unrolling the stack + block = self.unrollstack(unroller.kind) + if block is None: + w_result = unroller.nomoreblocks() + self.pushvalue(w_result) + raise Return + else: + return block.handle(self, unroller) + + def POP_BLOCK(self, oparg, next_instr): + block = self.pop_block() + block.cleanupstack(self) # the block knows how to clean up the value stack def JUMP_ABSOLUTE(self, jumpto, next_instr): return jumpto @@ -603,11 +631,48 @@ # isn't popped straightaway. self.pushvalue(None) + PRINT_EXPR = BAD_OPCODE + PRINT_ITEM_TO = BAD_OPCODE + PRINT_NEWLINE_TO = BAD_OPCODE + + def PRINT_ITEM(self, oparg, next_instr): + w_item = self.popvalue() + w_s = self.space.do_operation('str', w_item) + self.space.appcall(rpython_print_item, w_s) + + def PRINT_NEWLINE(self, oparg, next_instr): + self.space.appcall(rpython_print_newline) + + def FOR_ITER(self, jumpby, next_instr): + w_iterator = self.peekvalue() + try: + w_nextitem = self.space.next(w_iterator) + except FSException, e: + if not self.space.exception_match(e.w_type, self.space.w_StopIteration): + raise + # iterator exhausted + self.popvalue() + next_instr += jumpby + else: + self.pushvalue(w_nextitem) + return next_instr + + def SETUP_LOOP(self, offsettoend, next_instr): + block = LoopBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + + def SETUP_EXCEPT(self, offsettoend, next_instr): + block = ExceptBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + + def SETUP_FINALLY(self, offsettoend, next_instr): + block = FinallyBlock(self, next_instr + offsettoend, self.lastblock) + self.lastblock = block + def SETUP_WITH(self, offsettoend, next_instr): # A simpler version than the 'real' 2.7 one: # directly call manager.__enter__(), don't use special lookup functions # which don't make sense on the RPython type system. - from pypy.interpreter.pyopcode import WithBlock w_manager = self.peekvalue() w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__")) self.settopvalue(w_exit) @@ -616,10 +681,47 @@ self.lastblock = block self.pushvalue(w_result) + def WITH_CLEANUP(self, oparg, next_instr): + # Note: RPython context managers receive None in lieu of tracebacks + # and cannot suppress the exception. + # This opcode changed a lot between CPython versions + if (self.pycode.magic >= 0xa0df2ef + # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) + or self.pycode.magic >= 0xa0df2d1): + # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) + w_unroller = self.popvalue() + w_exitfunc = self.popvalue() + self.pushvalue(w_unroller) + elif self.pycode.magic >= 0xa0df28c: + # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) + w_exitfunc = self.popvalue() + w_unroller = self.peekvalue(0) + else: + raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") + + unroller = self.space.unwrap(w_unroller) + w_None = self.space.w_None + if isinstance(unroller, SApplicationException): + operr = unroller.operr + # 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) + else: + self.space.call_function(w_exitfunc, w_None, w_None, w_None) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) + def LOAD_ATTR(self, nameindex, next_instr): + "obj.attributename" + w_obj = self.popvalue() + w_attributename = self.getname_w(nameindex) + w_value = self.space.getattr(w_obj, w_attributename) + self.pushvalue(w_value) + LOOKUP_METHOD = LOAD_ATTR + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. @@ -647,23 +749,173 @@ def argument_factory(self, *args): return ArgumentsForTranslation(self.space, *args) - def call_contextmanager_exit_function(self, w_func, w_typ, w_val, w_tb): - if w_typ is not self.space.w_None: - # The annotator won't allow to merge exception types with None. - # Replace it with the exception value... - w_typ = w_val - self.space.call_function(w_func, w_typ, w_val, w_tb) - # Return None so that the flow space statically knows that we didn't - # swallow the exception - return self.space.w_None - ### Frame blocks ### -class SFlowException(SApplicationException): - """Flowspace override for SApplicationException""" +class SuspendedUnroller(object): + """Abstract base class for interpreter-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: + + WHY_NOT, OK, not this one :-) + WHY_EXCEPTION, SApplicationException + WHY_RERAISE, implemented differently, see Reraise + WHY_RETURN, SReturnValue + WHY_BREAK, SBreakLoop + WHY_CONTINUE, SContinueLoop + WHY_YIELD not needed + """ + 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): + """Signals a 'return' statement. + Argument is the wrapped object to return.""" + kind = 0x01 + def __init__(self, w_returnvalue): + self.w_returnvalue = w_returnvalue + + def nomoreblocks(self): + return self.w_returnvalue + + def state_unpack_variables(self, space): + return [self.w_returnvalue] + + @staticmethod + def state_pack_variables(space, w_returnvalue): + return SReturnValue(w_returnvalue) + +class SApplicationException(SuspendedUnroller): + """Signals an application-level exception + (i.e. an OperationException).""" + kind = 0x02 + def __init__(self, operr): + self.operr = operr + + def nomoreblocks(self): + raise self.operr + def state_unpack_variables(self, space): return [self.operr.w_type, self.operr.w_value] @staticmethod def state_pack_variables(space, w_type, w_value): - return SFlowException(FSException(w_type, w_value)) + return SApplicationException(FSException(w_type, w_value)) + +class SBreakLoop(SuspendedUnroller): + """Signals a 'break' statement.""" + kind = 0x04 + + def state_unpack_variables(self, space): + return [] + + @staticmethod + def state_pack_variables(space): + return SBreakLoop.singleton + +SBreakLoop.singleton = SBreakLoop() + +class SContinueLoop(SuspendedUnroller): + """Signals a 'continue' statement. + Argument is the bytecode position of the beginning of the loop.""" + kind = 0x08 + def __init__(self, jump_to): + self.jump_to = jump_to + + def state_unpack_variables(self, space): + return [space.wrap(self.jump_to)] + + @staticmethod + def state_pack_variables(space, w_jump_to): + return SContinueLoop(space.int_w(w_jump_to)) + + +class FrameBlock(object): + """Abstract base class for frame blocks from the blockstack, + used by the SETUP_XXX and POP_BLOCK opcodes.""" + + def __init__(self, frame, handlerposition, previous): + self.handlerposition = handlerposition + self.valuestackdepth = frame.valuestackdepth + self.previous = previous # this makes a linked list of blocks + + def __eq__(self, other): + return (self.__class__ is other.__class__ and + self.handlerposition == other.handlerposition and + self.valuestackdepth == other.valuestackdepth) + + def __ne__(self, other): + return not (self == other) + + def __hash__(self): + return hash((self.handlerposition, self.valuestackdepth)) + + def cleanupstack(self, frame): + frame.dropvaluesuntil(self.valuestackdepth) + + def handle(self, frame, unroller): + raise NotImplementedError + +class LoopBlock(FrameBlock): + """A loop block. Stores the end-of-loop pointer in case of 'break'.""" + + _opname = 'SETUP_LOOP' + handling_mask = SBreakLoop.kind | SContinueLoop.kind + + def handle(self, frame, unroller): + if isinstance(unroller, SContinueLoop): + # 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 + frame.append_block(self) + return unroller.jump_to + else: + # jump to the end of the loop + self.cleanupstack(frame) + return self.handlerposition + +class ExceptBlock(FrameBlock): + """An try:except: block. Stores the position of the exception handler.""" + + _opname = 'SETUP_EXCEPT' + handling_mask = SApplicationException.kind + + 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) + operationerr = unroller.operr + # the stack setup is slightly different than in CPython: + # instead of the traceback, we store the unroller object, + # wrapped. + frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(operationerr.get_w_value(frame.space)) + frame.pushvalue(operationerr.w_type) + frame.last_exception = operationerr + return self.handlerposition # jump to the handler + +class FinallyBlock(FrameBlock): + """A try:finally: block. Stores the position of the exception handler.""" + + _opname = 'SETUP_FINALLY' + handling_mask = -1 # handles every kind of SuspendedUnroller + + def handle(self, frame, unroller): + # any abnormal reason for unrolling a finally: triggers the end of + # the block unrolling and the entering the finally: handler. + self.cleanupstack(frame) + frame.pushvalue(frame.space.wrap(unroller)) + return self.handlerposition # jump to the handler + + +class WithBlock(FinallyBlock): + + def handle(self, frame, unroller): + return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -1,4 +1,3 @@ -from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.rlib.unroll import SpecTag from pypy.objspace.flow.model import * @@ -106,6 +105,7 @@ UNPICKLE_TAGS = {} def recursively_flatten(space, lst): + from pypy.objspace.flow.flowcontext import SuspendedUnroller i = 0 while i < len(lst): item = lst[i] diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -1,14 +1,14 @@ # ______________________________________________________________________ import __builtin__ import sys -import operator import types -from pypy.interpreter.baseobjspace import ObjSpace, Wrappable -from pypy.interpreter import pyframe, argument -from pypy.objspace.flow.model import * +from pypy.interpreter.baseobjspace import ObjSpace +from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.model import (Constant, Variable, WrapException, + UnwrapException, checkgraph, SpaceOperation) from pypy.objspace.flow import operation from pypy.objspace.flow.flowcontext import (FlowSpaceFrame, fixeggblocks, - OperationThatShouldNotBePropagatedError, FSException, FlowingError) + FSException, FlowingError) from pypy.objspace.flow.specialcase import SPECIAL_CASES from pypy.rlib.unroll import unrolling_iterable, _unroller from pypy.rlib import rstackovf, rarithmetic @@ -38,47 +38,32 @@ } # ______________________________________________________________________ -class FlowObjSpace(ObjSpace): +class FlowObjSpace(object): """NOT_RPYTHON. The flow objspace space is used to produce a flow graph by recording the space operations that the interpreter generates when it interprets (the bytecode of) some function. """ + w_None = Constant(None) + builtin = Constant(__builtin__) + sys = Constant(sys) + w_False = Constant(False) + w_True = Constant(True) + w_type = Constant(type) + w_tuple = Constant(tuple) + for exc in [KeyError, ValueError, IndexError, StopIteration, + AssertionError, TypeError, AttributeError, ImportError]: + clsname = exc.__name__ + locals()['w_' + clsname] = Constant(exc) - full_exceptions = False - FrameClass = FlowSpaceFrame + # the following exceptions should not show up From noreply at buildbot.pypy.org Wed Oct 3 09:56:47 2012 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Wed, 3 Oct 2012 09:56:47 +0200 (CEST) Subject: [pypy-commit] pypy pytest: indentation Message-ID: <20121003075647.707691C002D@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r57759:2d4adb7a8852 Date: 2012-10-03 09:56 +0200 http://bitbucket.org/pypy/pypy/changeset/2d4adb7a8852/ Log: indentation diff --git a/pypy/tool/pytest/viewerplugin.py b/pypy/tool/pytest/viewerplugin.py --- a/pypy/tool/pytest/viewerplugin.py +++ b/pypy/tool/pytest/viewerplugin.py @@ -33,5 +33,5 @@ if 'pygame' in sys.modules: assert item.config.option.view, ("should not invoke Pygame " - "if view option is False") + "if view option is False") From noreply at buildbot.pypy.org Wed Oct 3 09:57:06 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 3 Oct 2012 09:57:06 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: start slides Message-ID: <20121003075706.714971C002D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4832:d390cfda3556 Date: 2012-10-03 09:56 +0200 http://bitbucket.org/pypy/extradoc/changeset/d390cfda3556/ Log: start slides diff --git a/talk/pyconza2012/examples/alloc.py b/talk/pyconza2012/examples/alloc.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/examples/alloc.py @@ -0,0 +1,20 @@ + +import sys, time + +def f(): + l = [None] + for i in range(int(sys.argv[1])): + l[0] = (i,) + +def g(): + m = int(sys.argv[1]) + l = [None] * m + for i in range(m): + l[i] = i + +t0 = time.time() +f() +t1 = time.time() +g() +t2 = time.time() +print "long living", t2 - t1, "short living", t1 - t0 diff --git a/talk/pyconza2012/examples/datastructure.py b/talk/pyconza2012/examples/datastructure.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/examples/datastructure.py @@ -0,0 +1,26 @@ + +class View(object): + def __init__(self, arr, start, stop): + self.arr = arr + self.start = start + self.stop = stop + + def __getitem__(self, item): + if not isinstance(item, int): + return NotImplemented + if self.start + item <= self.stop: + raise IndexError + return self.arr[self.start + item] + +class Wrapper(object): + def __init__(self, arr): + self.arr = arr + + def __getitem__(self, item): + if isinstance(item, int): + return self.arr[item] + elif isinstance(item, slice): + if item.step != 1 or item.start < 0 or item.stop < 0: + raise TypeError("step not implemented") + return View(self.arr, item.start, item.stop) + return NotImplemented diff --git a/talk/pyconza2012/examples/interpreter.py b/talk/pyconza2012/examples/interpreter.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/examples/interpreter.py @@ -0,0 +1,57 @@ + +(LOAD_FAST, LOAD_CONST, COMPARE_OP, POP_JUMP_IF_FALSE, + ADD, STORE_FAST, JUMP_ABSOLUTE) = range(7) + +has_arg = [True, True, False, True, False, True, True] + +class BaseObject(object): + def add(left, right): + # try right + return right.radd(left) + +class Long(BaseObject): + pass + +class Integer(BaseObject): + def __init__(self, v): + self.intval = v + + def add(self, right): + if isinstance(right, Integer): + try: + return Integer(self.intval + right.intval) + except OverflowError: + return Long(self.intval).add(Long(right.intval)) + +def interpret(bytecode, variables, constants): + stack = [] + pos = 0 + arg0 = None + while True: + b = ord(bytecode[pos]) + if has_arg[b]: + pos += 1 + arg0 = ord(bytecode[pos]) + if b == LOAD_FAST: + stack.append(variables[arg0]) + elif b == LOAD_CONST: + stack.append(constants[arg0]) + elif b == COMPARE_OP: + right = stack.pop() + left = stack.pop() + stack.append(left.compare(right)) + elif b == ADD: + right = stack.pop() + left = stack.pop() + stack.append(left.add(right)) + elif b == POP_JUMP_IF_FALSE: + val = stack.pop() + if not val.is_true(): + pos = arg0 + continue + elif b == STORE_FAST: + variables[arg0] = stack.pop() + elif b == JUMP_ABSOLUTE: + pos = arg0 + continue + pos += 1 diff --git a/talk/pyconza2012/examples/jit01.py b/talk/pyconza2012/examples/jit01.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/examples/jit01.py @@ -0,0 +1,10 @@ + +def f(): + i = 0 + while i < 1000000: + i = i + 1 + return i + +if __name__ == '__main__': + f() + diff --git a/talk/pyconza2012/slides.rst b/talk/pyconza2012/slides.rst new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/slides.rst @@ -0,0 +1,128 @@ +================================== +Python performance characteristics +================================== + +Who am I? +--------- + +* Maciej Fijałkowski (yes this is unicode) + +* PyPy core developer for I don't remember + +* performance freak + +What this talk is about? +------------------------ + +* I'll start where Larry finished + +* describe a bit how the PyPy JIT works + +* what's the difference between interpretation and JIT compilation + +|pause| + +* who some assembler + +|pause| + +* just joking + +What is PyPy? +------------- + +* PyPy is a Python interpreter (that's what we care about) + +* PyPy is a toolchain for creating dynamic language implementations + + * we try to rename the latter RPython + +* also, an Open Source project that has been around for a while + +Compilers vs interpreters +------------------------- + +* compilers compile language X (C, Python) to a lower level language + (C, assembler) ahead of time + +* interpreters compile language X to bytecode and have a big interpreter + loop + +|pause| + +* PyPy has a hybrid approach. It's an interpreter, but hot paths are + compiled directly to assembler during runtime + +What is just in time (JIT) compilation? +--------------------------------------- + +* few different flavors + +* observe runtime values + +* compile code with agressive optimizations + +* have checks if assumptions still stand + +So what PyPy does? +------------------ + +* interprets a Python program + +* the JIT observes python **interpreter** + +* producing code through the path followed by the interpreter + +* compiles loops and functions + +Some example +------------ + +* integer addition! + +So wait, where are those allocations? +------------------------------------- + +* they don't escape, so they're removed! + +Abstractions +------------ + +* inlining, malloc removal + +* abstractions are cheap + +|pause| + +* if they don't introduce too much complexity + +Allocations +----------- + +* allocation is expensive + +* for a good GC, short living objects don't matter + +* it's better to have a small persistent structure and abstraction + on allocation + +|pause| + +* copying however is expensive + +* we have hacks for strings, but they're not complete + +Calls +----- + +* Python calls are an incredible mess + +* simple is better than complex + +* simple call comes with no cost, the cost grows with growing complexity + +Attribute access +---------------- + +Other sorts of loops +-------------------- From noreply at buildbot.pypy.org Wed Oct 3 10:34:20 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 3 Oct 2012 10:34:20 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Remove ll_strtod.c from the RPython core C files. Message-ID: <20121003083420.1FFFB1C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57760:898ed07c26b4 Date: 2012-10-02 23:27 +0200 http://bitbucket.org/pypy/pypy/changeset/898ed07c26b4/ Log: Remove ll_strtod.c from the RPython core C files. The ExternalCompilationInfo object should be enough to add it to the Makefile. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -921,7 +921,6 @@ srcdir / 'thread.c', srcdir / 'asm.c', srcdir / 'instrument.c', - srcdir / 'll_strtod.c', # ifdef HAVE_RTYPER srcdir / 'int.c', ] if _CYGWIN: diff --git a/pypy/translator/c/src/g_include.h b/pypy/translator/c/src/g_include.h --- a/pypy/translator/c/src/g_include.h +++ b/pypy/translator/c/src/g_include.h @@ -45,7 +45,6 @@ #ifdef HAVE_RTYPER /* only if we have an RTyper */ # include "src/rtyper.h" # include "src/debug_traceback.h" -# include "src/ll_strtod.h" #endif #ifdef PYPY_STANDALONE diff --git a/pypy/translator/c/test/test_standalone.py b/pypy/translator/c/test/test_standalone.py --- a/pypy/translator/c/test/test_standalone.py +++ b/pypy/translator/c/test/test_standalone.py @@ -241,7 +241,7 @@ def test_separate_files(self): # One file in translator/c/src fname = py.path.local(pypydir).join( - 'translator', 'c', 'src', 'll_strtod.h') + 'translator', 'c', 'src', 'll_strtod.c') # One file in (another) subdir of the temp directory dirname = udir.join("test_dir").ensure(dir=1) @@ -273,7 +273,7 @@ # but files from pypy source dir must be copied assert "translator/c/src" not in makefile - assert " ll_strtod.h" in makefile + assert " ll_strtod.c" in makefile assert " ll_strtod.o" in makefile def test_debug_print_start_stop(self): From noreply at buildbot.pypy.org Wed Oct 3 10:34:23 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 3 Oct 2012 10:34:23 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Fix compilation warning. Message-ID: <20121003083423.C870E1C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57761:5bd32c540fbe Date: 2012-10-03 08:35 +0200 http://bitbucket.org/pypy/pypy/changeset/5bd32c540fbe/ Log: Fix compilation warning. diff --git a/pypy/translator/c/src/profiling.c b/pypy/translator/c/src/profiling.c --- a/pypy/translator/c/src/profiling.c +++ b/pypy/translator/c/src/profiling.c @@ -1,4 +1,3 @@ - #include #if defined(__GNUC__) && defined(__linux__) diff --git a/pypy/translator/c/src/profiling.h b/pypy/translator/c/src/profiling.h --- a/pypy/translator/c/src/profiling.h +++ b/pypy/translator/c/src/profiling.h @@ -1,6 +1,5 @@ - -#ifndef PROFILING_H -#define PROFILING_H +#ifndef _PYPY_PROFILING_H +#define _PYPY_PROFILING_H void pypy_setup_profiling(); void pypy_teardown_profiling(); diff --git a/pypy/translator/c/src/support.c b/pypy/translator/c/src/support.c --- a/pypy/translator/c/src/support.c +++ b/pypy/translator/c/src/support.c @@ -1,5 +1,6 @@ #include "common_header.h" #include +#include /************************************************************/ /*** C header subsection: support functions ***/ From noreply at buildbot.pypy.org Wed Oct 3 10:34:24 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 3 Oct 2012 10:34:24 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Fix a crash in some module/thread test. Message-ID: <20121003083424.F16F51C0E8B@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r57762:60130da446c6 Date: 2012-10-03 10:33 +0200 http://bitbucket.org/pypy/pypy/changeset/60130da446c6/ Log: Fix a crash in some module/thread test. diff --git a/pypy/translator/c/src/thread.c b/pypy/translator/c/src/thread.c --- a/pypy/translator/c/src/thread.c +++ b/pypy/translator/c/src/thread.c @@ -1,6 +1,12 @@ /* Thread implementation */ #include "src/thread.h" +/* The following include is required by the Boehm GC, which apparently + * crashes where pthread_create() is not redefined to call a Boehm + * wrapper function instead. Ugly. + */ +#include "common_header.h" + #ifdef _WIN32 #include "src/thread_nt.c" #else From noreply at buildbot.pypy.org Wed Oct 3 13:10:47 2012 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Wed, 3 Oct 2012 13:10:47 +0200 (CEST) Subject: [pypy-commit] pypy pytest: use importorskip instead of custom handling Message-ID: <20121003111047.9D5201C002D@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r57763:e880a84e5be1 Date: 2012-10-03 13:10 +0200 http://bitbucket.org/pypy/pypy/changeset/e880a84e5be1/ Log: use importorskip instead of custom handling diff --git a/pypy/rpython/module/test/test_ll_termios.py b/pypy/rpython/module/test/test_ll_termios.py --- a/pypy/rpython/module/test/test_ll_termios.py +++ b/pypy/rpython/module/test/test_ll_termios.py @@ -1,12 +1,8 @@ -import py +import pytest # tests here are run as snippets through a pexpected python subprocess def setup_module(mod): - try: - import termios - mod.termios = termios - except ImportError: - py.test.skip("termios not found") + pytest.importorskip('termios') class ExpectTestLLTermios(object): def test_tcgetattr(self): From noreply at buildbot.pypy.org Wed Oct 3 14:34:17 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 3 Oct 2012 14:34:17 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: fix fix fix in-progress Message-ID: <20121003123417.C04DE1C00EE@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57764:d0f15e8614e4 Date: 2012-10-03 14:34 +0200 http://bitbucket.org/pypy/pypy/changeset/d0f15e8614e4/ Log: fix fix fix in-progress diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -30,7 +30,6 @@ from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.jit.backend.x86 import rx86, regloc, codebuf from pypy.jit.metainterp.resoperation import rop, ResOperation -from pypy.jit.backend.x86.support import values_array from pypy.jit.backend.x86 import support from pypy.rlib.debug import (debug_print, debug_start, debug_stop, have_debug_prints) @@ -41,6 +40,7 @@ from pypy.jit.codewriter import longlong from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import compute_unique_id +from pypy.jit.backend.x86 import stmtlocal # darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 4.5.0, # better safe than sorry @@ -68,16 +68,11 @@ _regalloc = None _output_loop_log = None - def __init__(self, cpu, translate_support_code=False, - failargs_limit=1000): + def __init__(self, cpu, translate_support_code=False): self.cpu = cpu self.verbose = False self.rtyper = cpu.rtyper - self.fail_boxes_int = values_array(lltype.Signed, failargs_limit) - self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit) - self.fail_boxes_float = values_array(longlong.FLOATSTORAGE, - failargs_limit) - self.fail_ebp = 0 + self.asmtlocals = {} self.loop_run_counters = [] self.float_const_neg_addr = 0 self.float_const_abs_addr = 0 @@ -87,7 +82,6 @@ self.setup_failure_recovery() self._debug = False self.debug_counter_descr = cpu.fielddescrof(DEBUG_COUNTER, 'i') - self.fail_boxes_count = 0 self.datablockwrapper = None self.stack_check_slowpath = 0 self.propagate_exception_path = 0 @@ -95,7 +89,7 @@ self.teardown() def leave_jitted_hook(self): - ptrs = self.fail_boxes_ptr.ar + ptrs = stmtlocal.get_asm_tlocal(self.cpu) llop.gc_assume_young_pointers(lltype.Void, llmemory.cast_ptr_to_adr(ptrs)) @@ -140,9 +134,9 @@ self.mc = codebuf.MachineCodeBlockWrapper() #assert self.datablockwrapper is None --- but obscure case # possible, e.g. getting MemoryError and continuing - allblocks = self.get_asmmemmgr_blocks(looptoken) + self.allblocks = self.get_asmmemmgr_blocks(looptoken) self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, - allblocks) + self.allblocks) self.target_tokens_currently_compiling = {} def teardown(self): @@ -151,6 +145,7 @@ self.pending_memoryerror_trampoline_from = None self.mc = None self.current_clt = None + self.allblocks = None def finish_once(self): if self._debug: @@ -554,7 +549,7 @@ self.write_pending_failure_recoveries() full_size = self.mc.get_relative_pos() # - rawstart = self.materialize_loop(looptoken) + rawstart = self.materialize_loop() debug_start("jit-backend-addr") debug_print("Loop %d (%s) has address %x to %x (bootstrap %x)" % ( looptoken.number, loopname, @@ -613,7 +608,7 @@ self.write_pending_failure_recoveries() fullsize = self.mc.get_relative_pos() # - rawstart = self.materialize_loop(original_loop_token) + rawstart = self.materialize_loop() debug_start("jit-backend-addr") debug_print("bridge out of Guard %d has address %x to %x" % (descr_number, rawstart, rawstart + codeendpos)) @@ -692,11 +687,10 @@ clt.asmmemmgr_blocks = [] return clt.asmmemmgr_blocks - def materialize_loop(self, looptoken): + def materialize_loop(self): self.datablockwrapper.done() # finish using cpu.asmmemmgr self.datablockwrapper = None - allblocks = self.get_asmmemmgr_blocks(looptoken) - return self.mc.materialize(self.cpu.asmmemmgr, allblocks, + return self.mc.materialize(self.cpu.asmmemmgr, self.allblocks, self.cpu.gc_ll_descr.gcrootmap) def _register_counter(self, tp, number, token): @@ -1900,12 +1894,9 @@ assert mc.get_relative_pos() == start + 13 # write tight data that describes the failure recovery self.write_failure_recovery_description(mc, guardtok.failargs, - guardtok.fail_locs) - # write the fail_index too - mc.writeimm32(fail_index) - # for testing the decoding, write a final byte 0xCC + guardtok.fail_locs, + fail_index) if not we_are_translated(): - mc.writechar('\xCC') faillocs = [loc for loc in guardtok.fail_locs if loc is not None] guardtok.faildescr._x86_debug_faillocs = faillocs return startpos @@ -1919,7 +1910,8 @@ CODE_HOLE = 4 | DESCR_SPECIAL CODE_INPUTARG = 8 | DESCR_SPECIAL - def write_failure_recovery_description(self, mc, failargs, locs): + def write_failure_recovery_description(self, mc, failargs, locs, + fail_index): for i in range(len(failargs)): arg = failargs[i] if arg is not None: @@ -1950,7 +1942,12 @@ mc.writechar(chr(n)) mc.writechar(chr(self.CODE_STOP)) # assert that the fail_boxes lists are big enough - assert len(failargs) <= self.fail_boxes_int.SIZE + assert len(failargs) <= stmtlocal.FAILARGS_LIMIT + # write the fail_index too + mc.writeimm32(fail_index) + # for testing the decoding, write a final byte 0xCC + if not we_are_translated(): + mc.writechar('\xCC') def rebuild_faillocs_from_descr(self, bytecode): from pypy.jit.backend.x86.regalloc import X86FrameManager @@ -2001,7 +1998,8 @@ @rgc.no_collect def grab_frame_values(self, bytecode, frame_addr, allregisters): # no malloc allowed here!! - self.fail_ebp = allregisters[16 + ebp.value] + asmtlocal = stmtlocal.get_asm_tlocal(self.cpu) + asmtlocal.fail_ebp = allregisters[16 + ebp.value] code_inputarg = False num = 0 value_hi = 0 @@ -2055,11 +2053,11 @@ # store the loaded value into fail_boxes_ if kind == self.DESCR_INT: - tgt = self.fail_boxes_int.get_addr_for_num(num) + tgt = stmtlocal.fail_boxes_int_addr(asmtlocal, num) elif kind == self.DESCR_REF: - tgt = self.fail_boxes_ptr.get_addr_for_num(num) + tgt = stmtlocal.fail_boxes_ptr_addr(asmtlocal, num) elif kind == self.DESCR_FLOAT: - tgt = self.fail_boxes_float.get_addr_for_num(num) + tgt = stmtlocal.fail_boxes_float_addr(asmtlocal, num) if WORD == 4: rffi.cast(rffi.LONGP, tgt)[1] = value_hi else: @@ -2069,7 +2067,7 @@ # if not we_are_translated(): assert bytecode[4] == 0xCC - self.fail_boxes_count = num + asmtlocal.fail_boxes_count = num fail_index = rffi.cast(rffi.INTP, bytecode)[0] fail_index = rffi.cast(lltype.Signed, fail_index) return fail_index @@ -2152,7 +2150,45 @@ self.failure_recovery_code[exc + 2 * withfloats] = rawstart self.mc = None - def generate_failure(self, fail_index, locs, exc, locs_are_ref): + def generate_failure(self, fail_index, locs, boxes): + mc2 = codebuf.MachineCodeBlockWrapper() + self.write_failure_recovery_description(mc2, boxes, locs, fail_index) + bytecode = mc2.materialize(self.cpu.asmmemmgr, self.allblocks) + # + failure_recovery_func = llhelper(self._FAILURE_RECOVERY_FUNC, + self.failure_recovery_func) + failure_recovery_func = rffi.cast(lltype.Signed, + failure_recovery_func) + mc = self.mc + # Push the address of the recovery bytecode + mc.PUSH(imm(bytecode)) + # Reserve space for all general purpose registers + mc.ADD_ri(esp.value, -self.cpu.NUM_REGS * WORD) + # Save the surviving registers in there + for loc in locs: + if isinstance(loc, RegLoc): + assert not loc.is_xmm, "XXX returning an xmm reg: fixme" + mc.MOV_sr(loc.value * WORD, loc.value) + # ebx/rbx is callee-save in both i386 and x86-64 + mc.MOV_rr(ebx.value, esp.value) + + addr = self.cpu.get_on_leave_jitted_int(save_exception=False) + self.mc.CALL(imm(addr)) + + if IS_X86_32: + mc.PUSH_r(ebx.value) + elif IS_X86_64: + mc.MOV_rr(edi.value, ebx.value) + else: + raise AssertionError("Shouldn't happen") + mc.CALL(imm(failure_recovery_func)) + # returns in eax the fail_index + self._call_footer() + return + + # ---------- below, the original code, more efficient but not + # ---------- ready to handle stm thread-locals + xxxxxxxx self.mc.begin_reuse_scratch_register() for i in range(len(locs)): loc = locs[i] diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py --- a/pypy/jit/backend/x86/regalloc.py +++ b/pypy/jit/backend/x86/regalloc.py @@ -486,14 +486,13 @@ consider_guard_isnull = _consider_guard def consider_finish(self, op): - locs = [self.loc(op.getarg(i)) for i in range(op.numargs())] - locs_are_ref = [op.getarg(i).type == REF for i in range(op.numargs())] + boxes = [op.getarg(i) for i in range(op.numargs())] + locs = [self.loc(box) for box in boxes] fail_index = self.assembler.cpu.get_fail_descr_number(op.getdescr()) # note: no exception should currently be set in llop.get_exception_addr # even if this finish may be an exit_frame_with_exception (in this case # the exception instance is in locs[0]). - self.assembler.generate_failure(fail_index, locs, False, - locs_are_ref) + self.assembler.generate_failure(fail_index, locs, boxes) self.possibly_free_vars_for_op(op) def consider_guard_no_exception(self, op): diff --git a/pypy/jit/backend/x86/runner.py b/pypy/jit/backend/x86/runner.py --- a/pypy/jit/backend/x86/runner.py +++ b/pypy/jit/backend/x86/runner.py @@ -10,7 +10,7 @@ from pypy.jit.backend.x86.arch import FORCE_INDEX_OFS, IS_X86_32 from pypy.jit.backend.x86.profagent import ProfileAgent from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU -from pypy.jit.backend.x86 import regloc +from pypy.jit.backend.x86 import regloc, stmtlocal import sys from pypy.tool.ansi_print import ansi_log @@ -50,11 +50,8 @@ def setup(self): if self.opts is not None: - failargs_limit = self.opts.failargs_limit - else: - failargs_limit = 1000 - self.assembler = Assembler386(self, self.translate_support_code, - failargs_limit) + assert self.opts.failargs_limit == stmtlocal.FAILARGS_LIMIT + self.assembler = Assembler386(self, self.translate_support_code) def get_on_leave_jitted_hook(self): return self.assembler.leave_jitted_hook @@ -96,31 +93,32 @@ original_loop_token, log=log) def get_latest_value_int(self, index): - return self.assembler.fail_boxes_int.getitem(index) + return stmtlocal.get_asm_tlocal(self).fail_boxes_int[index] def get_latest_value_float(self, index): - return self.assembler.fail_boxes_float.getitem(index) + return stmtlocal.get_asm_tlocal(self).fail_boxes_float[index] def get_latest_value_ref(self, index): - return self.assembler.fail_boxes_ptr.getitem(index) + return stmtlocal.get_asm_tlocal(self).fail_boxes_ptr[index] def get_latest_value_count(self): - return self.assembler.fail_boxes_count + return stmtlocal.get_asm_tlocal(self).fail_boxes_count def clear_latest_values(self, count): - setitem = self.assembler.fail_boxes_ptr.setitem + asmtlocal = stmtlocal.get_asm_tlocal(self) null = lltype.nullptr(llmemory.GCREF.TO) for index in range(count): - setitem(index, null) + asmtlocal.fail_boxes_ptr[index] = null def get_latest_force_token(self): # the FORCE_TOKEN operation and this helper both return 'ebp'. - return self.assembler.fail_ebp + return stmtlocal.get_asm_tlocal(self).fail_ebp def make_execute_token(self, *ARGS): FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, lltype.Signed)) # def execute_token(executable_token, *args): + stmtlocal.prepare_asm_tlocal(self) clt = executable_token.compiled_loop_token assert len(args) == clt._debug_nbargs # diff --git a/pypy/jit/backend/x86/stmtlocal.py b/pypy/jit/backend/x86/stmtlocal.py --- a/pypy/jit/backend/x86/stmtlocal.py +++ b/pypy/jit/backend/x86/stmtlocal.py @@ -2,9 +2,14 @@ # This is hopefully a temporary hack for x86 and x86-64 # -from pypy.rpython.lltypesystem import lltype, rffi +from pypy.rpython.lltypesystem import lltype, rffi, llmemory +from pypy.rpython import annlowlevel +from pypy.jit.codewriter import longlong from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.jit.backend.x86.arch import WORD +from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib import rgc +from pypy.module.thread.ll_thread import get_ident if WORD == 4: @@ -34,3 +39,47 @@ mc.writechar('\x65') # %gs: else: mc.writechar('\x64') # %fs: + +# ____________________________________________________________ + + +FAILARGS_LIMIT = 1000 # xxx repeated constant + +ASSEMBLER_THREAD_LOCAL = lltype.GcStruct( + 'ASSEMBLER_THREAD_LOCAL', + ('fail_ebp', lltype.Signed), + ('fail_boxes_count', lltype.Signed), + ('fail_boxes_ptr', lltype.FixedSizeArray(llmemory.GCREF, FAILARGS_LIMIT)), + ('fail_boxes_int', lltype.FixedSizeArray(lltype.Signed, FAILARGS_LIMIT)), + ('fail_boxes_float', lltype.FixedSizeArray(longlong.FLOATSTORAGE, + FAILARGS_LIMIT)), + ) + + at rgc.no_collect +def get_asm_tlocal(cpu): + id = get_ident() + return cpu.assembler.asmtlocals[id] + +def prepare_asm_tlocal(cpu): + id = get_ident() + if id not in cpu.assembler.asmtlocals: + cpu.assembler.asmtlocals[id] = lltype.malloc(ASSEMBLER_THREAD_LOCAL) + +def fail_boxes_int_addr(tlocal, num): + tgt = llmemory.cast_ptr_to_adr(tlocal) + tgt += rffi.offsetof(ASSEMBLER_THREAD_LOCAL, 'fail_boxes_int') + tgt += num * rffi.sizeof(lltype.Signed) + return rffi.cast(lltype.Signed, tgt) + +def fail_boxes_ptr_addr(tlocal, num): + tgt = llmemory.cast_ptr_to_adr(tlocal) + tgt += rffi.offsetof(ASSEMBLER_THREAD_LOCAL, 'fail_boxes_ptr') + tgt = rffi.cast(lltype.Signed, tgt) + tgt += num * rffi.sizeof(llmemory.GCREF) + return tgt + +def fail_boxes_float_addr(tlocal, num): + tgt = llmemory.cast_ptr_to_adr(tlocal) + tgt += rffi.offsetof(ASSEMBLER_THREAD_LOCAL, 'fail_boxes_float') + tgt += num * rffi.sizeof(longlong.FLOATSTORAGE) + return rffi.cast(lltype.Signed, tgt) From noreply at buildbot.pypy.org Wed Oct 3 15:21:02 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 3 Oct 2012 15:21:02 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: Fixes Message-ID: <20121003132102.A1BBA1C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57765:c68951e7edec Date: 2012-10-03 15:20 +0200 http://bitbucket.org/pypy/pypy/changeset/c68951e7edec/ Log: Fixes diff --git a/pypy/jit/backend/x86/stmtlocal.py b/pypy/jit/backend/x86/stmtlocal.py --- a/pypy/jit/backend/x86/stmtlocal.py +++ b/pypy/jit/backend/x86/stmtlocal.py @@ -55,21 +55,28 @@ FAILARGS_LIMIT)), ) +def get_thread_ident(cpu): + if cpu.with_threads: + return get_ident() + else: + return 0 + @rgc.no_collect def get_asm_tlocal(cpu): - id = get_ident() + id = get_thread_ident(cpu) return cpu.assembler.asmtlocals[id] def prepare_asm_tlocal(cpu): - id = get_ident() + id = get_thread_ident(cpu) if id not in cpu.assembler.asmtlocals: cpu.assembler.asmtlocals[id] = lltype.malloc(ASSEMBLER_THREAD_LOCAL) def fail_boxes_int_addr(tlocal, num): tgt = llmemory.cast_ptr_to_adr(tlocal) tgt += rffi.offsetof(ASSEMBLER_THREAD_LOCAL, 'fail_boxes_int') + tgt = rffi.cast(lltype.Signed, tgt) tgt += num * rffi.sizeof(lltype.Signed) - return rffi.cast(lltype.Signed, tgt) + return tgt def fail_boxes_ptr_addr(tlocal, num): tgt = llmemory.cast_ptr_to_adr(tlocal) @@ -81,5 +88,6 @@ def fail_boxes_float_addr(tlocal, num): tgt = llmemory.cast_ptr_to_adr(tlocal) tgt += rffi.offsetof(ASSEMBLER_THREAD_LOCAL, 'fail_boxes_float') + tgt = rffi.cast(lltype.Signed, tgt) tgt += num * rffi.sizeof(longlong.FLOATSTORAGE) - return rffi.cast(lltype.Signed, tgt) + return tgt From noreply at buildbot.pypy.org Wed Oct 3 16:00:21 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 3 Oct 2012 16:00:21 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: hack hack Message-ID: <20121003140021.50BD51C0B32@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57766:62c032fbc968 Date: 2012-10-03 16:00 +0200 http://bitbucket.org/pypy/pypy/changeset/62c032fbc968/ Log: hack hack diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -2151,6 +2151,11 @@ self.mc = None def generate_failure(self, fail_index, locs, boxes): + # XXX temporary + if len(boxes) == 1 and isinstance(boxes[0], Const): + self.mc.MOV_ri(eax.value, boxes[0].getint()) + locs[0] = regloc.REGLOCS[0] + # mc2 = codebuf.MachineCodeBlockWrapper() self.write_failure_recovery_description(mc2, boxes, locs, fail_index) bytecode = mc2.materialize(self.cpu.asmmemmgr, self.allblocks) @@ -2165,6 +2170,7 @@ # Reserve space for all general purpose registers mc.ADD_ri(esp.value, -self.cpu.NUM_REGS * WORD) # Save the surviving registers in there + mc.MOV_sr(ebp.value * WORD, ebp.value) for loc in locs: if isinstance(loc, RegLoc): assert not loc.is_xmm, "XXX returning an xmm reg: fixme" From noreply at buildbot.pypy.org Wed Oct 3 16:07:18 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 3 Oct 2012 16:07:18 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: Comment out that too. Message-ID: <20121003140718.107E41C0E77@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57767:e971e420e8f5 Date: 2012-10-03 16:07 +0200 http://bitbucket.org/pypy/pypy/changeset/e971e420e8f5/ Log: Comment out that too. diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -2465,10 +2465,12 @@ value = self.cpu.done_with_this_frame_float_v else: raise AssertionError(kind) - self.mc.CMP_ri(eax.value, value) - # patched later - self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get 'done_with_this_frame' - je_location = self.mc.get_relative_pos() + +## # XXX killed temporarily +## self.mc.CMP_ri(eax.value, value) +## # patched later +## self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get 'done_with_this_frame' +## je_location = self.mc.get_relative_pos() # # Path A: use assembler_helper_adr jd = descr.outermost_jitdriver_sd @@ -2479,48 +2481,48 @@ if IS_X86_32 and isinstance(result_loc, StackLoc) and result_loc.type == FLOAT: self.mc.FSTPL_b(result_loc.value) #else: result_loc is already either eax or None, checked below - self.mc.JMP_l8(0) # jump to done, patched later - jmp_location = self.mc.get_relative_pos() - # - # Path B: fast path. Must load the return value, and reset the token - offset = jmp_location - je_location - assert 0 < offset <= 127 - self.mc.overwrite(je_location - 1, chr(offset)) - # - # Reset the vable token --- XXX really too much special logic here:-( - if jd.index_of_virtualizable >= 0: - from pypy.jit.backend.llsupport.descr import FieldDescr - fielddescr = jd.vable_token_descr - assert isinstance(fielddescr, FieldDescr) - ofs = fielddescr.offset - self.mc.MOV(eax, arglocs[1]) - self.mc.MOV_mi((eax.value, ofs), 0) - # in the line above, TOKEN_NONE = 0 - # - if op.result is not None: - # load the return value from fail_boxes_xxx[0] - kind = op.result.type - if kind == FLOAT: - xmmtmp = xmm0 - adr = self.fail_boxes_float.get_addr_for_num(0) - self.mc.MOVSD(xmmtmp, heap(adr)) - self.mc.MOVSD(result_loc, xmmtmp) - else: - assert result_loc is eax - if kind == INT: - adr = self.fail_boxes_int.get_addr_for_num(0) - self.mc.MOV(eax, heap(adr)) - elif kind == REF: - adr = self.fail_boxes_ptr.get_addr_for_num(0) - self.mc.MOV(eax, heap(adr)) - self.mc.MOV(heap(adr), imm0) - else: - raise AssertionError(kind) - # - # Here we join Path A and Path B again - offset = self.mc.get_relative_pos() - jmp_location - assert 0 <= offset <= 127 - self.mc.overwrite(jmp_location - 1, chr(offset)) +## self.mc.JMP_l8(0) # jump to done, patched later +## jmp_location = self.mc.get_relative_pos() +## # +## # Path B: fast path. Must load the return value, and reset the token +## offset = jmp_location - je_location +## assert 0 < offset <= 127 +## self.mc.overwrite(je_location - 1, chr(offset)) +## # +## # Reset the vable token --- XXX really too much special logic here:-( +## if jd.index_of_virtualizable >= 0: +## from pypy.jit.backend.llsupport.descr import FieldDescr +## fielddescr = jd.vable_token_descr +## assert isinstance(fielddescr, FieldDescr) +## ofs = fielddescr.offset +## self.mc.MOV(eax, arglocs[1]) +## self.mc.MOV_mi((eax.value, ofs), 0) +## # in the line above, TOKEN_NONE = 0 +## # +## if op.result is not None: +## # load the return value from fail_boxes_xxx[0] +## kind = op.result.type +## if kind == FLOAT: +## xmmtmp = xmm0 +## adr = self.fail_boxes_float.get_addr_for_num(0) +## self.mc.MOVSD(xmmtmp, heap(adr)) +## self.mc.MOVSD(result_loc, xmmtmp) +## else: +## assert result_loc is eax +## if kind == INT: +## adr = self.fail_boxes_int.get_addr_for_num(0) +## self.mc.MOV(eax, heap(adr)) +## elif kind == REF: +## adr = self.fail_boxes_ptr.get_addr_for_num(0) +## self.mc.MOV(eax, heap(adr)) +## self.mc.MOV(heap(adr), imm0) +## else: +## raise AssertionError(kind) +## # +## # Here we join Path A and Path B again +## offset = self.mc.get_relative_pos() - jmp_location +## assert 0 <= offset <= 127 +## self.mc.overwrite(jmp_location - 1, chr(offset)) self.mc.CMP_bi(FORCE_INDEX_OFS, 0) self.implement_guard(guard_token, 'L') From noreply at buildbot.pypy.org Wed Oct 3 16:28:03 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 3 Oct 2012 16:28:03 +0200 (CEST) Subject: [pypy-commit] pypy default: A constant offsetof() in a FixedSizeArray. Message-ID: <20121003142803.D62161C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57768:235ae082806e Date: 2012-10-03 16:27 +0200 http://bitbucket.org/pypy/pypy/changeset/235ae082806e/ Log: A constant offsetof() in a FixedSizeArray. diff --git a/pypy/translator/c/primitive.py b/pypy/translator/c/primitive.py --- a/pypy/translator/c/primitive.py +++ b/pypy/translator/c/primitive.py @@ -31,6 +31,11 @@ if isinstance(value, Symbolic): if isinstance(value, FieldOffset): structnode = db.gettypedefnode(value.TYPE) + if isinstance(value.TYPE, FixedSizeArray): + assert value.fldname.startswith('item') + repeat = value.fldname[4:] + size = 'sizeof(%s)' % (cdecl(db.gettype(value.TYPE.OF), ''),) + return '(%s * %s)' % (size, repeat) return 'offsetof(%s, %s)'%( cdecl(db.gettype(value.TYPE), ''), structnode.c_struct_field_name(value.fldname)) diff --git a/pypy/translator/c/test/test_lladdresses.py b/pypy/translator/c/test/test_lladdresses.py --- a/pypy/translator/c/test/test_lladdresses.py +++ b/pypy/translator/c/test/test_lladdresses.py @@ -52,6 +52,19 @@ res = fc(42.42) assert res == f(42.42) +def test_offset_inside_fixed_array(): + S = lltype.FixedSizeArray(lltype.Signed, 10) + offset = FieldOffset(S, 'item4') + def f(value): + s = lltype.malloc(S, flavor='raw') + s[4] = value + res = (cast_ptr_to_adr(s) + offset).signed[0] + lltype.free(s, flavor='raw') + return res + fc = compile(f, [int]) + res = fc(42) + assert res == 42 + def test_pointer_arithmetic(): def f(offset, char): addr = raw_malloc(10000) From noreply at buildbot.pypy.org Wed Oct 3 16:34:42 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 3 Oct 2012 16:34:42 +0200 (CEST) Subject: [pypy-commit] pypy py3k: kill some of the workarounds introduced in 03e3cf83880b about == and != Message-ID: <20121003143442.E994D1C002D@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57769:54ca17571e0f Date: 2012-10-03 12:10 +0200 http://bitbucket.org/pypy/pypy/changeset/54ca17571e0f/ Log: kill some of the workarounds introduced in 03e3cf83880b about == and != between sets and ANY, as they are no longer needed. This fixes the comparison of sets and dictviews diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -1017,7 +1017,7 @@ exec src.compile() in globals() - for opname in ['lt', 'le', 'eq', 'ne', 'ge', 'gt']: + for opname in ['lt', 'le', 'ne', 'ge', 'gt']: src = py.code.Source(""" def {opname}__DictViewKeys_ANY(space, w_dictview, w_other): w_left = space.call_function(space.w_set, w_dictview) diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -1058,13 +1058,6 @@ eq__Frozenset_settypedef = eq__Set_settypedef eq__Frozenset_frozensettypedef = eq__Set_settypedef -def eq__Set_ANY(space, w_left, w_other): - # workaround to have "set() == 42" return False instead of falling - # back to cmp(set(), 42) because the latter raises a TypeError - return space.w_False - -eq__Frozenset_ANY = eq__Set_ANY - def ne__Set_Set(space, w_left, w_other): return space.wrap(not w_left.equals(w_other)) @@ -1081,13 +1074,6 @@ ne__Frozenset_settypedef = ne__Set_settypedef ne__Frozenset_frozensettypedef = ne__Set_settypedef - -def ne__Set_ANY(space, w_left, w_other): - # more workarounds - return space.w_True - -ne__Frozenset_ANY = ne__Set_ANY - def contains__Set_ANY(space, w_left, w_other): try: return space.newbool(w_left.has_key(w_other)) diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -796,7 +796,12 @@ # assert d.keys() - {1} == {2, 3} assert {1, 4} - d.keys() == {4} - + # + assert d.keys() == {1, 2, 3} + assert {1, 2, 3} == d.keys() + assert not d.keys() != {1, 2, 3} + assert not {1, 2, 3} != d.keys() + def test_keys_items_contained(self): def helper(fn): empty = fn(dict()) From noreply at buildbot.pypy.org Wed Oct 3 16:34:44 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 3 Oct 2012 16:34:44 +0200 (CEST) Subject: [pypy-commit] pypy py3k: don't override the default 'ne' multimethod Message-ID: <20121003143444.441D11C002D@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57770:9184d8149ca0 Date: 2012-10-03 12:16 +0200 http://bitbucket.org/pypy/pypy/changeset/9184d8149ca0/ Log: don't override the default 'ne' multimethod diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -982,6 +982,7 @@ eq__DictViewItems_settypedef = eq__DictViewItems_DictViewItems eq__DictViewItems_frozensettypedef = eq__DictViewItems_DictViewItems + def repr__DictViewKeys(space, w_dictview): w_seq = space.call_function(space.w_list, w_dictview) w_repr = space.repr(w_seq) @@ -1017,7 +1018,7 @@ exec src.compile() in globals() - for opname in ['lt', 'le', 'ne', 'ge', 'gt']: + for opname in ['lt', 'le', 'ge', 'gt']: src = py.code.Source(""" def {opname}__DictViewKeys_ANY(space, w_dictview, w_other): w_left = space.call_function(space.w_set, w_dictview) From noreply at buildbot.pypy.org Wed Oct 3 16:34:45 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 3 Oct 2012 16:34:45 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fix != between dict.{keys, items} and {set, frozenset} Message-ID: <20121003143445.736D51C002D@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57771:2ea52932a24a Date: 2012-10-03 15:00 +0200 http://bitbucket.org/pypy/pypy/changeset/2ea52932a24a/ Log: fix != between dict.{keys,items} and {set,frozenset} diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -982,6 +982,13 @@ eq__DictViewItems_settypedef = eq__DictViewItems_DictViewItems eq__DictViewItems_frozensettypedef = eq__DictViewItems_DictViewItems +def ne__DictViewKeys_settypedef(space, w_dict, w_set): + return space.not_(eq__DictViewItems_settypedef(space, w_dict, w_set)) +ne__DictViewKeys_frozensettypedef = ne__DictViewKeys_settypedef + +def ne__DictViewItems_settypedef(space, w_dict, w_set): + return space.not_(eq__DictViewItems_settypedef(space, w_dict, w_set)) +ne__DictViewItems_frozensettypedef = ne__DictViewItems_settypedef def repr__DictViewKeys(space, w_dictview): w_seq = space.call_function(space.w_list, w_dictview) diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -784,7 +784,7 @@ assert d1.items() - d2.items() == set([('a', 1)]) assert d1.items() - d3.items() == set([('a', 1), ('b', 2)]) - def test_keys_items_set_operations_any_type(self): + def test_keys_set_operations_any_type(self): d = {1: 'a', 2: 'b', 3: 'c'} assert d.keys() & {1} == {1} assert d.keys() & {1: 'foo'} == {1} @@ -799,9 +799,35 @@ # assert d.keys() == {1, 2, 3} assert {1, 2, 3} == d.keys() + assert d.keys() == frozenset({1, 2, 3}) + assert frozenset({1, 2, 3}) == d.keys() assert not d.keys() != {1, 2, 3} assert not {1, 2, 3} != d.keys() - + assert not d.keys() != frozenset({1, 2, 3}) + assert not frozenset({1, 2, 3}) != d.keys() + + def test_items_set_operations_any_type(self): + d = {1: 'a', 2: 'b', 3: 'c'} + assert d.items() & {(1, 'a')} == {(1, 'a')} + assert d.items() & {(1, 'a'): 'foo'} == {(1, 'a')} + assert d.items() & [(1, 'a'), (2, 'b')] == {(1, 'a'), (2, 'b')} + # + assert {(1, 'a')} & d.items() == {(1, 'a')} + assert {(1, 'a'): 'foo'} & d.items() == {(1, 'a')} + assert [(1, 'a'), (2, 'b')] & d.items() == {(1, 'a'), (2, 'b')} + # + assert d.items() - {(1, 'a')} == {(2, 'b'), (3, 'c')} + assert {(1, 'a'), 4} - d.items() == {4} + # + assert d.items() == {(1, 'a'), (2, 'b'), (3, 'c')} + assert {(1, 'a'), (2, 'b'), (3, 'c')} == d.items() + assert d.items() == frozenset({(1, 'a'), (2, 'b'), (3, 'c')}) + assert frozenset({(1, 'a'), (2, 'b'), (3, 'c')}) == d.items() + assert not d.items() != {(1, 'a'), (2, 'b'), (3, 'c')} + assert not {(1, 'a'), (2, 'b'), (3, 'c')} != d.items() + assert not d.items() != frozenset({(1, 'a'), (2, 'b'), (3, 'c')}) + assert not frozenset({(1, 'a'), (2, 'b'), (3, 'c')}) != d.items() + def test_keys_items_contained(self): def helper(fn): empty = fn(dict()) From noreply at buildbot.pypy.org Wed Oct 3 16:34:46 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 3 Oct 2012 16:34:46 +0200 (CEST) Subject: [pypy-commit] pypy py3k: a failing test Message-ID: <20121003143446.9C8BB1C002D@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57772:824cb5f4ce81 Date: 2012-10-03 16:06 +0200 http://bitbucket.org/pypy/pypy/changeset/824cb5f4ce81/ Log: a failing test diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -828,6 +828,14 @@ assert not d.items() != frozenset({(1, 'a'), (2, 'b'), (3, 'c')}) assert not frozenset({(1, 'a'), (2, 'b'), (3, 'c')}) != d.items() + def test_dictviewset_unshasable_values(self): + class C: + def __eq__(self, other): + return True + d = {1: C()} + assert d.items() <= d.items() + + def test_keys_items_contained(self): def helper(fn): empty = fn(dict()) From noreply at buildbot.pypy.org Wed Oct 3 16:34:47 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 3 Oct 2012 16:34:47 +0200 (CEST) Subject: [pypy-commit] pypy py3k: implement all the cmp ops between dictviews and {set, frozenset} in terms of all_implemented_in, as CPython does. This is needed to be able tocompare .items() on dictionaries whose value are unhashable Message-ID: <20121003143447.CC75C1C002D@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57773:a9c7b9a2cb5d Date: 2012-10-03 16:34 +0200 http://bitbucket.org/pypy/pypy/changeset/a9c7b9a2cb5d/ Log: implement all the cmp ops between dictviews and {set,frozenset} in terms of all_implemented_in, as CPython does. This is needed to be able tocompare .items() on dictionaries whose value are unhashable diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -970,25 +970,51 @@ return space.w_True -def eq__DictViewKeys_DictViewKeys(space, w_dictview, w_otherview): - if space.eq_w(space.len(w_dictview), space.len(w_otherview)): - return all_contained_in(space, w_dictview, w_otherview) +def comparison_impl(fn): + opname = fn.func_name + types = ['DictViewKeys', 'DictViewItems', 'settypedef', 'frozensettypedef'] + for lefttype in types: + for righttype in types: + fnname = '%s__%s_%s' % (opname, lefttype, righttype) + globals()[fnname] = fn + return fn + + at comparison_impl +def eq(space, w_left, w_right): + if space.eq_w(space.len(w_left), space.len(w_right)): + return all_contained_in(space, w_left, w_right) return space.w_False -eq__DictViewKeys_settypedef = eq__DictViewKeys_DictViewKeys -eq__DictViewKeys_frozensettypedef = eq__DictViewKeys_DictViewKeys -eq__DictViewKeys_DictViewItems = eq__DictViewKeys_DictViewKeys -eq__DictViewItems_DictViewItems = eq__DictViewKeys_DictViewKeys -eq__DictViewItems_settypedef = eq__DictViewItems_DictViewItems -eq__DictViewItems_frozensettypedef = eq__DictViewItems_DictViewItems + at comparison_impl +def ne(space, w_left, w_right): + if not space.eq_w(space.len(w_left), space.len(w_right)): + return space.w_True + return space.not_(all_contained_in(space, w_left, w_right)) -def ne__DictViewKeys_settypedef(space, w_dict, w_set): - return space.not_(eq__DictViewItems_settypedef(space, w_dict, w_set)) -ne__DictViewKeys_frozensettypedef = ne__DictViewKeys_settypedef + at comparison_impl +def lt(space, w_left, w_right): + if space.len_w(w_left) < space.len_w(w_right): + return all_contained_in(space, w_left, w_right) + return space.w_False -def ne__DictViewItems_settypedef(space, w_dict, w_set): - return space.not_(eq__DictViewItems_settypedef(space, w_dict, w_set)) -ne__DictViewItems_frozensettypedef = ne__DictViewItems_settypedef + at comparison_impl +def le(space, w_left, w_right): + if space.len_w(w_left) <= space.len_w(w_right): + return all_contained_in(space, w_left, w_right) + return space.w_False + + at comparison_impl +def gt(space, w_left, w_right): + if space.len_w(w_left) > space.len_w(w_right): + return all_contained_in(space, w_right, w_left) + return space.w_False + + at comparison_impl +def ge(space, w_left, w_right): + if space.len_w(w_left) >= space.len_w(w_right): + return all_contained_in(space, w_right, w_left) + return space.w_False + def repr__DictViewKeys(space, w_dictview): w_seq = space.call_function(space.w_list, w_dictview) @@ -1024,24 +1050,6 @@ """.format(opname=opname, methodname=methodname)) exec src.compile() in globals() - - for opname in ['lt', 'le', 'ge', 'gt']: - src = py.code.Source(""" - def {opname}__DictViewKeys_ANY(space, w_dictview, w_other): - w_left = space.call_function(space.w_set, w_dictview) - w_right = space.call_function(space.w_set, w_other) - return space.{opname}(w_left, w_right) - - def {opname}__ANY_DictViewKeys(space, w_other, w_dictview): - w_left = space.call_function(space.w_set, w_other) - w_right = space.call_function(space.w_set, w_dictview) - return space.{opname}(w_left, w_right) - - {opname}__DictViewItems_ANY = {opname}__DictViewKeys_ANY - {opname}__ANY_DictViewItems = {opname}__ANY_DictViewKeys - """.format(opname=opname)) - exec src.compile() in globals() - generate_setops() diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -835,6 +835,10 @@ d = {1: C()} assert d.items() <= d.items() + def test_compare_keys_and_items(self): + d1 = {1: 2} + d2 = {(1, 2): 'foo'} + assert d1.items() == d2.keys() def test_keys_items_contained(self): def helper(fn): From noreply at buildbot.pypy.org Wed Oct 3 16:45:21 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 3 Oct 2012 16:45:21 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: hg merge default Message-ID: <20121003144521.DD9A61C00EC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57774:c3dbd0810819 Date: 2012-10-03 14:46 +0000 http://bitbucket.org/pypy/pypy/changeset/c3dbd0810819/ Log: hg merge default diff too long, truncating to 2000 out of 14552 lines diff --git a/lib-python/2.7/test/test_csv.py b/lib-python/2.7/test/test_csv.py --- a/lib-python/2.7/test/test_csv.py +++ b/lib-python/2.7/test/test_csv.py @@ -20,7 +20,8 @@ """ def _test_arg_valid(self, ctor, arg): self.assertRaises(TypeError, ctor) - self.assertRaises(TypeError, ctor, None) + # PyPy gets an AttributeError instead of a TypeError + self.assertRaises((TypeError, AttributeError), ctor, None) self.assertRaises(TypeError, ctor, arg, bad_attr = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 'XX') @@ -59,7 +60,8 @@ self.assertRaises((TypeError, AttributeError), setattr, obj.dialect, 'delimiter', ':') self.assertRaises(AttributeError, delattr, obj.dialect, 'quoting') - self.assertRaises(AttributeError, setattr, obj.dialect, + # PyPy gets a TypeError instead of an AttributeError + self.assertRaises((AttributeError, TypeError), setattr, obj.dialect, 'quoting', None) def test_reader_attrs(self): @@ -133,7 +135,8 @@ os.unlink(name) def test_write_arg_valid(self): - self.assertRaises(csv.Error, self._write_test, None, '') + # PyPy gets a TypeError instead of a csv.Error for "not a sequence" + self.assertRaises((csv.Error, TypeError), self._write_test, None, '') self._write_test((), '') self._write_test([None], '""') self.assertRaises(csv.Error, self._write_test, diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -183,7 +183,7 @@ RegrTest('test_cpickle.py', core=True), RegrTest('test_cprofile.py'), RegrTest('test_crypt.py', usemodules='crypt', skip=skip_win32), - RegrTest('test_csv.py'), + RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_curses.py', skip="unsupported extension module"), RegrTest('test_datetime.py'), diff --git a/lib_pypy/_csv.py b/lib_pypy/_csv.py --- a/lib_pypy/_csv.py +++ b/lib_pypy/_csv.py @@ -363,9 +363,7 @@ (self.dialect.delimiter, self.dialect.quotechar)) elif self.state == self.EAT_CRNL: - if c in '\r\n': - pass - else: + if c not in '\r\n': raise Error("new-line character seen in unquoted field - " "do you need to open the file " "in universal-newline mode?") diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py --- a/lib_pypy/_ctypes/pointer.py +++ b/lib_pypy/_ctypes/pointer.py @@ -81,7 +81,9 @@ addr = self._buffer[0] if addr == 0: raise ValueError("NULL pointer access") - return self._type_.from_address(addr) + instance = self._type_.from_address(addr) + instance.__dict__['_base'] = self + return instance def setcontents(self, value): if not isinstance(value, self._type_): diff --git a/lib_pypy/numpypy/core/_methods.py b/lib_pypy/numpypy/core/_methods.py --- a/lib_pypy/numpypy/core/_methods.py +++ b/lib_pypy/numpypy/core/_methods.py @@ -1,62 +1,77 @@ # Array methods which are called by the both the C-code for the method # and the Python code for the NumPy-namespace function +#from numpy.core import multiarray as mu +#from numpy.core import umath as um import _numpypy as mu um = mu -#from numpypy.core import umath as um -from numpypy.core.numeric import asanyarray +from numpy.core.numeric import asanyarray -def _amax(a, axis=None, out=None, skipna=False, keepdims=False): +def _amax(a, axis=None, out=None, keepdims=False): return um.maximum.reduce(a, axis=axis, - out=out, skipna=skipna, keepdims=keepdims) + out=out, keepdims=keepdims) -def _amin(a, axis=None, out=None, skipna=False, keepdims=False): +def _amin(a, axis=None, out=None, keepdims=False): return um.minimum.reduce(a, axis=axis, - out=out, skipna=skipna, keepdims=keepdims) + out=out, keepdims=keepdims) -def _sum(a, axis=None, dtype=None, out=None, skipna=False, keepdims=False): +def _sum(a, axis=None, dtype=None, out=None, keepdims=False): return um.add.reduce(a, axis=axis, dtype=dtype, - out=out, skipna=skipna, keepdims=keepdims) + out=out, keepdims=keepdims) -def _prod(a, axis=None, dtype=None, out=None, skipna=False, keepdims=False): +def _prod(a, axis=None, dtype=None, out=None, keepdims=False): return um.multiply.reduce(a, axis=axis, dtype=dtype, - out=out, skipna=skipna, keepdims=keepdims) + out=out, keepdims=keepdims) -def _mean(a, axis=None, dtype=None, out=None, skipna=False, keepdims=False): +def _any(a, axis=None, dtype=None, out=None, keepdims=False): + return um.logical_or.reduce(a, axis=axis, dtype=dtype, out=out, + keepdims=keepdims) + +def _all(a, axis=None, dtype=None, out=None, keepdims=False): + return um.logical_and.reduce(a, axis=axis, dtype=dtype, out=out, + keepdims=keepdims) + +def _count_reduce_items(arr, axis): + if axis is None: + axis = tuple(xrange(arr.ndim)) + if not isinstance(axis, tuple): + axis = (axis,) + items = 1 + for ax in axis: + items *= arr.shape[ax] + return items + +def _mean(a, axis=None, dtype=None, out=None, keepdims=False): arr = asanyarray(a) # Upgrade bool, unsigned int, and int to float64 if dtype is None and arr.dtype.kind in ['b','u','i']: ret = um.add.reduce(arr, axis=axis, dtype='f8', - out=out, skipna=skipna, keepdims=keepdims) + out=out, keepdims=keepdims) else: ret = um.add.reduce(arr, axis=axis, dtype=dtype, - out=out, skipna=skipna, keepdims=keepdims) - rcount = mu.count_reduce_items(arr, axis=axis, - skipna=skipna, keepdims=keepdims) + out=out, keepdims=keepdims) + rcount = _count_reduce_items(arr, axis) if isinstance(ret, mu.ndarray): ret = um.true_divide(ret, rcount, - casting='unsafe', subok=False) + out=ret, casting='unsafe', subok=False) else: ret = ret / float(rcount) return ret def _var(a, axis=None, dtype=None, out=None, ddof=0, - skipna=False, keepdims=False): + keepdims=False): arr = asanyarray(a) # First compute the mean, saving 'rcount' for reuse later if dtype is None and arr.dtype.kind in ['b','u','i']: - arrmean = um.add.reduce(arr, axis=axis, dtype='f8', - skipna=skipna, keepdims=True) + arrmean = um.add.reduce(arr, axis=axis, dtype='f8', keepdims=True) else: - arrmean = um.add.reduce(arr, axis=axis, dtype=dtype, - skipna=skipna, keepdims=True) - rcount = mu.count_reduce_items(arr, axis=axis, - skipna=skipna, keepdims=True) + arrmean = um.add.reduce(arr, axis=axis, dtype=dtype, keepdims=True) + rcount = _count_reduce_items(arr, axis) if isinstance(arrmean, mu.ndarray): arrmean = um.true_divide(arrmean, rcount, - casting='unsafe', subok=False) + out=arrmean, casting='unsafe', subok=False) else: arrmean = arrmean / float(rcount) @@ -65,13 +80,12 @@ # (arr - arrmean) ** 2 if arr.dtype.kind == 'c': - x = um.multiply(x, um.conjugate(x)).real + x = um.multiply(x, um.conjugate(x), out=x).real else: - x = um.multiply(x, x) + x = um.multiply(x, x, out=x) # add.reduce((arr - arrmean) ** 2, axis) - ret = um.add.reduce(x, axis=axis, dtype=dtype, out=out, - skipna=skipna, keepdims=keepdims) + ret = um.add.reduce(x, axis=axis, dtype=dtype, out=out, keepdims=keepdims) # add.reduce((arr - arrmean) ** 2, axis) / (n - ddof) if not keepdims and isinstance(rcount, mu.ndarray): @@ -79,19 +93,18 @@ rcount -= ddof if isinstance(ret, mu.ndarray): ret = um.true_divide(ret, rcount, - casting='unsafe', subok=False) + out=ret, casting='unsafe', subok=False) else: ret = ret / float(rcount) return ret -def _std(a, axis=None, dtype=None, out=None, ddof=0, - skipna=False, keepdims=False): +def _std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof, - skipna=skipna, keepdims=keepdims) + keepdims=keepdims) if isinstance(ret, mu.ndarray): - ret = um.sqrt(ret) + ret = um.sqrt(ret, out=ret) else: ret = um.sqrt(ret) diff --git a/lib_pypy/numpypy/core/arrayprint.py b/lib_pypy/numpypy/core/arrayprint.py --- a/lib_pypy/numpypy/core/arrayprint.py +++ b/lib_pypy/numpypy/core/arrayprint.py @@ -14,9 +14,9 @@ import sys import _numpypy as _nt -from _numpypy import maximum, minimum, absolute, not_equal, isinf, isnan, isna +from _numpypy import maximum, minimum, absolute, not_equal, isnan, isinf #from _numpypy import format_longfloat, datetime_as_string, datetime_data -from .fromnumeric import ravel +from fromnumeric import ravel def product(x, y): return x*y @@ -29,7 +29,6 @@ _line_width = 75 _nan_str = 'nan' _inf_str = 'inf' -_na_str = 'NA' _formatter = None # formatting function for array elements if sys.version_info[0] >= 3: @@ -37,7 +36,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None, linewidth=None, suppress=None, - nanstr=None, infstr=None, nastr=None, + nanstr=None, infstr=None, formatter=None): """ Set printing options. @@ -65,8 +64,6 @@ String representation of floating point not-a-number (default nan). infstr : str, optional String representation of floating point infinity (default inf). - nastr : str, optional - String representation of NA missing value (default NA). formatter : dict of callables, optional If not None, the keys should indicate the type(s) that the respective formatting function applies to. Callables should return a string. @@ -144,7 +141,7 @@ global _summaryThreshold, _summaryEdgeItems, _float_output_precision, \ _line_width, _float_output_suppress_small, _nan_str, _inf_str, \ - _na_str, _formatter + _formatter if linewidth is not None: _line_width = linewidth if threshold is not None: @@ -159,8 +156,6 @@ _nan_str = nanstr if infstr is not None: _inf_str = infstr - if nastr is not None: - _na_str = nastr _formatter = formatter def get_printoptions(): @@ -195,7 +190,6 @@ suppress=_float_output_suppress_small, nanstr=_nan_str, infstr=_inf_str, - nastr=_na_str, formatter=_formatter) return d @@ -219,19 +213,14 @@ return b def _boolFormatter(x): - if isna(x): - return str(x).replace('NA', _na_str, 1) - elif x: + if x: return ' True' else: return 'False' def repr_format(x): - if isna(x): - return str(x).replace('NA', _na_str, 1) - else: - return repr(x) + return repr(x) def _array2string(a, max_line_width, precision, suppress_small, separator=' ', prefix="", formatter=None): @@ -262,8 +251,8 @@ #'complexfloat' : ComplexFormat(data, precision, # suppress_small), #'longcomplexfloat' : LongComplexFormat(precision), - #'datetime' : DatetimeFormat(data), - #'timedelta' : TimedeltaFormat(data), + 'datetime' : DatetimeFormat(data), + 'timedelta' : TimedeltaFormat(data), 'numpystr' : repr_format, 'str' : str} @@ -309,11 +298,11 @@ # format_function = formatdict['longfloat'] #else: format_function = formatdict['float'] - elif issubclass(dtypeobj, _nt.complexfloating): - if issubclass(dtypeobj, _nt.clongfloat): - format_function = formatdict['longcomplexfloat'] - else: - format_function = formatdict['complexfloat'] + #elif issubclass(dtypeobj, _nt.complexfloating): + # if issubclass(dtypeobj, _nt.clongfloat): + # format_function = formatdict['longcomplexfloat'] + # else: + # format_function = formatdict['complexfloat'] elif issubclass(dtypeobj, (_nt.unicode_, _nt.string_)): format_function = formatdict['numpystr'] elif issubclass(dtypeobj, _nt.datetime64): @@ -437,20 +426,17 @@ if a.shape == (): x = a.item() - if isna(x): - lst = str(x).replace('NA', _na_str, 1) - else: - try: - lst = a._format(x) - msg = "The `_format` attribute is deprecated in Numpy " \ - "2.0 and will be removed in 2.1. Use the " \ - "`formatter` kw instead." - import warnings - warnings.warn(msg, DeprecationWarning) - except AttributeError: - if isinstance(x, tuple): - x = _convert_arrays(x) - lst = style(x) + try: + lst = a._format(x) + msg = "The `_format` attribute is deprecated in Numpy " \ + "2.0 and will be removed in 2.1. Use the " \ + "`formatter` kw instead." + import warnings + warnings.warn(msg, DeprecationWarning) + except AttributeError: + if isinstance(x, tuple): + x = _convert_arrays(x) + lst = style(x) elif reduce(product, a.shape) == 0: # treat as a null array if any of shape elements == 0 lst = "[]" @@ -542,38 +528,33 @@ self.exp_format = False self.large_exponent = False self.max_str_len = 0 - #try: - self.fillFormat(data) - #except (TypeError, NotImplementedError): + try: + self.fillFormat(data) + except (TypeError, NotImplementedError): # if reduce(data) fails, this instance will not be called, just # instantiated in formatdict. - #pass + pass def fillFormat(self, data): import numeric as _nc - # XXX pypy unimplemented - #errstate = _nc.seterr(all='ignore') + errstate = _nc.seterr(all='ignore') try: - special = isnan(data) | isinf(data) | isna(data) - special[isna(data)] = False + special = isnan(data) | isinf(data) valid = not_equal(data, 0) & ~special - valid[isna(data)] = False non_zero = absolute(data.compress(valid)) if len(non_zero) == 0: max_val = 0. min_val = 0. else: - max_val = maximum.reduce(non_zero, skipna=True) - min_val = minimum.reduce(non_zero, skipna=True) + max_val = maximum.reduce(non_zero) + min_val = minimum.reduce(non_zero) if max_val >= 1.e8: self.exp_format = True if not self.suppress_small and (min_val < 0.0001 or max_val/min_val > 1000.): self.exp_format = True finally: - pass - # XXX pypy unimplemented - #_nc.seterr(**errstate) + _nc.seterr(**errstate) if self.exp_format: self.large_exponent = 0 < min_val < 1e-99 or max_val >= 1e100 @@ -594,11 +575,10 @@ precision = 0 precision = min(self.precision, precision) self.max_str_len = len(str(int(max_val))) + precision + 2 - if special.any(): + if _nc.any(special): self.max_str_len = max(self.max_str_len, len(_nan_str), - len(_inf_str)+1, - len(_na_str)) + len(_inf_str)+1) if self.sign: format = '%#+' else: @@ -610,11 +590,9 @@ def __call__(self, x, strip_zeros=True): import numeric as _nc - #err = _nc.seterr(invalid='ignore') + err = _nc.seterr(invalid='ignore') try: - if isna(x): - return self.special_fmt % (str(x).replace('NA', _na_str, 1),) - elif isnan(x): + if isnan(x): if self.sign: return self.special_fmt % ('+' + _nan_str,) else: @@ -628,8 +606,7 @@ else: return self.special_fmt % ('-' + _inf_str,) finally: - pass - #_nc.seterr(**err) + _nc.seterr(**err) s = self.format % x if self.large_exponent: @@ -658,10 +635,10 @@ class IntegerFormat(object): def __init__(self, data): try: - max_str_len = max(len(str(maximum.reduce(data, skipna=True))), - len(str(minimum.reduce(data, skipna=True)))) + max_str_len = max(len(str(maximum.reduce(data))), + len(str(minimum.reduce(data)))) self.format = '%' + str(max_str_len) + 'd' - except TypeError, NotImplementedError: + except (TypeError, NotImplementedError): # if reduce(data) fails, this instance will not be called, just # instantiated in formatdict. pass @@ -670,9 +647,7 @@ pass def __call__(self, x): - if isna(x): - return str(x).replace('NA', _na_str, 1) - elif _MININT < x < _MAXINT: + if _MININT < x < _MAXINT: return self.format % x else: return "%s" % x @@ -685,9 +660,7 @@ self.sign = sign def __call__(self, x): - if isna(x): - return str(x).replace('NA', _na_str, 1) - elif isnan(x): + if isnan(x): if self.sign: return '+' + _nan_str else: @@ -715,12 +688,9 @@ self.imag_format = LongFloatFormat(precision, sign=True) def __call__(self, x): - if isna(x): - return str(x).replace('NA', _na_str, 1) - else: - r = self.real_format(x.real) - i = self.imag_format(x.imag) - return r + i + 'j' + r = self.real_format(x.real) + i = self.imag_format(x.imag) + return r + i + 'j' class ComplexFormat(object): @@ -730,17 +700,14 @@ sign=True) def __call__(self, x): - if isna(x): - return str(x).replace('NA', _na_str, 1) + r = self.real_format(x.real, strip_zeros=False) + i = self.imag_format(x.imag, strip_zeros=False) + if not self.imag_format.exp_format: + z = i.rstrip('0') + i = z + 'j' + ' '*(len(i)-len(z)) else: - r = self.real_format(x.real, strip_zeros=False) - i = self.imag_format(x.imag, strip_zeros=False) - if not self.imag_format.exp_format: - z = i.rstrip('0') - i = z + 'j' + ' '*(len(i)-len(z)) - else: - i = i + 'j' - return r + i + i = i + 'j' + return r + i class DatetimeFormat(object): def __init__(self, x, unit=None, @@ -765,13 +732,10 @@ self.casting = casting def __call__(self, x): - if isna(x): - return str(x).replace('NA', _na_str, 1) - else: - return "'%s'" % datetime_as_string(x, - unit=self.unit, - timezone=self.timezone, - casting=self.casting) + return "'%s'" % datetime_as_string(x, + unit=self.unit, + timezone=self.timezone, + casting=self.casting) class TimedeltaFormat(object): def __init__(self, data): @@ -782,8 +746,5 @@ self.format = '%' + str(max_str_len) + 'd' def __call__(self, x): - if isna(x): - return str(x).replace('NA', _na_str, 1) - else: - return self.format % x.astype('i8') + return self.format % x.astype('i8') diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,6 +1,7 @@ from _numpypy import array, ndarray, int_, float_, bool_ #, complex_# , longlong from _numpypy import concatenate +from .fromnumeric import any import math import sys import _numpypy as multiarray # ARGH @@ -8,7 +9,11 @@ newaxis = None -def asanyarray(a, dtype=None, order=None, maskna=None, ownmaskna=False): +# XXX this file to be reviewed +def seterr(**args): + return args + +def asanyarray(a, dtype=None, order=None): """ Convert the input to an ndarray, but pass ndarray subclasses through. @@ -23,13 +28,6 @@ order : {'C', 'F'}, optional Whether to use row-major ('C') or column-major ('F') memory representation. Defaults to 'C'. - maskna : bool or None, optional - If this is set to True, it forces the array to have an NA mask. - If this is set to False, it forces the array to not have an NA - mask. - ownmaskna : bool, optional - If this is set to True, forces the array to have a mask which - it owns. Returns ------- @@ -65,8 +63,7 @@ True """ - return array(a, dtype, copy=False, order=order, subok=True, - maskna=maskna, ownmaskna=ownmaskna) + return array(a, dtype, copy=False, order=order, subok=True) def base_repr(number, base=2, padding=0): """ @@ -347,7 +344,7 @@ return False return bool((a1 == a2).all()) -def asarray(a, dtype=None, order=None, maskna=None, ownmaskna=False): +def asarray(a, dtype=None, order=None): """ Convert the input to an array. @@ -362,13 +359,6 @@ order : {'C', 'F'}, optional Whether to use row-major ('C') or column-major ('F' for FORTRAN) memory representation. Defaults to 'C'. - maskna : bool or None, optional - If this is set to True, it forces the array to have an NA mask. - If this is set to False, it forces the array to not have an NA - mask. - ownmaskna : bool, optional - If this is set to True, forces the array to have a mask which - it owns. Returns ------- @@ -422,8 +412,7 @@ True """ - return array(a, dtype, copy=False, order=order, - maskna=maskna, ownmaskna=ownmaskna) + return array(a, dtype, copy=False, order=order) set_string_function(array_str, 0) set_string_function(array_repr, 1) diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -34,7 +34,7 @@ "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array", "_bisect", "binascii", "_multiprocessing", '_warnings', "_collections", "_multibytecodec", "micronumpy", "_ffi", - "_continuation", "_cffi_backend"] + "_continuation", "_cffi_backend", "_csv"] )) translation_modules = default_modules.copy() diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -23,7 +23,7 @@ The tools required to cross translate from a Linux based host to an ARM based Linux target are: -- A checkout of PyPy's arm-backend-2 branch. +- A checkout of PyPy (default branch). - The GCC ARM cross compiler (on Ubuntu it is the ``gcc-arm-linux-gnueabi package``) but other toolchains should also work. - Scratchbox 2, a cross-compilation engine (``scratchbox2`` Ubuntu package). - A 32-bit PyPy or Python. @@ -147,4 +147,4 @@ return 0 def target(*args): - return main, None \ No newline at end of file + return main, None diff --git a/pypy/doc/config/objspace.usemodules._csv.txt b/pypy/doc/config/objspace.usemodules._csv.txt new file mode 100644 --- /dev/null +++ b/pypy/doc/config/objspace.usemodules._csv.txt @@ -0,0 +1,2 @@ +Implementation in RPython for the core of the 'csv' module + diff --git a/pypy/doc/jit/pyjitpl5.rst b/pypy/doc/jit/pyjitpl5.rst --- a/pypy/doc/jit/pyjitpl5.rst +++ b/pypy/doc/jit/pyjitpl5.rst @@ -149,7 +149,7 @@ A *virtual* value is an array, struct, or RPython level instance that is created during the loop and does not escape from it via calls or longevity past the -loop. Since it is only used by the JIT, it be "optimized out"; the value +loop. Since it is only used by the JIT, it can be "optimized out"; the value doesn't have to be allocated at all and its fields can be stored as first class values instead of deferencing them in memory. Virtuals allow temporary objects in the interpreter to be unwrapped. For example, a W_IntObject in the PyPy can diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -21,7 +21,7 @@ ------------------------- PyPy's implementation of the Python ``long`` type is slower than CPython's. -Find out why and optimize them. +Find out why and optimize them. **UPDATE:** this was done (thanks stian). Make bytearray type fast ------------------------ @@ -103,13 +103,35 @@ * A concurrent garbage collector (a lot of work) -STM, a.k.a. "remove the GIL" ----------------------------- +STM (Software Transactional Memory) +----------------------------------- -Removing the GIL --- or more precisely, a GIL-less thread-less solution --- -is `now work in progress.`__ Contributions welcome. +This is work in progress. Besides the main development path, whose goal is +to make a (relatively fast) version of pypy which includes STM, there are +independent topics that can already be experimented with on the existing, +JIT-less pypy-stm version: + +* What kind of conflicts do we get in real use cases? And, sometimes, + which data structures would be more appropriate? For example, a dict + implemented as a hash table will suffer "stm collisions" in all threads + whenever one thread writes anything to it; but there could be other + implementations. Maybe alternate strategies can be implemented at the + level of the Python interpreter (see list/dict strategies, + ``pypy/objspace/std/{list,dict}object.py``). -.. __: http://pypy.org/tmdonate.html +* More generally, there is the idea that we would need some kind of + "debugger"-like tool to "debug" things that are not bugs, but stm + conflicts. How would this tool look like to the end Python + programmers? Like a profiler? Or like a debugger with breakpoints + on aborted transactions? It would probably be all app-level, with + a few hooks e.g. for transaction conflicts. + +* Find good ways to have libraries using internally threads and atomics, + but not exposing threads to the user. Right now there is a rough draft + in ``lib_pypy/transaction.py``, but much better is possible. For example + we could probably have an iterator-like concept that allows each loop + iteration to run in parallel. + Introduce new benchmarks ------------------------ 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 @@ -16,6 +16,11 @@ .. branch: iterator-in-rpython .. branch: numpypy_count_nonzero +.. branch: numpy-refactor +Remove numpy lazy evaluation and simplify everything +.. branch: numpy-reintroduce-jit-drivers +.. branch: numpy-fancy-indexing +Support for array[array-of-ints] in numpy .. branch: even-more-jit-hooks Implement better JIT hooks .. branch: virtual-arguments diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py --- a/pypy/interpreter/astcompiler/assemble.py +++ b/pypy/interpreter/astcompiler/assemble.py @@ -65,24 +65,44 @@ self.marked = False self.have_return = False - def _post_order(self, blocks): - if self.marked: - return - self.marked = True - if self.next_block is not None: - self.next_block._post_order(blocks) - for instr in self.instructions: - if instr.has_jump: - instr.jump[0]._post_order(blocks) - blocks.append(self) - self.marked = True + def _post_order_see(self, stack, nextblock): + if nextblock.marked == 0: + nextblock.marked = 1 + stack.append(nextblock) def post_order(self): - """Return this block and its children in post order.""" - blocks = [] - self._post_order(blocks) - blocks.reverse() - return blocks + """Return this block and its children in post order. + This means that the graph of blocks is first cleaned up to + ignore back-edges, thus turning it into a DAG. Then the DAG + is linearized. For example: + + A --> B -\ => [A, D, B, C] + \-> D ---> C + """ + resultblocks = [] + stack = [self] + self.marked = 1 + while stack: + current = stack[-1] + if current.marked == 1: + current.marked = 2 + if current.next_block is not None: + self._post_order_see(stack, current.next_block) + else: + i = current.marked - 2 + assert i >= 0 + while i < len(current.instructions): + instr = current.instructions[i] + i += 1 + if instr.has_jump: + current.marked = i + 2 + self._post_order_see(stack, instr.jump[0]) + break + else: + resultblocks.append(current) + stack.pop() + resultblocks.reverse() + return resultblocks def code_size(self): """Return the encoded size of all the instructions in this block.""" @@ -353,20 +373,26 @@ def _stacksize(self, blocks): """Compute co_stacksize.""" for block in blocks: - block.marked = False - block.initial_depth = -1000 - return self._recursive_stack_depth_walk(blocks[0], 0, 0) + block.initial_depth = 0 + # Assumes that it is sufficient to walk the blocks in 'post-order'. + # This means we ignore all back-edges, but apart from that, we only + # look into a block when all the previous blocks have been done. + self._max_depth = 0 + for block in blocks: + self._do_stack_depth_walk(block) + return self._max_depth - def _recursive_stack_depth_walk(self, block, depth, max_depth): - if block.marked or block.initial_depth >= depth: - return max_depth - block.marked = True - block.initial_depth = depth + def _next_stack_depth_walk(self, nextblock, depth): + if depth > nextblock.initial_depth: + nextblock.initial_depth = depth + + def _do_stack_depth_walk(self, block): + depth = block.initial_depth done = False for instr in block.instructions: depth += _opcode_stack_effect(instr.opcode, instr.arg) - if depth >= max_depth: - max_depth = depth + if depth >= self._max_depth: + self._max_depth = depth if instr.has_jump: target_depth = depth jump_op = instr.opcode @@ -376,20 +402,15 @@ jump_op == ops.SETUP_EXCEPT or jump_op == ops.SETUP_WITH): target_depth += 3 - if target_depth > max_depth: - max_depth = target_depth - max_depth = self._recursive_stack_depth_walk(instr.jump[0], - target_depth, - max_depth) + if target_depth > self._max_depth: + self._max_depth = target_depth + self._next_stack_depth_walk(instr.jump[0], target_depth) if jump_op == ops.JUMP_ABSOLUTE or jump_op == ops.JUMP_FORWARD: # Nothing more can occur. done = True break if block.next_block and not done: - max_depth = self._recursive_stack_depth_walk(block.next_block, - depth, max_depth) - block.marked = False - return max_depth + max_depth = self._next_stack_depth_walk(block.next_block, depth) def _build_lnotab(self, blocks): """Build the line number table for tracebacks and tracing.""" 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 @@ -474,7 +474,7 @@ if f_type == F_BLOCK_LOOP: self.emit_jump(ops.CONTINUE_LOOP, block, True) break - if self.frame_blocks[i][0] == F_BLOCK_FINALLY_END: + if f_type == F_BLOCK_FINALLY_END: self.error("'continue' not supported inside 'finally' " \ "clause", cont) diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -778,6 +778,10 @@ raise AssertionError("attribute not removed")""" yield self.st, test, "X.__name__", "X" + def test_lots_of_loops(self): + source = "for x in y: pass\n" * 1000 + compile_with_astcompiler(source, 'exec', self.space) + class AppTestCompiler: diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -208,11 +208,11 @@ def int_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def bigint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -292,8 +292,6 @@ """Base class for the interpreter-level implementations of object spaces. http://pypy.readthedocs.org/en/latest/objspace.html""" - full_exceptions = True # full support for exceptions (normalization & more) - def __init__(self, config=None): "NOT_RPYTHON: Basic initialization of objects." self.fromcache = InternalSpaceCache(self).getorbuild @@ -590,10 +588,6 @@ w_exc = self.getitem(w_dic, w_name) exc_types_w[name] = w_exc setattr(self, "w_" + excname, w_exc) - # Make a prebuilt recursion error - w_msg = self.wrap("maximum recursion depth exceeded") - self.prebuilt_recursion_error = OperationError(self.w_RuntimeError, - w_msg) return exc_types_w def install_mixedmodule(self, mixedname, installed_builtin_modules): @@ -838,7 +832,8 @@ return isinstance(obj, RequiredClass) def unpackiterable(self, w_iterable, expected_length=-1): - """Unpack an iterable object into a real (interpreter-level) list. + """Unpack an iterable into a real (interpreter-level) list. + Raise an OperationError(w_ValueError) if the length is wrong.""" w_iterator = self.iter(w_iterable) if expected_length == -1: @@ -858,12 +853,10 @@ def iteriterable(self, w_iterable): return W_InterpIterable(self, w_iterable) - @jit.dont_look_inside def _unpackiterable_unknown_length(self, w_iterator, w_iterable): - # Unpack a variable-size list of unknown length. - # The JIT does not look inside this function because it - # contains a loop (made explicit with the decorator above). - # + """Unpack an iterable of unknown length into an interp-level + list. + """ # If we can guess the expected length we can preallocate. try: lgt_estimate = self.len_w(w_iterable) @@ -1133,13 +1126,9 @@ def exception_is_valid_obj_as_class_w(self, w_obj): if not self.isinstance_w(w_obj, self.w_type): return False - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_obj, self.w_BaseException)) def exception_is_valid_class_w(self, w_cls): - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_cls, self.w_BaseException)) def exception_getclass(self, w_obj): @@ -1390,7 +1379,7 @@ if not self.is_true(self.isinstance(w_obj, self.w_str)): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) - return self.str_w(w_obj) + return self.str_w(w_obj) def unicode_w(self, w_obj): return w_obj.unicode_w(self) @@ -1711,7 +1700,7 @@ 'ValueError', 'ZeroDivisionError', ] - + if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -21,9 +21,7 @@ _application_traceback = None def __init__(self, w_type, w_value, tb=None): - if not we_are_translated() and w_type is None: - from pypy.tool.error import FlowingError - raise FlowingError(w_value) + assert w_type is not None self.setup(w_type) self._w_value = w_value self._application_traceback = tb @@ -47,11 +45,6 @@ def async(self, space): "Check if this is an exception that should better not be caught." - if not space.full_exceptions: - # flow objspace does not support such exceptions and more - # importantly, raises KeyboardInterrupt if you try to access - # space.w_KeyboardInterrupt - return False return (self.match(space, space.w_SystemExit) or self.match(space, space.w_KeyboardInterrupt)) @@ -168,9 +161,7 @@ # Or 'Class' can also be an old-style class and 'inst' an old-style # instance of it. # - # Note that 'space.full_exceptions' is set to False by the flow - # object space; in this case we must assume that we are in a - # non-advanced case, and ignore the advanced cases. Old-style + # The flow object space only deals with non-advanced case. Old-style # classes and instances *are* advanced. # # input (w_type, w_value)... becomes... advanced case? @@ -185,9 +176,8 @@ # w_type = self.w_type w_value = self.get_w_value(space) - if space.full_exceptions: - while space.is_true(space.isinstance(w_type, space.w_tuple)): - w_type = space.getitem(w_type, space.wrap(0)) + while space.is_true(space.isinstance(w_type, space.w_tuple)): + w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): # this is for all cases of the form (Class, something) @@ -201,8 +191,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.full_exceptions and space.is_true( - space.isinstance(w_value, space.w_tuple)): + if space.is_true(space.isinstance(w_value, space.w_tuple)): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) @@ -327,9 +316,7 @@ self.xstrings = strings for i, attr in entries: setattr(self, attr, args[i]) - if not we_are_translated() and w_type is None: - from pypy.tool.error import FlowingError - raise FlowingError(self._compute_value()) + assert w_type is not None def _compute_value(self): lst = [None] * (len(formats) + len(formats) + 1) for i, attr in entries: @@ -393,7 +380,7 @@ return OperationError(exc, w_error) def wrap_oserror2(space, e, w_filename=None, exception_name='w_OSError', - w_exception_class=None): + w_exception_class=None): assert isinstance(e, OSError) if _WINDOWS and isinstance(e, WindowsError): diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -158,17 +158,13 @@ self._trace(frame, 'exception', None, operationerr) #operationerr.print_detailed_traceback(self.space) - def _convert_exc(self, operr): - # Only for the flow object space - return operr - def sys_exc_info(self): # attn: the result is not the wrapped sys.exc_info() !!! """Implements sys.exc_info(). Return an OperationError instance or None.""" frame = self.gettopframe_nohidden() while frame: if frame.last_exception is not None: - return self._convert_exc(frame.last_exception) + return frame.last_exception frame = self.getnextframe_nohidden(frame) return None diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -651,7 +651,8 @@ raise OperationError(space.w_MemoryError, space.w_None) except rstackovf.StackOverflow, e: rstackovf.check_stack_overflow() - raise space.prebuilt_recursion_error + raise OperationError(space.w_RuntimeError, + space.wrap("maximum recursion depth exceeded")) except RuntimeError: # not on top of py.py raise OperationError(space.w_RuntimeError, space.w_None) @@ -943,14 +944,6 @@ def appcaller(space, *args_w): if not isinstance(space, ObjSpace): raise TypeError("first argument must be a space instance.") - # redirect if the space handles this specially - # XXX can this be factored a bit less flow space dependently? - if hasattr(space, 'specialcases'): - sc = space.specialcases - if ApplevelClass in sc: - ret_w = sc[ApplevelClass](space, self, name, args_w) - if ret_w is not None: # it was RPython - return ret_w # the last argument can be an Arguments w_func = self.wget(space, name) if not args_w: diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -136,10 +136,6 @@ next_instr = self.dispatch_bytecode(co_code, next_instr, ec) except OperationError, operr: next_instr = self.handle_operation_error(ec, operr) - except Reraise: - operr = self.last_exception - next_instr = self.handle_operation_error(ec, operr, - attach_tb=False) except RaiseWithExplicitTraceback, e: next_instr = self.handle_operation_error(ec, e.operr, attach_tb=False) @@ -150,9 +146,11 @@ next_instr = self.handle_asynchronous_error(ec, self.space.w_MemoryError) except rstackovf.StackOverflow, e: + # Note that this case catches AttributeError! rstackovf.check_stack_overflow() - w_err = self.space.prebuilt_recursion_error - next_instr = self.handle_operation_error(ec, w_err) + next_instr = self.handle_asynchronous_error(ec, + self.space.w_RuntimeError, + self.space.wrap("maximum recursion depth exceeded")) return next_instr def handle_asynchronous_error(self, ec, w_type, w_value=None): @@ -275,7 +273,7 @@ next_instr = block.handle(self, unroller) elif opcode == self.opcodedesc.JUMP_ABSOLUTE.index: - next_instr = self.jump_absolute(oparg, next_instr, ec) + next_instr = self.jump_absolute(oparg, ec) elif we_are_translated(): for opdesc in unrolling_all_opcode_descs: @@ -609,7 +607,7 @@ ec = self.space.getexecutioncontext() while frame: if frame.last_exception is not None: - operror = ec._convert_exc(frame.last_exception) + operror = frame.last_exception break frame = frame.f_backref() else: @@ -617,7 +615,7 @@ space.wrap("raise: no active exception to re-raise")) # re-raise, no new traceback obj will be attached self.last_exception = operror - raise Reraise + raise RaiseWithExplicitTraceback(operror) w_value = w_traceback = space.w_None if nbargs >= 3: @@ -628,7 +626,7 @@ w_type = self.popvalue() operror = OperationError(w_type, w_value) operror.normalize_exception(space) - if not space.full_exceptions or space.is_w(w_traceback, space.w_None): + if space.is_w(w_traceback, space.w_None): # common case raise operror else: @@ -929,7 +927,8 @@ def YIELD_VALUE(self, oparg, next_instr): raise Yield - def jump_absolute(self, jumpto, next_instr, ec): + def jump_absolute(self, jumpto, ec): + # this function is overridden by pypy.module.pypyjit.interp_jit check_nonneg(jumpto) return jumpto @@ -1015,26 +1014,15 @@ def WITH_CLEANUP(self, oparg, next_instr): # see comment in END_FINALLY for stack state - # This opcode changed a lot between CPython versions - if (self.pycode.magic >= 0xa0df2ef - # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) - or self.pycode.magic >= 0xa0df2d1): - # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) - w_unroller = self.popvalue() - w_exitfunc = self.popvalue() - self.pushvalue(w_unroller) - elif self.pycode.magic >= 0xa0df28c: - # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) - w_exitfunc = self.popvalue() - w_unroller = self.peekvalue(0) - else: - raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") - + w_unroller = self.popvalue() + w_exitfunc = self.popvalue() + self.pushvalue(w_unroller) unroller = self.space.interpclass_w(w_unroller) is_app_exc = (unroller is not None and isinstance(unroller, SApplicationException)) if is_app_exc: operr = unroller.operr + self.last_exception = operr w_traceback = self.space.wrap(operr.get_traceback()) w_suppress = self.call_contextmanager_exit_function( w_exitfunc, @@ -1234,10 +1222,8 @@ class Yield(ExitFrame): """Raised when exiting a frame via a 'yield' statement.""" -class Reraise(Exception): - """Raised at interp-level by a bare 'raise' statement.""" class RaiseWithExplicitTraceback(Exception): - """Raised at interp-level by a 3-arguments 'raise' statement.""" + """Raised at interp-level by a 0- or 3-arguments 'raise' statement.""" def __init__(self, operr): self.operr = operr @@ -1264,10 +1250,6 @@ 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): """Signals a 'return' statement. Argument is the wrapped object to return.""" @@ -1278,12 +1260,6 @@ def nomoreblocks(self): return self.w_returnvalue - def state_unpack_variables(self, space): - return [self.w_returnvalue] - def state_pack_variables(space, w_returnvalue): - return SReturnValue(w_returnvalue) - state_pack_variables = staticmethod(state_pack_variables) - class SApplicationException(SuspendedUnroller): """Signals an application-level exception (i.e. an OperationException).""" @@ -1294,23 +1270,10 @@ def nomoreblocks(self): raise RaiseWithExplicitTraceback(self.operr) - def state_unpack_variables(self, space): - return [self.operr.w_type, self.operr.get_w_value(space)] - def state_pack_variables(space, w_type, w_value): - return SApplicationException(OperationError(w_type, w_value)) - state_pack_variables = staticmethod(state_pack_variables) - class SBreakLoop(SuspendedUnroller): """Signals a 'break' statement.""" _immutable_ = True kind = 0x04 - - def state_unpack_variables(self, space): - return [] - def state_pack_variables(space): - return SBreakLoop.singleton - state_pack_variables = staticmethod(state_pack_variables) - SBreakLoop.singleton = SBreakLoop() class SContinueLoop(SuspendedUnroller): @@ -1321,12 +1284,6 @@ def __init__(self, jump_to): self.jump_to = jump_to - def state_unpack_variables(self, space): - return [space.wrap(self.jump_to)] - def state_pack_variables(space, w_jump_to): - return SContinueLoop(space.int_w(w_jump_to)) - state_pack_variables = staticmethod(state_pack_variables) - class FrameBlock(object): """Abstract base class for frame blocks from the blockstack, @@ -1381,7 +1338,9 @@ # and jump to the beginning of the loop, stored in the # exception's argument frame.append_block(self) - return r_uint(unroller.jump_to) + jumpto = unroller.jump_to + ec = frame.space.getexecutioncontext() + return r_uint(frame.jump_absolute(jumpto, ec)) else: # jump to the end of the loop self.cleanupstack(frame) @@ -1401,8 +1360,7 @@ self.cleanupstack(frame) assert isinstance(unroller, SApplicationException) operationerr = unroller.operr - if frame.space.full_exceptions: - operationerr.normalize_exception(frame.space) + operationerr.normalize_exception(frame.space) # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. @@ -1434,8 +1392,7 @@ _immutable_ = True def handle(self, frame, unroller): - if (frame.space.full_exceptions and - isinstance(unroller, SApplicationException)): + if isinstance(unroller, SApplicationException): unroller.operr.normalize_exception(frame.space) return FinallyBlock.handle(self, frame, unroller) diff --git a/pypy/interpreter/test/test_syntax.py b/pypy/interpreter/test/test_syntax.py --- a/pypy/interpreter/test/test_syntax.py +++ b/pypy/interpreter/test/test_syntax.py @@ -1,3 +1,4 @@ +from __future__ import with_statement import py from pypy.conftest import gettestobjspace @@ -567,6 +568,24 @@ import types assert isinstance(acontextfact.exit_params[2], types.TracebackType) + def test_with_reraise_exception(self): + class Context: + def __enter__(self): + self.calls = [] + def __exit__(self, exc_type, exc_value, exc_tb): + self.calls.append('exit') + raise + + c = Context() + try: + with c: + 1 / 0 + except ZeroDivisionError: + pass + else: + raise AssertionError('Should have reraised initial exception') + assert c.calls == ['exit'] + def test_with_break(self): s = """ diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -131,13 +131,13 @@ def get_latest_value_float(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a float.""" + or from 'args' if it was a FINISH). Returns a FLOATSTORAGE.""" raise NotImplementedError def get_latest_value_ref(self, index): """Returns the value for the index'th argument to the last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a ptr or an obj.""" + or from 'args' if it was a FINISH). Returns a GCREF.""" raise NotImplementedError def get_latest_value_count(self): diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -994,6 +994,7 @@ ('p', lltype.Ptr(TP))) a_box, A = self.alloc_array_of(ITEM, 15) s_box, S = self.alloc_instance(TP) + vsdescr = self.cpu.interiorfielddescrof(A, 'vs') kdescr = self.cpu.interiorfielddescrof(A, 'k') pdescr = self.cpu.interiorfielddescrof(A, 'p') self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, BoxInt(3), @@ -1045,6 +1046,13 @@ r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], 'ref', descr=pdescr) assert r.getref_base() == s_box.getref_base() + # + # test a corner case that used to fail on x86 + i4 = BoxInt(4) + self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, i4, i4], + 'void', descr=vsdescr) + r = self.cpu.bh_getinteriorfield_gc_i(a_box.getref_base(), 4, vsdescr) + assert r == 4 def test_string_basic(self): s_box = self.alloc_string("hello\xfe") diff --git a/pypy/jit/backend/test/test_random.py b/pypy/jit/backend/test/test_random.py --- a/pypy/jit/backend/test/test_random.py +++ b/pypy/jit/backend/test/test_random.py @@ -465,6 +465,16 @@ # ____________________________________________________________ +def do_assert(condition, error_message): + if condition: + return + seed = pytest.config.option.randomseed + message = "%s\nPython: %s\nRandom seed: %r" % ( + error_message, + sys.executable, + seed) + raise AssertionError(message) + def Random(): import random seed = pytest.config.option.randomseed @@ -544,6 +554,7 @@ self.startvars = startvars self.prebuilt_ptr_consts = [] self.r = r + self.subloops = [] self.build_random_loop(cpu, builder_factory, r, startvars, allow_delay) def build_random_loop(self, cpu, builder_factory, r, startvars, allow_delay): @@ -668,13 +679,15 @@ arguments = [box.value for box in self.loop.inputargs] fail = cpu.execute_token(self.runjitcelltoken(), *arguments) - assert fail is self.should_fail_by.getdescr() + do_assert(fail is self.should_fail_by.getdescr(), + "Got %r, expected %r" % (fail, + self.should_fail_by.getdescr())) for i, v in enumerate(self.get_fail_args()): if isinstance(v, (BoxFloat, ConstFloat)): value = cpu.get_latest_value_float(i) else: value = cpu.get_latest_value_int(i) - assert value == self.expected[v], ( + do_assert(value == self.expected[v], "Got %r, expected %r for value #%d" % (value, self.expected[v], i) @@ -683,9 +696,11 @@ if (self.guard_op is not None and self.guard_op.is_guard_exception()): if self.guard_op.getopnum() == rop.GUARD_NO_EXCEPTION: - assert exc + do_assert(exc, + "grab_exc_value() should not be %r" % (exc,)) else: - assert not exc + do_assert(not exc, + "unexpected grab_exc_value(): %r" % (exc,)) def build_bridge(self): def exc_handling(guard_op): @@ -710,6 +725,7 @@ return False # generate the branch: a sequence of operations that ends in a FINISH subloop = DummyLoop([]) + self.subloops.append(subloop) # keep around for debugging if guard_op.is_guard_exception(): subloop.operations.append(exc_handling(guard_op)) bridge_builder = self.builder.fork(self.builder.cpu, subloop, @@ -746,9 +762,6 @@ args = [x.clonebox() for x in subset] rl = RandomLoop(self.builder.cpu, self.builder.fork, r, args) - dump(rl.loop) - self.cpu.compile_loop(rl.loop.inputargs, rl.loop.operations, - rl.loop._jitcelltoken) # done self.should_fail_by = rl.should_fail_by self.expected = rl.expected diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py --- a/pypy/jit/backend/x86/regalloc.py +++ b/pypy/jit/backend/x86/regalloc.py @@ -1005,14 +1005,18 @@ # If 'index_loc' is not an immediate, then we need a 'temp_loc' that # is a register whose value will be destroyed. It's fine to destroy # the same register as 'index_loc', but not the other ones. - self.rm.possibly_free_var(box_index) if not isinstance(index_loc, ImmedLoc): + # ...that is, except in a corner case where 'index_loc' would be + # in the same register as 'value_loc'... + if index_loc is not value_loc: + self.rm.possibly_free_var(box_index) tempvar = TempBox() temp_loc = self.rm.force_allocate_reg(tempvar, [box_base, box_value]) self.rm.possibly_free_var(tempvar) else: temp_loc = None + self.rm.possibly_free_var(box_index) self.rm.possibly_free_var(box_base) self.possibly_free_var(box_value) self.PerformDiscard(op, [base_loc, ofs, itemsize, fieldsize, diff --git a/pypy/jit/backend/x86/rx86.py b/pypy/jit/backend/x86/rx86.py --- a/pypy/jit/backend/x86/rx86.py +++ b/pypy/jit/backend/x86/rx86.py @@ -576,7 +576,7 @@ J_il8 = insn(immediate(1, 'o'), '\x70', immediate(2, 'b')) J_il = insn('\x0F', immediate(1,'o'), '\x80', relative(2)) - SET_ir = insn(rex_w, '\x0F', immediate(1,'o'),'\x90', byte_register(2), '\xC0') + SET_ir = insn(rex_fw, '\x0F', immediate(1,'o'),'\x90', byte_register(2), '\xC0') # The 64-bit version of this, CQO, is defined in X86_64_CodeBuilder CDQ = insn(rex_nw, '\x99') diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -106,7 +106,8 @@ def compile_loop(metainterp, greenkey, start, inputargs, jumpargs, - resume_at_jump_descr, full_preamble_needed=True): + resume_at_jump_descr, full_preamble_needed=True, + try_disabling_unroll=False): """Try to compile a new procedure by closing the current history back to the first operation. """ @@ -116,6 +117,13 @@ jitdriver_sd = metainterp.jitdriver_sd history = metainterp.history + enable_opts = jitdriver_sd.warmstate.enable_opts + if try_disabling_unroll: + if 'unroll' not in enable_opts: + return None + enable_opts = enable_opts.copy() + del enable_opts['unroll'] + jitcell_token = make_jitcell_token(jitdriver_sd) part = create_empty_loop(metainterp) part.inputargs = inputargs[:] @@ -126,7 +134,7 @@ [ResOperation(rop.LABEL, jumpargs, None, descr=jitcell_token)] try: - optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts) + optimize_trace(metainterp_sd, part, enable_opts) except InvalidLoop: return None target_token = part.operations[0].getdescr() @@ -153,7 +161,7 @@ jumpargs = part.operations[-1].getarglist() try: - optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts) + optimize_trace(metainterp_sd, part, enable_opts) except InvalidLoop: return None diff --git a/pypy/jit/metainterp/optimizeopt/util.py b/pypy/jit/metainterp/optimizeopt/util.py --- a/pypy/jit/metainterp/optimizeopt/util.py +++ b/pypy/jit/metainterp/optimizeopt/util.py @@ -2,9 +2,10 @@ from pypy.rlib.objectmodel import r_dict, compute_identity_hash from pypy.rlib.rarithmetic import intmask from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp import resoperation, history +from pypy.jit.metainterp import resoperation from pypy.rlib.debug import make_sure_not_resized from pypy.jit.metainterp.resoperation import rop +from pypy.rlib.objectmodel import we_are_translated # ____________________________________________________________ # Misc. utilities @@ -28,13 +29,20 @@ def make_dispatcher_method(Class, name_prefix, op_prefix=None, default=None): ops = _findall(Class, name_prefix, op_prefix) def dispatch(self, op, *args): - opnum = op.getopnum() - for value, cls, func in ops: - if opnum == value: - assert isinstance(op, cls) + if we_are_translated(): + opnum = op.getopnum() + for value, cls, func in ops: + if opnum == value: + assert isinstance(op, cls) + return func(self, op, *args) + if default: + return default(self, op, *args) + else: + func = getattr(Class, name_prefix + op.getopname().upper(), None) + if func is not None: return func(self, op, *args) - if default: - return default(self, op, *args) + if default: + return default(self, op, *args) dispatch.func_name = "dispatch_" + name_prefix return dispatch diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -2039,8 +2039,9 @@ memmgr = self.staticdata.warmrunnerdesc.memory_manager if memmgr: if self.cancel_count > memmgr.max_unroll_loops: - self.staticdata.log('cancelled too many times!') - raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) + self.compile_loop_or_abort(original_boxes, + live_arg_boxes, + start, resumedescr) self.staticdata.log('cancelled, tracing more...') # Otherwise, no loop found so far, so continue tracing. @@ -2140,7 +2141,8 @@ return None return token - def compile_loop(self, original_boxes, live_arg_boxes, start, resume_at_jump_descr): + def compile_loop(self, original_boxes, live_arg_boxes, start, + resume_at_jump_descr, try_disabling_unroll=False): num_green_args = self.jitdriver_sd.num_green_args greenkey = original_boxes[:num_green_args] if not self.partial_trace: @@ -2156,7 +2158,8 @@ target_token = compile.compile_loop(self, greenkey, start, original_boxes[num_green_args:], live_arg_boxes[num_green_args:], - resume_at_jump_descr) + resume_at_jump_descr, + try_disabling_unroll=try_disabling_unroll) if target_token is not None: assert isinstance(target_token, TargetToken) self.jitdriver_sd.warmstate.attach_procedure_to_interp(greenkey, target_token.targeting_jitcell_token) @@ -2168,6 +2171,18 @@ jitcell_token = target_token.targeting_jitcell_token self.raise_continue_running_normally(live_arg_boxes, jitcell_token) + def compile_loop_or_abort(self, original_boxes, live_arg_boxes, + start, resume_at_jump_descr): + """Called after we aborted more than 'max_unroll_loops' times. + As a last attempt, try to compile the loop with unrolling disabled. + """ + if not self.partial_trace: + self.compile_loop(original_boxes, live_arg_boxes, start, + resume_at_jump_descr, try_disabling_unroll=True) + # + self.staticdata.log('cancelled too many times!') + raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) + def compile_trace(self, live_arg_boxes, resume_at_jump_descr): num_green_args = self.jitdriver_sd.num_green_args greenkey = live_arg_boxes[:num_green_args] diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py --- a/pypy/jit/metainterp/test/test_ajit.py +++ b/pypy/jit/metainterp/test/test_ajit.py @@ -2028,6 +2028,7 @@ y -= 1 return res def g(x, y): + set_param(myjitdriver, 'max_unroll_loops', 5) a1 = f(A(x), y) a2 = f(A(x), y) b1 = f(B(x), y) @@ -2734,6 +2735,35 @@ finally: optimizeopt.optimize_trace = old_optimize_trace + def test_max_unroll_loops_retry_without_unroll(self): + from pypy.jit.metainterp.optimize import InvalidLoop + from pypy.jit.metainterp import optimizeopt + myjitdriver = JitDriver(greens = [], reds = ['n', 'i']) + # + def f(n, limit): + set_param(myjitdriver, 'threshold', 5) + set_param(myjitdriver, 'max_unroll_loops', limit) + i = 0 + while i < n: + myjitdriver.jit_merge_point(n=n, i=i) + print i + i += 1 + return i + # + seen = [] + def my_optimize_trace(metainterp_sd, loop, enable_opts, *args, **kwds): + seen.append('unroll' in enable_opts) + raise InvalidLoop + old_optimize_trace = optimizeopt.optimize_trace + optimizeopt.optimize_trace = my_optimize_trace + try: + res = self.meta_interp(f, [23, 4]) + assert res == 23 + assert False in seen + assert True in seen + finally: + optimizeopt.optimize_trace = old_optimize_trace + def test_retrace_limit_with_extra_guards(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a', 'node']) diff --git a/pypy/jit/metainterp/test/test_send.py b/pypy/jit/metainterp/test/test_send.py --- a/pypy/jit/metainterp/test/test_send.py +++ b/pypy/jit/metainterp/test/test_send.py @@ -1,5 +1,5 @@ import py -from pypy.rlib.jit import JitDriver, promote, elidable +from pypy.rlib.jit import JitDriver, promote, elidable, set_param from pypy.jit.codewriter.policy import StopAtXPolicy from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin @@ -181,6 +181,7 @@ def getvalue(self): return self.y def f(x, y): + set_param(myjitdriver, 'max_unroll_loops', 5) if x & 1: w = W1(x) else: @@ -226,6 +227,7 @@ w2 = W2(20) def f(x, y): + set_param(myjitdriver, 'max_unroll_loops', 5) if x & 1: w = w1 else: diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -1,11 +1,13 @@ from pypy.interpreter.mixedmodule import MixedModule +from pypy.rlib import rdynload + class Module(MixedModule): appleveldefs = { } interpleveldefs = { - '__version__': 'space.wrap("0.3")', + '__version__': 'space.wrap("0.4")', 'nonstandard_integer_types': 'misc.nonstandard_integer_types', @@ -27,7 +29,8 @@ 'alignof': 'func.alignof', 'sizeof': 'func.sizeof', 'typeof': 'func.typeof', - 'offsetof': 'func.offsetof', + 'typeoffsetof': 'func.typeoffsetof', + 'rawaddressof': 'func.rawaddressof', '_getfields': 'func._getfields', 'getcname': 'func.getcname', '_get_types': 'func._get_types', @@ -41,3 +44,12 @@ 'FFI_DEFAULT_ABI': 'ctypefunc._get_abi(space, "FFI_DEFAULT_ABI")', 'FFI_CDECL': 'ctypefunc._get_abi(space,"FFI_DEFAULT_ABI")',#win32 name } + +for _name in ["RTLD_LAZY", "RTLD_NOW", "RTLD_GLOBAL", "RTLD_LOCAL", + "RTLD_NODELETE", "RTLD_NOLOAD", "RTLD_DEEPBIND"]: + if getattr(rdynload.cConfig, _name) is not None: + Module.interpleveldefs[_name] = 'space.wrap(%d)' % ( + getattr(rdynload.cConfig, _name),) + +for _name in ["RTLD_LAZY", "RTLD_NOW", "RTLD_GLOBAL", "RTLD_LOCAL"]: + Module.interpleveldefs.setdefault(_name, 'space.wrap(0)') diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -286,8 +286,8 @@ for i, cf in enumerate(ctype.fields_list): if cf.is_bitfield(): raise OperationError(space.w_NotImplementedError, - space.wrap("cannot pass as argument a struct " - "with bit fields")) + space.wrap("cannot pass as argument or return value " + "a struct with bit fields")) ffi_subtype = self.fb_fill_type(cf.ctype, False) if elements: elements[i] = ffi_subtype diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -134,14 +134,22 @@ "ctype '%s' is of unknown alignment", self.name) - def offsetof(self, fieldname): + def typeoffsetof(self, fieldname): space = self.space - raise OperationError(space.w_TypeError, - space.wrap("not a struct or union ctype")) + if fieldname is None: + msg = "expected a struct or union ctype" + else: + msg = "expected a struct or union ctype, or a pointer to one" + raise OperationError(space.w_TypeError, space.wrap(msg)) def _getfields(self): return None + def rawaddressof(self, cdata, offset): + space = self.space + raise OperationError(space.w_TypeError, + space.wrap("expected a pointer ctype")) + def call(self, funcaddr, args_w): space = self.space raise operationerrfmt(space.w_TypeError, diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -52,19 +52,25 @@ if (isinstance(ob, cdataobj.W_CData) and isinstance(ob.ctype, ctypeptr.W_CTypePtrOrArray)): value = rffi.cast(lltype.Signed, ob._cdata) - value = r_ulonglong(value) + value = self._cast_result(value) elif space.isinstance_w(w_ob, space.w_str): value = self.cast_str(w_ob) - value = r_ulonglong(value) + value = self._cast_result(value) elif space.isinstance_w(w_ob, space.w_unicode): value = self.cast_unicode(w_ob) - value = r_ulonglong(value) + value = self._cast_result(value) else: - value = misc.as_unsigned_long_long(space, w_ob, strict=False) + value = self._cast_generic(w_ob) w_cdata = cdataobj.W_CDataMem(space, self.size, self) w_cdata.write_raw_integer_data(value) return w_cdata + def _cast_result(self, intvalue): + return r_ulonglong(intvalue) + + def _cast_generic(self, w_ob): + return misc.as_unsigned_long_long(self.space, w_ob, strict=False) + def _overflow(self, w_ob): space = self.space s = space.str_w(space.str(w_ob)) @@ -163,13 +169,9 @@ self.vrangemax = (r_ulonglong(1) << sh) - 1 def int(self, cdata): - if self.value_fits_long: - # this case is to handle enums, but also serves as a slight - # performance improvement for some other primitive types - value = misc.read_raw_long_data(cdata, self.size) - return self.space.wrap(value) - else: - return self.convert_to_object(cdata) + # enums: really call convert_to_object() just below, + # and not the one overridden in W_CTypeEnum. + return W_CTypePrimitiveSigned.convert_to_object(self, cdata) def convert_to_object(self, cdata): if self.value_fits_long: @@ -203,8 +205,11 @@ W_CTypePrimitive.__init__(self, *args) self.value_fits_long = self.size < rffi.sizeof(lltype.Signed) if self.size < rffi.sizeof(lltype.SignedLongLong): - sh = self.size * 8 - self.vrangemax = (r_ulonglong(1) << sh) - 1 + self.vrangemax = self._compute_vrange_max() + + def _compute_vrange_max(self): + sh = self.size * 8 + return (r_ulonglong(1) << sh) - 1 def int(self, cdata): return self.convert_to_object(cdata) @@ -231,6 +236,23 @@ return self +class W_CTypePrimitiveBool(W_CTypePrimitiveUnsigned): + _attrs_ = [] + + def _compute_vrange_max(self): + return r_ulonglong(1) + + def _cast_result(self, intvalue): + return r_ulonglong(intvalue != 0) + + def _cast_generic(self, w_ob): + return misc.object_as_bool(self.space, w_ob) + + def string(self, cdataobj, maxlen): + # bypass the method 'string' implemented in W_CTypePrimitive + return W_CType.string(self, cdataobj, maxlen) + + class W_CTypePrimitiveFloat(W_CTypePrimitive): _attrs_ = [] 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 @@ -70,7 +70,8 @@ for i in range(len(lst_w)): ctitem.convert_from_object(cdata, lst_w[i]) cdata = rffi.ptradd(cdata, ctitem.size) - elif isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveChar): + elif (self.ctitem.is_primitive_integer and + self.ctitem.size == rffi.sizeof(lltype.Char)): try: s = space.str_w(w_ob) except OperationError, e: @@ -274,18 +275,26 @@ return True else: set_mustfree_flag(cdata, False) - try: - self.convert_from_object(cdata, w_ob) - except OperationError: - if (self.is_struct_ptr and isinstance(ob, cdataobj.W_CData) - and ob.ctype is self.ctitem): - # special case to make the life of verifier.py easier: - # if the formal argument type is 'struct foo *' but - # we pass a 'struct foo', then get a pointer to it - rffi.cast(rffi.CCHARPP, cdata)[0] = ob._cdata - else: - raise + self.convert_from_object(cdata, w_ob) return False def getcfield(self, attr): return self.ctitem.getcfield(attr) + + def typeoffsetof(self, fieldname): + if fieldname is None: + return W_CTypePtrBase.typeoffsetof(self, fieldname) + else: + return self.ctitem.typeoffsetof(fieldname) + + def rawaddressof(self, cdata, offset): + from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion + space = self.space + ctype2 = cdata.ctype + if (isinstance(ctype2, W_CTypeStructOrUnion) or + (isinstance(ctype2, W_CTypePtrOrArray) and ctype2.is_struct_ptr)): + ptrdata = rffi.ptradd(cdata._cdata, offset) + return cdataobj.W_CData(space, ptrdata, self) + else: + raise OperationError(space.w_TypeError, + space.wrap("expected a 'cdata struct-or-union' object")) diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -61,14 +61,19 @@ keepalive_until_here(ob) return ob - def offsetof(self, fieldname): + def typeoffsetof(self, fieldname): + if fieldname is None: + return (self, 0) self.check_complete() + space = self.space try: cfield = self.fields_dict[fieldname] except KeyError: - space = self.space raise OperationError(space.w_KeyError, space.wrap(fieldname)) - return cfield.offset + if cfield.bitshift >= 0: + raise OperationError(space.w_TypeError, + space.wrap("not supported for bitfields")) + return (cfield.ctype, cfield.offset) def _copy_from_same(self, cdata, w_ob): space = self.space diff --git a/pypy/module/_cffi_backend/func.py b/pypy/module/_cffi_backend/func.py --- a/pypy/module/_cffi_backend/func.py +++ b/pypy/module/_cffi_backend/func.py @@ -53,15 +53,19 @@ From noreply at buildbot.pypy.org Wed Oct 3 17:09:12 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 3 Oct 2012 17:09:12 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: some benchmark, very informative IMO Message-ID: <20121003150912.4198B1C002D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4833:63504cdb16b2 Date: 2012-10-03 10:08 +0200 http://bitbucket.org/pypy/extradoc/changeset/63504cdb16b2/ Log: some benchmark, very informative IMO diff --git a/talk/pyconza2012/examples/calls.py b/talk/pyconza2012/examples/calls.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/examples/calls.py @@ -0,0 +1,32 @@ + +import sys, time + +def inner(a, b, c): + pass + +def simple_call(a, b, c): + inner(a, b, c) + +def simple_call2(a, b, c): + inner(a, c=c, b=b) + +def star_call(a, b, c): + inner(*(a, b, c)) + +def star_call_complex(a, b, c): + inner(*(a, b), **{'c': c}) + +def abomination(a, b, c): + inner(**locals()) + +def run(func): + count = int(sys.argv[1]) + t0 = time.time() + for i in range(count): + func(i, i, i) + tk = time.time() + t = (tk - t0) / count + print "%.2e per call, %d cycles" % (t, int(t * 1.7e9)) + +for f in [simple_call, simple_call2, star_call, star_call_complex, abomination]: + run(f) From noreply at buildbot.pypy.org Wed Oct 3 17:09:13 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 3 Oct 2012 17:09:13 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: work work work Message-ID: <20121003150913.730141C002D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4834:4bd5e4d143e3 Date: 2012-10-03 17:02 +0200 http://bitbucket.org/pypy/extradoc/changeset/4bd5e4d143e3/ Log: work work work diff --git a/talk/pyconza2012/examples/calls.py b/talk/pyconza2012/examples/calls.py --- a/talk/pyconza2012/examples/calls.py +++ b/talk/pyconza2012/examples/calls.py @@ -10,6 +10,9 @@ def simple_call2(a, b, c): inner(a, c=c, b=b) +def simple_method(a, b, c): + c.m(a, b) + def star_call(a, b, c): inner(*(a, b, c)) @@ -19,14 +22,20 @@ def abomination(a, b, c): inner(**locals()) +class A(object): + def m(self, a, b): + pass + def run(func): count = int(sys.argv[1]) t0 = time.time() + o = A() for i in range(count): - func(i, i, i) + func(i, i, o) tk = time.time() t = (tk - t0) / count - print "%.2e per call, %d cycles" % (t, int(t * 1.7e9)) + print "%s %.2e per call, %d cycles" % (func.func_name, t, int(t * 1.7e9)) -for f in [simple_call, simple_call2, star_call, star_call_complex, abomination]: +for f in [simple_call, simple_call2, simple_method, star_call, star_call_complex, abomination]: run(f) + diff --git a/talk/pyconza2012/slides.rst b/talk/pyconza2012/slides.rst --- a/talk/pyconza2012/slides.rst +++ b/talk/pyconza2012/slides.rst @@ -22,12 +22,17 @@ |pause| -* who some assembler +* show some assembler |pause| * just joking +Disclaimer +---------- + +* we're trying to make it better + What is PyPy? ------------- @@ -124,5 +129,29 @@ Attribute access ---------------- +* if optimized, almost as fast as local var access + +* ``dict`` lookup optimized away + +* class attributes considered constant + +* meta programming is better than dynamism + +* objects for small number of constant keys, dicts for large + numbers of changing keys + Other sorts of loops -------------------- + +* there is more! + +* ``tuple(iterable)``, ``map(iterable)``, ``re.search`` + +* they're all jitted + +* not all nicely + +Future improvements +------------------- + +Xxxx From noreply at buildbot.pypy.org Wed Oct 3 17:09:14 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 3 Oct 2012 17:09:14 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: make slides viewab le Message-ID: <20121003150914.AAA6D1C002D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4835:153804ce4fc3 Date: 2012-10-03 17:08 +0200 http://bitbucket.org/pypy/extradoc/changeset/153804ce4fc3/ Log: make slides viewab le diff --git a/talk/pyconza2012/Makefile b/talk/pyconza2012/Makefile new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/Makefile @@ -0,0 +1,12 @@ + +talk.pdf: talk.rst author.latex title.latex stylesheet.latex + rst2beamer.py --stylesheet=stylesheet.latex --documentoptions=14pt --output-encoding=utf-8 talk.rst talk.latex || exit + sed 's/\\date{}/\\input{author.latex}/' -i talk.latex || exit + sed 's/\\maketitle/\\input{title.latex}/' -i talk.latex || exit + pdflatex talk.latex || exit + +view: talk.pdf + evince talk.pdf & + +xpdf: talk.pdf + xpdf talk.pdf & diff --git a/talk/pyconza2012/author.latex b/talk/pyconza2012/author.latex new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/author.latex @@ -0,0 +1,8 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[Python performance characteristics]{Python performance characteristics} +\author[Maciej Fijałkowski] +{Maciej Fijałkowski} + +\institute{PyCon 2012} +\date{October 5, 2012} diff --git a/talk/pyconza2012/beamerdefs.txt b/talk/pyconza2012/beamerdefs.txt new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/beamerdefs.txt @@ -0,0 +1,108 @@ +.. colors +.. =========================== + +.. role:: green +.. role:: red + + +.. general useful commands +.. =========================== + +.. |pause| raw:: latex + + \pause + +.. |small| raw:: latex + + {\small + +.. |end_small| raw:: latex + + } + +.. |scriptsize| raw:: latex + + {\scriptsize + +.. |end_scriptsize| raw:: latex + + } + +.. |strike<| raw:: latex + + \sout{ + +.. closed bracket +.. =========================== + +.. |>| raw:: latex + + } + + +.. example block +.. =========================== + +.. |example<| raw:: latex + + \begin{exampleblock}{ + + +.. |end_example| raw:: latex + + \end{exampleblock} + + + +.. alert block +.. =========================== + +.. |alert<| raw:: latex + + \begin{alertblock}{ + + +.. |end_alert| raw:: latex + + \end{alertblock} + + + +.. columns +.. =========================== + +.. |column1| raw:: latex + + \begin{columns} + \begin{column}{0.45\textwidth} + +.. |column2| raw:: latex + + \end{column} + \begin{column}{0.45\textwidth} + + +.. |end_columns| raw:: latex + + \end{column} + \end{columns} + + + +.. |snake| image:: ../img/py-web-new.png + :scale: 15% + + + +.. nested blocks +.. =========================== + +.. |nested| raw:: latex + + \begin{columns} + \begin{column}{0.85\textwidth} + +.. |end_nested| raw:: latex + + \end{column} + \end{columns} diff --git a/talk/pyconza2012/stylesheet.latex b/talk/pyconza2012/stylesheet.latex new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stylesheet.latex @@ -0,0 +1,12 @@ +\usepackage{ulem} +\usetheme{Boadilla} +\usecolortheme{whale} +\setbeamercovered{transparent} +\setbeamertemplate{navigation symbols}{} + +\definecolor{darkgreen}{rgb}{0, 0.5, 0.0} +\newcommand{\docutilsrolegreen}[1]{\color{darkgreen}#1\normalcolor} +\newcommand{\docutilsrolered}[1]{\color{red}#1\normalcolor} + +\newcommand{\green}[1]{\color{darkgreen}#1\normalcolor} +\newcommand{\red}[1]{\color{red}#1\normalcolor} diff --git a/talk/pyconza2012/slides.rst b/talk/pyconza2012/talk.rst rename from talk/pyconza2012/slides.rst rename to talk/pyconza2012/talk.rst --- a/talk/pyconza2012/slides.rst +++ b/talk/pyconza2012/talk.rst @@ -1,3 +1,5 @@ +.. include:: beamerdefs.txt + ================================== Python performance characteristics ================================== @@ -40,7 +42,7 @@ * PyPy is a toolchain for creating dynamic language implementations - * we try to rename the latter RPython + * we try to rename the latter to RPython * also, an Open Source project that has been around for a while diff --git a/talk/pyconza2012/title.latex b/talk/pyconza2012/title.latex new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/title.latex @@ -0,0 +1,5 @@ +\begin{titlepage} +\begin{figure}[h] +\includegraphics[width=60px]{../img/py-web-new.png} +\end{figure} +\end{titlepage} From noreply at buildbot.pypy.org Wed Oct 3 17:17:47 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 3 Oct 2012 17:17:47 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: Fix the previous merge :-/ Message-ID: <20121003151747.7C7EB1C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57775:6987a98100d0 Date: 2012-10-03 15:18 +0000 http://bitbucket.org/pypy/pypy/changeset/6987a98100d0/ Log: Fix the previous merge :-/ diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py --- a/pypy/rpython/memory/gctransform/framework.py +++ b/pypy/rpython/memory/gctransform/framework.py @@ -271,6 +271,9 @@ def _declare_functions(self, GCClass, getfn, s_gc, s_typeid16): + from pypy.rpython.memory.gc.base import ARRAY_TYPEID_MAP + from pypy.rpython.memory.gc import inspector + s_gcref = annmodel.SomePtr(llmemory.GCREF) gcdata = self.gcdata translator = self.translator @@ -327,7 +330,6 @@ annmodel.s_None) if hasattr(GCClass, 'heap_stats'): - from pypy.rpython.memory.gc.base import ARRAY_TYPEID_MAP self.heap_stats_ptr = getfn(GCClass.heap_stats.im_func, [s_gc], annmodel.SomePtr(lltype.Ptr(ARRAY_TYPEID_MAP)), minimal_transform=False) @@ -435,7 +437,6 @@ else: self.id_ptr = None - from pypy.rpython.memory.gc import inspector self.get_rpy_roots_ptr = getfn(inspector.get_rpy_roots, [s_gc], rgc.s_list_of_gcrefs(), @@ -510,38 +511,6 @@ [s_gc, annmodel.SomeInteger()], annmodel.SomeInteger()) - # thread support - if translator.config.translation.continuation: - root_walker.need_stacklet_support(self, getfn) - if translator.config.translation.thread: - root_walker.need_thread_support(self, getfn) - - self.layoutbuilder.encode_type_shapes_now() - - annhelper.finish() # at this point, annotate all mix-level helpers - annhelper.backend_optimize() - - self.collect_analyzer = CollectAnalyzer(self.translator) - self.collect_analyzer.analyze_all() - - s_gc = self.translator.annotator.bookkeeper.valueoftype(GCClass) - r_gc = self.translator.rtyper.getrepr(s_gc) - self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc) - s_gc_data = self.translator.annotator.bookkeeper.valueoftype( - gctypelayout.GCData) - r_gc_data = self.translator.rtyper.getrepr(s_gc_data) - self.c_const_gcdata = rmodel.inputconst(r_gc_data, self.gcdata) - self.malloc_zero_filled = GCClass.malloc_zero_filled - - HDR = self.HDR = self.gcdata.gc.gcheaderbuilder.HDR - - size_gc_header = self.gcdata.gc.gcheaderbuilder.size_gc_header - vtableinfo = (HDR, size_gc_header, self.gcdata.gc.typeid_is_in_field) - self.c_vtableinfo = rmodel.inputconst(lltype.Void, vtableinfo) - tig = self.layoutbuilder.type_info_group._as_ptr() - self.c_type_info_group = rmodel.inputconst(lltype.typeOf(tig), tig) - sko = llmemory.sizeof(gcdata.TYPE_INFO) - self.c_vtinfo_skip_offset = rmodel.inputconst(lltype.typeOf(sko), sko) def consider_constant(self, TYPE, value): self.layoutbuilder.consider_constant(TYPE, value, self.gcdata.gc) diff --git a/pypy/rpython/memory/gctransform/stmframework.py b/pypy/rpython/memory/gctransform/stmframework.py --- a/pypy/rpython/memory/gctransform/stmframework.py +++ b/pypy/rpython/memory/gctransform/stmframework.py @@ -1,4 +1,4 @@ -from pypy.rpython.memory.gctransform.framework import FrameworkGCTransformer +from pypy.rpython.memory.gctransform import shadowstack from pypy.rpython.memory.gctransform.framework import BaseRootWalker from pypy.rpython.memory.gctransform.framework import sizeofaddr from pypy.rpython.lltypesystem import lltype, llmemory @@ -12,7 +12,7 @@ END_MARKER = -8 # keep in sync with src_stm/rpyintf.c -class StmFrameworkGCTransformer(FrameworkGCTransformer): +class StmFrameworkGCTransformer(shadowstack.ShadowStackFrameworkGCTransformer): def _declare_functions(self, GCClass, getfn, s_gc, *args): super(StmFrameworkGCTransformer, self)._declare_functions( diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py --- a/pypy/translator/c/gc.py +++ b/pypy/translator/c/gc.py @@ -429,7 +429,7 @@ def OP_GC_STACK_BOTTOM(self, funcgen, op): return 'pypy_asm_stack_bottom();' -class StmFrameworkGcPolicy(FrameworkGcPolicy): +class StmFrameworkGcPolicy(BasicFrameworkGcPolicy): def gettransformer(self): from pypy.rpython.memory.gctransform import stmframework @@ -441,6 +441,6 @@ 'ref': RefcountingGcPolicy, 'none': NoneGcPolicy, 'framework+shadowstack': ShadowStackFrameworkGcPolicy, - 'framework+asmgcc': AsmGcRootFrameworkGcPolicy + 'framework+asmgcc': AsmGcRootFrameworkGcPolicy, 'framework+stm': StmFrameworkGcPolicy, } From noreply at buildbot.pypy.org Wed Oct 3 17:19:14 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 3 Oct 2012 17:19:14 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: 64-bit fix Message-ID: <20121003151914.709AA1C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57776:b673b45b1219 Date: 2012-10-03 17:18 +0200 http://bitbucket.org/pypy/pypy/changeset/b673b45b1219/ Log: 64-bit fix diff --git a/pypy/translator/c/src/debug_print.c b/pypy/translator/c/src/debug_print.c --- a/pypy/translator/c/src/debug_print.c +++ b/pypy/translator/c/src/debug_print.c @@ -162,10 +162,10 @@ } color = 31 + (color % 7); p = malloc(20); /* leak */ - sprintf(p, "\033[1m\033[%dm", color); + sprintf(p, "\033[1m\033[%dm", (int)color); debug_start_colors_1 = p; p = malloc(16); - sprintf(p, "\033[%dm", color); + sprintf(p, "\033[%dm", (int)color); debug_start_colors_2 = p; #endif } From noreply at buildbot.pypy.org Wed Oct 3 17:36:33 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 3 Oct 2012 17:36:33 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: Pffff. Message-ID: <20121003153633.3E2491C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57777:3dfd319c247e Date: 2012-10-03 17:36 +0200 http://bitbucket.org/pypy/pypy/changeset/3dfd319c247e/ Log: Pffff. diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -434,7 +434,7 @@ if self.with_stm(): from pypy.jit.backend.x86 import stmtlocal globaladdr -= stmtlocal.threadlocal_base() - assert 0 <= globaladdr < 0x10000 # estimate: "should be small" + assert -0x10000 <= globaladdr < 0x10000 #estimate: "should be small" # --- in particular, fits_in_32bits() must be true return globaladdr From noreply at buildbot.pypy.org Wed Oct 3 18:19:00 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 3 Oct 2012 18:19:00 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Kill unused attr PyGraph.is_generator Message-ID: <20121003161900.7520F1C002D@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57778:3397c9b8fc68 Date: 2012-10-03 17:13 +0100 http://bitbucket.org/pypy/pypy/changeset/3397c9b8fc68/ Log: Kill unused attr PyGraph.is_generator diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -253,7 +253,7 @@ frame.build_flow() fixeggblocks(graph) checkgraph(graph) - if graph.is_generator: + if code.is_generator: tweak_generator_graph(graph) return graph diff --git a/pypy/objspace/flow/pygraph.py b/pypy/objspace/flow/pygraph.py --- a/pypy/objspace/flow/pygraph.py +++ b/pypy/objspace/flow/pygraph.py @@ -25,7 +25,6 @@ self.func = func self.signature = code.signature() self.defaults = func.func_defaults or () - self.is_generator = code.is_generator @staticmethod def _sanitize_funcname(func): From noreply at buildbot.pypy.org Wed Oct 3 23:12:05 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 3 Oct 2012 23:12:05 +0200 (CEST) Subject: [pypy-commit] pypy default: Issue1276: (dalcinl) in PyBuffer_FillInfo, respect the readonly parameter Message-ID: <20121003211205.049881C002D@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r57779:624f21864eba Date: 2012-10-03 23:02 +0200 http://bitbucket.org/pypy/pypy/changeset/624f21864eba/ Log: Issue1276: (dalcinl) in PyBuffer_FillInfo, respect the readonly parameter and fail if it set and we asked for a PyBUF_WRITABLE buffer. diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py --- a/pypy/module/cpyext/object.py +++ b/pypy/module/cpyext/object.py @@ -451,7 +451,7 @@ PyBUF_WRITABLE = 0x0001 # Copied from object.h @cpython_api([lltype.Ptr(Py_buffer), PyObject, rffi.VOIDP, Py_ssize_t, - lltype.Signed, lltype.Signed], rffi.INT, error=CANNOT_FAIL) + lltype.Signed, lltype.Signed], rffi.INT, error=-1) def PyBuffer_FillInfo(space, view, obj, buf, length, readonly, flags): """ Fills in a buffer-info structure correctly for an exporter that can only @@ -461,15 +461,16 @@ This is not a complete re-implementation of the CPython API; it only provides a subset of CPython's behavior. """ + if flags & PyBUF_WRITABLE and readonly: + raise OperationError( + space.w_ValueError, space.wrap( + "Object is not writable")) view.c_buf = buf view.c_len = length view.c_obj = obj Py_IncRef(space, obj) view.c_itemsize = 1 - if flags & PyBUF_WRITABLE: - rffi.setintfield(view, 'c_readonly', 0) - else: - rffi.setintfield(view, 'c_readonly', 1) + rffi.setintfield(view, 'c_readonly', readonly) rffi.setintfield(view, 'c_ndim', 0) view.c_format = lltype.nullptr(rffi.CCHARP.TO) view.c_shape = lltype.nullptr(Py_ssize_tP.TO) diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py --- a/pypy/module/cpyext/test/test_object.py +++ b/pypy/module/cpyext/test/test_object.py @@ -342,6 +342,29 @@ assert "hello, world." == result + def test_fillReadonly(self): + """ + PyBuffer_FillInfo fails if WRITABLE is passed but object is readonly. + """ + module = self.import_extension('foo', [ + ("fillinfo", "METH_VARARGS", + """ + Py_buffer buf; + PyObject *str = PyString_FromString("hello, world."); + PyObject *result; + + if (PyBuffer_FillInfo(&buf, str, PyString_AsString(str), 13, + 1, PyBUF_WRITABLE)) { + Py_DECREF(str); + return NULL; + } + Py_DECREF(str); + PyBuffer_Release(&buf); + Py_RETURN_NONE; + """)]) + raises(ValueError, module.fillinfo) + + class AppTestPyBuffer_Release(AppTestCpythonExtensionBase): """ PyBuffer_Release releases the resources held by a Py_buffer. From noreply at buildbot.pypy.org Thu Oct 4 14:59:37 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Thu, 4 Oct 2012 14:59:37 +0200 (CEST) Subject: [pypy-commit] pypy default: (alex, fijal) Make char.{lower, upper}() return chars instead of upcasting to strings. Message-ID: <20121004125937.317431C002D@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r57780:26fac494c60a Date: 2012-10-04 05:58 -0700 http://bitbucket.org/pypy/pypy/changeset/26fac494c60a/ Log: (alex, fijal) Make char.{lower,upper}() return chars instead of upcasting to strings. diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -3859,6 +3859,14 @@ a = self.RPythonAnnotator() py.test.raises(Exception, a.build_types, fn, []) + def test_lower_char(self): + def fn(c): + return c.lower() + a = self.RPythonAnnotator() + s = a.build_types(fn, [annmodel.SomeChar()]) + assert s == annmodel.SomeChar() + + def g(n): return [0,1,2,n] diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -586,6 +586,12 @@ def method_isupper(chr): return s_Bool + def method_lower(chr): + return chr + + def method_upper(chr): + return chr + class __extend__(SomeIterator): def iter(itr): diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py --- a/pypy/rpython/lltypesystem/rstr.py +++ b/pypy/rpython/lltypesystem/rstr.py @@ -405,13 +405,15 @@ result = mallocstr(s_len) # ^^^^^^^^^ specifically to explode on unicode while i < s_len: - ch = s_chars[i] - if 'a' <= ch <= 'z': - ch = chr(ord(ch) - 32) - result.chars[i] = ch + result.chars[i] = LLHelpers.ll_upper_char(s_chars[i]) i += 1 return result + def ll_upper_char(ch): + if 'a' <= ch <= 'z': + ch = chr(ord(ch) - 32) + return ch + @jit.elidable def ll_lower(s): s_chars = s.chars @@ -422,13 +424,15 @@ result = mallocstr(s_len) # ^^^^^^^^^ specifically to explode on unicode while i < s_len: - ch = s_chars[i] - if 'A' <= ch <= 'Z': - ch = chr(ord(ch) + 32) - result.chars[i] = ch + result.chars[i] = LLHelpers.ll_lower_char(s_chars[i]) i += 1 return result + def ll_lower_char(ch): + if 'A' <= ch <= 'Z': + ch = chr(ord(ch) + 32) + return ch + def ll_join(s, length, items): s_chars = s.chars s_len = len(s_chars) diff --git a/pypy/rpython/rstr.py b/pypy/rpython/rstr.py --- a/pypy/rpython/rstr.py +++ b/pypy/rpython/rstr.py @@ -40,7 +40,18 @@ class AbstractCharRepr(AbstractStringRepr): - pass + def rtype_method_lower(self, hop): + char_repr = hop.args_r[0].char_repr + v_chr, = hop.inputargs(char_repr) + hop.exception_cannot_occur() + return hop.gendirectcall(self.ll.ll_lower_char, v_chr) + + def rtype_method_upper(self, hop): + char_repr = hop.args_r[0].char_repr + v_chr, = hop.inputargs(char_repr) + hop.exception_cannot_occur() + return hop.gendirectcall(self.ll.ll_upper_char, v_chr) + class AbstractUniCharRepr(AbstractStringRepr): pass diff --git a/pypy/rpython/test/test_rstr.py b/pypy/rpython/test/test_rstr.py --- a/pypy/rpython/test/test_rstr.py +++ b/pypy/rpython/test/test_rstr.py @@ -1026,6 +1026,19 @@ const = str constchar = chr + def test_lower_char(self): + def fn(i): + return chr(i).lower() + for c in ["a", "A", "1"]: + assert self.interpret(fn, [ord(c)]) == c.lower() + + def test_upper_char(self): + def fn(i): + return chr(i).upper() + for c in ["a", "A", "1"]: + assert self.interpret(fn, [ord(c)]) == c.upper() + + class TestLLtype(BaseTestRstr, LLRtypeMixin): def test_ll_find_rfind(self): @@ -1056,4 +1069,8 @@ class TestOOtype(BaseTestRstr, OORtypeMixin): - pass + def test_lower_char(self): + py.test.skip() + + def test_upper_char(self): + py.test.skip() From noreply at buildbot.pypy.org Thu Oct 4 17:50:12 2012 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 4 Oct 2012 17:50:12 +0200 (CEST) Subject: [pypy-commit] buildbot default: add a step to move generated and copied header files to the checkout used to run the app-level tests Message-ID: <20121004155012.0EEA91C0013@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r703:a0e1acb66eda Date: 2012-10-04 12:46 -0300 http://bitbucket.org/pypy/buildbot/changeset/a0e1acb66eda/ Log: add a step to move generated and copied header files to the checkout used to run the app-level tests diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -415,7 +415,11 @@ workdir='.', blocksize=100 * 1024)) + class TranslatedTests(factory.BuildFactory): + ''' + Download a pypy nightly build and run the app-level tests on the binary + ''' def __init__(self, platform='linux', app_tests=False, @@ -455,10 +459,15 @@ command=['tar', '--extract', '--file=pypy_build'+ extension, '--strip-components=1', '--directory=.'], workdir='pypy-c')) - # copy pypy-c to the expected location within the pypy source checkout + # copy pypy-c to the expected location within the pypy source checkout self.addStep(ShellCmd( description="move pypy-c", - command=['cp', 'pypy-c/bin/pypy', 'build/pypy/translator/goal/pypy-c'], + command=['cp', '-v', 'pypy-c/bin/pypy', 'build/pypy/translator/goal/pypy-c'], + workdir='.')) + # copy generated and copied header files + self.addStep(ShellCmd( + description="move header files", + command=['cp', '-vr', 'pypy-c/include/', 'build/include/'], workdir='.')) add_translated_tests(self, prefix, platform, app_tests, lib_python, pypyjit) From noreply at buildbot.pypy.org Thu Oct 4 20:10:58 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 4 Oct 2012 20:10:58 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Copy and adapt PyCode._from_code() into HostCode Message-ID: <20121004181058.41B921C0013@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57781:59858f210807 Date: 2012-10-04 01:10 +0100 http://bitbucket.org/pypy/pypy/changeset/59858f210807/ Log: Copy and adapt PyCode._from_code() into HostCode diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,6 +1,7 @@ """ Bytecode handling classes and functions for use by the flow space. """ +from types import CodeType from pypy.interpreter.pycode import (PyCode, BytecodeCorruption, cpython_magic, cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, @@ -67,6 +68,33 @@ self._args_as_cellvars.append(-1) # pad self._args_as_cellvars[i] = j + @classmethod + def _from_code(cls, space, code, hidden_applevel=False): + """Initialize the code object from a real (CPython) one. + """ + newconsts_w = [] + for num, const in enumerate(code.co_consts): + if isinstance(const, CodeType): + const = cls._from_code(space, const, hidden_applevel) + newconsts_w.append(space.wrap(const)) + # stick the underlying CPython magic value, if the code object + # comes from there + return cls(space, code.co_argcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + newconsts_w[:], + list(code.co_names), + list(code.co_varnames), + code.co_filename, + code.co_name, + code.co_firstlineno, + code.co_lnotab, + list(code.co_freevars), + list(code.co_cellvars), + hidden_applevel, cpython_magic) + def make_cells(self, closure): """Convert a Python closure object into a list of Cells""" if closure is not None: From noreply at buildbot.pypy.org Thu Oct 4 20:10:59 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 4 Oct 2012 20:10:59 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Don't wrap objects inside HostCode Message-ID: <20121004181059.8E63F1C0473@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57782:1e60a9eae76b Date: 2012-10-04 19:10 +0100 http://bitbucket.org/pypy/pypy/changeset/1e60a9eae76b/ Log: Don't wrap objects inside HostCode HostCode attributes could only contain Constants, not Variables, so that wrapping and unwrapping was always trivial and can therefore be skipped. diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -30,8 +30,8 @@ self.co_stacksize = stacksize self.co_flags = flags self.co_code = code - self.co_consts_w = consts - self.co_names_w = [space.wrap(aname) for aname in names] + self.consts = consts + self.names = names self.co_varnames = varnames self.co_freevars = freevars self.co_cellvars = cellvars @@ -72,11 +72,11 @@ def _from_code(cls, space, code, hidden_applevel=False): """Initialize the code object from a real (CPython) one. """ - newconsts_w = [] - for num, const in enumerate(code.co_consts): + newconsts = [] + for const in code.co_consts: if isinstance(const, CodeType): const = cls._from_code(space, const, hidden_applevel) - newconsts_w.append(space.wrap(const)) + newconsts.append(const) # stick the underlying CPython magic value, if the code object # comes from there return cls(space, code.co_argcount, @@ -84,7 +84,7 @@ code.co_stacksize, code.co_flags, code.co_code, - newconsts_w[:], + newconsts, list(code.co_names), list(code.co_varnames), code.co_filename, diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -420,6 +420,18 @@ next_instr = block.handle(self, unroller) return next_instr + def getlocalvarname(self, index): + return self.pycode.co_varnames[index] + + def getconstant_w(self, index): + return self.space.wrap(self.pycode.consts[index]) + + def getname_u(self, index): + return self.pycode.names[index] + + def getname_w(self, index): + return Constant(self.pycode.names[index]) + def BAD_OPCODE(self, _, next_instr): raise FlowingError(self, "This operation is not RPython") From noreply at buildbot.pypy.org Thu Oct 4 20:32:58 2012 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 4 Oct 2012 20:32:58 +0200 (CEST) Subject: [pypy-commit] pypy default: workaround for issue #1259, use a module that has a correct __file__ attribute to compute the path to the math_testcases.txt file Message-ID: <20121004183258.4E4631C0473@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r57783:17ffe013d44c Date: 2012-10-04 15:32 -0300 http://bitbucket.org/pypy/pypy/changeset/17ffe013d44c/ Log: workaround for issue #1259, use a module that has a correct __file__ attribute to compute the path to the math_testcases.txt file diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -130,7 +130,7 @@ def test_mtestfile(self): import math - import abc + import zipfile import os import struct def _parse_mtestfile(fname): @@ -207,7 +207,7 @@ fail_fmt = "{}:{}({!r}): expected {!r}, got {!r}" failures = [] - math_testcases = os.path.join(os.path.dirname(abc.__file__), "test", + math_testcases = os.path.join(os.path.dirname(zipfile.__file__), "test", "math_testcases.txt") for id, fn, arg, expected, flags in _parse_mtestfile(math_testcases): func = getattr(math, fn) From noreply at buildbot.pypy.org Thu Oct 4 21:03:36 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 4 Oct 2012 21:03:36 +0200 (CEST) Subject: [pypy-commit] pypy default: Issue1277: fix signature of PyCode_GetNumFree(). Message-ID: <20121004190336.91E401C0EE8@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r57784:bdee7a1c7e4c Date: 2012-10-04 19:06 +0200 http://bitbucket.org/pypy/pypy/changeset/bdee7a1c7e4c/ Log: Issue1277: fix signature of PyCode_GetNumFree(). diff --git a/pypy/module/cpyext/funcobject.py b/pypy/module/cpyext/funcobject.py --- a/pypy/module/cpyext/funcobject.py +++ b/pypy/module/cpyext/funcobject.py @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( - PyObjectFields, generic_cpy_call, CONST_STRING, CANNOT_FAIL, + PyObjectFields, generic_cpy_call, CONST_STRING, CANNOT_FAIL, Py_ssize_t, cpython_api, bootstrap_function, cpython_struct, build_type_checkers) from pypy.module.cpyext.pyobject import ( PyObject, make_ref, from_ref, Py_DecRef, make_typedescr, borrow_from) @@ -168,7 +168,7 @@ freevars=[], cellvars=[])) - at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) + at cpython_api([PyCodeObject], Py_ssize_t, error=CANNOT_FAIL) def PyCode_GetNumFree(space, w_co): """Return the number of free variables in co.""" co = space.interp_w(PyCode, w_co) From noreply at buildbot.pypy.org Thu Oct 4 21:52:04 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 4 Oct 2012 21:52:04 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Don't derive HostCode from PyCode. Message-ID: <20121004195204.B40BE1C002D@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57785:375bfab2defa Date: 2012-10-04 20:03 +0100 http://bitbucket.org/pypy/pypy/changeset/375bfab2defa/ Log: Don't derive HostCode from PyCode. * Make HostCode.signature an ordinary attribute instead of a method. * Add HostCode.formalargcount property, replacing .getformalargcount(). diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -2,7 +2,7 @@ Bytecode handling classes and functions for use by the flow space. """ from types import CodeType -from pypy.interpreter.pycode import (PyCode, BytecodeCorruption, cpython_magic, +from pypy.interpreter.pycode import (BytecodeCorruption, cpython_magic, cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) @@ -11,7 +11,7 @@ from pypy.interpreter.nestedscope import Cell from pypy.objspace.flow.model import Constant -class HostCode(PyCode): +class HostCode(object): """ A wrapper around a native code object of the host interpreter """ @@ -41,7 +41,7 @@ self.co_lnotab = lnotab self.hidden_applevel = hidden_applevel self.magic = magic - self._signature = cpython_code_signature(self) + self.signature = cpython_code_signature(self) self._initialize() def _initialize(self): @@ -95,6 +95,12 @@ list(code.co_cellvars), hidden_applevel, cpython_magic) + @property + def formalargcount(self): + """Total number of arguments passed into the frame, including *vararg + and **varkwarg, if they exist.""" + return self.signature.scope_length() + def make_cells(self, closure): """Convert a Python closure object into a list of Cells""" if closure is not None: diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -240,7 +240,7 @@ """ Initialize the locals and the stack. - The locals are ordered according to self.pycode.signature(). + The locals are ordered according to self.pycode.signature. """ self.valuestackdepth = code.co_nlocals self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals) diff --git a/pypy/objspace/flow/pygraph.py b/pypy/objspace/flow/pygraph.py --- a/pypy/objspace/flow/pygraph.py +++ b/pypy/objspace/flow/pygraph.py @@ -13,7 +13,7 @@ def __init__(self, func, code): from pypy.objspace.flow.flowcontext import SpamBlock data = [None] * code.co_nlocals - for i in range(code.getformalargcount()): + for i in range(code.formalargcount): data[i] = Variable() state = FrameState(data + [Constant(None), Constant(None)], [], 0) initialblock = SpamBlock(state) @@ -23,7 +23,7 @@ super(PyGraph, self).__init__(self._sanitize_funcname(func), initialblock) self.func = func - self.signature = code.signature() + self.signature = code.signature self.defaults = func.func_defaults or () @staticmethod From noreply at buildbot.pypy.org Thu Oct 4 22:37:33 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 4 Oct 2012 22:37:33 +0200 (CEST) Subject: [pypy-commit] pypy py3k: The default implementation of __ne__ should now call not(x==y). Message-ID: <20121004203733.850321C0013@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57786:31bd302f43ac Date: 2012-10-04 22:06 +0200 http://bitbucket.org/pypy/pypy/changeset/31bd302f43ac/ Log: The default implementation of __ne__ should now call not(x==y). This explains why running CPython test suite always displayed "Warning -- threading._dangling was modified". diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -572,11 +572,14 @@ # # we did not find any special method, let's do the default logic for # == and != - if left == '__eq__' or left == '__ne__': + if left == '__eq__': # they are not identical, else it would have been caught by the if # at the top of the function assert not space.is_w(w_obj1, w_obj2) - return space.wrap(left != '__eq__') + return space.w_False + elif left == '__ne__': + assert not space.is_w(w_obj1, w_obj2) + return space.not_(space.eq(w_obj1, w_obj2)) # # if we arrived here, they are unorderable typename1 = space.type(w_obj1).getname(space) diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py --- a/pypy/objspace/test/test_descroperation.py +++ b/pypy/objspace/test/test_descroperation.py @@ -440,6 +440,10 @@ assert B(1) == A(1) assert not(A(1) == B(2)) assert not(B(1) == A(2)) + assert A(1) != B(2) + assert B(1) != A(2) + assert not(A(1) != B(1)) + assert not(B(1) != A(1)) def test_partial_ordering(self): class A(object): From noreply at buildbot.pypy.org Thu Oct 4 22:37:34 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 4 Oct 2012 22:37:34 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix implementation details in test_list. Message-ID: <20121004203734.D8B771C0013@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57787:bd24b426f108 Date: 2012-10-04 22:08 +0200 http://bitbucket.org/pypy/pypy/changeset/bd24b426f108/ Log: Fix implementation details in test_list. diff --git a/lib-python/3.2/test/list_tests.py b/lib-python/3.2/test/list_tests.py --- a/lib-python/3.2/test/list_tests.py +++ b/lib-python/3.2/test/list_tests.py @@ -48,7 +48,7 @@ self.assertEqual(repr(a2), "[0, 1, 2, [...], 3]") l0 = [] - for i in range(sys.getrecursionlimit() + 100): + for i in range(sys.getrecursionlimit() + 10000): l0 = [l0] self.assertRaises(RuntimeError, repr, l0) @@ -482,7 +482,7 @@ u += "eggs" self.assertEqual(u, self.type2test("spameggs")) - self.assertRaises(TypeError, u.__iadd__, None) + self.assertRaises(TypeError, "u += None") def test_imul(self): u = self.type2test([0, 1]) From noreply at buildbot.pypy.org Thu Oct 4 22:37:36 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 4 Oct 2012 22:37:36 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix tuple.__repr__ containing non-ascii strings. Message-ID: <20121004203736.1871F1C0013@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57788:290b886bc923 Date: 2012-10-04 22:37 +0200 http://bitbucket.org/pypy/pypy/changeset/290b886bc923/ Log: Fix tuple.__repr__ containing non-ascii strings. diff --git a/pypy/objspace/std/test/test_tupleobject.py b/pypy/objspace/std/test/test_tupleobject.py --- a/pypy/objspace/std/test/test_tupleobject.py +++ b/pypy/objspace/std/test/test_tupleobject.py @@ -330,6 +330,8 @@ assert repr((1,)) == '(1,)' assert repr(()) == '()' assert repr((1,2,3)) == '(1, 2, 3)' + assert repr(('\xe9',)) == "('\xe9',)" + assert repr(('\xe9', 1)) == "('\xe9', 1)" def test_getslice(self): assert ('a', 'b', 'c')[-17: 2] == ('a', 'b') diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -161,10 +161,11 @@ # XXX this is quite innefficient, still better than calling # it via applevel if len(items) == 1: - return space.wrap("(" + space.str_w(space.repr(items[0])) + ",)") - return space.wrap("(" + - (", ".join([space.str_w(space.repr(item)) for item in items])) - + ")") + return space.wrap(u"(" + space.unicode_w(space.repr(items[0])) + u",)") + return space.wrap(u"(" + + (u", ".join([space.unicode_w(space.repr(item)) + for item in items])) + + u")") def hash__Tuple(space, w_tuple): return space.wrap(hash_tuple(space, w_tuple.wrappeditems)) From noreply at buildbot.pypy.org Thu Oct 4 23:06:38 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 4 Oct 2012 23:06:38 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix error message for int('invalid'). Message-ID: <20121004210638.3A8F21C0013@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57789:8879a47cad40 Date: 2012-10-04 22:57 +0200 http://bitbucket.org/pypy/pypy/changeset/8879a47cad40/ Log: Fix error message for int('invalid'). Yes, CPython has a test for it. diff --git a/pypy/objspace/std/strutil.py b/pypy/objspace/std/strutil.py --- a/pypy/objspace/std/strutil.py +++ b/pypy/objspace/std/strutil.py @@ -138,7 +138,7 @@ if (s.endswith(u'l') or s.endswith(u'L')) and base < 22: # in base 22 and above, 'L' is a valid digit! try: long('L',22) s = s[:-1] - p = NumberStringParser(s, literal, base, u'long') + p = NumberStringParser(s, literal, base, u'int') else: p = parser return parse_digit_string(p) From noreply at buildbot.pypy.org Thu Oct 4 23:06:39 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 4 Oct 2012 23:06:39 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Somehow SSLContext.options was defined but not exported for applevel. Message-ID: <20121004210639.8B96E1C0013@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57790:5804e3969810 Date: 2012-10-04 23:00 +0200 http://bitbucket.org/pypy/pypy/changeset/5804e3969810/ Log: Somehow SSLContext.options was defined but not exported for applevel. 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 @@ -266,6 +266,8 @@ SSLContext.typedef = TypeDef( "_SSLContext", __new__ = interp2app(SSLContext.descr_new.im_func), + options = GetSetProperty(SSLContext.get_options_w, + SSLContext.set_options_w), verify_mode = GetSetProperty(SSLContext.get_verify_mode_w, SSLContext.set_verify_mode_w), _wrap_socket = interp2app(SSLContext.wrap_socket_w), From noreply at buildbot.pypy.org Fri Oct 5 01:33:05 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 5 Oct 2012 01:33:05 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Remove now unused attribute HostCode.space Message-ID: <20121004233305.141221C0013@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57791:baf75ba3392b Date: 2012-10-05 00:20 +0100 http://bitbucket.org/pypy/pypy/changeset/baf75ba3392b/ Log: Remove now unused attribute HostCode.space diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -17,12 +17,11 @@ """ opnames = host_bytecode_spec.method_names - def __init__(self, space, argcount, nlocals, stacksize, flags, + def __init__(self, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, hidden_applevel=False, magic=cpython_magic): """Initialize a new code object""" - self.space = space self.co_name = name assert nlocals >= 0 self.co_argcount = argcount @@ -69,17 +68,17 @@ self._args_as_cellvars[i] = j @classmethod - def _from_code(cls, space, code, hidden_applevel=False): + def _from_code(cls, code, hidden_applevel=False): """Initialize the code object from a real (CPython) one. """ newconsts = [] for const in code.co_consts: if isinstance(const, CodeType): - const = cls._from_code(space, const, hidden_applevel) + const = cls._from_code(const, hidden_applevel) newconsts.append(const) # stick the underlying CPython magic value, if the code object # comes from there - return cls(space, code.co_argcount, + return cls(code.co_argcount, code.co_nlocals, code.co_stacksize, code.co_flags, diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -239,7 +239,7 @@ """ if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): raise Exception, "%r is tagged as NOT_RPYTHON" % (func,) - code = HostCode._from_code(self, func.func_code) + code = HostCode._from_code(func.func_code) if (code.is_generator and not hasattr(func, '_generator_next_method_of_')): graph = PyGraph(func, code) diff --git a/pypy/objspace/flow/test/test_framestate.py b/pypy/objspace/flow/test/test_framestate.py --- a/pypy/objspace/flow/test/test_framestate.py +++ b/pypy/objspace/flow/test/test_framestate.py @@ -14,7 +14,7 @@ func = func.im_func except AttributeError: pass - code = HostCode._from_code(self.space, func.func_code) + code = HostCode._from_code(func.func_code) graph = PyGraph(func, code) frame = FlowSpaceFrame(self.space, graph, code) # hack the frame From noreply at buildbot.pypy.org Fri Oct 5 13:56:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 5 Oct 2012 13:56:34 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: Delayed pointers are not the same as external pointers. Message-ID: <20121005115634.D098A1C0F28@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57792:5b4fe54db34a Date: 2012-10-05 13:23 +0200 http://bitbucket.org/pypy/pypy/changeset/5b4fe54db34a/ Log: Delayed pointers are not the same as external pointers. For now, just return top_result(). diff --git a/pypy/translator/backendopt/graphanalyze.py b/pypy/translator/backendopt/graphanalyze.py --- a/pypy/translator/backendopt/graphanalyze.py +++ b/pypy/translator/backendopt/graphanalyze.py @@ -73,6 +73,15 @@ if op.opname == "direct_call": graph = get_graph(op.args[0], self.translator) if graph is None: + try: # detect calls to DelayedPointers + op.args[0].value._obj + except AttributeError: + pass # ootype + except lltype.DelayedPointer: + x = self.top_result() + if self.verbose: + print '\tdelayed pointer %s: %r' % (op, x) + return x x = self.analyze_external_call(op, seen) if self.verbose and x: print '\tanalyze_external_call %s: %r' % (op, x) diff --git a/pypy/translator/simplify.py b/pypy/translator/simplify.py --- a/pypy/translator/simplify.py +++ b/pypy/translator/simplify.py @@ -21,9 +21,9 @@ Return an object which is supposed to have attributes such as graph and _callable """ - if hasattr(func, '_obj'): + try: return func._obj # lltypesystem - else: + except AttributeError: return func # ootypesystem def get_functype(TYPE): From noreply at buildbot.pypy.org Fri Oct 5 13:56:36 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 5 Oct 2012 13:56:36 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: Fix Message-ID: <20121005115636.1B6DC1C0F28@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57793:ae67b1d5b010 Date: 2012-10-05 11:57 +0000 http://bitbucket.org/pypy/pypy/changeset/ae67b1d5b010/ Log: Fix diff --git a/pypy/translator/backendopt/graphanalyze.py b/pypy/translator/backendopt/graphanalyze.py --- a/pypy/translator/backendopt/graphanalyze.py +++ b/pypy/translator/backendopt/graphanalyze.py @@ -71,17 +71,14 @@ def analyze(self, op, seen=None, graphinfo=None): if op.opname == "direct_call": - graph = get_graph(op.args[0], self.translator) + try: + graph = get_graph(op.args[0], self.translator) + except lltype.DelayedPointer: + x = self.top_result() + if self.verbose: + print '\tdelayed pointer %s: %r' % (op, x) + return x if graph is None: - try: # detect calls to DelayedPointers - op.args[0].value._obj - except AttributeError: - pass # ootype - except lltype.DelayedPointer: - x = self.top_result() - if self.verbose: - print '\tdelayed pointer %s: %r' % (op, x) - return x x = self.analyze_external_call(op, seen) if self.verbose and x: print '\tanalyze_external_call %s: %r' % (op, x) From noreply at buildbot.pypy.org Fri Oct 5 14:54:00 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 5 Oct 2012 14:54:00 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: Ignore calls to _gctransformer_hint_close_stack_ functions. Message-ID: <20121005125400.722ED1C0F3A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57794:fd5a4f54ed7a Date: 2012-10-05 12:55 +0000 http://bitbucket.org/pypy/pypy/changeset/fd5a4f54ed7a/ Log: Ignore calls to _gctransformer_hint_close_stack_ functions. diff --git a/pypy/jit/codewriter/call.py b/pypy/jit/codewriter/call.py --- a/pypy/jit/codewriter/call.py +++ b/pypy/jit/codewriter/call.py @@ -137,6 +137,10 @@ if (hasattr(targetgraph, 'func') and hasattr(targetgraph.func, 'oopspec')): return 'builtin' + if (hasattr(targetgraph, 'func') and + getattr(targetgraph.func, '_gctransformer_hint_close_stack_', + False)): + return 'residual' elif op.opname == 'oosend': SELFTYPE, methname, opargs = support.decompose_oosend(op) if SELFTYPE.oopspec_name is not None: From noreply at buildbot.pypy.org Fri Oct 5 15:44:07 2012 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 5 Oct 2012 15:44:07 +0200 (CEST) Subject: [pypy-commit] buildbot default: grrr, tweak Message-ID: <20121005134407.5E8621C0F1C@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r704:c8e0191cbbfa Date: 2012-10-05 10:43 -0300 http://bitbucket.org/pypy/buildbot/changeset/c8e0191cbbfa/ Log: grrr, tweak diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -464,10 +464,10 @@ description="move pypy-c", command=['cp', '-v', 'pypy-c/bin/pypy', 'build/pypy/translator/goal/pypy-c'], workdir='.')) - # copy generated and copied header files + # copy generated and copied header files to build/include self.addStep(ShellCmd( description="move header files", - command=['cp', '-vr', 'pypy-c/include/', 'build/include/'], + command=['cp', '-vr', 'pypy-c/include', 'build'], workdir='.')) add_translated_tests(self, prefix, platform, app_tests, lib_python, pypyjit) From noreply at buildbot.pypy.org Fri Oct 5 16:35:24 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 5 Oct 2012 16:35:24 +0200 (CEST) Subject: [pypy-commit] pypy numpy-reintroduce-zjit-tests: Start working on porting those tests Message-ID: <20121005143524.E97A71C0F30@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: numpy-reintroduce-zjit-tests Changeset: r57795:8dae1efc1609 Date: 2012-10-05 16:33 +0200 http://bitbucket.org/pypy/pypy/changeset/8dae1efc1609/ Log: Start working on porting those tests 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 @@ -64,7 +64,6 @@ self.__class__.graph = graph reset_stats() pyjitpl._warmrunnerdesc.memory_manager.alive_loops.clear() - py.test.skip("don't run for now") return self.interp.eval_graph(self.graph, [i]) def define_add(): @@ -76,10 +75,10 @@ def test_add(self): result = self.run("add") - self.check_simple_loop({'raw_load': 2, 'float_add': 1, - 'raw_store': 1, 'int_add': 1, - 'int_ge': 1, 'guard_false': 1, 'jump': 1, - 'arraylen_gc': 1}) + self.check_simple_loop({'float_add': 1, 'getfield_gc': 4, + 'raw_load': 2, 'setfield_gc': 3, + 'raw_store': 1, 'int_add': 3, + 'int_ge': 1, 'guard_false': 1, 'jump': 1}) assert result == 3 + 3 def define_float_add(): @@ -91,24 +90,24 @@ def test_floatadd(self): result = self.run("float_add") assert result == 3 + 3 - self.check_simple_loop({"raw_load": 1, "float_add": 1, - "raw_store": 1, "int_add": 1, - "int_ge": 1, "guard_false": 1, "jump": 1, - 'arraylen_gc': 1}) + self.check_simple_loop({"getfield_gc": 2, "setfield_gc": 2, + "raw_load": 1, "float_add": 1, + "raw_store": 1, "int_add": 2, + "int_ge": 1, "guard_false": 1, "jump": 1}) def define_sum(): return """ a = |30| - b = a + a - sum(b) + sum(a) """ def test_sum(self): result = self.run("sum") - assert result == 2 * sum(range(30)) - self.check_simple_loop({"raw_load": 2, "float_add": 2, + assert result == sum(range(30)) + self.check_simple_loop({"raw_load": 1, "float_add": 1, "int_add": 1, "int_ge": 1, "guard_false": 1, - "jump": 1, 'arraylen_gc': 1}) + "setfield_gc": 1, "setfield_gc": 1, + "jump": 1}) def define_axissum(): return """ @@ -120,71 +119,33 @@ def test_axissum(self): result = self.run("axissum") assert result == 30 - # XXX note - the bridge here is fairly crucial and yet it's pretty - # bogus. We need to improve the situation somehow. - self.check_simple_loop({'raw_load': 2, - 'raw_store': 1, - 'arraylen_gc': 2, - 'guard_true': 1, - 'int_lt': 1, - 'jump': 1, - 'float_add': 1, - 'int_add': 3, - }) - - def define_prod(): - return """ - a = |30| - b = a + a - prod(b) - """ - - def test_prod(self): - result = self.run("prod") - expected = 1 - for i in range(30): - expected *= i * 2 - assert result == expected - self.check_simple_loop({"raw_load": 2, "float_add": 1, - "float_mul": 1, "int_add": 1, - "int_ge": 1, "guard_false": 1, "jump": 1, - 'arraylen_gc': 1}) + # XXX deal with the bridge at some point + self.check_simple_loop({'raw_load':2, 'float_add': 1, + 'raw_store': 1, 'getarrayitem_gc': 3, + 'getarrayitem_gc_pure': 1, 'int_add': 2, + 'int_sub': 1, 'setfield_gc': 1, + 'int_lt': 1, 'guard_true': 1, + 'setarrayitem_gc': 1}) def define_max(): return """ a = |30| a[13] = 128 - b = a + a - max(b) + max(a) """ def test_max(self): result = self.run("max") - assert result == 256 - py.test.skip("not there yet, getting though") - self.check_simple_loop({"raw_load": 2, "float_add": 1, - "float_mul": 1, "int_add": 1, - "int_lt": 1, "guard_true": 1, "jump": 1}) - - def test_min(self): - py.test.skip("broken, investigate") - result = self.run(""" - a = |30| - a[15] = -12 - b = a + a - min(b) - """) - assert result == -24 - self.check_simple_loop({"raw_load": 2, "float_add": 1, - "float_mul": 1, "int_add": 1, - "int_lt": 1, "guard_true": 1, "jump": 1}) + assert result == 128 + self.check_simple_loop({"raw_load": 1, "float_gt": 1, + "guard_false": 2, "int_add": 1, + "int_ge": 1, "setfield_gc": 1}) def define_any(): return """ a = [0,0,0,0,0,0,0,0,0,0,0] a[8] = -12 - b = a + a - any(b) + any(a) """ def test_any(self): @@ -196,35 +157,10 @@ "int_ge": 1, "jump": 1, "guard_false": 2, 'arraylen_gc': 1}) - def define_already_forced(): - return """ - a = |30| - b = a + 4.5 - b -> 5 # forces - c = b * 8 - c -> 5 - """ - - def test_already_forced(self): - result = self.run("already_forced") - assert result == (5 + 4.5) * 8 - # This is the sum of the ops for both loops, however if you remove the - # optimization then you end up with 2 float_adds, so we can still be - # sure it was optimized correctly. - py.test.skip("too fragile") - self.check_resops({'raw_store': 4, 'getfield_gc': 22, - 'getarrayitem_gc': 4, 'getarrayitem_gc_pure': 2, - 'getfield_gc_pure': 8, - 'guard_class': 8, 'int_add': 8, 'float_mul': 2, - 'jump': 2, 'int_ge': 4, - 'raw_load': 4, 'float_add': 2, - 'guard_false': 4, 'arraylen_gc': 2, 'same_as': 2}) - def define_ufunc(): return """ a = |30| - b = a + a - c = unegative(b) + c = unegative(a) c -> 3 """ @@ -237,31 +173,6 @@ "int_ge": 1, "guard_false": 1, "jump": 1, 'arraylen_gc': 1}) - def define_specialization(): - return """ - a = |30| - b = a + a - c = unegative(b) - c -> 3 - d = a * a - unegative(d) - d -> 3 - d = a * a - unegative(d) - d -> 3 - d = a * a - unegative(d) - d -> 3 - d = a * a - unegative(d) - d -> 3 - """ - - def test_specialization(self): - self.run("specialization") - # This is 3, not 2 because there is a bridge for the exit. - self.check_trace_count(3) - def define_slice(): return """ a = |30| From noreply at buildbot.pypy.org Fri Oct 5 19:02:18 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 5 Oct 2012 19:02:18 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Kill unused attribute HostCode.hidden_applevel Message-ID: <20121005170218.AE08A1C0F28@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57796:86c16645d4b7 Date: 2012-10-05 00:57 +0100 http://bitbucket.org/pypy/pypy/changeset/86c16645d4b7/ Log: Kill unused attribute HostCode.hidden_applevel diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -20,7 +20,7 @@ def __init__(self, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic=cpython_magic): + magic=cpython_magic): """Initialize a new code object""" self.co_name = name assert nlocals >= 0 @@ -38,7 +38,6 @@ self.co_name = name self.co_firstlineno = firstlineno self.co_lnotab = lnotab - self.hidden_applevel = hidden_applevel self.magic = magic self.signature = cpython_code_signature(self) self._initialize() @@ -68,13 +67,13 @@ self._args_as_cellvars[i] = j @classmethod - def _from_code(cls, code, hidden_applevel=False): + def _from_code(cls, code): """Initialize the code object from a real (CPython) one. """ newconsts = [] for const in code.co_consts: if isinstance(const, CodeType): - const = cls._from_code(const, hidden_applevel) + const = cls._from_code(const) newconsts.append(const) # stick the underlying CPython magic value, if the code object # comes from there @@ -92,7 +91,7 @@ code.co_lnotab, list(code.co_freevars), list(code.co_cellvars), - hidden_applevel, cpython_magic) + cpython_magic) @property def formalargcount(self): From noreply at buildbot.pypy.org Fri Oct 5 19:02:19 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 5 Oct 2012 19:02:19 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Remove HostCode.magic and simplify WITH_CLEANUP Message-ID: <20121005170219.ECED81C0F2D@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57797:618bf2b10fd1 Date: 2012-10-05 01:49 +0100 http://bitbucket.org/pypy/pypy/changeset/618bf2b10fd1/ Log: Remove HostCode.magic and simplify WITH_CLEANUP diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -38,7 +38,6 @@ self.co_name = name self.co_firstlineno = firstlineno self.co_lnotab = lnotab - self.magic = magic self.signature = cpython_code_signature(self) self._initialize() diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -1,4 +1,6 @@ +import sys import collections + from pypy.tool.error import source_lines from pypy.interpreter import pyframe from pypy.interpreter.nestedscope import Cell @@ -636,19 +638,13 @@ # Note: RPython context managers receive None in lieu of tracebacks # and cannot suppress the exception. # This opcode changed a lot between CPython versions - if (self.pycode.magic >= 0xa0df2ef - # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) - or self.pycode.magic >= 0xa0df2d1): - # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) + if sys.version_info >= (2, 6): w_unroller = self.popvalue() w_exitfunc = self.popvalue() self.pushvalue(w_unroller) - elif self.pycode.magic >= 0xa0df28c: - # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) + else: w_exitfunc = self.popvalue() w_unroller = self.peekvalue(0) - else: - raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") unroller = self.space.unwrap(w_unroller) w_None = self.space.w_None From noreply at buildbot.pypy.org Fri Oct 5 19:02:21 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 5 Oct 2012 19:02:21 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Allow const-folding of inner functions Message-ID: <20121005170221.2B73B1C0F30@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57798:92f1d72513e1 Date: 2012-10-05 06:29 +0100 http://bitbucket.org/pypy/pypy/changeset/92f1d72513e1/ Log: Allow const-folding of inner functions * Implement FlowSpaceFrame.MAKE_FUNCTION * Add tests * Don't wrap code constants in HostCode diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -19,8 +19,7 @@ def __init__(self, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, - name, firstlineno, lnotab, freevars, cellvars, - magic=cpython_magic): + name, firstlineno, lnotab, freevars, cellvars): """Initialize a new code object""" self.co_name = name assert nlocals >= 0 @@ -69,19 +68,12 @@ def _from_code(cls, code): """Initialize the code object from a real (CPython) one. """ - newconsts = [] - for const in code.co_consts: - if isinstance(const, CodeType): - const = cls._from_code(const) - newconsts.append(const) - # stick the underlying CPython magic value, if the code object - # comes from there return cls(code.co_argcount, code.co_nlocals, code.co_stacksize, code.co_flags, code.co_code, - newconsts, + list(code.co_consts), list(code.co_names), list(code.co_varnames), code.co_filename, @@ -89,8 +81,7 @@ code.co_firstlineno, code.co_lnotab, list(code.co_freevars), - list(code.co_cellvars), - cpython_magic) + list(code.co_cellvars)) @property def formalargcount(self): diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -676,6 +676,12 @@ self.pushvalue(self.space.newlist([])) self.pushvalue(last_val) + def MAKE_FUNCTION(self, numdefaults, next_instr): + w_codeobj = self.popvalue() + defaults = self.popvalues(numdefaults) + fn = self.space.newfunction(w_codeobj, self.w_globals, defaults) + self.pushvalue(fn) + # XXX Unimplemented 2.7 opcodes ---------------- # Set literals, set comprehensions diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -98,6 +98,17 @@ else: return self.w_False + def newfunction(self, w_code, w_globals, defaults_w): + try: + code = self.unwrap(w_code) + globals = self.unwrap(w_globals) + defaults = tuple([self.unwrap(value) for value in defaults_w]) + except UnwrapException: + raise FlowingError(self.frame, "Dynamically created function must" + " have constant default values.") + fn = types.FunctionType(code, globals, code.co_name, defaults) + return Constant(fn) + def wrap(self, obj): if isinstance(obj, (Variable, Constant)): raise TypeError("already wrapped: " + repr(obj)) diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1063,6 +1063,32 @@ assert len(graph.startblock.exits) == 1 assert graph.startblock.exits[0].target == graph.returnblock + def test_lambda(self): + def f(): + g = lambda m, n: n*m + return g + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + g = graph.startblock.exits[0].args[0].value + assert g(4, 4) == 16 + + def test_lambda_with_defaults(self): + def f(): + g = lambda m, n=5: n*m + return g + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + g = graph.startblock.exits[0].args[0].value + assert g(4) == 20 + + def f2(x): + g = lambda m, n=x: n*m + return g + with py.test.raises(FlowingError): + self.codetest(f2) + DATA = {'x': 5, 'y': 6} From noreply at buildbot.pypy.org Sat Oct 6 09:29:48 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 6 Oct 2012 09:29:48 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: Be more careful about having no extrainfo on the call descr. Message-ID: <20121006072948.F184A1C00E1@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r57799:f06b3e93beb8 Date: 2012-10-05 17:21 +0200 http://bitbucket.org/pypy/pypy/changeset/f06b3e93beb8/ Log: Be more careful about having no extrainfo on the call descr. diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py --- a/pypy/jit/backend/x86/regalloc.py +++ b/pypy/jit/backend/x86/regalloc.py @@ -883,8 +883,9 @@ def consider_call(self, op): effectinfo = op.getdescr().get_extra_info() - oopspecindex = effectinfo.oopspecindex - if oopspecindex != EffectInfo.OS_NONE: + if effectinfo is not None and ( + effectinfo.oopspecindex != EffectInfo.OS_NONE): + oopspecindex = effectinfo.oopspecindex if IS_X86_32: # support for some of the llong operations, # which only exist on x86-32 From noreply at buildbot.pypy.org Sat Oct 6 12:44:53 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 6 Oct 2012 12:44:53 +0200 (CEST) Subject: [pypy-commit] pypy default: Optimization: avoids long longs when they are not needed. Message-ID: <20121006104453.134671C0B9A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57800:4a5735975712 Date: 2012-10-06 11:41 +0200 http://bitbucket.org/pypy/pypy/changeset/4a5735975712/ Log: Optimization: avoids long longs when they are not needed. 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 @@ -53,7 +53,7 @@ isinstance(ob.ctype, W_CTypePtrOrArray)): value = ob._cdata else: - value = misc.as_unsigned_long_long(space, w_ob, strict=False) + value = misc.as_unsigned_long_nonstrict(space, w_ob) value = rffi.cast(rffi.CCHARP, value) return cdataobj.W_CData(space, value, self) 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 @@ -1,7 +1,7 @@ from __future__ import with_statement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib.rarithmetic import r_ulonglong +from pypy.rlib.rarithmetic import r_uint, r_ulonglong from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib import jit @@ -181,6 +181,20 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" +def as_unsigned_long_nonstrict(space, w_ob): + # optimized version of as_unsigned_long_long(strict=False) if we're + # only interested in an Unsigned value + if space.is_w(space.type(w_ob), space.w_int): # shortcut + value = space.int_w(w_ob) + return r_uint(value) + try: + bigint = space.bigint_w(w_ob) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + bigint = space.bigint_w(space.int(w_ob)) + return bigint.uintmask() + # ____________________________________________________________ class _NotStandardObject(Exception): From noreply at buildbot.pypy.org Sat Oct 6 12:44:54 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 6 Oct 2012 12:44:54 +0200 (CEST) Subject: [pypy-commit] pypy default: Document this function's purpose Message-ID: <20121006104454.379B91C0B9A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57801:a455c5066d0e Date: 2012-10-06 11:45 +0200 http://bitbucket.org/pypy/pypy/changeset/a455c5066d0e/ Log: Document this function's purpose 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 @@ -47,9 +47,10 @@ raise NotImplementedError("bad integer size") def read_raw_ulong_data(target, size): + # only for types smaller than Unsigned for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): - assert rffi.sizeof(TP) < rffi.sizeof(lltype.Signed) + assert rffi.sizeof(TP) < rffi.sizeof(lltype.Unsigned) return rffi.cast(lltype.Signed, rffi.cast(TPP,target)[0]) raise NotImplementedError("bad integer size") From noreply at buildbot.pypy.org Sat Oct 6 12:44:55 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 6 Oct 2012 12:44:55 +0200 (CEST) Subject: [pypy-commit] pypy default: Another case of avoiding long longs. Message-ID: <20121006104455.546C51C0B9A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57802:0ee8b99d39c5 Date: 2012-10-06 11:47 +0200 http://bitbucket.org/pypy/pypy/changeset/0ee8b99d39c5/ Log: Another case of avoiding long longs. diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -45,7 +45,7 @@ return w_result def convert_to_object(self, cdata): - value = intmask(misc.read_raw_signed_data(cdata, self.size)) + value = misc.read_raw_long_data(cdata, self.size) try: enumerator = self.enumvalues2erators[value] except KeyError: From noreply at buildbot.pypy.org Sat Oct 6 12:44:56 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 6 Oct 2012 12:44:56 +0200 (CEST) Subject: [pypy-commit] pypy default: More long long removal. Message-ID: <20121006104456.7D6911C0B9A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57803:a3bed57683e8 Date: 2012-10-06 12:01 +0200 http://bitbucket.org/pypy/pypy/changeset/a3bed57683e8/ Log: More long long removal. diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -223,7 +223,7 @@ def convert_to_object(self, cdata): if self.value_fits_long: - value = misc.read_raw_ulong_data(cdata, self.size) + value = misc.read_raw_uint_data(cdata, self.size) return self.space.wrap(value) else: value = misc.read_raw_unsigned_data(cdata, self.size) diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -7,7 +7,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.rlib.objectmodel import keepalive_until_here -from pypy.rlib.rarithmetic import r_ulonglong, r_longlong, intmask +from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask from pypy.rlib import jit from pypy.module._cffi_backend.ctypeobj import W_CType @@ -195,14 +195,19 @@ space = ctype.space # if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned): - value = r_ulonglong(misc.read_raw_signed_data(cdata, ctype.size)) - valuemask = (r_ulonglong(1) << self.bitsize) - 1 - shiftforsign = r_ulonglong(1) << (self.bitsize - 1) - value = ((value >> self.bitshift) + shiftforsign) & valuemask - result = r_longlong(value) - r_longlong(shiftforsign) if ctype.value_fits_long: - return space.wrap(intmask(result)) + value = r_uint(misc.read_raw_long_data(cdata, ctype.size)) + valuemask = (r_uint(1) << self.bitsize) - 1 + shiftforsign = r_uint(1) << (self.bitsize - 1) + value = ((value >> self.bitshift) + shiftforsign) & valuemask + result = intmask(value) - intmask(shiftforsign) + return space.wrap(result) else: + value = misc.read_raw_unsigned_data(cdata, ctype.size) + valuemask = (r_ulonglong(1) << self.bitsize) - 1 + shiftforsign = r_ulonglong(1) << (self.bitsize - 1) + value = ((value >> self.bitshift) + shiftforsign) & valuemask + result = r_longlong(value) - r_longlong(shiftforsign) return space.wrap(result) # if isinstance(ctype, ctypeprim.W_CTypePrimitiveUnsigned): @@ -212,12 +217,15 @@ else: raise NotImplementedError # - value = misc.read_raw_unsigned_data(cdata, ctype.size) - valuemask = (r_ulonglong(1) << self.bitsize) - 1 - value = (value >> self.bitshift) & valuemask if value_fits_long: + value = r_uint(misc.read_raw_uint_data(cdata, ctype.size)) + valuemask = (r_uint(1) << self.bitsize) - 1 + value = (value >> self.bitshift) & valuemask return space.wrap(intmask(value)) else: + value = misc.read_raw_unsigned_data(cdata, ctype.size) + valuemask = (r_ulonglong(1) << self.bitsize) - 1 + value = (value >> self.bitshift) & valuemask return space.wrap(value) def convert_bitfield_from_object(self, cdata, w_ob): 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 @@ -46,7 +46,7 @@ return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP,target)[0]) raise NotImplementedError("bad integer size") -def read_raw_ulong_data(target, size): +def read_raw_uint_data(target, size): # only for types smaller than Unsigned for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): From noreply at buildbot.pypy.org Sat Oct 6 12:44:57 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 6 Oct 2012 12:44:57 +0200 (CEST) Subject: [pypy-commit] pypy default: More removal of long longs. Message-ID: <20121006104457.A2C701C0B9A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57804:628675137bde Date: 2012-10-06 12:44 +0200 http://bitbucket.org/pypy/pypy/changeset/628675137bde/ Log: More removal of long longs. 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 @@ -133,8 +133,7 @@ # manual inlining and tweaking of # W_CTypePrimitiveSigned.convert_from_object() in order # to write a whole 'ffi_arg'. - value = misc.as_long_long(space, w_res) - value = r_ulonglong(value) + value = misc.as_long(space, w_res) misc.write_raw_integer_data(ll_res, value, SIZE_OF_FFI_ARG) return else: diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -4,7 +4,7 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rlib.objectmodel import keepalive_until_here +from pypy.rlib.objectmodel import keepalive_until_here, specialize from pypy.rlib import objectmodel, rgc from pypy.tool.sourcetools import func_with_new_name @@ -190,6 +190,7 @@ def iter(self): return self.ctype.iter(self) + @specialize.argtype(1) def write_raw_integer_data(self, source): misc.write_raw_integer_data(self._cdata, source, self.ctype.size) keepalive_until_here(self) diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -4,7 +4,7 @@ from pypy.interpreter.error import operationerrfmt from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rlib.rarithmetic import r_ulonglong +from pypy.rlib.rarithmetic import r_uint, r_ulonglong, intmask from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib import jit @@ -164,9 +164,10 @@ W_CTypePrimitive.__init__(self, *args) self.value_fits_long = self.size <= rffi.sizeof(lltype.Signed) if self.size < rffi.sizeof(lltype.SignedLongLong): + assert self.value_fits_long sh = self.size * 8 - self.vmin = r_ulonglong(-1) << (sh - 1) - self.vrangemax = (r_ulonglong(1) << sh) - 1 + self.vmin = r_uint(-1) << (sh - 1) + self.vrangemax = (r_uint(1) << sh) - 1 def int(self, cdata): # enums: really call convert_to_object() just below, @@ -182,12 +183,15 @@ return self.space.wrap(value) # r_longlong => on 32-bit, 'long' def convert_from_object(self, cdata, w_ob): - value = misc.as_long_long(self.space, w_ob) - if self.size < rffi.sizeof(lltype.SignedLongLong): - if r_ulonglong(value) - self.vmin > self.vrangemax: - self._overflow(w_ob) - value = r_ulonglong(value) - misc.write_raw_integer_data(cdata, value, self.size) + if self.value_fits_long: + value = misc.as_long(self.space, w_ob) + if self.size < rffi.sizeof(lltype.Signed): + if r_uint(value) - self.vmin > self.vrangemax: + self._overflow(w_ob) + misc.write_raw_integer_data(cdata, value, self.size) + else: + value = misc.as_long_long(self.space, w_ob) + misc.write_raw_integer_data(cdata, value, self.size) def get_vararg_type(self): if self.size < rffi.sizeof(rffi.INT): @@ -197,34 +201,42 @@ class W_CTypePrimitiveUnsigned(W_CTypePrimitive): - _attrs_ = ['value_fits_long', 'vrangemax'] - _immutable_fields_ = ['value_fits_long', 'vrangemax'] + _attrs_ = ['value_fits_long', 'value_fits_ulong', 'vrangemax'] + _immutable_fields_ = ['value_fits_long', 'value_fits_ulong', 'vrangemax'] is_primitive_integer = True def __init__(self, *args): W_CTypePrimitive.__init__(self, *args) self.value_fits_long = self.size < rffi.sizeof(lltype.Signed) - if self.size < rffi.sizeof(lltype.SignedLongLong): + self.value_fits_ulong = self.size <= rffi.sizeof(lltype.Unsigned) + if self.value_fits_long: self.vrangemax = self._compute_vrange_max() def _compute_vrange_max(self): sh = self.size * 8 - return (r_ulonglong(1) << sh) - 1 + return (r_uint(1) << sh) - 1 def int(self, cdata): return self.convert_to_object(cdata) def convert_from_object(self, cdata, w_ob): - value = misc.as_unsigned_long_long(self.space, w_ob, strict=True) - if self.size < rffi.sizeof(lltype.SignedLongLong): - if value > self.vrangemax: - self._overflow(w_ob) - misc.write_raw_integer_data(cdata, value, self.size) + if self.value_fits_ulong: + value = misc.as_unsigned_long(self.space, w_ob, strict=True) + if self.value_fits_long: + if value > self.vrangemax: + self._overflow(w_ob) + misc.write_raw_integer_data(cdata, value, self.size) + else: + value = misc.as_unsigned_long_long(self.space, w_ob, strict=True) + misc.write_raw_integer_data(cdata, value, self.size) def convert_to_object(self, cdata): - if self.value_fits_long: - value = misc.read_raw_uint_data(cdata, self.size) - return self.space.wrap(value) + if self.value_fits_ulong: + value = misc.read_raw_ulong_data(cdata, self.size) + if self.value_fits_long: + return self.space.wrap(intmask(value)) + else: + return self.space.wrap(value) # r_uint => 'long' object else: value = misc.read_raw_unsigned_data(cdata, self.size) return self.space.wrap(value) # r_ulonglong => 'long' object @@ -240,7 +252,7 @@ _attrs_ = [] def _compute_vrange_max(self): - return r_ulonglong(1) + return r_uint(1) def _cast_result(self, intvalue): return r_ulonglong(intvalue != 0) 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 @@ -53,7 +53,7 @@ isinstance(ob.ctype, W_CTypePtrOrArray)): value = ob._cdata else: - value = misc.as_unsigned_long_nonstrict(space, w_ob) + value = misc.as_unsigned_long(space, w_ob, strict=False) value = rffi.cast(rffi.CCHARP, value) return cdataobj.W_CData(space, value, self) diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -3,7 +3,7 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.rpython.lltypesystem import rffi +from pypy.rpython.lltypesystem import lltype, rffi from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.rlib.objectmodel import keepalive_until_here @@ -212,21 +212,26 @@ # if isinstance(ctype, ctypeprim.W_CTypePrimitiveUnsigned): value_fits_long = ctype.value_fits_long + value_fits_ulong = ctype.value_fits_ulong elif isinstance(ctype, ctypeprim.W_CTypePrimitiveCharOrUniChar): value_fits_long = True + value_fits_ulong = True else: raise NotImplementedError # - if value_fits_long: - value = r_uint(misc.read_raw_uint_data(cdata, ctype.size)) + if value_fits_ulong: + value = misc.read_raw_ulong_data(cdata, ctype.size) valuemask = (r_uint(1) << self.bitsize) - 1 value = (value >> self.bitshift) & valuemask - return space.wrap(intmask(value)) + if value_fits_long: + return space.wrap(intmask(value)) + else: + return space.wrap(value) # uint => wrapped long object else: value = misc.read_raw_unsigned_data(cdata, ctype.size) valuemask = (r_ulonglong(1) << self.bitsize) - 1 value = (value >> self.bitshift) & valuemask - return space.wrap(value) + return space.wrap(value) # ulonglong => wrapped long object def convert_bitfield_from_object(self, cdata, w_ob): ctype = self.ctype 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 @@ -3,7 +3,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rlib.rarithmetic import r_uint, r_ulonglong from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.objectmodel import keepalive_until_here +from pypy.rlib.objectmodel import keepalive_until_here, specialize from pypy.rlib import jit from pypy.translator.tool.cbuild import ExternalCompilationInfo @@ -46,12 +46,11 @@ return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP,target)[0]) raise NotImplementedError("bad integer size") -def read_raw_uint_data(target, size): - # only for types smaller than Unsigned +def read_raw_ulong_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): - assert rffi.sizeof(TP) < rffi.sizeof(lltype.Unsigned) - return rffi.cast(lltype.Signed, rffi.cast(TPP,target)[0]) + assert rffi.sizeof(TP) <= rffi.sizeof(lltype.Unsigned) + return rffi.cast(lltype.Unsigned, rffi.cast(TPP,target)[0]) raise NotImplementedError("bad integer size") def read_raw_float_data(target, size): @@ -63,6 +62,7 @@ def read_raw_longdouble_data(target): return rffi.cast(rffi.LONGDOUBLEP, target)[0] + at specialize.argtype(1) def write_raw_integer_data(target, source, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): @@ -151,6 +151,23 @@ except OverflowError: raise OperationError(space.w_OverflowError, space.wrap(ovf_msg)) +def as_long(space, w_ob): + # Same as as_long_long(), but returning an int instead. + if space.is_w(space.type(w_ob), space.w_int): # shortcut + return space.int_w(w_ob) + try: + bigint = space.bigint_w(w_ob) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + if _is_a_float(space, w_ob): + raise + bigint = space.bigint_w(space.int(w_ob)) + try: + return bigint.toint() + except OverflowError: + raise OperationError(space.w_OverflowError, space.wrap(ovf_msg)) + def as_unsigned_long_long(space, w_ob, strict): # (possibly) convert and cast a Python object to an unsigned long long. # This accepts a Python int too, and does convertions from other types of @@ -179,22 +196,33 @@ else: return bigint.ulonglongmask() -neg_msg = "can't convert negative number to unsigned" -ovf_msg = "long too big to convert" - -def as_unsigned_long_nonstrict(space, w_ob): - # optimized version of as_unsigned_long_long(strict=False) if we're - # only interested in an Unsigned value +def as_unsigned_long(space, w_ob, strict): + # same as as_unsigned_long_long(), but returning just an Unsigned if space.is_w(space.type(w_ob), space.w_int): # shortcut value = space.int_w(w_ob) + if strict and value < 0: + raise OperationError(space.w_OverflowError, space.wrap(neg_msg)) return r_uint(value) try: bigint = space.bigint_w(w_ob) except OperationError, e: if not e.match(space, space.w_TypeError): raise + if strict and _is_a_float(space, w_ob): + raise bigint = space.bigint_w(space.int(w_ob)) - return bigint.uintmask() + if strict: + try: + return bigint.touint() + except ValueError: + raise OperationError(space.w_OverflowError, space.wrap(neg_msg)) + except OverflowError: + raise OperationError(space.w_OverflowError, space.wrap(ovf_msg)) + else: + return bigint.uintmask() + +neg_msg = "can't convert negative number to unsigned" +ovf_msg = "long too big to convert" # ____________________________________________________________ From noreply at buildbot.pypy.org Sat Oct 6 12:51:41 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 6 Oct 2012 12:51:41 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: talk as it went Message-ID: <20121006105141.758731C0B9A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4836:7648e9939155 Date: 2012-10-06 12:51 +0200 http://bitbucket.org/pypy/extradoc/changeset/7648e9939155/ Log: talk as it went diff --git a/talk/pyconza2012/examples/alloc.py b/talk/pyconza2012/examples/alloc.py --- a/talk/pyconza2012/examples/alloc.py +++ b/talk/pyconza2012/examples/alloc.py @@ -3,14 +3,14 @@ def f(): l = [None] - for i in range(int(sys.argv[1])): + for i in xrange(int(sys.argv[1])): l[0] = (i,) def g(): m = int(sys.argv[1]) l = [None] * m - for i in range(m): - l[i] = i + for i in xrange(m): + l[i] = (i,) t0 = time.time() f() diff --git a/talk/pyconza2012/examples/calls.py b/talk/pyconza2012/examples/calls.py --- a/talk/pyconza2012/examples/calls.py +++ b/talk/pyconza2012/examples/calls.py @@ -30,7 +30,7 @@ count = int(sys.argv[1]) t0 = time.time() o = A() - for i in range(count): + for i in xrange(count): func(i, i, o) tk = time.time() t = (tk - t0) / count diff --git a/talk/pyconza2012/examples/interpreter.py b/talk/pyconza2012/examples/interpreter.py --- a/talk/pyconza2012/examples/interpreter.py +++ b/talk/pyconza2012/examples/interpreter.py @@ -9,6 +9,9 @@ # try right return right.radd(left) + def radd(self, left): + raise TypeError + class Long(BaseObject): pass @@ -22,6 +25,8 @@ return Integer(self.intval + right.intval) except OverflowError: return Long(self.intval).add(Long(right.intval)) + else: + return right.radd(self) def interpret(bytecode, variables, constants): stack = [] @@ -55,3 +60,13 @@ pos = arg0 continue pos += 1 + + +def f(a, b): + return a + b + +stack.append(variables[arg0]) +stack.append(variables[arg0]) +right = stack.pop() +left = stack.pop() +stack.append(left.add(right)) diff --git a/talk/pyconza2012/talk.pdf b/talk/pyconza2012/talk.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8eb88f4bb2440dcede688672bdf6b31b30be2d4d GIT binary patch [cut] diff --git a/talk/pyconza2012/talk.rst b/talk/pyconza2012/talk.rst --- a/talk/pyconza2012/talk.rst +++ b/talk/pyconza2012/talk.rst @@ -16,24 +16,79 @@ What this talk is about? ------------------------ -* I'll start where Larry finished +* python performance (or lack of it) -* describe a bit how the PyPy JIT works +* why does it matter -* what's the difference between interpretation and JIT compilation +* what can we do about it + +* how PyPy works + +Python performance message +--------------------------- + +* according to Guido + +* "Avoid overengineering datastructures. Tuples are better than objects (try namedtuple too though). Prefer simple fields over getter/setter functions." + +* "Built-in datatypes are your friends. Use more numbers, strings, tuples, lists, sets, dicts. Also check out the collections library, esp. deque." + +* "Be suspicious of function/method calls; creating a stack frame is expensive." + +* "The universal speed-up is rewriting small bits of code in C. Do this only when all else fails." + +What does it mean? +------------------ + +* don't use abstractions |pause| -* show some assembler +* don't use Python + +But also +-------- + +* measure! + +* there are so many variables, you cannot care without benchmarks |pause| -* just joking +* if you have no benchmarks, you don't care -Disclaimer ----------- +This is not how I want to write software +---------------------------------------- -* we're trying to make it better +* I like my abstractions + +* I like Python + +* I don't want to rewrite stuff for performance + +|pause| + +* in C/C++ + +Second best +----------- + +* keep my abstractions + +* do arcane voodoo to keep my programs fast + +* but you have to understand the voodo in the first place + +But Python performance! +----------------------- + +* there is no such thing as language performance + +* there is implementation performance + +* the language might be easier or harder to optimize + +* CPython performance characteristics is relatively straightforward What is PyPy? ------------- @@ -42,8 +97,6 @@ * PyPy is a toolchain for creating dynamic language implementations - * we try to rename the latter to RPython - * also, an Open Source project that has been around for a while Compilers vs interpreters @@ -82,16 +135,20 @@ * compiles loops and functions +Some properties +--------------- + +* the code speed **changes** over time + +* hopefully from slow to fast + +* you need to warm up things before they get fast + Some example ------------ * integer addition! -So wait, where are those allocations? -------------------------------------- - -* they don't escape, so they're removed! - Abstractions ------------ @@ -103,8 +160,28 @@ * if they don't introduce too much complexity -Allocations ------------ +Few words about garbage collection +---------------------------------- + +* ``CPython``: refcounting + cyclic collector + +* ``PyPy``: generational mark & sweep + +|pause| + +* errr.... + +The rest +-------- + +* I'll explain various PyPy strategies + +* ideally all this knowledge will be unnecessary + +* this is the second best, how to please the JIT compiler + +Allocations (PyPy) +------------------ * allocation is expensive @@ -153,7 +230,18 @@ * not all nicely -Future improvements -------------------- +Summary +------- -Xxxx +* we hope this knowledge will not be needed + +* the more you care, the better you need to know + +Questions? +---------- + +* Thank you! + +* http://pypy.org + +* http://baroquesoftware.com From noreply at buildbot.pypy.org Sat Oct 6 13:37:27 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 6 Oct 2012 13:37:27 +0200 (CEST) Subject: [pypy-commit] pypy default: Grumble, we must actually not kill duplicates from PYTHONPATH. Message-ID: <20121006113727.846641C01BD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57805:41121ed0f5c1 Date: 2012-10-06 13:37 +0200 http://bitbucket.org/pypy/pypy/changeset/41121ed0f5c1/ Log: Grumble, we must actually not kill duplicates from PYTHONPATH. setuptools's site.py relies on that. diff --git a/pypy/translator/goal/app_main.py b/pypy/translator/goal/app_main.py --- a/pypy/translator/goal/app_main.py +++ b/pypy/translator/goal/app_main.py @@ -226,17 +226,18 @@ def setup_and_fix_paths(ignore_environment=False, **extra): import os newpath = sys.path[:] + del sys.path[:] + # first prepend PYTHONPATH readenv = not ignore_environment path = readenv and os.getenv('PYTHONPATH') if path: - newpath = path.split(os.pathsep) + newpath - # remove duplicates - _seen = {} - del sys.path[:] + sys.path.extend(path.split(os.pathsep)) + # then add again the original entries, ignoring duplicates + _seen = set() for dir in newpath: if dir not in _seen: sys.path.append(dir) - _seen[dir] = True + _seen.add(dir) def set_stdio_encodings(ignore_environment): import os diff --git a/pypy/translator/goal/test2/test_app_main.py b/pypy/translator/goal/test2/test_app_main.py --- a/pypy/translator/goal/test2/test_app_main.py +++ b/pypy/translator/goal/test2/test_app_main.py @@ -397,6 +397,15 @@ finally: del os.environ['PYTHONINSPECT_'] + def test_python_path_keeps_duplicates(self): + old = os.environ.get('PYTHONPATH', '') + try: + os.environ['PYTHONPATH'] = 'foobarbaz:foobarbaz' + child = self.spawn(['-c', 'import sys; print sys.path']) + child.expect(r"\['', 'foobarbaz', 'foobarbaz', ") + finally: + os.environ['PYTHONPATH'] = old + def test_ignore_python_path(self): old = os.environ.get('PYTHONPATH', '') try: From noreply at buildbot.pypy.org Sat Oct 6 14:31:48 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 6 Oct 2012 14:31:48 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: My talk, mostly copied from googlezurich2012. Message-ID: <20121006123148.95F871C01BD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r4837:383391c34716 Date: 2012-10-06 14:31 +0200 http://bitbucket.org/pypy/extradoc/changeset/383391c34716/ Log: My talk, mostly copied from googlezurich2012. diff --git a/talk/googlezurich2012/Makefile b/talk/pyconza2012/stm-talk/Makefile copy from talk/googlezurich2012/Makefile copy to talk/pyconza2012/stm-talk/Makefile diff --git a/talk/pyconza2012/stm-talk/author.latex b/talk/pyconza2012/stm-talk/author.latex new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stm-talk/author.latex @@ -0,0 +1,8 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[PyPy in Production]{PyPy} +\author[Armin Rigo] +{Armin Rigo} + +\institute{PyCon ZA 2012} +\date{October 4, 2012} diff --git a/talk/googlezurich2012/beamerdefs.txt b/talk/pyconza2012/stm-talk/beamerdefs.txt copy from talk/googlezurich2012/beamerdefs.txt copy to talk/pyconza2012/stm-talk/beamerdefs.txt --- a/talk/googlezurich2012/beamerdefs.txt +++ b/talk/pyconza2012/stm-talk/beamerdefs.txt @@ -89,7 +89,7 @@ -.. |snake| image:: ../img/py-web-new.png +.. |snake| image:: ../../img/py-web-new.png :scale: 15% diff --git a/talk/pyconza2012/stm-talk/demo1.py b/talk/pyconza2012/stm-talk/demo1.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stm-talk/demo1.py @@ -0,0 +1,19 @@ + +class Number(object): + + def __init__(self, num): + self.num = num + + def __add__(self, other): + return Number(self.num + other.num) + + def __invert__(self): + return Number(~self.num) + +def foo(n): + total = Number(0) + for i in range(n): + total += Number(i) + total += ~ Number(i) + return total.num + diff --git a/talk/googlezurich2012/standards.png b/talk/pyconza2012/stm-talk/standards.png copy from talk/googlezurich2012/standards.png copy to talk/pyconza2012/stm-talk/standards.png diff --git a/talk/googlezurich2012/stylesheet.latex b/talk/pyconza2012/stm-talk/stylesheet.latex copy from talk/googlezurich2012/stylesheet.latex copy to talk/pyconza2012/stm-talk/stylesheet.latex diff --git a/talk/pyconza2012/stm-talk/talk.rst b/talk/pyconza2012/stm-talk/talk.rst new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stm-talk/talk.rst @@ -0,0 +1,205 @@ +.. include:: beamerdefs.txt + +============================================================ +PyPy +============================================================ + + +PyPy is... +-------------------------- + +* Another Python interpreter + +* with a JIT compiler + + +PyPy was... +------------------- + +* Around since 2003 + +* (advertised as) production ready since December 2010 + + - release 1.4 + +* Funding + + - EU FP6 programme + + - Eurostars programme + + - donations + + - ... + + +PyPy 1.9: current status +------------------------ + +* Faster + + - **1.7x** than 1.5 (Summer 2011) + + - **2.2x** than 1.4 (December 2010) + + - **5.5x** than CPython + +* Implements Python 2.7.3 + +* Many more "PyPy-friendly" programs than before + +* Packaging + + - |scriptsize| Debian, Ubuntu, Fedora, Homebrew, Gentoo, ArchLinux, ... |end_scriptsize| + + - |scriptsize| Windows (32bit only), OS X |end_scriptsize| + +* C extension compatibility + + - runs (big part of) **PyOpenSSL** and **lxml** + + +PyPy organization +----------------- + +* Part of SFC -- Software Freedom Conservancy + + - Bradley successfully fighting U.S. bureaucracy + + - we are happy about it + + +* Funding model + + - py3k, numpy, STM + + - more than 100'000$ in donations + + - from individuals, large companies and the PSF + + +PyPy's JIT compiler +------------------- + +* Removes abstraction + +* Almost never gives up + +* x86-32, x86-64, ARMv7, (POWER64) + +* (Works with other languages) + + +Real world applications +----------------------- + +* Positive feedback + +* http://speed.pypy.org/ + + + +py3k +------------------------ + +* ``py3k`` branch in mercurial + + - developed in parallel + + - Python 3 written in Python 2 + +* Focus on correctness + +* Dropped some interpreter optimizations for now + +* First 90% done, remaining 90% not done + +* Majority of the funds by Google + + +NumPy +----- + +* progress going slowly + +* multi dimensional arrays, broadcasting, fancy indexing + +* all dtypes, except complex, strings and objects + +* good results for performance + + +STM +--------------------------- + +* Software Transactional Memory + +* "Remove the GIL" + +* But also, new models (better than threads) + + + +Calling C +--------- + +.. image:: standards.png + :scale: 60% + :align: center + +Calling C landscape +------------------- + +* CPython C extensions + +* SWIG, SIP, wrapper generators + +* ctypes + +* Cython + +* CFFI (our new thing) + +CFFI +---------- + +|scriptsize| +|example<| Example |>| + + .. sourcecode:: pycon + + >>> from cffi import FFI + >>> ffi = FFI() + >>> ffi.cdef(""" + ... int printf(const char *format, ...); + ... """) + >>> C = ffi.dlopen(None) + >>> arg = ffi.new("char[]", "world") + >>> C.printf("hi there, %s!\n", arg) + hi there, world! + +|end_example| +|end_scriptsize| + +CFFI +---- + +* Many more examples + +* Including macro calls and most subtleties of C + +* http://cffi.readthedocs.org + + +STM +--- + + +Conclusion +---------- + +* Try out PyPy on real code + +* http://pypy.org/ + +* Thank you! diff --git a/talk/googlezurich2012/title.latex b/talk/pyconza2012/stm-talk/title.latex copy from talk/googlezurich2012/title.latex copy to talk/pyconza2012/stm-talk/title.latex --- a/talk/googlezurich2012/title.latex +++ b/talk/pyconza2012/stm-talk/title.latex @@ -1,5 +1,5 @@ \begin{titlepage} \begin{figure}[h] -\includegraphics[width=60px]{../img/py-web-new.png} +\includegraphics[width=60px]{../../img/py-web-new.png} \end{figure} \end{titlepage} From noreply at buildbot.pypy.org Sat Oct 6 16:23:00 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Sat, 6 Oct 2012 16:23:00 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: copy pycon uk talk from europython Message-ID: <20121006142300.6F7DD1C0B64@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: extradoc Changeset: r4838:0a6fb4a1e03f Date: 2012-09-27 18:26 +0200 http://bitbucket.org/pypy/extradoc/changeset/0a6fb4a1e03f/ Log: copy pycon uk talk from europython diff --git a/talk/ep2012/jit/abstract.rst b/talk/pycon-uk-2012/abstract.rst copy from talk/ep2012/jit/abstract.rst copy to talk/pycon-uk-2012/abstract.rst diff --git a/talk/ep2012/jit/talk/Makefile b/talk/pycon-uk-2012/talk/Makefile copy from talk/ep2012/jit/talk/Makefile copy to talk/pycon-uk-2012/talk/Makefile diff --git a/talk/ep2012/jit/talk/author.latex b/talk/pycon-uk-2012/talk/author.latex copy from talk/ep2012/jit/talk/author.latex copy to talk/pycon-uk-2012/talk/author.latex --- a/talk/ep2012/jit/talk/author.latex +++ b/talk/pycon-uk-2012/talk/author.latex @@ -1,8 +1,8 @@ \definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} \title[PyPy JIT under the hood]{PyPy JIT under the hood} -\author[antocuni, arigo] -{Antonio Cuni \\ Armin Rigo (guest star)} +\author[antocuni] +{Antonio Cuni} -\institute{EuroPython 2012} -\date{July 4 2012} +\institute{PyCon UK 2012} +\date{September 28 2012} diff --git a/talk/ep2012/jit/talk/beamerdefs.txt b/talk/pycon-uk-2012/talk/beamerdefs.txt copy from talk/ep2012/jit/talk/beamerdefs.txt copy to talk/pycon-uk-2012/talk/beamerdefs.txt diff --git a/talk/ep2012/jit/talk/diagrams/architecture.svg b/talk/pycon-uk-2012/talk/diagrams/architecture.svg copy from talk/ep2012/jit/talk/diagrams/architecture.svg copy to talk/pycon-uk-2012/talk/diagrams/architecture.svg diff --git a/talk/ep2012/jit/talk/diagrams/pypytrace.svg b/talk/pycon-uk-2012/talk/diagrams/pypytrace.svg copy from talk/ep2012/jit/talk/diagrams/pypytrace.svg copy to talk/pycon-uk-2012/talk/diagrams/pypytrace.svg diff --git a/talk/ep2012/jit/talk/diagrams/trace.svg b/talk/pycon-uk-2012/talk/diagrams/trace.svg copy from talk/ep2012/jit/talk/diagrams/trace.svg copy to talk/pycon-uk-2012/talk/diagrams/trace.svg diff --git a/talk/ep2012/jit/talk/diagrams/tracetree.svg b/talk/pycon-uk-2012/talk/diagrams/tracetree.svg copy from talk/ep2012/jit/talk/diagrams/tracetree.svg copy to talk/pycon-uk-2012/talk/diagrams/tracetree.svg diff --git a/talk/ep2012/jit/talk/diagrams/tracing-phases.svg b/talk/pycon-uk-2012/talk/diagrams/tracing-phases.svg copy from talk/ep2012/jit/talk/diagrams/tracing-phases.svg copy to talk/pycon-uk-2012/talk/diagrams/tracing-phases.svg diff --git a/talk/ep2012/jit/talk/stylesheet.latex b/talk/pycon-uk-2012/talk/stylesheet.latex copy from talk/ep2012/jit/talk/stylesheet.latex copy to talk/pycon-uk-2012/talk/stylesheet.latex diff --git a/talk/ep2012/jit/talk/talk.pdf.info b/talk/pycon-uk-2012/talk/talk.pdf.info copy from talk/ep2012/jit/talk/talk.pdf.info copy to talk/pycon-uk-2012/talk/talk.pdf.info --- a/talk/ep2012/jit/talk/talk.pdf.info +++ b/talk/pycon-uk-2012/talk/talk.pdf.info @@ -1,6 +1,6 @@ AvailableTransitions=[Crossfade] TransitionDuration = 100 -EstimatedDuration = 60*60 # in seconds +EstimatedDuration = 30*60 # in seconds MinutesOnly = True PageProps = { diff --git a/talk/ep2012/jit/talk/talk.rst b/talk/pycon-uk-2012/talk/talk.rst copy from talk/ep2012/jit/talk/talk.rst copy to talk/pycon-uk-2012/talk/talk.rst --- a/talk/ep2012/jit/talk/talk.rst +++ b/talk/pycon-uk-2012/talk/talk.rst @@ -29,10 +29,6 @@ * The PyPy JIT generator -* Just In Time talk - - last-modified: July, 4th, 12:06 - Part 0: What is PyPy? ---------------------- diff --git a/talk/ep2012/jit/talk/title.latex b/talk/pycon-uk-2012/talk/title.latex copy from talk/ep2012/jit/talk/title.latex copy to talk/pycon-uk-2012/talk/title.latex From noreply at buildbot.pypy.org Sat Oct 6 16:23:01 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Sat, 6 Oct 2012 16:23:01 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: small tweaks Message-ID: <20121006142301.A59661C0B64@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: extradoc Changeset: r4839:4932938427c2 Date: 2012-09-27 18:32 +0200 http://bitbucket.org/pypy/extradoc/changeset/4932938427c2/ Log: small tweaks diff --git a/talk/pycon-uk-2012/talk/author.latex b/talk/pycon-uk-2012/talk/author.latex --- a/talk/pycon-uk-2012/talk/author.latex +++ b/talk/pycon-uk-2012/talk/author.latex @@ -5,4 +5,4 @@ {Antonio Cuni} \institute{PyCon UK 2012} -\date{September 28 2012} +\date{September 28, 2012} diff --git a/talk/pycon-uk-2012/talk/talk.pdf.info b/talk/pycon-uk-2012/talk/talk.pdf.info --- a/talk/pycon-uk-2012/talk/talk.pdf.info +++ b/talk/pycon-uk-2012/talk/talk.pdf.info @@ -1,6 +1,6 @@ AvailableTransitions=[Crossfade] TransitionDuration = 100 -EstimatedDuration = 30*60 # in seconds +EstimatedDuration = 60*60 # in seconds MinutesOnly = True PageProps = { diff --git a/talk/pycon-uk-2012/talk/talk.rst b/talk/pycon-uk-2012/talk/talk.rst --- a/talk/pycon-uk-2012/talk/talk.rst +++ b/talk/pycon-uk-2012/talk/talk.rst @@ -15,6 +15,8 @@ - Consultant, trainer +- You can hire me :-) + - http://antocuni.eu @@ -23,8 +25,6 @@ * What is PyPy? (in 30 seconds) - - (for those who missed the keynote :-)) - * Overview of tracing JITs * The PyPy JIT generator From noreply at buildbot.pypy.org Sat Oct 6 16:23:02 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Sat, 6 Oct 2012 16:23:02 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: merge Message-ID: <20121006142302.DB6E01C0B64@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: extradoc Changeset: r4840:2a3bbf1385ee Date: 2012-10-06 16:21 +0200 http://bitbucket.org/pypy/extradoc/changeset/2a3bbf1385ee/ Log: merge diff --git a/blog/draft/py3k-status-update-6.rst b/blog/draft/py3k-status-update-6.rst --- a/blog/draft/py3k-status-update-6.rst +++ b/blog/draft/py3k-status-update-6.rst @@ -4,20 +4,20 @@ This is the sixth status update about our work on the `py3k branch`_, which we can work on thanks to all of the people who donated_ to the `py3k proposal`_. -The coolest new is not about what we did in the past weeks, but what we will -do in the next: I am pleased to announce that Philip Jenvey has been selected -to be funded for his upcoming work on py3k, thanks to your generous -donations. He will start to work on it shortly, and he will surely help the -branch to make faster progress. I am also particularly happy of this because -Philip is the first non-core developer who is getting paid with donations: he -demonstrated over the past months to be able to work effectively on PyPy, and -so we were happy to approve his application for the job. This means that -everyone can be potentially selected in the future, the only strict -requirement is prove to be able to work on PyPy by contributing to the -project. +The coolest news is not about what we did in the past weeks, but what we will +do in the next: I am pleased to announce that `Philip Jenvey`_ has been +selected by the PyPy communitiy to be funded for his upcoming work on py3k, +thanks to your generous donations. He will start to work on it shortly, and he +will surely help the branch to make faster progress. I am also particularly +happy of this because Philip is the first non-core developer who is getting +paid with donations: he demonstrated over the past months to be able to work +effectively on PyPy, and so we were happy to approve his application for the +job. This means that anyone can potentially be selected in the future, the +only strict requirement is to have a deep interest in working on PyPy and to +prove to be able to do so by contributing to the project. Back to the status of the branch. Most of the work since the last status -update has been done in the area of, guess what?, unicode strings. As usual, +update has been done in the area of, guess what? Unicode strings. As usual, this is one of the most important changes between Python 2 and Python 3, so it's not surprising. The biggest news is that now PyPy internally supports unicode identifiers (such as names of variables, functions, attributes, etc.), @@ -40,20 +40,28 @@ operator) and the methods ``.encode/.decode('utf-8')``. Other than that there is the usual list of smaller issues and bugs that got -fixed, such as: teach the compiler when to emit the new opcode -``DELETE_DEREF`` (and implement it!); detect when we use spaces and TABs -inconsistently in the source code, as CPython does; fix yet another bug -related to the new lexically scoped exceptions (this is the last one, -hopefully); port some of the changes that we did to the standard CPython 2.7 -tests to 3.2, to mark those which are implementation details and should not be -run on PyPy. +fixed, including (but not limited to): -Finally, I would like to thanks Amaury and Ariel Ben-Yehuda for his work on -the branch; among other things, Amaury recently worked on ``cpyext`` and on -the PyPy ``_cffi_backend``, while Ariel submitted a patch to implement `PEP -3138`. + - teach the compiler when to emit the new opcode ``DELETE_DEREF`` (and + implement it!) + + - detect when we use spaces and TABs inconsistently in the source code, as + CPython does + + - fix yet another bug related to the new lexically scoped exceptions (this + is the last one, hopefully) + + - port some of the changes that we did to the standard CPython 2.7 tests to + 3.2, to mark those which are implementation details and should not be run on + PyPy + +Finally, I would like to thank Amaury Forgeot d'Arc and Ariel Ben-Yehuda for +their work on the branch; among other things, Amaury recently worked on +``cpyext`` and on the PyPy ``_cffi_backend``, while Ariel submitted a patch to +implement `PEP 3138`. .. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html .. _`py3k proposal`: http://pypy.org/py3donate.html .. _`py3k branch`: https://bitbucket.org/pypy/pypy/src/py3k .. _`PEP 3138`: http://www.python.org/dev/peps/pep-3138/ +.. _`Philip Jenvey`: https://twitter.com/pjenvey diff --git a/talk/confoo2013/abstract_hippy.rst b/talk/confoo2013/abstract_hippy.rst --- a/talk/confoo2013/abstract_hippy.rst +++ b/talk/confoo2013/abstract_hippy.rst @@ -2,18 +2,9 @@ How I created a proof-of-concept PHP interpreter in 2 months. ============================================================= -HipPy is a proof of concept PHP VM developed as a research effort sponsored -by Facebook using PyPy. After two months, while not production ready, -it implements enough of the PHP language to run shootout benchmarks, without -compromising PHP semantics. It's also very fast - over 2x faster than hiphop, -a compiler from PHP to C++ developed by Facebook. +HipPy is a proof of concept PHP VM developed as a research effort sponsored by Facebook using PyPy. After two months, while not production ready, it implements enough of the PHP language to run shootout benchmarks, without compromising PHP semantics. It's also very fast - over 2x faster than hiphop, a compiler from PHP to C++ developed by Facebook. NOTES TO ORGANIZERS: -PyPy is not only a python interpreter but also a toolchain for creating dynamic -language virtual machines. In the past we developed a Prolog VM, -a scheme VM and some others. Laurence Tratt developed a new VM for -the converge language which outperformed the C implementation. -I'm going to present how easy it is to use PyPy than implementing a VM -by hand. +PyPy is not only a python interpreter but also a toolchain for creating dynamic language virtual machines. In the past we developed a Prolog VM, a scheme VM and some others. Laurence Tratt developed a new VM for the converge language which outperformed the C implementation. I'm going to present how easy it is to use PyPy than implementing a VM by hand. diff --git a/talk/confoo2013/abstract_pypy.rst b/talk/confoo2013/abstract_pypy.rst --- a/talk/confoo2013/abstract_pypy.rst +++ b/talk/confoo2013/abstract_pypy.rst @@ -2,17 +2,9 @@ PyPy - the fastest Python interpreter ============================================= -The PyPy project has recently gathered a lot of attention for its -progress in speeding up the Python language -- it is the fastest, -most compatible and most stable 'alternative´ Python interpreter. No -longer merely a research curiosity, PyPy is now suitable for production -use. I would like to present PyPy, its current status and it' near future goals. +The PyPy project has recently gathered a lot of attention for its progress in speeding up the Python language. It is the fastest, most compatible and most stable 'alternative´ Python interpreter. No longer merely a research, PyPy is now suitable for production use. I would like to present PyPy, its current status and it's near future goals. NOTES TO ORGANIZERS: -I've been PyPy core developer since 2006 and presenting PyPy to wider audience -since 2007. I've been to conferences all over the world, speaking about PyPy -and other Python topics. This talk will hopefully introduce the conference -audience to what PyPy is, how to use it in your code and what benefits can -you expect. +I've been PyPy core developer since 2006 and presenting PyPy to wider audience since 2007. I've been to conferences all over the world, speaking about PyPy and other Python topics. This talk will hopefully introduce the conference audience to what PyPy is, how to use it in your code and what benefits can you expect. diff --git a/talk/pycon2013/abstract_fijal.rst b/talk/pycon2013/abstract_fijal.rst new file mode 100644 --- /dev/null +++ b/talk/pycon2013/abstract_fijal.rst @@ -0,0 +1,23 @@ +Speeding up existing code using PyPy +==================================== + +Brief outline: + +I spent quite some time profiling existing python programs under PyPy. +This talk will walk through an existing Python library (undecided which yet) +and showcase how to write benchmarks, how to find bottlenecks, how to analyze +them and how to improve them when running on the PyPy interpreter and what +are the theoretical and pracitcal limits. + +Detailed abstract: + +In this talk I would like to share my experience when optimizing existing +Python codebases. I spend copious amounts of time staring at profiling data, +improving profilers to see anything and improving PyPy to work better +on real-life workloads. I would like to give the audience insight what +sort of constructs are optimized by PyPy, what sort of constructs can +possibly be optimized and which ones are out of question. This talk is +an intermediate one and assumes good enough knowledge of Python to understand +code of a given library (Twisted, Django, Flask, Gunicorn and some stdlib +module are potential candidates), however no prior knowledge of PyPy or +the processor performance characteristics is necessary. diff --git a/talk/pyconza2012/Makefile b/talk/pyconza2012/Makefile new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/Makefile @@ -0,0 +1,12 @@ + +talk.pdf: talk.rst author.latex title.latex stylesheet.latex + rst2beamer.py --stylesheet=stylesheet.latex --documentoptions=14pt --output-encoding=utf-8 talk.rst talk.latex || exit + sed 's/\\date{}/\\input{author.latex}/' -i talk.latex || exit + sed 's/\\maketitle/\\input{title.latex}/' -i talk.latex || exit + pdflatex talk.latex || exit + +view: talk.pdf + evince talk.pdf & + +xpdf: talk.pdf + xpdf talk.pdf & diff --git a/talk/pyconza2012/author.latex b/talk/pyconza2012/author.latex new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/author.latex @@ -0,0 +1,8 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[Python performance characteristics]{Python performance characteristics} +\author[Maciej Fijałkowski] +{Maciej Fijałkowski} + +\institute{PyCon 2012} +\date{October 5, 2012} diff --git a/talk/pyconza2012/beamerdefs.txt b/talk/pyconza2012/beamerdefs.txt new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/beamerdefs.txt @@ -0,0 +1,108 @@ +.. colors +.. =========================== + +.. role:: green +.. role:: red + + +.. general useful commands +.. =========================== + +.. |pause| raw:: latex + + \pause + +.. |small| raw:: latex + + {\small + +.. |end_small| raw:: latex + + } + +.. |scriptsize| raw:: latex + + {\scriptsize + +.. |end_scriptsize| raw:: latex + + } + +.. |strike<| raw:: latex + + \sout{ + +.. closed bracket +.. =========================== + +.. |>| raw:: latex + + } + + +.. example block +.. =========================== + +.. |example<| raw:: latex + + \begin{exampleblock}{ + + +.. |end_example| raw:: latex + + \end{exampleblock} + + + +.. alert block +.. =========================== + +.. |alert<| raw:: latex + + \begin{alertblock}{ + + +.. |end_alert| raw:: latex + + \end{alertblock} + + + +.. columns +.. =========================== + +.. |column1| raw:: latex + + \begin{columns} + \begin{column}{0.45\textwidth} + +.. |column2| raw:: latex + + \end{column} + \begin{column}{0.45\textwidth} + + +.. |end_columns| raw:: latex + + \end{column} + \end{columns} + + + +.. |snake| image:: ../img/py-web-new.png + :scale: 15% + + + +.. nested blocks +.. =========================== + +.. |nested| raw:: latex + + \begin{columns} + \begin{column}{0.85\textwidth} + +.. |end_nested| raw:: latex + + \end{column} + \end{columns} diff --git a/talk/pyconza2012/examples/alloc.py b/talk/pyconza2012/examples/alloc.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/examples/alloc.py @@ -0,0 +1,20 @@ + +import sys, time + +def f(): + l = [None] + for i in xrange(int(sys.argv[1])): + l[0] = (i,) + +def g(): + m = int(sys.argv[1]) + l = [None] * m + for i in xrange(m): + l[i] = (i,) + +t0 = time.time() +f() +t1 = time.time() +g() +t2 = time.time() +print "long living", t2 - t1, "short living", t1 - t0 diff --git a/talk/pyconza2012/examples/calls.py b/talk/pyconza2012/examples/calls.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/examples/calls.py @@ -0,0 +1,41 @@ + +import sys, time + +def inner(a, b, c): + pass + +def simple_call(a, b, c): + inner(a, b, c) + +def simple_call2(a, b, c): + inner(a, c=c, b=b) + +def simple_method(a, b, c): + c.m(a, b) + +def star_call(a, b, c): + inner(*(a, b, c)) + +def star_call_complex(a, b, c): + inner(*(a, b), **{'c': c}) + +def abomination(a, b, c): + inner(**locals()) + +class A(object): + def m(self, a, b): + pass + +def run(func): + count = int(sys.argv[1]) + t0 = time.time() + o = A() + for i in xrange(count): + func(i, i, o) + tk = time.time() + t = (tk - t0) / count + print "%s %.2e per call, %d cycles" % (func.func_name, t, int(t * 1.7e9)) + +for f in [simple_call, simple_call2, simple_method, star_call, star_call_complex, abomination]: + run(f) + diff --git a/talk/pyconza2012/examples/datastructure.py b/talk/pyconza2012/examples/datastructure.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/examples/datastructure.py @@ -0,0 +1,26 @@ + +class View(object): + def __init__(self, arr, start, stop): + self.arr = arr + self.start = start + self.stop = stop + + def __getitem__(self, item): + if not isinstance(item, int): + return NotImplemented + if self.start + item <= self.stop: + raise IndexError + return self.arr[self.start + item] + +class Wrapper(object): + def __init__(self, arr): + self.arr = arr + + def __getitem__(self, item): + if isinstance(item, int): + return self.arr[item] + elif isinstance(item, slice): + if item.step != 1 or item.start < 0 or item.stop < 0: + raise TypeError("step not implemented") + return View(self.arr, item.start, item.stop) + return NotImplemented diff --git a/talk/pyconza2012/examples/interpreter.py b/talk/pyconza2012/examples/interpreter.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/examples/interpreter.py @@ -0,0 +1,72 @@ + +(LOAD_FAST, LOAD_CONST, COMPARE_OP, POP_JUMP_IF_FALSE, + ADD, STORE_FAST, JUMP_ABSOLUTE) = range(7) + +has_arg = [True, True, False, True, False, True, True] + +class BaseObject(object): + def add(left, right): + # try right + return right.radd(left) + + def radd(self, left): + raise TypeError + +class Long(BaseObject): + pass + +class Integer(BaseObject): + def __init__(self, v): + self.intval = v + + def add(self, right): + if isinstance(right, Integer): + try: + return Integer(self.intval + right.intval) + except OverflowError: + return Long(self.intval).add(Long(right.intval)) + else: + return right.radd(self) + +def interpret(bytecode, variables, constants): + stack = [] + pos = 0 + arg0 = None + while True: + b = ord(bytecode[pos]) + if has_arg[b]: + pos += 1 + arg0 = ord(bytecode[pos]) + if b == LOAD_FAST: + stack.append(variables[arg0]) + elif b == LOAD_CONST: + stack.append(constants[arg0]) + elif b == COMPARE_OP: + right = stack.pop() + left = stack.pop() + stack.append(left.compare(right)) + elif b == ADD: + right = stack.pop() + left = stack.pop() + stack.append(left.add(right)) + elif b == POP_JUMP_IF_FALSE: + val = stack.pop() + if not val.is_true(): + pos = arg0 + continue + elif b == STORE_FAST: + variables[arg0] = stack.pop() + elif b == JUMP_ABSOLUTE: + pos = arg0 + continue + pos += 1 + + +def f(a, b): + return a + b + +stack.append(variables[arg0]) +stack.append(variables[arg0]) +right = stack.pop() +left = stack.pop() +stack.append(left.add(right)) diff --git a/talk/pyconza2012/examples/jit01.py b/talk/pyconza2012/examples/jit01.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/examples/jit01.py @@ -0,0 +1,10 @@ + +def f(): + i = 0 + while i < 1000000: + i = i + 1 + return i + +if __name__ == '__main__': + f() + diff --git a/talk/googlezurich2012/Makefile b/talk/pyconza2012/stm-talk/Makefile copy from talk/googlezurich2012/Makefile copy to talk/pyconza2012/stm-talk/Makefile diff --git a/talk/pyconza2012/stm-talk/author.latex b/talk/pyconza2012/stm-talk/author.latex new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stm-talk/author.latex @@ -0,0 +1,8 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[PyPy in Production]{PyPy} +\author[Armin Rigo] +{Armin Rigo} + +\institute{PyCon ZA 2012} +\date{October 4, 2012} diff --git a/talk/googlezurich2012/beamerdefs.txt b/talk/pyconza2012/stm-talk/beamerdefs.txt copy from talk/googlezurich2012/beamerdefs.txt copy to talk/pyconza2012/stm-talk/beamerdefs.txt --- a/talk/googlezurich2012/beamerdefs.txt +++ b/talk/pyconza2012/stm-talk/beamerdefs.txt @@ -89,7 +89,7 @@ -.. |snake| image:: ../img/py-web-new.png +.. |snake| image:: ../../img/py-web-new.png :scale: 15% diff --git a/talk/pyconza2012/stm-talk/demo1.py b/talk/pyconza2012/stm-talk/demo1.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stm-talk/demo1.py @@ -0,0 +1,19 @@ + +class Number(object): + + def __init__(self, num): + self.num = num + + def __add__(self, other): + return Number(self.num + other.num) + + def __invert__(self): + return Number(~self.num) + +def foo(n): + total = Number(0) + for i in range(n): + total += Number(i) + total += ~ Number(i) + return total.num + diff --git a/talk/googlezurich2012/standards.png b/talk/pyconza2012/stm-talk/standards.png copy from talk/googlezurich2012/standards.png copy to talk/pyconza2012/stm-talk/standards.png diff --git a/talk/googlezurich2012/stylesheet.latex b/talk/pyconza2012/stm-talk/stylesheet.latex copy from talk/googlezurich2012/stylesheet.latex copy to talk/pyconza2012/stm-talk/stylesheet.latex diff --git a/talk/pyconza2012/stm-talk/talk.rst b/talk/pyconza2012/stm-talk/talk.rst new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stm-talk/talk.rst @@ -0,0 +1,205 @@ +.. include:: beamerdefs.txt + +============================================================ +PyPy +============================================================ + + +PyPy is... +-------------------------- + +* Another Python interpreter + +* with a JIT compiler + + +PyPy was... +------------------- + +* Around since 2003 + +* (advertised as) production ready since December 2010 + + - release 1.4 + +* Funding + + - EU FP6 programme + + - Eurostars programme + + - donations + + - ... + + +PyPy 1.9: current status +------------------------ + +* Faster + + - **1.7x** than 1.5 (Summer 2011) + + - **2.2x** than 1.4 (December 2010) + + - **5.5x** than CPython + +* Implements Python 2.7.3 + +* Many more "PyPy-friendly" programs than before + +* Packaging + + - |scriptsize| Debian, Ubuntu, Fedora, Homebrew, Gentoo, ArchLinux, ... |end_scriptsize| + + - |scriptsize| Windows (32bit only), OS X |end_scriptsize| + +* C extension compatibility + + - runs (big part of) **PyOpenSSL** and **lxml** + + +PyPy organization +----------------- + +* Part of SFC -- Software Freedom Conservancy + + - Bradley successfully fighting U.S. bureaucracy + + - we are happy about it + + +* Funding model + + - py3k, numpy, STM + + - more than 100'000$ in donations + + - from individuals, large companies and the PSF + + +PyPy's JIT compiler +------------------- + +* Removes abstraction + +* Almost never gives up + +* x86-32, x86-64, ARMv7, (POWER64) + +* (Works with other languages) + + +Real world applications +----------------------- + +* Positive feedback + +* http://speed.pypy.org/ + + + +py3k +------------------------ + +* ``py3k`` branch in mercurial + + - developed in parallel + + - Python 3 written in Python 2 + +* Focus on correctness + +* Dropped some interpreter optimizations for now + +* First 90% done, remaining 90% not done + +* Majority of the funds by Google + + +NumPy +----- + +* progress going slowly + +* multi dimensional arrays, broadcasting, fancy indexing + +* all dtypes, except complex, strings and objects + +* good results for performance + + +STM +--------------------------- + +* Software Transactional Memory + +* "Remove the GIL" + +* But also, new models (better than threads) + + + +Calling C +--------- + +.. image:: standards.png + :scale: 60% + :align: center + +Calling C landscape +------------------- + +* CPython C extensions + +* SWIG, SIP, wrapper generators + +* ctypes + +* Cython + +* CFFI (our new thing) + +CFFI +---------- + +|scriptsize| +|example<| Example |>| + + .. sourcecode:: pycon + + >>> from cffi import FFI + >>> ffi = FFI() + >>> ffi.cdef(""" + ... int printf(const char *format, ...); + ... """) + >>> C = ffi.dlopen(None) + >>> arg = ffi.new("char[]", "world") + >>> C.printf("hi there, %s!\n", arg) + hi there, world! + +|end_example| +|end_scriptsize| + +CFFI +---- + +* Many more examples + +* Including macro calls and most subtleties of C + +* http://cffi.readthedocs.org + + +STM +--- + + +Conclusion +---------- + +* Try out PyPy on real code + +* http://pypy.org/ + +* Thank you! diff --git a/talk/googlezurich2012/title.latex b/talk/pyconza2012/stm-talk/title.latex copy from talk/googlezurich2012/title.latex copy to talk/pyconza2012/stm-talk/title.latex --- a/talk/googlezurich2012/title.latex +++ b/talk/pyconza2012/stm-talk/title.latex @@ -1,5 +1,5 @@ \begin{titlepage} \begin{figure}[h] -\includegraphics[width=60px]{../img/py-web-new.png} +\includegraphics[width=60px]{../../img/py-web-new.png} \end{figure} \end{titlepage} diff --git a/talk/pyconza2012/stylesheet.latex b/talk/pyconza2012/stylesheet.latex new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stylesheet.latex @@ -0,0 +1,12 @@ +\usepackage{ulem} +\usetheme{Boadilla} +\usecolortheme{whale} +\setbeamercovered{transparent} +\setbeamertemplate{navigation symbols}{} + +\definecolor{darkgreen}{rgb}{0, 0.5, 0.0} +\newcommand{\docutilsrolegreen}[1]{\color{darkgreen}#1\normalcolor} +\newcommand{\docutilsrolered}[1]{\color{red}#1\normalcolor} + +\newcommand{\green}[1]{\color{darkgreen}#1\normalcolor} +\newcommand{\red}[1]{\color{red}#1\normalcolor} diff --git a/talk/pyconza2012/talk.pdf b/talk/pyconza2012/talk.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8eb88f4bb2440dcede688672bdf6b31b30be2d4d GIT binary patch [cut] diff --git a/talk/pyconza2012/talk.rst b/talk/pyconza2012/talk.rst new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/talk.rst @@ -0,0 +1,247 @@ +.. include:: beamerdefs.txt + +================================== +Python performance characteristics +================================== + +Who am I? +--------- + +* Maciej Fijałkowski (yes this is unicode) + +* PyPy core developer for I don't remember + +* performance freak + +What this talk is about? +------------------------ + +* python performance (or lack of it) + +* why does it matter + +* what can we do about it + +* how PyPy works + +Python performance message +--------------------------- + +* according to Guido + +* "Avoid overengineering datastructures. Tuples are better than objects (try namedtuple too though). Prefer simple fields over getter/setter functions." + +* "Built-in datatypes are your friends. Use more numbers, strings, tuples, lists, sets, dicts. Also check out the collections library, esp. deque." + +* "Be suspicious of function/method calls; creating a stack frame is expensive." + +* "The universal speed-up is rewriting small bits of code in C. Do this only when all else fails." + +What does it mean? +------------------ + +* don't use abstractions + +|pause| + +* don't use Python + +But also +-------- + +* measure! + +* there are so many variables, you cannot care without benchmarks + +|pause| + +* if you have no benchmarks, you don't care + +This is not how I want to write software +---------------------------------------- + +* I like my abstractions + +* I like Python + +* I don't want to rewrite stuff for performance + +|pause| + +* in C/C++ + +Second best +----------- + +* keep my abstractions + +* do arcane voodoo to keep my programs fast + +* but you have to understand the voodo in the first place + +But Python performance! +----------------------- + +* there is no such thing as language performance + +* there is implementation performance + +* the language might be easier or harder to optimize + +* CPython performance characteristics is relatively straightforward + +What is PyPy? +------------- + +* PyPy is a Python interpreter (that's what we care about) + +* PyPy is a toolchain for creating dynamic language implementations + +* also, an Open Source project that has been around for a while + +Compilers vs interpreters +------------------------- + +* compilers compile language X (C, Python) to a lower level language + (C, assembler) ahead of time + +* interpreters compile language X to bytecode and have a big interpreter + loop + +|pause| + +* PyPy has a hybrid approach. It's an interpreter, but hot paths are + compiled directly to assembler during runtime + +What is just in time (JIT) compilation? +--------------------------------------- + +* few different flavors + +* observe runtime values + +* compile code with agressive optimizations + +* have checks if assumptions still stand + +So what PyPy does? +------------------ + +* interprets a Python program + +* the JIT observes python **interpreter** + +* producing code through the path followed by the interpreter + +* compiles loops and functions + +Some properties +--------------- + +* the code speed **changes** over time + +* hopefully from slow to fast + +* you need to warm up things before they get fast + +Some example +------------ + +* integer addition! + +Abstractions +------------ + +* inlining, malloc removal + +* abstractions are cheap + +|pause| + +* if they don't introduce too much complexity + +Few words about garbage collection +---------------------------------- + +* ``CPython``: refcounting + cyclic collector + +* ``PyPy``: generational mark & sweep + +|pause| + +* errr.... + +The rest +-------- + +* I'll explain various PyPy strategies + +* ideally all this knowledge will be unnecessary + +* this is the second best, how to please the JIT compiler + +Allocations (PyPy) +------------------ + +* allocation is expensive + +* for a good GC, short living objects don't matter + +* it's better to have a small persistent structure and abstraction + on allocation + +|pause| + +* copying however is expensive + +* we have hacks for strings, but they're not complete + +Calls +----- + +* Python calls are an incredible mess + +* simple is better than complex + +* simple call comes with no cost, the cost grows with growing complexity + +Attribute access +---------------- + +* if optimized, almost as fast as local var access + +* ``dict`` lookup optimized away + +* class attributes considered constant + +* meta programming is better than dynamism + +* objects for small number of constant keys, dicts for large + numbers of changing keys + +Other sorts of loops +-------------------- + +* there is more! + +* ``tuple(iterable)``, ``map(iterable)``, ``re.search`` + +* they're all jitted + +* not all nicely + +Summary +------- + +* we hope this knowledge will not be needed + +* the more you care, the better you need to know + +Questions? +---------- + +* Thank you! + +* http://pypy.org + +* http://baroquesoftware.com diff --git a/talk/pyconza2012/title.latex b/talk/pyconza2012/title.latex new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/title.latex @@ -0,0 +1,5 @@ +\begin{titlepage} +\begin{figure}[h] +\includegraphics[width=60px]{../img/py-web-new.png} +\end{figure} +\end{titlepage} From noreply at buildbot.pypy.org Sun Oct 7 12:37:02 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 12:37:02 +0200 (CEST) Subject: [pypy-commit] cffi default: Point again to 0.3 here, to make pip happy :-/ Message-ID: <20121007103702.1F3B21C0C15@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r981:b112b2dc3fba Date: 2012-10-07 12:36 +0200 http://bitbucket.org/cffi/cffi/changeset/b112b2dc3fba/ Log: Point again to 0.3 here, to make pip happy :-/ diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -89,11 +89,14 @@ Download and Installation: -* http://pypi.python.org/packages/source/c/cffi/cffi-0.4.tar.gz +* http://pypi.python.org/packages/source/c/cffi/cffi-0.3.tar.gz - - MD5: FILE NOT AVAILABLE YET! + - Note that this is the slightly outdated version 0.3! + Grab the current version by following the instructions below. - - SHA: FILE NOT AVAILABLE YET! + - MD5: 25dbc7b6182c64d08adeb6077bfa2743 + + - SHA: 922680f1aeb4392ab715cbe572fdc071cdbc4a35 * Or get it from the `Bitbucket page`_: ``hg clone https://bitbucket.org/cffi/cffi`` From noreply at buildbot.pypy.org Sun Oct 7 12:47:18 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 12:47:18 +0200 (CEST) Subject: [pypy-commit] pypy default: Include the root of the module name in the files that are generated by translation. Message-ID: <20121007104718.598681C041E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r57806:69e8fe5fc905 Date: 2012-10-07 03:46 -0700 http://bitbucket.org/pypy/pypy/changeset/69e8fe5fc905/ Log: Include the root of the module name in the files that are generated by translation. diff --git a/pypy/rlib/rsre/rsre_re.py b/pypy/rlib/rsre/rsre_re.py --- a/pypy/rlib/rsre/rsre_re.py +++ b/pypy/rlib/rsre/rsre_re.py @@ -75,7 +75,7 @@ else: item = match.groups("") matchlist.append(item) - return matchlist + return matchlist def finditer(self, string, pos=0, endpos=sys.maxint): return iter(self.scanner(string, pos, endpos).search, None) diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -701,7 +701,7 @@ localpath = py.path.local(g.filename) pypkgpath = localpath.pypkgpath() if pypkgpath: - relpypath = localpath.relto(pypkgpath) + relpypath = localpath.relto(pypkgpath.dirname) return relpypath.replace('.py', '.c') return None if hasattr(node.obj, 'graph'): diff --git a/pypy/translator/c/test/test_dlltool.py b/pypy/translator/c/test/test_dlltool.py --- a/pypy/translator/c/test/test_dlltool.py +++ b/pypy/translator/c/test/test_dlltool.py @@ -28,4 +28,4 @@ d = DLLDef('lib', [(f, [int]), (b, [int])]) so = d.compile() dirpath = py.path.local(so).dirpath() - assert dirpath.join('translator_c_test_test_dlltool.c').check() + assert dirpath.join('pypy_translator_c_test_test_dlltool.c').check() diff --git a/pypy/translator/c/test/test_standalone.py b/pypy/translator/c/test/test_standalone.py --- a/pypy/translator/c/test/test_standalone.py +++ b/pypy/translator/c/test/test_standalone.py @@ -57,9 +57,9 @@ # Verify that the generated C files have sane names: gen_c_files = [str(f) for f in cbuilder.extrafiles] - for expfile in ('rlib_rposix.c', - 'rpython_lltypesystem_rstr.c', - 'translator_c_test_test_standalone.c'): + for expfile in ('pypy_rlib_rposix.c', + 'pypy_rpython_lltypesystem_rstr.c', + 'pypy_translator_c_test_test_standalone.c'): assert cbuilder.targetdir.join(expfile) in gen_c_files def test_print(self): From noreply at buildbot.pypy.org Sun Oct 7 12:56:56 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 12:56:56 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (fijal, arigo) Message-ID: <20121007105656.C42251C0B64@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57807:fa72a07de9f2 Date: 2012-10-07 12:56 +0200 http://bitbucket.org/pypy/pypy/changeset/fa72a07de9f2/ Log: (fijal, arigo) A branch to really kill SomeObject support. Kill kill kill old old old code. diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -39,21 +39,8 @@ self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +64,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +165,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +182,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +193,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +243,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +266,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +284,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +334,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -435,23 +362,22 @@ self.annotated[block] = False # must re-flow self.blocked_blocks[block] = graph - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. self.blocked_blocks[block] = graph - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -476,9 +402,6 @@ self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +485,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +495,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +531,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,15 +29,6 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', 'truediv', 'floordiv', 'divmod', 'pow', @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -238,7 +201,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -566,7 +552,7 @@ if len(tup1.items) != len(tup2.items): return SomeObject() else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): @@ -723,8 +709,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -764,7 +749,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -778,7 +763,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -806,7 +791,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,7 +10,7 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef @@ -325,8 +325,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -445,6 +443,11 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if x is type(None): # add cases here if needed + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) 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 @@ -455,19 +458,11 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) + result = SomePBC([self.getdesc(x)]) elif hasattr(x, '_freeze_') and x._freeze_(): # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,7 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + if not isinstance(s_type, SomeBuiltin): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,9 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype - knowntype = object immutable = False + def __init__(self): + assert type(self) is not SomeObject + def __eq__(self, other): return (self.__class__ is other.__class__ and self.__dict__ == other.__dict__) @@ -105,61 +105,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: - self = new(cls, *args, **kw) - if DEBUG: - try: - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - position_key = bookkeeper.position_key - except AttributeError: - pass - else: - bookkeeper._isomeobject_coming_from[self] = position_key, None - return self - - def origin(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] - origin = property(origin) - - def caused_by_merge(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] - def set_caused_by_merge(self, nvalue): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return - bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue - caused_by_merge = property(caused_by_merge, set_caused_by_merge) - del set_caused_by_merge - def can_be_none(self): return True def nonnoneify(self): return self +class SomeType(SomeObject): + "Stands for a type. We might not be sure which one it is." + knowntype = type + immutable = True + + def can_be_none(self): + return False + class SomeFloat(SomeObject): "Stands for a float or an integer." knowntype = float # if we don't know if it's a float or an int, @@ -517,6 +484,7 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) @@ -710,14 +678,8 @@ # this is just a performance shortcut if s1 != s2: s1 = pair(s1, s2).union() - if DEBUG: - if s1.caused_by_merge is None and len(somevalues) > 1: - s1.caused_by_merge = somevalues return s1 -def isdegenerated(s_value): - return s_value.__class__ is SomeObject and s_value.knowntype is not type - # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -10,7 +10,6 @@ class BasicAnnotatorPolicy(object): - allow_someobjects = True def event(pol, bookkeeper, what, *args): pass diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -3,9 +3,9 @@ from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF -from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF + unionof, SomeUnicodeString, SomeType +from pypy.annotation.listdef import ListDef +from pypy.annotation.dictdef import DictDef _annotation_cache = {} @@ -78,13 +78,10 @@ return SomeString() elif t is unicode: return SomeUnicodeString() - elif t is list: - return SomeList(MOST_GENERAL_LISTDEF) - elif t is dict: - return SomeDict(MOST_GENERAL_DICTDEF) - # can't do tuple elif t is types.NoneType: return s_None + elif t is type: + return SomeType() elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) @@ -92,10 +89,7 @@ classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) else: - o = SomeObject() - if t != object: - o.knowntype = t - return o + raise AssertionError("annotationoftype(%r)" % (t,)) class Sig(object): diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -24,7 +24,7 @@ assert isinstance(s_list, annmodel.SomeList) return s_list.listdef.listitem.s_value -def somelist(s_type=annmodel.SomeObject()): +def somelist(s_type): return annmodel.SomeList(ListDef(None, s_type)) def dictkey(s_dict): @@ -35,7 +35,7 @@ assert isinstance(s_dict, annmodel.SomeDict) return s_dict.dictdef.dictvalue.s_value -def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()): +def somedict(s_key, s_value): return annmodel.SomeDict(DictDef(None, s_key, s_value)) @@ -205,15 +205,6 @@ annmodel.SomeInteger() ]) - def test_inheritance2(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet._inheritance_nonrunnable, []) - # result should be exactly: - assert s == annmodel.SomeTuple([ - annmodel.SomeInteger(), - annmodel.SomeObject() - ]) - def test_poor_man_range(self): a = self.RPythonAnnotator() s = a.build_types(snippet.poor_man_range, [int]) @@ -336,9 +327,13 @@ def test_flow_type_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_type_info, [object]) + s = a.build_types(snippet.flow_type_info, [int]) a.simplify() - #a.translator.view() + assert s.knowntype == int + + a = self.RPythonAnnotator() + s = a.build_types(snippet.flow_type_info, [str]) + a.simplify() assert s.knowntype == int def test_flow_type_info_2(self): @@ -351,7 +346,7 @@ def test_flow_usertype_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_usertype_info, [object]) + s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit]) #a.translator.view() assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit) @@ -363,13 +358,6 @@ assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit) - def test_flow_identity_info(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_identity_info, [object, object]) - a.simplify() - #a.translator.view() - assert s == a.bookkeeper.immutablevalue((None, None)) - def test_mergefunctions(self): a = self.RPythonAnnotator() s = a.build_types(snippet.mergefunctions, [int]) @@ -431,11 +419,11 @@ # the annotator (it doesn't check that they operate property, though) for example, methname, s_example in [ ('', 'join', annmodel.SomeString()), - ([], 'append', somelist()), - ([], 'extend', somelist()), - ([], 'reverse', somelist()), - ([], 'insert', somelist()), - ([], 'pop', somelist()), + ([], 'append', somelist(annmodel.s_Int)), + ([], 'extend', somelist(annmodel.s_Int)), + ([], 'reverse', somelist(annmodel.s_Int)), + ([], 'insert', somelist(annmodel.s_Int)), + ([], 'pop', somelist(annmodel.s_Int)), ]: constmeth = getattr(example, methname) s_constmeth = iv(constmeth) @@ -497,12 +485,12 @@ def test_simple_slicing(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_slice, [list]) + s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeList) def test_simple_iter_list(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_iter, [list]) + s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeIterator) def test_simple_iter_next(self): @@ -542,11 +530,6 @@ assert isinstance(dictkey(s), annmodel.SomeInteger) assert isinstance(dictvalue(s), annmodel.SomeInteger) - a = self.RPythonAnnotator() - s = a.build_types(snippet.dict_update, [str]) - assert not isinstance(dictkey(s), annmodel.SomeString) - assert not isinstance(dictvalue(s), annmodel.SomeString) - def test_dict_update_2(self): a = self.RPythonAnnotator() def g(n): @@ -568,7 +551,7 @@ def test_dict_keys2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_keys2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_values(self): a = self.RPythonAnnotator() @@ -578,7 +561,7 @@ def test_dict_values2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_items(self): a = self.RPythonAnnotator() @@ -643,25 +626,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_bltin_code_frame_confusion(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_confusion,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - # annotator confused by original bltin code/frame setup, we just get SomeObject here - assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - - def test_bltin_code_frame_reorg(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_reorg,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - assert isinstance(a.binding(f_flowgraph.getreturnvar()), - annmodel.SomeInteger) - assert isinstance(a.binding(g_flowgraph.getreturnvar()), - annmodel.SomeString) - def test_propagation_of_fresh_instances_through_attrs(self): a = self.RPythonAnnotator() s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int]) @@ -748,14 +712,15 @@ assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc) def test_type_is(self): - class C(object): + class B(object): + pass + class C(B): pass def f(x): - if type(x) is C: - return x - raise Exception - a = self.RPythonAnnotator() - s = a.build_types(f, [object]) + assert type(x) is C + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) def test_ann_assert(self): @@ -793,7 +758,7 @@ return None a = self.RPythonAnnotator() - s = a.build_types(f, [list]) + s = a.build_types(f, [somelist(annmodel.s_Int)]) assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list def test_freeze_protocol(self): @@ -854,7 +819,7 @@ def f(a,b): return bool(a) or bool(b) a = self.RPythonAnnotator() - s = a.build_types(f, [int,list]) + s = a.build_types(f, [int, somelist(annmodel.s_Int)]) assert s.knowntype == bool def test_float(self): @@ -1299,22 +1264,6 @@ assert isinstance(s_item, annmodel.SomeInstance) assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - def test_assert_type_is_list_doesnt_lose_info(self): - class T(object): - pass - def g(l): - assert type(l) is list - return l - def f(): - l = [T()] - return g(l) - a = self.RPythonAnnotator() - s = a.build_types(f, []) - s_item = listitem(s) - assert isinstance(s_item, annmodel.SomeInstance) - assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - - def test_int_str_mul(self): def f(x,a,b): return a*x+x*b @@ -1395,11 +1344,10 @@ except KeyError: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.const = KeyError t.is_type_of = [ev] assert a.binding(et) == t @@ -1412,11 +1360,10 @@ except: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t @@ -1448,11 +1395,10 @@ finally: h() a = self.RPythonAnnotator() - a.build_types(f, [int, list]) + a.build_types(f, [int, somelist(annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) @@ -1474,24 +1420,11 @@ a.build_types(f, []) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_sys_attrs(self): - def f(): - return sys.argv[0] - a = self.RPythonAnnotator() - try: - oldvalue = sys.argv - sys.argv = [] - s = a.build_types(f, []) - finally: - sys.argv = oldvalue - assert s is not None - def test_pow(self): def f(n): n **= 2 @@ -1523,7 +1456,6 @@ a = self.RPythonAnnotator() 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)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] def test_is_true_coalesce2(self): def f(a,b,a1,b1,c,d,e): @@ -1532,9 +1464,12 @@ return d,c return e,c a = self.RPythonAnnotator() - s = a.build_types(f, [int, str, float, list, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) - assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] + s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int), + 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_coalesce_sanity(self): def f(a): @@ -1954,16 +1889,7 @@ t = type(x) return issubclass(t, A) - def f(): - x = g(1) - y = g(0) - return x or y - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert s.knowntype == bool - assert not s.is_constant() - a = self.RPythonAnnotator() - # sanity check + a = self.RPythonAnnotator() x = annmodel.SomeInteger() x.const = 1 s = a.build_types(g, [x]) @@ -2383,8 +2309,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int]) - assert s.__class__ == annmodel.SomeObject - assert s.knowntype == type + assert isinstance(s, annmodel.SomeType) def test_annotate_iter_empty_container(self): def f(): diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -2,20 +2,19 @@ import autopath import py from pypy.annotation.model import * -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF +from pypy.annotation.listdef import ListDef from pypy.rpython.ootypesystem.ootype import ROOT listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) -s1 = SomeObject() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s1,s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -100,7 +99,8 @@ def test_list_contains(): listdef1 = ListDef(None, SomeInteger(nonneg=True)) s1 = SomeList(listdef1) - s2 = SomeList(MOST_GENERAL_LISTDEF) + listdef2 = ListDef(None, SomeInteger(nonneg=False)) + s2 = SomeList(listdef2) assert s1 != s2 assert s2.contains(s1) assert s1 != s2 diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -7,7 +7,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -45,8 +45,7 @@ else: r = immutablevalue(obj.knowntype) else: - r = SomeObject() - r.knowntype = type + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -129,8 +129,6 @@ # misc BoolOption("verbose", "Print extra information", default=False), - BoolOption("debug", "Record extra annotation information", - cmdline="-d --debug", default=True), BoolOption("insist", "Try hard to go on RTyping", default=False, cmdline="--insist"), StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), diff --git a/pypy/tool/error.py b/pypy/tool/error.py --- a/pypy/tool/error.py +++ b/pypy/tool/error.py @@ -72,6 +72,7 @@ pass def gather_error(annotator, block, graph): + XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX msg = [""] msg.append('-+' * 30) from pypy.annotation import model @@ -147,6 +148,7 @@ msg.append("") def format_someobject_error(annotator, position_key, what, s_value, called_from_graph, binding=""): + XXXXXXXXXXXXXXXXXXXXXX #block = getattr(annotator, 'flowin_block', None) or block msg = ["annotation of %r degenerated to SomeObject()" % (what,)] if position_key is not None: @@ -167,9 +169,6 @@ if called_from_graph is not None: msg.append(".. called from %r" % (called_from_graph,)) - if s_value.origin is not None: - msg.append(".. SomeObject() origin: %s" % ( - annotator.whereami(s_value.origin),)) msg.append("Previous annotation:") msg.append(" " + str(binding)) return "\n".join(msg) diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py --- a/pypy/translator/driver.py +++ b/pypy/translator/driver.py @@ -309,7 +309,6 @@ policy = self.policy self.log.info('with policy: %s.%s' % (policy.__class__.__module__, policy.__class__.__name__)) - annmodel.DEBUG = self.config.translation.debug annotator = translator.buildannotator(policy=policy) if self.secondary_entrypoints is not None: diff --git a/pypy/translator/test/snippet.py b/pypy/translator/test/snippet.py --- a/pypy/translator/test/snippet.py +++ b/pypy/translator/test/snippet.py @@ -522,9 +522,10 @@ def methodcall_is_precise(cond): if cond: x = CSub1() + x.m() else: x = CSub2() - x.m() + x.m() return CSub1().m() @@ -541,18 +542,6 @@ else: return WithMoreInit(1, 2) -def flow_identity_info(x=object, y=object): - if x is None: - if y is None: - return (x, y) - else: - return (x, None) - else: - if y is None: - return (None, y) - else: - return (None, None) - def star_args0(*args): return args[0] / 2 @@ -658,13 +647,6 @@ break return v -def _inheritance_nonrunnable(): - d = D() - d.stuff = (-12, -12) - e = E() - e.stuff = (3, "world") - return C().stuff - def _getstuff(x): return x.stuff @@ -788,7 +770,7 @@ def dict_keys2(): d = {"a" : 1} keys = d.keys() - d[1] = 12 + d["123"] = 12 return keys def dict_values(): @@ -796,9 +778,9 @@ return d.values() def dict_values2(): - d = {"a" : "a"} + d = {54312 : "a"} values = d.values() - d[1] = 12 + d[1] = "12" return values def dict_items(): @@ -942,94 +924,6 @@ return fn(n) -class BltinCode: - def __init__(self, func, framecls): - self.func = func - self.framecls = framecls - - def call(self, x): - return self.framecls(self).run(x) - -class BltinFrame: - def __init__(self, code): - self.code = code - -def bltin_code_frame_f(x): - return x - -def bltin_code_frame_g(x): - return x - -class FBltinFrame(BltinFrame): - - def run(self, x): - return self.code.func(x) - -class GBltinFrame(BltinFrame): - - def run(self, x): - return self.code.func(x) - -bltin_code_for_f = BltinCode(bltin_code_frame_f, FBltinFrame) -bltin_code_for_g = BltinCode(bltin_code_frame_g, GBltinFrame) - -def bltin_code_frame_confusion(): - a = bltin_code_for_f.call(0) - a1 = bltin_code_for_f.call(1) - b = bltin_code_for_g.call("a") - b1 = bltin_code_for_g.call("b") - return (a,a1,b,b1) - - -# reorg - -class BltinCodeReorg: - def __init__(self, framecls): - self.framecls = framecls - - def call(self, x): - frame = self.framecls() - frame.set(x) - return frame.run() - -class BltinFrameReorg: - def __init__(self): - pass - - def set(self,x): - pass - - def run(self): - pass - -class FBltinFrameReorg(BltinFrameReorg): - - def set(self, x): - self.arg = int(x) - - def run(self): - return bltin_code_frame_f(self.arg) - -class GBltinFrameReorg(BltinFrameReorg): - - def set(self, x): - self.arg = str(x) - - def run(self): - return bltin_code_frame_g(self.arg) - - -bltin_code_for_f_reorg = BltinCodeReorg(FBltinFrameReorg) -bltin_code_for_g_reorg = BltinCodeReorg(GBltinFrameReorg) - -def bltin_code_frame_reorg(): - a = bltin_code_for_f_reorg.call(0) - a1 = bltin_code_for_f_reorg.call(1) - b = bltin_code_for_g_reorg.call("a") - b1 = bltin_code_for_g_reorg.call("b") - return (a,a1,b,b1) - - # constant instances with __init__ vs. __new__ class Thing1: diff --git a/pypy/translator/tool/graphpage.py b/pypy/translator/tool/graphpage.py --- a/pypy/translator/tool/graphpage.py +++ b/pypy/translator/tool/graphpage.py @@ -27,9 +27,6 @@ label += "\\n" + self.createlink(info.origin, 'Originated at') if caused_by is not None: label += '\\n' + self.createlink(caused_by) - if info.caused_by_merge is not None: - data = 'unionof%r' % (info.caused_by_merge,) - label += '\\n%s' % nottoowide(data) dotgen.emit_node('0', shape="box", color="red", label=label) for n, (data, caused_by) in zip(range(len(history)), history): From noreply at buildbot.pypy.org Sun Oct 7 13:00:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 13:00:34 +0200 (CEST) Subject: [pypy-commit] cffi default: Make this particular test always pass or skip. Message-ID: <20121007110034.F1EEC1C0B64@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r982:f8991af91eed Date: 2012-10-07 13:00 +0200 http://bitbucket.org/cffi/cffi/changeset/f8991af91eed/ Log: Make this particular test always pass or skip. diff --git a/testing/test_version.py b/testing/test_version.py --- a/testing/test_version.py +++ b/testing/test_version.py @@ -1,4 +1,4 @@ -import os +import py, os import cffi, _cffi_backend def test_version(): @@ -15,10 +15,14 @@ v = cffi.__version__ assert ("version = '%s'\n" % v) in content assert ("release = '%s'\n" % v) in content - # + +def test_doc_version_file(): + parent = os.path.dirname(os.path.dirname(__file__)) + v = cffi.__version__ p = os.path.join(parent, 'doc', 'source', 'index.rst') content = open(p).read() - assert ("cffi/cffi-%s.tar.gz" % v) in content + if ("cffi/cffi-%s.tar.gz" % v) not in content: + py.test.skip("XXX fix the file referenced by the doc!") def test_setup_version(): parent = os.path.dirname(os.path.dirname(__file__)) From noreply at buildbot.pypy.org Sun Oct 7 13:02:30 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 13:02:30 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: make translator/transform use the new API Message-ID: <20121007110230.4954F1C0B64@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57808:52ba24c94555 Date: 2012-10-07 04:02 -0700 http://bitbucket.org/pypy/pypy/changeset/52ba24c94555/ Log: make translator/transform use the new API diff --git a/pypy/translator/transform.py b/pypy/translator/transform.py --- a/pypy/translator/transform.py +++ b/pypy/translator/transform.py @@ -194,8 +194,7 @@ self.links_followed[errlink] = True # fix the annotation of the exceptblock.inputargs etype, evalue = graph.exceptblock.inputargs - s_type = annmodel.SomeObject() - s_type.knowntype = type + s_type = annmodel.SomeType() s_type.is_type_of = [evalue] s_value = annmodel.SomeInstance(self.bookkeeper.getuniqueclassdef(Exception)) self.setbinding(etype, s_type) From noreply at buildbot.pypy.org Sun Oct 7 14:52:14 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 14:52:14 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix up annotation/test_model Message-ID: <20121007125214.9B1FD1C03FB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57809:3b88de34eb5b Date: 2012-10-07 05:51 -0700 http://bitbucket.org/pypy/pypy/changeset/3b88de34eb5b/ Log: Fix up annotation/test_model diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -9,12 +9,13 @@ listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) +s1 = SomeType() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s1, s2, s3, s4, s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -41,7 +42,7 @@ def test_equality(): assert s1 != s2 != s3 != s4 != s5 != s6 - assert s1 == SomeObject() + assert s1 == SomeType() assert s2 == SomeInteger(nonneg=True) assert s3 == SomeInteger(nonneg=False) assert s4 == SomeList(listdef1) @@ -50,19 +51,11 @@ def test_contains(): assert ([(s,t) for s in slist for t in slist if s.contains(t)] == - [(s1,s1), (s1,s2), (s1,s3), (s1,s4), (s1,s6), - (s2,s2), (s2,s6), - (s3,s2), (s3,s3), (s3,s6), - (s4,s4), (s4,s6), - (s6,s6)]) - -def test_union(): - assert ([unionof(s,t) for s in slist for t in slist] == - [s1, s1, s1, s1, s1, - s1, s2, s3, s1, s2, - s1, s3, s3, s1, s3, - s1, s1, s1, s4, s4, - s1, s2, s3, s4, s6]) + [(s1, s1), (s1, s6), + (s2, s2), (s2, s6), + (s3, s2), (s3, s3), (s3, s6), + (s4, s4), (s4, s6), + (s6, s6)]) def test_commonbase_simple(): class A0: @@ -102,7 +95,7 @@ listdef2 = ListDef(None, SomeInteger(nonneg=False)) s2 = SomeList(listdef2) assert s1 != s2 - assert s2.contains(s1) + assert not s2.contains(s1) assert s1 != s2 assert not s1.contains(s2) assert s1 != s2 From noreply at buildbot.pypy.org Sun Oct 7 15:18:53 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 15:18:53 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Progress into removing allow_someobjects and PyObject from the rtyper Message-ID: <20121007131853.97F311C041E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57810:42d771824b52 Date: 2012-10-07 06:18 -0700 http://bitbucket.org/pypy/pypy/changeset/42d771824b52/ Log: Progress into removing allow_someobjects and PyObject from the rtyper diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -79,6 +79,3 @@ def specialize__ll_and_arg(pol, *args): from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args) - -class StrictAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -3000,7 +3000,6 @@ v = -maxint return intmask(v * 10) P = policy.AnnotatorPolicy() - P.allow_someobjects = False a = self.RPythonAnnotator(policy=P) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py --- a/pypy/jit/codewriter/support.py +++ b/pypy/jit/codewriter/support.py @@ -43,7 +43,6 @@ for key, value in translationoptions.items(): setattr(t.config.translation, key, value) annpolicy = AnnotatorPolicy() - annpolicy.allow_someobjects = False a = t.buildannotator(policy=annpolicy) argtypes = getargtypes(a, values) a.build_types(func, argtypes, main_entry_point=True) diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -275,7 +275,6 @@ t = TranslationContext(config=config) self.t = t # for debugging ann = t.buildannotator() - ann.policy.allow_someobjects = False if func is not None: ann.build_types(func, argtypes, complete_now=False) # diff --git a/pypy/rlib/test/test_timer.py b/pypy/rlib/test/test_timer.py --- a/pypy/rlib/test/test_timer.py +++ b/pypy/rlib/test/test_timer.py @@ -22,7 +22,5 @@ def test_compile_timer(): policy = AnnotatorPolicy() - policy.allow_someobjects = False f_compiled = compile(timer_user, [], annotatorpolicy=policy) f_compiled(expected_extra_mallocs=2) - diff --git a/pypy/rpython/annlowlevel.py b/pypy/rpython/annlowlevel.py --- a/pypy/rpython/annlowlevel.py +++ b/pypy/rpython/annlowlevel.py @@ -38,8 +38,6 @@ __repr__ = __str__ class LowLevelAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False - def __init__(pol, rtyper=None): pol.rtyper = rtyper diff --git a/pypy/rpython/lltypesystem/exceptiondata.py b/pypy/rpython/lltypesystem/exceptiondata.py --- a/pypy/rpython/lltypesystem/exceptiondata.py +++ b/pypy/rpython/lltypesystem/exceptiondata.py @@ -1,11 +1,11 @@ from pypy.annotation import model as annmodel from pypy.rpython.lltypesystem import rclass -from pypy.rpython.lltypesystem.lltype import \ - Array, malloc, Ptr, PyObject, pyobjectptr, \ - FuncType, functionptr, Signed +from pypy.rpython.lltypesystem.lltype import (Array, malloc, Ptr, FuncType, + functionptr, Signed) from pypy.rpython.exceptiondata import AbstractExceptionData from pypy.annotation.classdef import FORCE_ATTRIBUTES_INTO_CLASSES + class ExceptionData(AbstractExceptionData): """Public information for the code generators to help with exceptions.""" @@ -13,7 +13,6 @@ # create helper functionptrs self.fn_exception_match = self.make_exception_matcher(rtyper) self.fn_type_of_exc_inst = self.make_type_of_exc_inst(rtyper) - self.fn_pyexcclass2exc = self.make_pyexcclass2exc(rtyper) self.fn_raise_OSError = self.make_raise_OSError(rtyper) def make_exception_matcher(self, rtyper): @@ -22,87 +21,11 @@ helper_fn = rtyper.annotate_helper_fn(rclass.ll_issubclass, [s_typeptr, s_typeptr]) return helper_fn - def make_type_of_exc_inst(self, rtyper): # ll_type_of_exc_inst(exception_instance) -> exception_vtable s_excinst = annmodel.SomePtr(self.lltype_of_exception_value) helper_fn = rtyper.annotate_helper_fn(rclass.ll_type, [s_excinst]) return helper_fn - - def make_pyexcclass2exc(self, rtyper): - # ll_pyexcclass2exc(python_exception_class) -> exception_instance - table = {} - Exception_def = rtyper.annotator.bookkeeper.getuniqueclassdef(Exception) - for clsdef in rtyper.class_reprs: - if (clsdef and clsdef is not Exception_def - and clsdef.issubclass(Exception_def)): - if not hasattr(clsdef.classdesc, 'pyobj'): - continue - cls = clsdef.classdesc.pyobj - if cls in self.standardexceptions and cls not in FORCE_ATTRIBUTES_INTO_CLASSES: - is_standard = True - assert not clsdef.attrs, ( - "%r should not have grown attributes" % (cls,)) - else: - is_standard = (cls.__module__ == 'exceptions' - and not clsdef.attrs) - if is_standard: - example = self.get_standard_ll_exc_instance(rtyper, clsdef) - table[cls] = example - #else: - # assert cls.__module__ != 'exceptions', ( - # "built-in exceptions should not grow attributes") - r_inst = rclass.getinstancerepr(rtyper, None) - r_inst.setup() - default_excinst = malloc(self.lltype_of_exception_value.TO, - immortal=True) - default_excinst.typeptr = r_inst.rclass.getvtable() - - # build the table in order base classes first, subclasses last - sortedtable = [] - def add_class(cls): - if cls in table: - for base in cls.__bases__: - add_class(base) - sortedtable.append((cls, table[cls])) - del table[cls] - for cls in table.keys(): - add_class(cls) - assert table == {} - #print sortedtable - - A = Array(('pycls', Ptr(PyObject)), - ('excinst', self.lltype_of_exception_value)) - pycls2excinst = malloc(A, len(sortedtable), immortal=True) - for i in range(len(sortedtable)): - cls, example = sortedtable[i] - pycls2excinst[i].pycls = pyobjectptr(cls) - pycls2excinst[i].excinst = example - - FUNCTYPE = FuncType([Ptr(PyObject), Ptr(PyObject)], Signed) - PyErr_GivenExceptionMatches = functionptr( - FUNCTYPE, "PyErr_GivenExceptionMatches", external="C", - _callable=lambda pyobj1, pyobj2: - int(issubclass(pyobj1._obj.value, pyobj2._obj.value))) - - initial_value_of_i = len(pycls2excinst)-1 - - def ll_pyexcclass2exc(python_exception_class): - """Return an RPython instance of the best approximation of the - Python exception identified by its Python class. - """ - i = initial_value_of_i - while i >= 0: - if PyErr_GivenExceptionMatches(python_exception_class, - pycls2excinst[i].pycls): - return pycls2excinst[i].excinst - i -= 1 - return default_excinst - - s_pyobj = annmodel.SomePtr(Ptr(PyObject)) - helper_fn = rtyper.annotate_helper_fn(ll_pyexcclass2exc, [s_pyobj]) - return helper_fn - def cast_exception(self, TYPE, value): return rclass.ll_cast_to_object(value) diff --git a/pypy/rpython/lltypesystem/llheap.py b/pypy/rpython/lltypesystem/llheap.py --- a/pypy/rpython/lltypesystem/llheap.py +++ b/pypy/rpython/lltypesystem/llheap.py @@ -1,6 +1,6 @@ # only for the LLInterpreter. Don't use directly. -from pypy.rpython.lltypesystem.lltype import pyobjectptr, malloc, free, typeOf +from pypy.rpython.lltypesystem.lltype import malloc, free, typeOf from pypy.rpython.lltypesystem.llmemory import weakref_create, weakref_deref setfield = setattr diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py --- a/pypy/rpython/lltypesystem/lltype.py +++ b/pypy/rpython/lltypesystem/lltype.py @@ -268,7 +268,7 @@ if self._names: first = self._names[0] FIRSTTYPE = self._flds[first] - if (isinstance(FIRSTTYPE, (Struct, PyObjectType)) and + if (isinstance(FIRSTTYPE, Struct) and self._gckind == FIRSTTYPE._gckind): return first, FIRSTTYPE return None, None @@ -587,19 +587,6 @@ def _inline_is_varsize(self, last): raise TypeError, "%r cannot be inlined in structure" % self -class PyObjectType(ContainerType): - _gckind = 'cpy' - __name__ = 'PyObject' - def __str__(self): - return "PyObject" - def _inline_is_varsize(self, last): - return False - def _defl(self, parent=None, parentindex=None): - return _pyobject(None) - def _allocate(self, initialization, parent=None, parentindex=None): - return self._defl(parent=parent, parentindex=parentindex) - -PyObject = PyObjectType() class ForwardReference(ContainerType): _gckind = 'raw' @@ -912,8 +899,8 @@ % (CURTYPE, PTRTYPE)) if CURTYPE == PTRTYPE: return 0 - if (not isinstance(CURTYPE.TO, (Struct, PyObjectType)) or - not isinstance(PTRTYPE.TO, (Struct, PyObjectType))): + if (not isinstance(CURTYPE.TO, Struct) or + not isinstance(PTRTYPE.TO, Struct)): raise InvalidCast(CURTYPE, PTRTYPE) CURSTRUC = CURTYPE.TO PTRSTRUC = PTRTYPE.TO @@ -1958,21 +1945,6 @@ return _parentable._normalizedcontainer(self) -class _pyobject(Hashable, _container): - __slots__ = [] # or we get in trouble with pickling - - _TYPE = PyObject - - def __repr__(self): - return '<%s>' % (self,) - - def __str__(self): - return "pyobject %s" % (Hashable.__str__(self),) - - def _getid(self): - return id(self.value) - - def malloc(T, n=None, flavor='gc', immortal=False, zero=False, track_allocation=True, add_memory_pressure=False): assert flavor in ('gc', 'raw') @@ -2063,9 +2035,6 @@ o = _opaque(TYPE, _name=name, **attrs) return _ptr(Ptr(TYPE), o, solid=True) -def pyobjectptr(obj): - o = _pyobject(obj) - return _ptr(Ptr(PyObject), o) def cast_ptr_to_int(ptr): return ptr._cast_to_int() diff --git a/pypy/rpython/lltypesystem/rbuiltin.py b/pypy/rpython/lltypesystem/rbuiltin.py --- a/pypy/rpython/lltypesystem/rbuiltin.py +++ b/pypy/rpython/lltypesystem/rbuiltin.py @@ -5,18 +5,12 @@ from pypy.rpython.lltypesystem.rdict import rtype_r_dict from pypy.rlib import objectmodel from pypy.rpython.rmodel import TyperError, Constant -from pypy.rpython.robject import pyobj_repr from pypy.rpython.rbool import bool_repr def rtype_builtin_isinstance(hop): hop.exception_cannot_occur() if hop.s_result.is_constant(): return hop.inputconst(lltype.Bool, hop.s_result.const) - if hop.args_r[0] == pyobj_repr or hop.args_r[1] == pyobj_repr: - v_obj, v_typ = hop.inputargs(pyobj_repr, pyobj_repr) - c = hop.inputconst(pyobj_repr, isinstance) - v = hop.genop('simple_call', [c, v_obj, v_typ], resulttype = pyobj_repr) - return hop.llops.convertvar(v, pyobj_repr, bool_repr) if hop.args_s[1].is_constant() and hop.args_s[1].const == list: if hop.args_s[0].knowntype != list: @@ -51,12 +45,8 @@ hop.exception_cannot_occur() if hop.s_result.is_constant(): return hop.inputconst(lltype.Bool, hop.s_result.const) - if hop.args_r[0] == pyobj_repr: - v_obj, v_name = hop.inputargs(pyobj_repr, pyobj_repr) - c = hop.inputconst(pyobj_repr, hasattr) - v = hop.genop('simple_call', [c, v_obj, v_name], resulttype = pyobj_repr) - return hop.llops.convertvar(v, pyobj_repr, bool_repr) - raise TyperError("hasattr is only suported on a constant or on PyObject") + + raise TyperError("hasattr is only suported on a constant") BUILTIN_TYPER = {} BUILTIN_TYPER[objectmodel.instantiate] = rtype_instantiate diff --git a/pypy/rpython/lltypesystem/rclass.py b/pypy/rpython/lltypesystem/rclass.py --- a/pypy/rpython/lltypesystem/rclass.py +++ b/pypy/rpython/lltypesystem/rclass.py @@ -14,9 +14,8 @@ cast_pointer, cast_ptr_to_int, castable, nullptr, \ RuntimeTypeInfo, getRuntimeTypeInfo, typeOf, \ Array, Char, Void, \ - FuncType, Bool, Signed, functionptr, PyObject + FuncType, Bool, Signed, functionptr from pypy.rpython.lltypesystem import lltype -from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.extregistry import ExtRegistryEntry from pypy.annotation import model as annmodel from pypy.rlib.rarithmetic import intmask diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py --- a/pypy/rpython/lltypesystem/rstr.py +++ b/pypy/rpython/lltypesystem/rstr.py @@ -8,7 +8,6 @@ from pypy.rlib.debug import ll_assert from pypy.rlib import jit from pypy.rlib.rarithmetic import ovfcheck -from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.rmodel import inputconst, IntegerRepr from pypy.rpython.rstr import AbstractStringRepr,AbstractCharRepr,\ AbstractUniCharRepr, AbstractStringIteratorRepr,\ @@ -16,7 +15,7 @@ from pypy.rpython.lltypesystem import ll_str from pypy.rpython.lltypesystem.lltype import \ GcStruct, Signed, Array, Char, UniChar, Ptr, malloc, \ - Bool, Void, GcArray, nullptr, pyobjectptr, cast_primitive, typeOf,\ + Bool, Void, GcArray, nullptr, cast_primitive, typeOf,\ staticAdtMethod, GcForwardReference from pypy.rpython.rmodel import Repr from pypy.rpython.lltypesystem import llmemory @@ -193,43 +192,8 @@ class UniCharRepr(AbstractUniCharRepr, UnicodeRepr): lowleveltype = UniChar -class __extend__(pairtype(PyObjRepr, AbstractStringRepr)): - def convert_from_to((r_from, r_to), v, llops): - v_len = llops.gencapicall('PyString_Size', [v], resulttype=Signed) - cstr = inputconst(Void, STR) - cflags = inputconst(Void, {'flavor': 'gc'}) - v_result = llops.genop('malloc_varsize', [cstr, cflags, v_len], - resulttype=Ptr(STR)) - llops.gencapicall('PyString_ToRPyString', [v, v_result]) - string_repr = llops.rtyper.type_system.rstr.string_repr - v_result = llops.convertvar(v_result, string_repr, r_to) - return v_result -class __extend__(pairtype(AbstractStringRepr, PyObjRepr)): - def convert_from_to((r_from, r_to), v, llops): - string_repr = llops.rtyper.type_system.rstr.string_repr - v = llops.convertvar(v, r_from, string_repr) - cchars = inputconst(Void, "chars") - # xxx put in table - return llops.gencapicall( - 'PyString_FromRPyString', - [v], - resulttype=pyobj_repr, - _callable=lambda v: pyobjectptr(''.join(v.chars))) - -class __extend__(pairtype(AbstractUnicodeRepr, PyObjRepr)): - def convert_from_to((r_from, r_to), v, llops): - unicode_repr = llops.rtyper.type_system.rstr.unicode_repr - v = llops.convertvar(v, r_from, unicode_repr) - cchars = inputconst(Void, "chars") - # xxx put in table - return llops.gencapicall( - 'PyUnicode_FromRPyUnicode', - [v], - resulttype=pyobj_repr, - _callable=lambda v: pyobjectptr(u''.join(v.chars))) - # ____________________________________________________________ # # Low-level methods. These can be run for testing, but are meant to diff --git a/pypy/rpython/rbool.py b/pypy/rpython/rbool.py --- a/pypy/rpython/rbool.py +++ b/pypy/rpython/rbool.py @@ -3,7 +3,6 @@ from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float from pypy.rpython.error import TyperError from pypy.rpython.rmodel import IntegerRepr, BoolRepr -from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.rmodel import log @@ -62,18 +61,3 @@ log.debug('explicit cast_int_to_bool') return llops.genop('int_is_true', [v], resulttype=Bool) return NotImplemented - -class __extend__(pairtype(PyObjRepr, BoolRepr)): - def convert_from_to((r_from, r_to), v, llops): - if r_to.lowleveltype == Bool: - # xxx put in table - return llops.gencapicall('PyObject_IsTrue', [v], resulttype=Bool, - _callable=lambda pyo: bool(pyo._obj.value)) - return NotImplemented - -class __extend__(pairtype(BoolRepr, PyObjRepr)): - def convert_from_to((r_from, r_to), v, llops): - if r_from.lowleveltype == Bool: - return llops.gencapicall('PyBool_FromLong', [v], - resulttype = pyobj_repr) - return NotImplemented diff --git a/pypy/rpython/rbuiltin.py b/pypy/rpython/rbuiltin.py --- a/pypy/rpython/rbuiltin.py +++ b/pypy/rpython/rbuiltin.py @@ -10,7 +10,6 @@ from pypy.rpython.rrange import rtype_builtin_enumerate from pypy.rpython import rstr from pypy.rpython import rptr -from pypy.rpython.robject import pyobj_repr from pypy.tool import sourcetools from pypy.rpython import extregistry @@ -25,10 +24,7 @@ # built-in method case assert self.methodname is not None result = BuiltinMethodRepr(rtyper, self.s_self, self.methodname) - if result.self_repr == pyobj_repr: - return pyobj_repr # special case: methods of 'PyObject*' - else: - return result + return result def rtyper_makekey(self): if self.s_self is None: # built-in function case diff --git a/pypy/rpython/rdict.py b/pypy/rpython/rdict.py --- a/pypy/rpython/rdict.py +++ b/pypy/rpython/rdict.py @@ -4,7 +4,6 @@ from pypy.rpython.lltypesystem import lltype from pypy.rlib.rarithmetic import r_uint from pypy.rlib.objectmodel import hlinvoke -from pypy.rpython import robject from pypy.rlib import objectmodel from pypy.rpython import rmodel @@ -16,22 +15,18 @@ s_key = dictkey .s_value s_value = dictvalue.s_value force_non_null = self.dictdef.force_non_null - if (s_key.__class__ is annmodel.SomeObject and s_key.knowntype == object and - s_value.__class__ is annmodel.SomeObject and s_value.knowntype == object): - return robject.pyobj_repr + if dictkey.custom_eq_hash: + custom_eq_hash = lambda: (rtyper.getrepr(dictkey.s_rdict_eqfn), + rtyper.getrepr(dictkey.s_rdict_hashfn)) else: - if dictkey.custom_eq_hash: - custom_eq_hash = lambda: (rtyper.getrepr(dictkey.s_rdict_eqfn), - rtyper.getrepr(dictkey.s_rdict_hashfn)) - else: - custom_eq_hash = None - return rtyper.type_system.rdict.DictRepr(rtyper, - lambda: rtyper.getrepr(s_key), - lambda: rtyper.getrepr(s_value), - dictkey, - dictvalue, - custom_eq_hash, - force_non_null) + custom_eq_hash = None + return rtyper.type_system.rdict.DictRepr(rtyper, + lambda: rtyper.getrepr(s_key), + lambda: rtyper.getrepr(s_value), + dictkey, + dictvalue, + custom_eq_hash, + force_non_null) def rtyper_makekey(self): self.dictdef.dictkey .dont_change_any_more = True diff --git a/pypy/rpython/rfloat.py b/pypy/rpython/rfloat.py --- a/pypy/rpython/rfloat.py +++ b/pypy/rpython/rfloat.py @@ -1,13 +1,11 @@ from pypy.tool.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython.lltypesystem.lltype import ( - Signed, Unsigned, SignedLongLong, UnsignedLongLong, - Bool, Float, Void, pyobjectptr) +from pypy.rpython.lltypesystem.lltype import (Signed, Unsigned, SignedLongLong, + UnsignedLongLong, Bool, Float) from pypy.rpython.error import TyperError from pypy.rpython.rmodel import FloatRepr from pypy.rpython.rmodel import IntegerRepr, BoolRepr from pypy.rpython.rstr import AbstractStringRepr -from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.rmodel import log from pypy.rlib.rarithmetic import base_int @@ -196,22 +194,6 @@ return llops.genop('float_is_true', [v], resulttype=Bool) return NotImplemented -class __extend__(pairtype(PyObjRepr, FloatRepr)): - def convert_from_to((r_from, r_to), v, llops): - if r_to.lowleveltype == Float: - return llops.gencapicall('PyFloat_AsDouble', [v], - resulttype=Float, - _callable=lambda pyo: float(pyo._obj.value)) - return NotImplemented - -class __extend__(pairtype(FloatRepr, PyObjRepr)): - def convert_from_to((r_from, r_to), v, llops): - if r_from.lowleveltype == Float: - return llops.gencapicall('PyFloat_FromDouble', [v], - resulttype=pyobj_repr, - _callable=lambda x: pyobjectptr(x)) - return NotImplemented - # ______________________________________________________________________ # Support for r_singlefloat and r_longfloat from pypy.rlib.rarithmetic diff --git a/pypy/rpython/rint.py b/pypy/rpython/rint.py --- a/pypy/rpython/rint.py +++ b/pypy/rpython/rint.py @@ -3,11 +3,10 @@ from pypy.annotation import model as annmodel from pypy.objspace.flow.operation import op_appendices from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float, \ - Void, Char, UniChar, malloc, pyobjectptr, UnsignedLongLong, \ + Void, Char, UniChar, malloc, UnsignedLongLong, \ SignedLongLong, build_number, Number, cast_primitive, typeOf, \ SignedLongLongLong from pypy.rpython.rmodel import IntegerRepr, inputconst -from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rlib.rarithmetic import intmask, r_int, r_uint, r_ulonglong, \ r_longlong, is_emulated_long from pypy.rpython.error import TyperError, MissingRTypeOperation @@ -411,7 +410,7 @@ self = self.as_int varg = hop.inputarg(self, 0) true = inputconst(Bool, True) - fn = hop.rtyper.type_system.ll_str.ll_int2oct + fn = hop.rtyper.type_system.ll_str.ll_int2oct return hop.gendirectcall(fn, varg, true) def ll_hash_int(n): @@ -432,46 +431,3 @@ return else: raise ValueError - -# -# _________________________ Conversions _________________________ - - -py_to_ll_conversion_functions = { - UnsignedLongLong: ('RPyLong_AsUnsignedLongLong', lambda pyo: r_ulonglong(pyo._obj.value)), - SignedLongLong: ('RPyLong_AsLongLong', lambda pyo: r_longlong(pyo._obj.value)), - Unsigned: ('RPyLong_AsUnsignedLong', lambda pyo: r_uint(pyo._obj.value)), - Signed: ('PyInt_AsLong', lambda pyo: int(pyo._obj.value)) -} -if is_emulated_long: # win64 - py_to_ll_conversion_functions.update( { - Unsigned: ('RPyLong_AsUnsignedLongLong', lambda pyo: r_ulonglong(pyo._obj.value)), - Signed: ('RPyLong_AsLongLong', lambda pyo: r_longlong(pyo._obj.value)), - } ) - -ll_to_py_conversion_functions = { - UnsignedLongLong: ('PyLong_FromUnsignedLongLong', lambda i: pyobjectptr(i)), - SignedLongLong: ('PyLong_FromLongLong', lambda i: pyobjectptr(i)), - Unsigned: ('PyLong_FromUnsignedLong', lambda i: pyobjectptr(i)), - Signed: ('PyInt_FromLong', lambda i: pyobjectptr(i)), -} -if is_emulated_long: # win64 - ll_to_py_conversion_functions.update( { - Unsigned: ('PyLong_FromUnsignedLongLong', lambda i: pyobjectptr(i)), - Signed: ('PyLong_FromLongLong', lambda i: pyobjectptr(i)), - } ) - - -class __extend__(pairtype(PyObjRepr, IntegerRepr)): - def convert_from_to((r_from, r_to), v, llops): - tolltype = r_to.lowleveltype - fnname, callable = py_to_ll_conversion_functions[tolltype] - return llops.gencapicall(fnname, [v], - resulttype=r_to, _callable=callable) - -class __extend__(pairtype(IntegerRepr, PyObjRepr)): - def convert_from_to((r_from, r_to), v, llops): - fromlltype = r_from.lowleveltype - fnname, callable = ll_to_py_conversion_functions[fromlltype] - return llops.gencapicall(fnname, [v], - resulttype=pyobj_repr, _callable=callable) diff --git a/pypy/rpython/rlist.py b/pypy/rpython/rlist.py --- a/pypy/rpython/rlist.py +++ b/pypy/rpython/rlist.py @@ -6,7 +6,6 @@ from pypy.rpython.rstr import AbstractStringRepr, AbstractCharRepr from pypy.rpython.lltypesystem.lltype import typeOf, Ptr, Void, Signed, Bool from pypy.rpython.lltypesystem.lltype import nullptr, Char, UniChar, Number -from pypy.rpython import robject from pypy.rlib.objectmodel import malloc_zero_filled from pypy.rlib.debug import ll_assert from pypy.rlib.rarithmetic import ovfcheck, widen, r_uint, intmask @@ -40,8 +39,6 @@ if (listitem.range_step is not None and not listitem.mutated and not isinstance(s_value, annmodel.SomeImpossibleValue)): return rtyper.type_system.rrange.RangeRepr(listitem.range_step) - elif (s_value.__class__ is annmodel.SomeObject and s_value.knowntype == object): - return robject.pyobj_repr else: # cannot do the rtyper.getrepr() call immediately, for the case # of recursive structures -- i.e. if the listdef contains itself @@ -351,15 +348,6 @@ def rtype_newlist(hop, v_sizehint=None): nb_args = hop.nb_args r_list = hop.r_result - if r_list == robject.pyobj_repr: # special case: SomeObject lists! - clist = hop.inputconst(robject.pyobj_repr, list) - v_result = hop.genop('simple_call', [clist], resulttype = robject.pyobj_repr) - cname = hop.inputconst(robject.pyobj_repr, 'append') - v_meth = hop.genop('getattr', [v_result, cname], resulttype = robject.pyobj_repr) - for i in range(nb_args): - v_item = hop.inputarg(robject.pyobj_repr, arg=i) - hop.genop('simple_call', [v_meth, v_item], resulttype = robject.pyobj_repr) - return v_result r_listitem = r_list.item_repr items_v = [hop.inputarg(r_listitem, arg=i) for i in range(nb_args)] return hop.rtyper.type_system.rlist.newlist(hop.llops, r_list, items_v, diff --git a/pypy/rpython/rmodel.py b/pypy/rpython/rmodel.py --- a/pypy/rpython/rmodel.py +++ b/pypy/rpython/rmodel.py @@ -4,7 +4,7 @@ from pypy.objspace.flow.model import Constant from pypy.rpython.lltypesystem.lltype import \ Void, Bool, Float, Signed, Char, UniChar, \ - typeOf, LowLevelType, Ptr, PyObject, isCompatibleType + typeOf, LowLevelType, Ptr, isCompatibleType from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype from pypy.rpython.error import TyperError, MissingRTypeOperation @@ -426,7 +426,6 @@ return '%s_%s' % (prefix, name) # __________ utilities __________ -PyObjPtr = Ptr(PyObject) def getgcflavor(classdef): classdesc = classdef.classdesc diff --git a/pypy/rpython/rpbc.py b/pypy/rpython/rpbc.py --- a/pypy/rpython/rpbc.py +++ b/pypy/rpython/rpbc.py @@ -10,7 +10,6 @@ from pypy.rpython.rmodel import Repr, inputconst, CanBeNull, \ mangle, inputdesc, warning, impossible_repr from pypy.rpython import rclass -from pypy.rpython import robject from pypy.rpython.annlowlevel import llstr, llunicode from pypy.rpython import callparse @@ -44,10 +43,6 @@ elif issubclass(kind, description.ClassDesc): # user classes getRepr = rtyper.type_system.rpbc.ClassesPBCRepr - # XXX what about this? -## elif type(x) is type and x.__module__ in sys.builtin_module_names: -## # special case for built-in types, seen in faking -## getRepr = getPyObjRepr elif issubclass(kind, description.MethodDesc): getRepr = rtyper.type_system.rpbc.MethodsPBCRepr elif issubclass(kind, description.FrozenDesc): @@ -57,11 +52,6 @@ else: raise TyperError("unexpected PBC kind %r"%(kind,)) -## elif isinstance(x, builtin_descriptor_type): -## # strange built-in functions, method objects, etc. from fake.py -## getRepr = getPyObjRepr - - return getRepr(rtyper, self) def rtyper_makekey(self): @@ -363,9 +353,6 @@ def rtype_simple_call(self, hop): from pypy.rpython.rspecialcase import rtype_call_specialcase return rtype_call_specialcase(hop) - -def getPyObjRepr(rtyper, s_pbc): - return robject.pyobj_repr def getFrozenPBCRepr(rtyper, s_pbc): descs = list(s_pbc.descriptions) diff --git a/pypy/rpython/rtyper.py b/pypy/rpython/rtyper.py --- a/pypy/rpython/rtyper.py +++ b/pypy/rpython/rtyper.py @@ -15,6 +15,7 @@ import py from pypy.tool.pairtype import pair from pypy.annotation import model as annmodel +from pypy.annotation.annrpython import FAIL from pypy.objspace.flow.model import Variable, Constant from pypy.objspace.flow.model import SpaceOperation, c_last_exception from pypy.rpython.lltypesystem.lltype import \ @@ -185,7 +186,7 @@ assert result is not None # recursive getrepr()! return result - def binding(self, var, default=annmodel.SomeObject()): + def binding(self, var, default=FAIL): s_obj = self.annotator.binding(var, default) return s_obj @@ -1017,7 +1018,6 @@ # _______________________________________________________________________ # this has the side-effect of registering the unary and binary operations # and the rtyper_chooserepr() methods -from pypy.rpython import robject from pypy.rpython import rint, rbool, rfloat from pypy.rpython import rrange from pypy.rpython import rstr, rdict, rlist diff --git a/pypy/rpython/test/test_extfunc.py b/pypy/rpython/test/test_extfunc.py --- a/pypy/rpython/test/test_extfunc.py +++ b/pypy/rpython/test/test_extfunc.py @@ -27,7 +27,6 @@ return b(2) policy = AnnotatorPolicy() - policy.allow_someobjects = False a = RPythonAnnotator(policy=policy) s = a.build_types(f, []) assert isinstance(s, annmodel.SomeInteger) @@ -79,7 +78,6 @@ return d(callback) policy = AnnotatorPolicy() - policy.allow_someobjects = False a = RPythonAnnotator(policy=policy) s = a.build_types(f, []) assert isinstance(s, annmodel.SomeFloat) @@ -97,7 +95,6 @@ return dd(3) policy = AnnotatorPolicy() - policy.allow_someobjects = False a = RPythonAnnotator(policy=policy) s = a.build_types(f, []) assert isinstance(s, annmodel.SomeInteger) @@ -120,7 +117,6 @@ return function_with_tuple_arg((1,)) policy = AnnotatorPolicy() - policy.allow_someobjects = False a = RPythonAnnotator(policy=policy) s = a.build_types(f, []) @@ -145,7 +141,6 @@ return function_with_list(function_returning_list()) policy = AnnotatorPolicy() - policy.allow_someobjects = False a = RPythonAnnotator(policy=policy) s = a.build_types(f, []) assert isinstance(s, annmodel.SomeInteger) @@ -163,7 +158,6 @@ return x(33) + x("aaa") + x([]) + "\n" policy = AnnotatorPolicy() - policy.allow_someobjects = False a = RPythonAnnotator(policy=policy) s = a.build_types(f, []) assert isinstance(s, annmodel.SomeString) @@ -176,7 +170,6 @@ def f(s): return os_open(s) policy = AnnotatorPolicy() - policy.allow_someobjects = False a = RPythonAnnotator(policy=policy) a.build_types(f, [str]) # Does not raise assert a.translator.config.translation.check_str_without_nul == False @@ -195,7 +188,6 @@ def f(l): return os_execve(l) policy = AnnotatorPolicy() - policy.allow_someobjects = False a = RPythonAnnotator(policy=policy) a.build_types(f, [[str]]) # Does not raise assert a.translator.config.translation.check_str_without_nul == False diff --git a/pypy/rpython/test/test_llinterp.py b/pypy/rpython/test/test_llinterp.py --- a/pypy/rpython/test/test_llinterp.py +++ b/pypy/rpython/test/test_llinterp.py @@ -1,22 +1,19 @@ from __future__ import with_statement import py import sys -from pypy.rpython.lltypesystem.lltype import typeOf, pyobjectptr, Ptr,\ - PyObject, Void, malloc, free -from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rpython.llinterp import LLInterpreter, LLException, log +from pypy.rpython.lltypesystem.lltype import typeOf, Void, malloc, free +from pypy.rpython.llinterp import LLInterpreter, LLException from pypy.rpython.rmodel import inputconst from pypy.rpython.annlowlevel import hlstr from pypy.translator.translator import TranslationContext, graphof -from pypy.rpython.rint import signed_repr -from pypy.rpython.lltypesystem import rstr, lltype +from pypy.rpython.lltypesystem import lltype from pypy.annotation import model as annmodel from pypy.annotation.model import lltype_to_annotation from pypy.rlib.rarithmetic import r_uint, ovfcheck -from pypy.rpython.ootypesystem import ootype from pypy.tool import leakfinder from pypy import conftest + # switch on logging of interp to show more info on failing tests def setup_module(mod): @@ -71,27 +68,23 @@ _tcache.clear() def get_interpreter(func, values, view='auto', viewbefore='auto', policy=None, - someobjects=False, type_system="lltype", backendopt=False, - config=None, **extraconfigopts): + type_system="lltype", backendopt=False, config=None, + **extraconfigopts): extra_key = [(key, value) for key, value in extraconfigopts.iteritems()] extra_key.sort() extra_key = tuple(extra_key) key = ((func,) + tuple([typeOf(x) for x in values]) + - (someobjects, backendopt, extra_key)) - try: + (backendopt, extra_key)) + try: (t, interp, graph) = _tcache[key] except KeyError: def annotation(x): T = typeOf(x) - if T == Ptr(PyObject) and someobjects: - return object - else: - return lltype_to_annotation(T) + return lltype_to_annotation(T) - if policy is None and not someobjects: + if policy is None: from pypy.annotation.policy import AnnotatorPolicy policy = AnnotatorPolicy() - policy.allow_someobjects = False t, typer, graph = gengraph(func, [annotation(x) for x in values], viewbefore, policy, type_system=type_system, @@ -110,10 +103,10 @@ return interp, graph def interpret(func, values, view='auto', viewbefore='auto', policy=None, - someobjects=False, type_system="lltype", backendopt=False, - config=None, malloc_check=True, **kwargs): + type_system="lltype", backendopt=False, config=None, + malloc_check=True, **kwargs): interp, graph = get_interpreter(func, values, view, viewbefore, policy, - someobjects, type_system=type_system, + type_system=type_system, backendopt=backendopt, config=config, **kwargs) if not malloc_check: @@ -129,10 +122,10 @@ return result def interpret_raises(exc, func, values, view='auto', viewbefore='auto', - policy=None, someobjects=False, type_system="lltype", + policy=None, type_system="lltype", backendopt=False): interp, graph = get_interpreter(func, values, view, viewbefore, policy, - someobjects, type_system=type_system, + type_system=type_system, backendopt=backendopt) info = py.test.raises(LLException, "interp.eval_graph(graph, values)") try: @@ -269,21 +262,6 @@ res = interpret(f, [3]) assert res == 3 -##def test_unicode(): -## def f(): -## return u'Hello world' -## res = interpret(f, [], someobjects=True) - -## assert res._obj.value == u'Hello world' - -##def test_unicode_split(): -## def f(): -## res = u'Hello world'.split() -## return u' '.join(res) -## res = interpret(f,[],True) -## -## assert res == u'Hello world' - def test_list_reverse(): def f(): l = [1,2,3] @@ -305,14 +283,6 @@ res = interpret(f,[]) assert len(res.ll_items()) == 3 -def test_obj_obj_add(): - def f(x,y): - return x+y - _1L = pyobjectptr(1L) - _2L = pyobjectptr(2L) - res = interpret(f, [_1L, _2L], someobjects=True) - assert res._obj.value == 3L - def test_ovf(): def f(x): try: @@ -367,14 +337,6 @@ assert res == (-sys.maxint - 1) % 30 -def test_obj_obj_is(): - def f(x,y): - return x is y - o = pyobjectptr(object()) - res = interpret(f, [o, o], someobjects=True) - assert res is True - - def test_funny_links(): from pypy.objspace.flow.model import Block, FunctionGraph, \ SpaceOperation, Variable, Constant, Link diff --git a/pypy/rpython/test/test_rpbc.py b/pypy/rpython/test/test_rpbc.py --- a/pypy/rpython/test/test_rpbc.py +++ b/pypy/rpython/test/test_rpbc.py @@ -1660,8 +1660,6 @@ return -1 class P(policy.AnnotatorPolicy): - allow_someobjects = False - def specialize__w(pol, funcdesc, args_s): typ = args_s[1].knowntype if args_s[0].is_constant() and args_s[1].is_constant(): diff --git a/pypy/tool/test/test_error.py b/pypy/tool/test/test_error.py --- a/pypy/tool/test/test_error.py +++ b/pypy/tool/test/test_error.py @@ -3,17 +3,14 @@ """ from pypy.translator.translator import TranslationContext -from pypy.tool.error import AnnotatorError, NoSuchAttrError -from pypy.annotation.policy import BasicAnnotatorPolicy +from pypy.tool.error import AnnotatorError import py -class Policy(BasicAnnotatorPolicy): - allow_someobjects = False def compile_function(function, annotation=[]): t = TranslationContext() - t.buildannotator(policy=Policy()).build_types(function, annotation) + t.buildannotator().build_types(function, annotation) class AAA(object): pass diff --git a/pypy/translator/c/src/exception.h b/pypy/translator/c/src/exception.h --- a/pypy/translator/c/src/exception.h +++ b/pypy/translator/c/src/exception.h @@ -2,25 +2,10 @@ /************************************************************/ /*** C header subsection: exceptions ***/ -#if defined(PYPY_CPYTHON_EXTENSION) && !defined(PYPY_NOT_MAIN_FILE) - PyObject *RPythonError; -#endif - /* just a renaming, unless DO_LOG_EXC is set */ #define RPyExceptionOccurred RPyExceptionOccurred1 #define RPY_DEBUG_RETURN() /* nothing */ -#ifndef PyExceptionClass_Check /* Python < 2.5 */ -# define PyExceptionClass_Check(x) PyClass_Check(x) -# define PyExceptionInstance_Check(x) PyInstance_Check(x) -# define PyExceptionInstance_Class(x) \ - (PyObject*)((PyInstanceObject*)(x))->in_class -#endif - - -/******************************************************************/ -#ifdef HAVE_RTYPER /* RPython version of exceptions */ -/******************************************************************/ #ifdef DO_LOG_EXC #undef RPyExceptionOccurred @@ -69,11 +54,6 @@ #define RPyRaiseSimpleException(exc, msg) _RPyRaiseSimpleException(R##exc) void _RPyRaiseSimpleException(RPYTHON_EXCEPTION rexc); -#ifndef PYPY_STANDALONE -void RPyConvertExceptionFromCPython(void); -void RPyConvertExceptionToCPython(void); -#endif - /* implementations */ #ifndef PYPY_NOT_MAIN_FILE @@ -83,82 +63,4 @@ /* XXX msg is ignored */ RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc); } - -#ifdef PYPY_CPYTHON_EXTENSION -void RPyConvertExceptionFromCPython(void) -{ - /* convert the CPython exception to an RPython one */ - PyObject *exc_type, *exc_value, *exc_tb; - RPYTHON_EXCEPTION rexc; - - assert(PyErr_Occurred()); - assert(!RPyExceptionOccurred()); - PyErr_Fetch(&exc_type, &exc_value, &exc_tb); - - /* XXX losing the error message here */ - rexc = RPYTHON_PYEXCCLASS2EXC(exc_type); - RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc); -} - -void RPyConvertExceptionToCPython(void) -{ - /* XXX 1. uses officially bad fishing */ - /* XXX 2. looks for exception classes by name, fragile */ - char* clsname; - PyObject *pycls, *v, *tb; - assert(RPyExceptionOccurred()); - assert(!PyErr_Occurred()); - clsname = RPyFetchExceptionType()->ov_name->items; - v = NULL; - if (strcmp(clsname, "AssertionError") == 0) { - /* workaround against the py lib's BuiltinAssertionError */ - pycls = PyExc_AssertionError; - } - else if (strcmp(clsname, "StackOverflow") == 0) { - pycls = PyExc_RuntimeError; - } - else { - pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); - if (pycls == NULL || !PyExceptionClass_Check(pycls) || - !PyObject_IsSubclass(pycls, PyExc_Exception)) { - pycls = PyExc_Exception; /* XXX RPythonError */ - v = PyString_FromString(clsname); - } - } - Py_INCREF(pycls); - tb = NULL; - RPyClearException(); - - PyErr_NormalizeException(&pycls, &v, &tb); - PyErr_Restore(pycls, v, tb); -} -#endif /* !PYPY_STANDALONE */ - #endif /* PYPY_NOT_MAIN_FILE */ - - - -/******************************************************************/ -#else /* non-RPython version of exceptions, using CPython only */ -/******************************************************************/ - -#define RPyExceptionOccurred1() PyErr_Occurred() -#define RPyRaiseException(etype, evalue) PyErr_Restore(etype, evalue, NULL) -#define RPyFetchException(etypevar, evaluevar, ignored) do { \ - PyObject *__tb; \ - PyErr_Fetch(&etypevar, &evaluevar, &__tb); \ - if (evaluevar == NULL) { \ - evaluevar = Py_None; \ - Py_INCREF(Py_None); \ - } \ - Py_XDECREF(__tb); \ - } while (0) -#define RPyConvertExceptionFromCPython() /* nothing */ -#define RPyConvertExceptionToCPython(vanishing) vanishing = NULL - -#define RPyRaiseSimpleException(exc, msg) \ - PyErr_SetString(exc, msg) - -/******************************************************************/ -#endif /* HAVE_RTYPER */ -/******************************************************************/ diff --git a/pypy/translator/c/support.py b/pypy/translator/c/support.py --- a/pypy/translator/c/support.py +++ b/pypy/translator/c/support.py @@ -7,8 +7,6 @@ # USESLOTS = True -PyObjPtr = lltype.Ptr(lltype.PyObject) - def barebonearray(ARRAY): """Check if ARRAY is a 'simple' array type, i.e. doesn't need a length nor GC headers.""" @@ -59,23 +57,17 @@ return isinstance(T.TO, lltype.ForwardReference) def llvalue_from_constant(c): - try: - T = c.concretetype - except AttributeError: - T = PyObjPtr - if T == PyObjPtr and not isinstance(c.value, lltype._ptr): - return lltype.pyobjectptr(c.value) + T = c.concretetype + if T == lltype.Void: + return None else: - if T == lltype.Void: - return None - else: - ACTUAL_TYPE = lltype.typeOf(c.value) - # If the type is still uncomputed, we can't make this - # check. Something else will blow up instead, probably - # very confusingly. - if not is_pointer_to_forward_ref(ACTUAL_TYPE): - assert ACTUAL_TYPE == T - return c.value + ACTUAL_TYPE = lltype.typeOf(c.value) + # If the type is still uncomputed, we can't make this + # check. Something else will blow up instead, probably + # very confusingly. + if not is_pointer_to_forward_ref(ACTUAL_TYPE): + assert ACTUAL_TYPE == T + return c.value class CNameManager(NameManager): diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py --- a/pypy/translator/driver.py +++ b/pypy/translator/driver.py @@ -188,8 +188,6 @@ if policy is None: policy = annpolicy.AnnotatorPolicy() - if standalone: - policy.allow_someobjects = False self.policy = policy self.extra = extra @@ -345,22 +343,6 @@ lost = query.qoutput(query.check_methods_qgen(translator)) assert not lost, "lost methods, something gone wrong with the annotation of method defs" - so = query.qoutput(query.polluted_qgen(translator)) - tot = len(translator.graphs) - percent = int(tot and (100.0*so / tot) or 0) - # if there are a few SomeObjects even if the policy doesn't allow - # them, it means that they were put there in a controlled way - # and then it's not a warning. - if not translator.annotator.policy.allow_someobjects: - pr = self.log.info - elif percent == 0: - pr = self.log.info - else: - pr = log.WARNING - pr("-- someobjectness %2d%% (%d of %d functions polluted by SomeObjects)" % (percent, so, tot)) - - - def task_rtype_lltype(self): """ RTyping - lltype version """ diff --git a/pypy/translator/goal/ann_override.py b/pypy/translator/goal/ann_override.py --- a/pypy/translator/goal/ann_override.py +++ b/pypy/translator/goal/ann_override.py @@ -19,8 +19,6 @@ class PyPyAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False - def __init__(pol, single_space=None): pol.lookups = {} pol.lookups_where = {} diff --git a/pypy/translator/goal/sharedpypy.py b/pypy/translator/goal/sharedpypy.py --- a/pypy/translator/goal/sharedpypy.py +++ b/pypy/translator/goal/sharedpypy.py @@ -6,7 +6,6 @@ from pypy.tool.option import make_objspace from pypy.interpreter.error import OperationError from pypy.config.pypyoption import pypy_optiondescription, set_pypy_opt_level -from pypy.interpreter.pyopcode import prepare_exec from pypy.translator.goal.ann_override import PyPyAnnotatorPolicy from pypy.config.translationoption import set_opt_level from pypy.config.pypyoption import enable_allworkingmodules @@ -26,8 +25,7 @@ enable_allworkingmodules(config) space = make_objspace(config) - policy = PyPyAnnotatorPolicy(single_space = space) - policy.allow_someobjects = False + policy = PyPyAnnotatorPolicy(single_space=space) def interpret(source, context): source = charp2str(source) From noreply at buildbot.pypy.org Sun Oct 7 15:20:38 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 15:20:38 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, arigato) really remove these files Message-ID: <20121007132038.9B2911C041E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57811:d841b47e2987 Date: 2012-10-07 06:20 -0700 http://bitbucket.org/pypy/pypy/changeset/d841b47e2987/ Log: (alex, arigato) really remove these files diff --git a/pypy/rpython/robject.py b/pypy/rpython/robject.py deleted file mode 100644 --- a/pypy/rpython/robject.py +++ /dev/null @@ -1,84 +0,0 @@ -from pypy.tool.pairtype import pairtype -from pypy.annotation import model as annmodel -from pypy.rpython.lltypesystem.lltype import \ - PyObject, Ptr, Void, pyobjectptr, nullptr, Bool -from pypy.rpython.rmodel import Repr, VoidRepr, inputconst -from pypy.rpython import rclass -from pypy.tool.sourcetools import func_with_new_name - - -class __extend__(annmodel.SomeObject): - def rtyper_makerepr(self, rtyper): - kind = getkind(self) - if kind == "type": - return rclass.get_type_repr(rtyper) - elif kind == "const": - return constpyobj_repr - else: - return pyobj_repr - def rtyper_makekey(self): - return self.__class__, getkind(self) - -def getkind(s_obj): - if s_obj.is_constant(): - if getattr(s_obj.const, '__module__', None) == '__builtin__': - return "const" - if s_obj.knowntype is type: - return "type" - if s_obj.is_constant(): - return "const" - return "pyobj" - - -class PyObjRepr(Repr): - def convert_const(self, value): - return pyobjectptr(value) - def make_iterator_repr(self): - return pyobj_repr - -pyobj_repr = PyObjRepr() -pyobj_repr.lowleveltype = Ptr(PyObject) -constpyobj_repr = PyObjRepr() -constpyobj_repr.lowleveltype = Void - - -class __extend__(pairtype(VoidRepr, PyObjRepr)): - # conversion used to return a PyObject* when a function can really only - # raise an exception, in which case the return value is a VoidRepr - def convert_from_to(_, v, llops): - return inputconst(Ptr(PyObject), nullptr(PyObject)) - - -# ____________________________________________________________ -# -# All operations involving a PyObjRepr are "replaced" by themselves, -# after converting all other arguments to PyObjRepr as well. This -# basically defers the operations to the care of the code generator. - -def make_operation(opname, cls=PyObjRepr): - def rtype_op(_, hop): - vlist = hop.inputargs(*([pyobj_repr]*hop.nb_args)) - hop.exception_is_here() - v = hop.genop(opname, vlist, resulttype=pyobj_repr) - if not isinstance(hop.r_result, VoidRepr): - return hop.llops.convertvar(v, pyobj_repr, hop.r_result) - - funcname = 'rtype_' + opname - func = func_with_new_name(rtype_op, funcname) - assert funcname not in cls.__dict__ # can be in Repr; overridden then. - setattr(cls, funcname, func) - - -for opname in annmodel.UNARY_OPERATIONS: - make_operation(opname) - -for opname in annmodel.BINARY_OPERATIONS: - make_operation(opname, pairtype(PyObjRepr, Repr)) - make_operation(opname, pairtype(Repr, PyObjRepr)) - - -class __extend__(pairtype(PyObjRepr, PyObjRepr)): - def rtype_contains((r_seq, r_item), hop): - v_seq, v_item = hop.inputargs(r_seq, r_item) - return hop.llops.gencapicall('PySequence_Contains_with_exc', - [v_seq, v_item], resulttype=Bool) diff --git a/pypy/translator/c/src/pyobj.h b/pypy/translator/c/src/pyobj.h deleted file mode 100644 --- a/pypy/translator/c/src/pyobj.h +++ /dev/null @@ -1,265 +0,0 @@ - -/************************************************************/ - /*** C header subsection: untyped operations ***/ - /*** as OP_XXX() macros calling the CPython API ***/ -#ifdef PYPY_CPYTHON_EXTENSION - -#define op_bool(r,what) { \ - int _retval = what; \ - if (_retval < 0) {CFAIL(); } \ - else \ - r = PyBool_FromLong(_retval); \ - } - -#define op_richcmp(x,y,r,dir) \ - if (!(r=PyObject_RichCompare(x,y,dir))) CFAIL() -#define OP_LT(x,y,r) op_richcmp(x,y,r, Py_LT) -#define OP_LE(x,y,r) op_richcmp(x,y,r, Py_LE) -#define OP_EQ(x,y,r) op_richcmp(x,y,r, Py_EQ) -#define OP_NE(x,y,r) op_richcmp(x,y,r, Py_NE) -#define OP_GT(x,y,r) op_richcmp(x,y,r, Py_GT) -#define OP_GE(x,y,r) op_richcmp(x,y,r, Py_GE) - -#define OP_IS_(x,y,r) op_bool(r,(x == y)) - -#define OP_IS_TRUE(x,r) op_bool(r,PyObject_IsTrue(x)) -#define OP_NONZERO(x,r) op_bool(r,PyObject_IsTrue(x)) - -#define OP_LEN(x,r) do { \ - int _retval = PyObject_Size(x); \ - if (_retval < 0) { CFAIL(); } \ - else \ - r = PyInt_FromLong(_retval); \ - } while (0) -#define OP_NEG(x,r) if (!(r=PyNumber_Negative(x))) CFAIL() -#define OP_POS(x,r) if (!(r=PyNumber_Positive(x))) CFAIL() -#define OP_INVERT(x,r) if (!(r=PyNumber_Invert(x))) CFAIL() -#define OP_ABS(x,r) if (!(r=PyNumber_Absolute(x))) CFAIL() - -#define OP_ADD(x,y,r) if (!(r=PyNumber_Add(x,y))) CFAIL() -#define OP_SUB(x,y,r) if (!(r=PyNumber_Subtract(x,y))) CFAIL() -#define OP_MUL(x,y,r) if (!(r=PyNumber_Multiply(x,y))) CFAIL() -#define OP_TRUEDIV(x,y,r) if (!(r=PyNumber_TrueDivide(x,y))) CFAIL() -#define OP_FLOORDIV(x,y,r) if (!(r=PyNumber_FloorDivide(x,y)))CFAIL() -#define OP_DIV(x,y,r) if (!(r=PyNumber_Divide(x,y))) CFAIL() -#define OP_MOD(x,y,r) if (!(r=PyNumber_Remainder(x,y))) CFAIL() -#define OP_DIVMOD(x,y,r) if (!(r=PyNumber_Divmod(x,y))) CFAIL() -#define OP_POW(x,y,z,r) if (!(r=PyNumber_Power(x,y,z))) CFAIL() -#define OP_LSHIFT(x,y,r) if (!(r=PyNumber_Lshift(x,y))) CFAIL() -#define OP_RSHIFT(x,y,r) if (!(r=PyNumber_Rshift(x,y))) CFAIL() -#define OP_AND_(x,y,r) if (!(r=PyNumber_And(x,y))) CFAIL() -#define OP_OR_(x,y,r) if (!(r=PyNumber_Or(x,y))) CFAIL() -#define OP_XOR(x,y,r) if (!(r=PyNumber_Xor(x,y))) CFAIL() - -#define OP_INPLACE_ADD(x,y,r) if (!(r=PyNumber_InPlaceAdd(x,y))) \ - CFAIL() -#define OP_INPLACE_SUB(x,y,r) if (!(r=PyNumber_InPlaceSubtract(x,y))) \ - CFAIL() -#define OP_INPLACE_MUL(x,y,r) if (!(r=PyNumber_InPlaceMultiply(x,y))) \ - CFAIL() -#define OP_INPLACE_TRUEDIV(x,y,r) if (!(r=PyNumber_InPlaceTrueDivide(x,y)))\ - CFAIL() -#define OP_INPLACE_FLOORDIV(x,y,r)if(!(r=PyNumber_InPlaceFloorDivide(x,y)))\ - CFAIL() -#define OP_INPLACE_DIV(x,y,r) if (!(r=PyNumber_InPlaceDivide(x,y))) \ - CFAIL() -#define OP_INPLACE_MOD(x,y,r) if (!(r=PyNumber_InPlaceRemainder(x,y))) \ - CFAIL() -#define OP_INPLACE_POW(x,y,r) if (!(r=PyNumber_InPlacePower(x,y,Py_None))) \ - CFAIL() -#define OP_INPLACE_LSHIFT(x,y,r) if (!(r=PyNumber_InPlaceLshift(x,y))) \ - CFAIL() -#define OP_INPLACE_RSHIFT(x,y,r) if (!(r=PyNumber_InPlaceRshift(x,y))) \ - CFAIL() -#define OP_INPLACE_AND(x,y,r) if (!(r=PyNumber_InPlaceAnd(x,y))) \ - CFAIL() -#define OP_INPLACE_OR(x,y,r) if (!(r=PyNumber_InPlaceOr(x,y))) \ - CFAIL() -#define OP_INPLACE_XOR(x,y,r) if (!(r=PyNumber_InPlaceXor(x,y))) \ - CFAIL() - -#define OP_GETITEM(x,y,r) if (!(r=PyObject_GetItem1(x,y))) CFAIL() -#define OP_SETITEM(x,y,z,r) if ((PyObject_SetItem1(x,y,z))<0) {CFAIL(); }\ - else \ - r=Py_None; Py_INCREF(r) -#define OP_DELITEM(x,y,r) if ((PyObject_DelItem(x,y))<0) CFAIL();\ - r=Py_None; Py_INCREF(r) -#define OP_CONTAINS(x,y,r) op_bool(r,(PySequence_Contains(x,y))) - -#define OP_GETATTR(x,y,r) if (!(r=PyObject_GetAttr(x,y))) CFAIL() -#define OP_SETATTR(x,y,z,r) if ((PyObject_SetAttr(x,y,z))<0) {CFAIL();}\ - else \ - r=Py_None; Py_INCREF(r) -#define OP_DELATTR(x,y,r) if ((PyObject_SetAttr(x,y,NULL))<0) {CFAIL();}\ - else \ - r=Py_None; Py_INCREF(r) - -#define OP_NEWSLICE(x,y,z,r) if (!(r=PySlice_New(x,y,z))) CFAIL() - -#define OP_GETSLICE(x,y,z,r) { \ - PyObject *__yo = y, *__zo = z; \ - int __y = 0, __z = INT_MAX; \ - if (__yo == Py_None) __yo = NULL; \ - if (__zo == Py_None) __zo = NULL; \ - if (!_PyEval_SliceIndex(__yo, &__y) || \ - !_PyEval_SliceIndex(__zo, &__z) || \ - !(r=PySequence_GetSlice(x, __y, __z))) CFAIL(); \ - } - -#define OP_ALLOC_AND_SET(x,y,r) { \ - /* XXX check for long/int overflow */ \ - int __i, __x = PyInt_AsLong(x); \ - if (PyErr_Occurred()) CFAIL(); \ - else { \ - if (!(r = PyList_New(__x))) CFAIL(); \ - else { \ - for (__i=0; __i<__x; __i++) { \ - Py_INCREF(y); \ - PyList_SET_ITEM(r, __i, y); \ - } \ - } \ - } \ - } - -#define OP_ITER(x,r) if (!(r=PyObject_GetIter(x))) CFAIL() -#define OP_NEXT(x,r) if (!(r=PyIter_Next(x))) { \ - if (!PyErr_Occurred()) PyErr_SetNone(PyExc_StopIteration); \ - CFAIL(); \ - } - -#define OP_STR(x,r) if (!(r=PyObject_Str(x))) CFAIL() -#define OP_REPR(x,r) if (!(r=PyObject_Repr(x))) CFAIL() -#define OP_ORD(s,r) { \ - char *__c = PyString_AsString(s); \ - int __len; \ - if ( !__c) CFAIL(); \ - else { \ - if ((__len = PyString_GET_SIZE(s)) != 1) { \ - PyErr_Format(PyExc_TypeError, \ - "ord() expected a character, but string of length %d found", \ - __len); \ - CFAIL(); \ - } \ - else if (!(r = PyInt_FromLong((unsigned char)(__c[0])))) \ - { CFAIL(); }\ - } \ - } -#define OP_ID(x,r) if (!(r=PyLong_FromVoidPtr(x))) CFAIL() -#define OP_HASH(x,r) { \ - long __hash = PyObject_Hash(x); \ - if (__hash == -1 && PyErr_Occurred()) CFAIL(); \ - else if (!(r = PyInt_FromLong(__hash))) { CFAIL(); } \ - } - -#define OP_HEX(x,r) { \ - PyNumberMethods *__nb; \ - if ((__nb = x->ob_type->tp_as_number) == NULL || \ - __nb->nb_hex == NULL) { \ - PyErr_SetString(PyExc_TypeError, \ - "hex() argument can't be converted to hex"); \ - CFAIL(); \ - } \ - else if (!(r = (*__nb->nb_hex)(x))) { CFAIL(); } \ - } -#define OP_OCT(x,r) { \ - PyNumberMethods *__nb; \ - if ((__nb = x->ob_type->tp_as_number) == NULL || \ - __nb->nb_oct == NULL) { \ - PyErr_SetString(PyExc_TypeError, \ - "oct() argument can't be converted to oct"); \ - CFAIL(); \ - } \ - else if (!(r = (*__nb->nb_oct)(x))) { CFAIL(); } \ - } - -#define OP_INT(x,r) { \ - long __val = PyInt_AsLong(x); \ - if (__val == -1 && PyErr_Occurred()) CFAIL(); \ - else if (!(r = PyInt_FromLong(__val))) { CFAIL (); } \ - } -#define OP_FLOAT(x,r) { \ - double __val = PyFloat_AsDouble(x); \ - if (PyErr_Occurred()) CFAIL(); \ - else if (!(r = PyFloat_FromDouble(__val))) { CFAIL (); } \ - } - -#define OP_CMP(x,y,r) { \ - int __val = PyObject_Compare(x, y); \ - if (PyErr_Occurred()) CFAIL(); \ - else if (!(r = PyInt_FromLong(__val))) { CFAIL (); }\ - } - - -#define OP_SIMPLE_CALL(args,r) if (!(r=PyObject_CallFunctionObjArgs args)) \ - CFAIL() -#define OP_CALL_ARGS(args,r) if (!(r=CallWithShape args)) CFAIL() - -/* Needs to act like getattr(x, '__class__', type(x)) */ -#define OP_TYPE(x,r) { \ - PyObject *o = x; \ - if (PyInstance_Check(o)) { \ - r = (PyObject*)(((PyInstanceObject*)o)->in_class); \ - } else { \ - r = (PyObject*)o->ob_type; \ - } \ - Py_INCREF(r); \ - } - -/* Needs to act like instance(x,y) */ -#define OP_ISSUBTYPE(x,y,r) \ - op_bool(r,PyObject_IsSubclass(x, y)) - - -/*** operations with a variable number of arguments ***/ - -#define OP_NEWLIST0(r) if (!(r=PyList_New(0))) CFAIL() -#define OP_NEWLIST(args,r) if (!(r=PyList_Pack args)) CFAIL() -#define OP_NEWDICT0(r) if (!(r=PyDict_New())) CFAIL() -#define OP_NEWDICT(args,r) if (!(r=PyDict_Pack args)) CFAIL() -#define OP_NEWTUPLE(args,r) if (!(r=PyTuple_Pack args)) CFAIL() - -unsigned long long RPyLong_AsUnsignedLongLong(PyObject *v); -long long RPyLong_AsLongLong(PyObject *v); - -#ifndef PYPY_NOT_MAIN_FILE - -#if (PY_VERSION_HEX < 0x02040000) - -unsigned long RPyLong_AsUnsignedLong(PyObject *v) -{ - if (PyInt_Check(v)) { - long val = PyInt_AsLong(v); - if (val < 0) { - PyErr_SetNone(PyExc_OverflowError); - return (unsigned long)-1; - } - return val; - } else { - return PyLong_AsUnsignedLong(v); - } -} - -#else -#define RPyLong_AsUnsignedLong PyLong_AsUnsignedLong -#endif - - -unsigned long long RPyLong_AsUnsignedLongLong(PyObject *v) -{ - if (PyInt_Check(v)) - return PyInt_AsLong(v); - else - return PyLong_AsUnsignedLongLong(v); -} - -long long RPyLong_AsLongLong(PyObject *v) -{ - if (PyInt_Check(v)) - return PyInt_AsLong(v); - else - return PyLong_AsLongLong(v); -} - -#endif - -#endif /* PYPY_CPYTHON_EXTENSION */ From noreply at buildbot.pypy.org Sun Oct 7 15:23:28 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 15:23:28 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, arigo) Reintroduce this very complicated logic. Message-ID: <20121007132328.C0C031C041E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57812:d3601d984ff2 Date: 2012-10-07 15:23 +0200 http://bitbucket.org/pypy/pypy/changeset/d3601d984ff2/ Log: (alex, arigo) Reintroduce this very complicated logic. diff --git a/pypy/rpython/rclass.py b/pypy/rpython/rclass.py --- a/pypy/rpython/rclass.py +++ b/pypy/rpython/rclass.py @@ -173,6 +173,12 @@ def rtyper_makekey(self): return self.__class__, self.classdef +class __extend__(annmodel.SomeType): + def rtyper_makerepr(self, rtyper): + return get_type_repr(rtyper) + def rtyper_makekey(self): + return self.__class__, + class AbstractInstanceRepr(Repr): def __init__(self, rtyper, classdef): From noreply at buildbot.pypy.org Sun Oct 7 15:33:47 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 15:33:47 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, arigato) fix some of the exception lgoic and remove pyobject stuff from rtuple Message-ID: <20121007133347.6F8C91C041E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57813:c5fb330531e5 Date: 2012-10-07 06:33 -0700 http://bitbucket.org/pypy/pypy/changeset/c5fb330531e5/ Log: (alex, arigato) fix some of the exception lgoic and remove pyobject stuff from rtuple diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -144,13 +144,8 @@ def find_exception(self, exc): assert isinstance(exc, LLException) klass, inst = exc.args[0], exc.args[1] - exdata = self.typer.getexceptiondata() - frame = self.frame_class(None, [], self) for cls in enumerate_exceptions_top_down(): - evalue = frame.op_direct_call(exdata.fn_pyexcclass2exc, - lltype.pyobjectptr(cls)) - etype = frame.op_direct_call(exdata.fn_type_of_exc_inst, evalue) - if etype == klass: + if "".join(klass.name).rstrip("\0") == cls.__name__: return cls raise ValueError("couldn't match exception, maybe it" " has RPython attributes like OSError?") @@ -427,7 +422,7 @@ if exc_data: etype = e.args[0] evalue = e.args[1] - exc_data.exc_type = etype + exc_data.exc_type = etype exc_data.exc_value = evalue from pypy.translator import exceptiontransform retval = exceptiontransform.error_value( diff --git a/pypy/rpython/lltypesystem/rtuple.py b/pypy/rpython/lltypesystem/rtuple.py --- a/pypy/rpython/lltypesystem/rtuple.py +++ b/pypy/rpython/lltypesystem/rtuple.py @@ -1,6 +1,5 @@ from pypy.tool.pairtype import pairtype from pypy.rpython.rmodel import inputconst -from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.rtuple import AbstractTupleRepr, AbstractTupleIteratorRepr from pypy.rpython.lltypesystem.lltype import \ Ptr, GcStruct, Void, Signed, malloc, typeOf, nullptr @@ -83,36 +82,6 @@ def dum_empty_tuple(): pass -# -# _________________________ Conversions _________________________ - -class __extend__(pairtype(PyObjRepr, TupleRepr)): - def convert_from_to((r_from, r_to), v, llops): - vlist = [] - for i in range(len(r_to.items_r)): - ci = inputconst(Signed, i) - v_item = llops.gencapicall('PyTuple_GetItem_WithIncref', [v, ci], - resulttype = pyobj_repr) - v_converted = llops.convertvar(v_item, pyobj_repr, - r_to.items_r[i]) - vlist.append(v_converted) - return r_to.newtuple(llops, r_to, vlist) - -class __extend__(pairtype(TupleRepr, PyObjRepr)): - def convert_from_to((r_from, r_to), v, llops): - ci = inputconst(Signed, len(r_from.items_r)) - v_result = llops.gencapicall('PyTuple_New', [ci], - resulttype = pyobj_repr) - for i in range(len(r_from.items_r)): - cname = inputconst(Void, r_from.fieldnames[i]) - v_item = llops.genop('getfield', [v, cname], - resulttype = r_from.external_items_r[i].lowleveltype) - v_converted = llops.convertvar(v_item, r_from.external_items_r[i], - pyobj_repr) - ci = inputconst(Signed, i) - llops.gencapicall('PyTuple_SetItem_WithIncref', [v_result, ci, - v_converted]) - return v_result # ____________________________________________________________ # From noreply at buildbot.pypy.org Sun Oct 7 15:34:52 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 15:34:52 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: We removed knowntype from the base class, so need to re-add it here. Message-ID: <20121007133452.A27A11C041E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57814:3e9ec97ae758 Date: 2012-10-07 15:34 +0200 http://bitbucket.org/pypy/pypy/changeset/3e9ec97ae758/ Log: We removed knowntype from the base class, so need to re-add it here. diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -505,6 +505,7 @@ class SomeAddress(SomeObject): immutable = True + knowntype = llmemory.Address def can_be_none(self): return False From noreply at buildbot.pypy.org Sun Oct 7 15:40:15 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 15:40:15 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Bah, nonsense. Re-add 'knowntype=object' and be done. Message-ID: <20121007134015.E91701C03FB@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57815:92afff50badd Date: 2012-10-07 15:39 +0200 http://bitbucket.org/pypy/pypy/changeset/92afff50badd/ Log: Bah, nonsense. Re-add 'knowntype=object' and be done. diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -47,6 +47,7 @@ for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype immutable = False + knowntype = object def __init__(self): assert type(self) is not SomeObject @@ -505,7 +506,6 @@ class SomeAddress(SomeObject): immutable = True - knowntype = llmemory.Address def can_be_none(self): return False From noreply at buildbot.pypy.org Sun Oct 7 16:30:15 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 16:30:15 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Slow progress. Did not find a better way than listing by hand Message-ID: <20121007143015.9DF281C041E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57816:8b728bceee27 Date: 2012-10-07 16:29 +0200 http://bitbucket.org/pypy/pypy/changeset/8b728bceee27/ Log: Slow progress. Did not find a better way than listing by hand the exceptions in make_raise_noarg(). diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -444,7 +444,8 @@ elif isinstance(x, (ootype._object)): result = SomeOOObject() elif tp is type: - if x is type(None): # add cases here if needed + if (x is type(None) or # add cases here if needed + x.__module__ == 'pypy.rpython.lltypesystem.lltype'): result = SomeType() else: result = SomePBC([self.getdesc(x)]) diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -189,7 +189,7 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if not isinstance(s_type, SomeBuiltin): + if isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -80,14 +80,14 @@ return SomeUnicodeString() elif t is types.NoneType: return s_None - elif t is type: - return SomeType() elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes: classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) + elif t is type: + return SomeType() else: raise AssertionError("annotationoftype(%r)" % (t,)) diff --git a/pypy/rpython/exceptiondata.py b/pypy/rpython/exceptiondata.py --- a/pypy/rpython/exceptiondata.py +++ b/pypy/rpython/exceptiondata.py @@ -51,6 +51,18 @@ classdef = bk.getuniqueclassdef(cls) rclass.getclassrepr(rtyper, classdef).setup() + def make_raise_noarg(self, rtyper): + def ll_raise_noarg(classname): + if classname == 'OverflowError': + raise OverflowError + if classname == 'ValueError': + raise ValueError + if classname == 'ZeroDivisionError': + raise ZeroDivisionError + raise NotImplementedError # we did not special-case this so far + helper_fn = rtyper.annotate_helper_fn(ll_raise_noarg, [annmodel.SomeString()]) + return helper_fn + def make_raise_OSError(self, rtyper): # ll_raise_OSError(errno) def ll_raise_OSError(errno): diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -459,13 +459,11 @@ exdata = typer.getexceptiondata() if isinstance(exc, OSError): self.op_direct_call(exdata.fn_raise_OSError, exc.errno) - assert False, "op_direct_call above should have raised" else: - exc_class = exc.__class__ - evalue = self.op_direct_call(exdata.fn_pyexcclass2exc, - self.heap.pyobjectptr(exc_class)) - etype = self.op_direct_call(exdata.fn_type_of_exc_inst, evalue) - raise LLException(etype, evalue, *extraargs) + exc_class = exc.__class__.__name__ + llname = typer.type_system.rstr.string_repr.convert_const(exc_class) + self.op_direct_call(exdata.fn_raise_noarg, llname) + assert False, "op_direct_call above should have raised" def invoke_callable_with_pyexceptions(self, fptr, *args): obj = self.llinterpreter.typer.type_system.deref(fptr) diff --git a/pypy/rpython/lltypesystem/exceptiondata.py b/pypy/rpython/lltypesystem/exceptiondata.py --- a/pypy/rpython/lltypesystem/exceptiondata.py +++ b/pypy/rpython/lltypesystem/exceptiondata.py @@ -14,6 +14,7 @@ self.fn_exception_match = self.make_exception_matcher(rtyper) self.fn_type_of_exc_inst = self.make_type_of_exc_inst(rtyper) self.fn_raise_OSError = self.make_raise_OSError(rtyper) + self.fn_raise_noarg = self.make_raise_noarg(rtyper) def make_exception_matcher(self, rtyper): # ll_exception_matcher(real_exception_vtable, match_exception_vtable) diff --git a/pypy/rpython/ootypesystem/exceptiondata.py b/pypy/rpython/ootypesystem/exceptiondata.py --- a/pypy/rpython/ootypesystem/exceptiondata.py +++ b/pypy/rpython/ootypesystem/exceptiondata.py @@ -21,9 +21,9 @@ def make_helpers(self, rtyper): self.fn_exception_match = self.make_exception_matcher(rtyper) - self.fn_pyexcclass2exc = self.make_pyexcclass2exc(rtyper) self.fn_type_of_exc_inst = self.make_type_of_exc_inst(rtyper) self.fn_raise_OSError = self.make_raise_OSError(rtyper) + self.fn_raise_noarg = self.make_raise_noarg(rtyper) def make_exception_matcher(self, rtyper): # ll_exception_matcher(real_exception_class, match_exception_class) @@ -38,64 +38,5 @@ helper_fn = rtyper.annotate_helper_fn(rclass.ll_inst_type, [s_excinst]) return helper_fn - def make_pyexcclass2exc(self, rtyper): - # ll_pyexcclass2exc(python_exception_class) -> exception_instance - table = {} - Exception_def = rtyper.annotator.bookkeeper.getuniqueclassdef(Exception) - for clsdef in rtyper.class_reprs: - if (clsdef and clsdef is not Exception_def - and clsdef.issubclass(Exception_def)): - if not hasattr(clsdef.classdesc, 'pyobj'): - continue - cls = clsdef.classdesc.pyobj - if cls in self.standardexceptions and cls not in FORCE_ATTRIBUTES_INTO_CLASSES: - is_standard = True - assert not clsdef.attrs, ( - "%r should not have grown attributes" % (cls,)) - else: - is_standard = (cls.__module__ == 'exceptions' - and not clsdef.attrs) - if is_standard: - example = self.get_standard_ll_exc_instance(rtyper, clsdef) - table[cls] = example - r_inst = rclass.getinstancerepr(rtyper, None) - r_inst.setup() - r_class = rclass.getclassrepr(rtyper, None) - r_class.setup() - default_excinst = ootype.new(self.lltype_of_exception_value) - - # build the table in order base classes first, subclasses last - sortedtable = [] - def add_class(cls): - if cls in table: - for base in cls.__bases__: - add_class(base) - sortedtable.append((cls, table[cls])) - del table[cls] - for cls in table.keys(): - add_class(cls) - assert table == {} - - initial_value_of_i = len(sortedtable) - 1 - def pyexcclass2exc(python_exception_class): - python_exception_class = python_exception_class._obj.value - i = initial_value_of_i - while i >= 0: - if issubclass(python_exception_class, sortedtable[i][0]): - return sortedtable[i][1] - i -= 1 - return default_excinst - - # This function will only be used by the llinterpreter which usually - # expects a low-level callable (_meth, _static_meth), so we just - # fake it here. - FakeCallableType = ootype.OOType() - FakeCallableType.ARGS = () - class fake_callable(object): - def __init__(self, fn): - self._TYPE = FakeCallableType - self._callable = fn - return fake_callable(pyexcclass2exc) - def cast_exception(self, TYPE, value): return ootype.ooupcast(TYPE, value) diff --git a/pypy/translator/tool/graphpage.py b/pypy/translator/tool/graphpage.py --- a/pypy/translator/tool/graphpage.py +++ b/pypy/translator/tool/graphpage.py @@ -106,22 +106,14 @@ name = 'no_graph' self.source = make_dot_graphs(name, gs, target=None) # make the dictionary of links -- one per annotated variable - self.binding_history = {} self.current_value = {} - self.caused_by = {} if self.annotator: for var, s_value in self.annotator.bindings.items(): info = '%s: %s' % (var.name, s_value) annotationcolor = getattr(s_value, 'annotationcolor', None) self.links[var.name] = info, annotationcolor self.current_value[var.name] = s_value - self.caused_by[var.name] = ( - self.annotator.binding_caused_by.get(var)) - for var, history in self.annotator.bindingshistory.items(): - cause_history = ( - self.annotator.binding_cause_history.get(var, [])) - self.binding_history[var.name] = zip(history, cause_history) - + #from pypy.jit.hintannotator.annotator import HintAnnotator #if isinstance(self.annotator, HintAnnotator): # return @@ -145,15 +137,6 @@ info = info, (160,160,160) self.links[var.name] = info - def followlink(self, varname): - # clicking on a variable name shows its binding history - cur_value = self.current_value[varname] - caused_by = self.caused_by[varname] - history = list(self.binding_history.get(varname, [])) - history.reverse() - return VariableHistoryGraphPage(self.translator, varname, cur_value, - caused_by, history, self.func_names) - class SingleGraphPage(FlowGraphPage): """ A GraphPage showing a single precomputed FlowGraph.""" From noreply at buildbot.pypy.org Sun Oct 7 16:31:48 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 16:31:48 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: A bunch more. Message-ID: <20121007143148.30EAF1C041E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57817:03894bc023c5 Date: 2012-10-07 16:31 +0200 http://bitbucket.org/pypy/pypy/changeset/03894bc023c5/ Log: A bunch more. diff --git a/pypy/rpython/exceptiondata.py b/pypy/rpython/exceptiondata.py --- a/pypy/rpython/exceptiondata.py +++ b/pypy/rpython/exceptiondata.py @@ -59,6 +59,16 @@ raise ValueError if classname == 'ZeroDivisionError': raise ZeroDivisionError + if classname == 'MemoryError': + raise MemoryError + if classname == 'IOError': + raise IOError + if classname == 'StopIteration': + raise StopIteration + if classname == 'KeyError': + raise KeyError + if classname == 'IndexError': + raise IndexError raise NotImplementedError # we did not special-case this so far helper_fn = rtyper.annotate_helper_fn(ll_raise_noarg, [annmodel.SomeString()]) return helper_fn From noreply at buildbot.pypy.org Sun Oct 7 16:35:05 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 16:35:05 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: remove robject from rdict Message-ID: <20121007143505.507B81C041E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57818:361aead052f6 Date: 2012-10-07 07:34 -0700 http://bitbucket.org/pypy/pypy/changeset/361aead052f6/ Log: remove robject from rdict diff --git a/pypy/rpython/ootypesystem/rdict.py b/pypy/rpython/ootypesystem/rdict.py --- a/pypy/rpython/ootypesystem/rdict.py +++ b/pypy/rpython/ootypesystem/rdict.py @@ -1,19 +1,12 @@ from pypy.rpython.error import TyperError from pypy.tool.pairtype import pairtype -from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant -from pypy.rpython.rdict import AbstractDictRepr, AbstractDictIteratorRepr,\ - rtype_newdict -from pypy.rpython.rpbc import MethodOfFrozenPBCRepr,\ - AbstractFunctionsPBCRepr, AbstractMethodsPBCRepr +from pypy.rpython.rdict import AbstractDictRepr, AbstractDictIteratorRepr +from pypy.rpython.rpbc import (MethodOfFrozenPBCRepr, AbstractFunctionsPBCRepr, + AbstractMethodsPBCRepr) from pypy.rpython.ootypesystem import ootype -from pypy.rpython.ootypesystem.rlist import ll_newlist -from pypy.rlib.rarithmetic import r_uint -from pypy.rlib.objectmodel import hlinvoke -from pypy.rpython import robject from pypy.rlib import objectmodel -from pypy.rpython import rmodel -from pypy.rpython import llinterp +from pypy.rpython import rmodel, llinterp class DictRepr(AbstractDictRepr): From noreply at buildbot.pypy.org Sun Oct 7 16:45:02 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 16:45:02 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Added rtyper_makekey to StringBuilder Message-ID: <20121007144502.0A5DC1C041E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57819:5397353bd973 Date: 2012-10-07 07:44 -0700 http://bitbucket.org/pypy/pypy/changeset/5397353bd973/ Log: Added rtyper_makekey to StringBuilder diff --git a/pypy/rlib/rstring.py b/pypy/rlib/rstring.py --- a/pypy/rlib/rstring.py +++ b/pypy/rlib/rstring.py @@ -134,6 +134,10 @@ def rtyper_makerepr(self, rtyper): return rtyper.type_system.rbuilder.stringbuilder_repr + def rtyper_makekey(self): + return self.__class__, + + class SomeUnicodeBuilder(SomeObject): def method_append(self, s_str): if s_str != s_None: @@ -166,6 +170,10 @@ def rtyper_makerepr(self, rtyper): return rtyper.type_system.rbuilder.unicodebuilder_repr + def rtyper_makekey(self): + return self.__class__, + + class BaseEntry(object): def compute_result_annotation(self, s_init_size=None): if s_init_size is not None: @@ -177,29 +185,35 @@ def specialize_call(self, hop): return hop.r_result.rtyper_new(hop) + class StringBuilderEntry(BaseEntry, ExtRegistryEntry): _about_ = StringBuilder use_unicode = False + class UnicodeBuilderEntry(BaseEntry, ExtRegistryEntry): _about_ = UnicodeBuilder use_unicode = True + class __extend__(pairtype(SomeStringBuilder, SomePBC)): def union((sb, p)): assert p.const is None return SomeStringBuilder(can_be_None=True) + class __extend__(pairtype(SomePBC, SomeStringBuilder)): def union((p, sb)): assert p.const is None return SomeStringBuilder(can_be_None=True) + class __extend__(pairtype(SomeUnicodeBuilder, SomePBC)): def union((sb, p)): assert p.const is None return SomeUnicodeBuilder(can_be_None=True) + class __extend__(pairtype(SomePBC, SomeUnicodeBuilder)): def union((p, sb)): assert p.const is None diff --git a/pypy/rpython/lltypesystem/rbuilder.py b/pypy/rpython/lltypesystem/rbuilder.py --- a/pypy/rpython/lltypesystem/rbuilder.py +++ b/pypy/rpython/lltypesystem/rbuilder.py @@ -1,7 +1,6 @@ from pypy.rlib import rgc, jit from pypy.rlib.objectmodel import enforceargs from pypy.rlib.rarithmetic import ovfcheck -from pypy.rpython.annlowlevel import llstr from pypy.rpython.rptr import PtrRepr from pypy.rpython.lltypesystem import lltype, rstr from pypy.rpython.lltypesystem.lltype import staticAdtMethod, nullptr @@ -13,7 +12,7 @@ # Think about heuristics below, maybe we can come up with something # better or at least compare it with list heuristics -GROW_FAST_UNTIL = 100*1024*1024 # 100 MB +GROW_FAST_UNTIL = 100 * 1024 * 1024 # 100 MB def new_grow_func(name, mallocfn, copycontentsfn): @enforceargs(None, int) diff --git a/pypy/rpython/rbuilder.py b/pypy/rpython/rbuilder.py --- a/pypy/rpython/rbuilder.py +++ b/pypy/rpython/rbuilder.py @@ -1,9 +1,9 @@ - from pypy.rpython.rmodel import Repr from pypy.rpython.lltypesystem import lltype from pypy.rlib.rstring import INIT_SIZE from pypy.annotation.model import SomeChar, SomeUnicodeCodePoint + class AbstractStringBuilderRepr(Repr): def rtyper_new(self, hop): if len(hop.args_v) == 0: @@ -53,7 +53,7 @@ vlist = hop.inputargs(self) hop.exception_cannot_occur() return hop.gendirectcall(self.ll_is_true, *vlist) - + def convert_const(self, value): if not value is None: raise TypeError("Prebuilt builedrs that are not none unsupported") From noreply at buildbot.pypy.org Sun Oct 7 16:52:24 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 16:52:24 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (arigato, alex) kill a test of an implementation detail Message-ID: <20121007145224.47C1B1C0B64@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57820:a12d86d5ef94 Date: 2012-10-07 16:51 +0200 http://bitbucket.org/pypy/pypy/changeset/a12d86d5ef94/ Log: (arigato, alex) kill a test of an implementation detail diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -116,10 +116,11 @@ def can_be_none(self): return True - + def nonnoneify(self): return self + class SomeType(SomeObject): "Stands for a type. We might not be sure which one it is." knowntype = type diff --git a/pypy/rpython/test/test_exception.py b/pypy/rpython/test/test_exception.py --- a/pypy/rpython/test/test_exception.py +++ b/pypy/rpython/test/test_exception.py @@ -3,7 +3,7 @@ from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rpython.llinterp import LLException -from pypy.rpython.error import MissingRTypeOperation +from pypy.rpython.error import MissingRTypeOperation class MyException(Exception): pass @@ -32,31 +32,6 @@ rtype(dummyfn) - -def test_exception_data(): - def f(n): - raise OverflowError() - - t = rtype(f, [int]) - - excdata = t.rtyper.getexceptiondata() - getcdef = t.annotator.bookkeeper.getuniqueclassdef - - #t.view() - ovferr_inst = excdata.fn_pyexcclass2exc(pyobjectptr(OverflowError)) - classdef = getcdef(OverflowError) - assert ovferr_inst.typeptr == t.rtyper.class_reprs[classdef].getvtable() - - taberr_inst = excdata.fn_pyexcclass2exc(pyobjectptr(TabError)) - classdef = getcdef(StandardError) # most precise class seen - assert taberr_inst.typeptr == t.rtyper.class_reprs[classdef].getvtable() - - myerr_inst = excdata.fn_pyexcclass2exc(pyobjectptr(MyException)) - assert myerr_inst.typeptr == t.rtyper.class_reprs[None].getvtable() - - strgerr_inst = excdata.fn_pyexcclass2exc(pyobjectptr(MyStrangeException)) - assert strgerr_inst.typeptr == t.rtyper.class_reprs[None].getvtable() - class BaseTestException(BaseRtypingTest): def test_exception_with_arg(self): def g(n): From noreply at buildbot.pypy.org Sun Oct 7 17:17:48 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 17:17:48 +0200 (CEST) Subject: [pypy-commit] pypy default: Use StringBuilder here too. Message-ID: <20121007151748.1794C1C0B64@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57821:95dbd25adece Date: 2012-10-07 17:16 +0200 http://bitbucket.org/pypy/pypy/changeset/95dbd25adece/ Log: Use StringBuilder here too. 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 @@ -185,7 +185,7 @@ return stream.readline() else: # very inefficient unless there is a peek() - result = [] + result = StringBuilder() while size > 0: # "peeks" on the underlying stream to see how many chars # we can safely read without reading past an end-of-line @@ -200,7 +200,7 @@ if c.endswith('\n'): break size -= len(c) - return ''.join(result) + return result.build() @unwrap_spec(size=int) def direct_readlines(self, size=0): From noreply at buildbot.pypy.org Sun Oct 7 17:17:49 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 17:17:49 +0200 (CEST) Subject: [pypy-commit] pypy default: Disable ReadlineInputStream for now. Needs thinking... Message-ID: <20121007151749.4BE5C1C0B64@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57822:ff186eda82f9 Date: 2012-10-07 17:17 +0200 http://bitbucket.org/pypy/pypy/changeset/ff186eda82f9/ Log: Disable ReadlineInputStream for now. Needs thinking... 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 @@ -428,6 +428,18 @@ pass assert f.subclass_closed + def test_readline_unbuffered_should_read_one_line_only(self): + import posix + + with self.file(self.temppath, 'w') as f: + f.write('foo\nbar\n') + + with self.file(self.temppath, 'r', 0) as f: + s = f.readline() + assert s == 'foo\n' + s = posix.read(f.fileno(), 10) + assert s == 'bar\n' + def test_flush_at_exit(): from pypy import conftest from pypy.tool.option import make_config, make_objspace diff --git a/pypy/rlib/streamio.py b/pypy/rlib/streamio.py --- a/pypy/rlib/streamio.py +++ b/pypy/rlib/streamio.py @@ -141,8 +141,11 @@ def construct_stream_tower(stream, buffering, universal, reading, writing, binary): if buffering == 0: # no buffering - if reading: # force some minimal buffering for readline() - stream = ReadlineInputStream(stream) + # XXX we cannot really use ReadlineInputStream: see module/_file/ + # test/test_file.py:test_readline_unbuffered_should_read_one_line_only + pass + #if reading: # force some minimal buffering for readline() + # stream = ReadlineInputStream(stream) elif buffering == 1: # line-buffering if writing: stream = LineBufferingOutputStream(stream) From noreply at buildbot.pypy.org Sun Oct 7 17:45:13 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 17:45:13 +0200 (CEST) Subject: [pypy-commit] pypy default: Redo a solution that is very inefficient but maybe not as bad as before. Message-ID: <20121007154513.AFB291C0B64@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57823:52c909884ae5 Date: 2012-10-07 17:44 +0200 http://bitbucket.org/pypy/pypy/changeset/52c909884ae5/ Log: Redo a solution that is very inefficient but maybe not as bad as before. diff --git a/pypy/rlib/streamio.py b/pypy/rlib/streamio.py --- a/pypy/rlib/streamio.py +++ b/pypy/rlib/streamio.py @@ -41,6 +41,7 @@ from pypy.rlib.objectmodel import specialize, we_are_translated from pypy.rlib.rarithmetic import r_longlong, intmask from pypy.rlib import rposix +from pypy.rlib.rstring import StringBuilder from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC O_BINARY = getattr(os, "O_BINARY", 0) @@ -141,11 +142,7 @@ def construct_stream_tower(stream, buffering, universal, reading, writing, binary): if buffering == 0: # no buffering - # XXX we cannot really use ReadlineInputStream: see module/_file/ - # test/test_file.py:test_readline_unbuffered_should_read_one_line_only pass - #if reading: # force some minimal buffering for readline() - # stream = ReadlineInputStream(stream) elif buffering == 1: # line-buffering if writing: stream = LineBufferingOutputStream(stream) @@ -306,6 +303,26 @@ raise # else try again + def readline(self): + # mostly inefficient, but not as laughably bad as with the default + # readline() from Stream + result = StringBuilder() + while True: + try: + c = os.read(self.fd, 1) + except OSError, e: + if e.errno != errno.EINTR: + raise + else: + continue # try again + if not c: + break + c = c[0] + result.append(c) + if c == '\n': + break + return result.build() + def write(self, data): while data: try: @@ -703,113 +720,6 @@ flush_buffers=False) -class ReadlineInputStream(Stream): - - """Minimal buffering input stream. - - Only does buffering for readline(). The other kinds of reads, and - all writes, are not buffered at all. - """ - - bufsize = 2**13 # 8 K - - def __init__(self, base, bufsize=-1): - self.base = base - self.do_read = base.read # function to fill buffer some more - self.do_seek = base.seek # seek to a byte offset - if bufsize == -1: # Get default from the class - bufsize = self.bufsize - self.bufsize = bufsize # buffer size (hint only) - self.buf = None # raw data (may contain "\n") - self.bufstart = 0 - - def flush_buffers(self): - if self.buf is not None: - try: - self.do_seek(self.bufstart-len(self.buf), 1) - except (MyNotImplementedError, OSError): - pass - else: - self.buf = None - self.bufstart = 0 - - def readline(self): - if self.buf is not None: - i = self.buf.find('\n', self.bufstart) - else: - self.buf = '' - i = -1 - # - if i < 0: - self.buf = self.buf[self.bufstart:] - self.bufstart = 0 - while True: - bufsize = max(self.bufsize, len(self.buf) >> 2) - data = self.do_read(bufsize) - if not data: - result = self.buf # end-of-file reached - self.buf = None - return result - startsearch = len(self.buf) # there is no '\n' in buf so far - self.buf += data - i = self.buf.find('\n', startsearch) - if i >= 0: - break - # - i += 1 - result = self.buf[self.bufstart:i] - self.bufstart = i - return result - - def peek(self): - if self.buf is None: - return '' - if self.bufstart > 0: - self.buf = self.buf[self.bufstart:] - self.bufstart = 0 - return self.buf - - def tell(self): - pos = self.base.tell() - if self.buf is not None: - pos -= (len(self.buf) - self.bufstart) - return pos - - def readall(self): - result = self.base.readall() - if self.buf is not None: - result = self.buf[self.bufstart:] + result - self.buf = None - self.bufstart = 0 - return result - - def read(self, n): - if self.buf is None: - return self.do_read(n) - else: - m = n - (len(self.buf) - self.bufstart) - start = self.bufstart - if m > 0: - result = self.buf[start:] + self.do_read(m) - self.buf = None - self.bufstart = 0 - return result - elif n >= 0: - self.bufstart = start + n - return self.buf[start : self.bufstart] - else: - return '' - - seek = PassThrough("seek", flush_buffers=True) - write = PassThrough("write", flush_buffers=True) - truncate = PassThrough("truncate", flush_buffers=True) - flush = PassThrough("flush", flush_buffers=True) - flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) - try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", - flush_buffers=False) - - class BufferingOutputStream(Stream): """Standard buffering output stream. diff --git a/pypy/rlib/test/test_streamio.py b/pypy/rlib/test/test_streamio.py --- a/pypy/rlib/test/test_streamio.py +++ b/pypy/rlib/test/test_streamio.py @@ -1026,7 +1026,7 @@ base.tell = f if not seek: base.seek = f - return streamio.ReadlineInputStream(base, bufsize) + return base def test_readline(self): for file in [self.makeStream(), self.makeStream(bufsize=2)]: From noreply at buildbot.pypy.org Sun Oct 7 17:50:25 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 17:50:25 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, fijal) kill nonsense Message-ID: <20121007155025.D8FE21C0B64@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57824:93067e51258a Date: 2012-10-07 17:49 +0200 http://bitbucket.org/pypy/pypy/changeset/93067e51258a/ Log: (alex, fijal) kill nonsense diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -167,9 +167,6 @@ self.stats = Stats(self) - # used in SomeObject.__new__ for keeping debugging info - self._isomeobject_coming_from = identity_dict() - delayed_imports() def count(self, category, *args): @@ -477,11 +474,11 @@ elif x is None: return s_None else: - result = SomeObject() + raise Exception("Don't know how to represent %r" % (x,)) if need_const: result.const = x return result - + def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -247,13 +247,16 @@ defs_s = [] if graph is None: signature = self.signature - defaults = self.defaults + defaults = self.defaults else: signature = graph.signature - defaults = graph.defaults + defaults = graph.defaults if defaults: for x in defaults: - defs_s.append(self.bookkeeper.immutablevalue(x)) + if x is NODEFAULT: + defs_s.append(None) + else: + defs_s.append(self.bookkeeper.immutablevalue(x)) try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py --- a/pypy/objspace/flow/model.py +++ b/pypy/objspace/flow/model.py @@ -5,7 +5,6 @@ # a discussion in Berlin, 4th of october 2003 import py from pypy.tool.uid import uid, Hashable -from pypy.tool.descriptor import roproperty from pypy.tool.sourcetools import PY_IDENTIFIER, nice_repr_for_func from pypy.rlib.rarithmetic import is_valid_int, r_longlong, r_ulonglong, r_uint @@ -34,8 +33,6 @@ class FunctionGraph(object): - __slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__'] - def __init__(self, name, startblock, return_var=None): self.name = name # function name (possibly mangled already) self.startblock = startblock @@ -56,23 +53,23 @@ def getreturnvar(self): return self.returnblock.inputargs[0] - def getsource(self): + @property + def source(self): from pypy.tool.sourcetools import getsource func = self.func # can raise AttributeError src = getsource(self.func) if src is None: raise AttributeError('source not found') return src - source = roproperty(getsource) - - def getstartline(self): + + @property + def startline(self): return self.func.func_code.co_firstlineno - startline = roproperty(getstartline) - - def getfilename(self): + + @property + def filename(self): return self.func.func_code.co_filename - filename = roproperty(getfilename) - + def __str__(self): if hasattr(self, 'func'): return nice_repr_for_func(self.func, self.name) diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py --- a/pypy/rpython/lltypesystem/lloperation.py +++ b/pypy/rpython/lltypesystem/lloperation.py @@ -3,7 +3,6 @@ """ from pypy.rpython.extregistry import ExtRegistryEntry -from pypy.tool.descriptor import roproperty class LLOp(object): @@ -65,7 +64,10 @@ val = lltype.enforce(RESULTTYPE, val) return val - def get_fold_impl(self): + @property + def fold(self): + if hasattr(self, "_fold"): + return self._fold global lltype # <- lazy import hack, worth an XXX from pypy.rpython.lltypesystem import lltype if self.canrun: @@ -80,9 +82,8 @@ def op_impl(*args): raise error # cache the implementation function into 'self' - self.fold = op_impl + self._fold = op_impl return op_impl - fold = roproperty(get_fold_impl) def is_pure(self, args_v): if self.canfold: # canfold => pure operation diff --git a/pypy/rpython/normalizecalls.py b/pypy/rpython/normalizecalls.py --- a/pypy/rpython/normalizecalls.py +++ b/pypy/rpython/normalizecalls.py @@ -12,6 +12,7 @@ from pypy.rlib.objectmodel import instantiate, ComputedIntSymbolic from pypy.interpreter.argument import Signature + def normalize_call_familes(annotator): for callfamily in annotator.bookkeeper.pbc_maximal_call_families.infos(): if not callfamily.modified: @@ -105,7 +106,6 @@ call_nbargs = shape_cnt + len(shape_keys) did_something = False - NODEFAULT = object() for graph in graphs: argnames, varargname, kwargname = graph.signature @@ -123,7 +123,7 @@ inlist = [] defaults = graph.defaults or () num_nondefaults = len(inputargs_s) - len(defaults) - defaults = [NODEFAULT] * num_nondefaults + list(defaults) + defaults = [description.NODEFAULT] * num_nondefaults + list(defaults) newdefaults = [] for j in argorder: v = Variable(graph.getargs()[j]) @@ -141,7 +141,7 @@ v = inlist[i] except ValueError: default = defaults[j] - if default is NODEFAULT: + if default is description.NODEFAULT: raise TyperError( "call pattern has %d positional arguments, " "but %r takes at least %d arguments" % ( @@ -151,7 +151,7 @@ newblock.closeblock(Link(outlist, oldblock)) graph.startblock = newblock for i in range(len(newdefaults)-1,-1,-1): - if newdefaults[i] is NODEFAULT: + if newdefaults[i] is description.NODEFAULT: newdefaults = newdefaults[i:] break graph.defaults = tuple(newdefaults) diff --git a/pypy/tool/descriptor.py b/pypy/tool/descriptor.py --- a/pypy/tool/descriptor.py +++ b/pypy/tool/descriptor.py @@ -1,14 +1,3 @@ - -class roproperty(object): - def __init__(self, getter): - self.getter = getter - def __get__(self, obj, cls=None): - if obj is None: - return self - else: - return self.getter(obj) - - class InstanceMethod(object): "Like types.InstanceMethod, but with a reasonable (structural) equality." From noreply at buildbot.pypy.org Sun Oct 7 18:01:32 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 18:01:32 +0200 (CEST) Subject: [pypy-commit] cffi default: Use dlerror() to report error conditions more precisely. Message-ID: <20121007160132.587861C0C00@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r983:aa47c6364769 Date: 2012-10-07 18:01 +0200 http://bitbucket.org/cffi/cffi/changeset/aa47c6364769/ Log: Use dlerror() to report error conditions more precisely. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2595,10 +2595,13 @@ ct->ct_name); return NULL; } + dlerror(); /* clear error condition */ funcptr = dlsym(dlobj->dl_handle, funcname); if (funcptr == NULL) { - PyErr_Format(PyExc_KeyError, "function '%s' not found in library '%s'", - funcname, dlobj->dl_name); + const char *error = dlerror(); + PyErr_Format(PyExc_KeyError, + "function '%s' not found in library '%s': %s", + funcname, dlobj->dl_name, error); return NULL; } @@ -2615,11 +2618,16 @@ &CTypeDescr_Type, &ct, &varname)) return NULL; + dlerror(); /* clear error condition */ data = dlsym(dlobj->dl_handle, varname); if (data == NULL) { - PyErr_Format(PyExc_KeyError, "variable '%s' not found in library '%s'", - varname, dlobj->dl_name); - return NULL; + const char *error = dlerror(); + if (error != NULL) { + PyErr_Format(PyExc_KeyError, + "variable '%s' not found in library '%s': %s", + varname, dlobj->dl_name, error); + return NULL; + } } return convert_to_object(data, ct); } @@ -2635,10 +2643,13 @@ &CTypeDescr_Type, &ct, &varname, &value)) return NULL; + dlerror(); /* clear error condition */ data = dlsym(dlobj->dl_handle, varname); if (data == NULL) { - PyErr_Format(PyExc_KeyError, "variable '%s' not found in library '%s'", - varname, dlobj->dl_name); + const char *error = dlerror(); + PyErr_Format(PyExc_KeyError, + "variable '%s' not found in library '%s': %s", + varname, dlobj->dl_name, error); return NULL; } if (convert_from_object(data, ct, value) < 0) @@ -2711,8 +2722,9 @@ printable_filename = filename_or_null ? filename_or_null : ""; handle = dlopen(filename_or_null, flags); if (handle == NULL) { + const char *error = dlerror(); PyErr_Format(PyExc_OSError, "cannot load library %s: %s", - printable_filename, dlerror()); + printable_filename, error); return NULL; } From noreply at buildbot.pypy.org Sun Oct 7 18:08:52 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 18:08:52 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Progress towards killing PyObject support Message-ID: <20121007160852.B7F441C0C00@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57825:c7d5af174015 Date: 2012-10-07 18:08 +0200 http://bitbucket.org/pypy/pypy/changeset/c7d5af174015/ Log: Progress towards killing PyObject support diff --git a/pypy/rlib/rstring.py b/pypy/rlib/rstring.py --- a/pypy/rlib/rstring.py +++ b/pypy/rlib/rstring.py @@ -199,25 +199,25 @@ class __extend__(pairtype(SomeStringBuilder, SomePBC)): def union((sb, p)): assert p.const is None - return SomeStringBuilder(can_be_None=True) + return SomeStringBuilder() class __extend__(pairtype(SomePBC, SomeStringBuilder)): def union((p, sb)): assert p.const is None - return SomeStringBuilder(can_be_None=True) + return SomeStringBuilder() class __extend__(pairtype(SomeUnicodeBuilder, SomePBC)): def union((sb, p)): assert p.const is None - return SomeUnicodeBuilder(can_be_None=True) + return SomeUnicodeBuilder() class __extend__(pairtype(SomePBC, SomeUnicodeBuilder)): def union((p, sb)): assert p.const is None - return SomeUnicodeBuilder(can_be_None=True) + return SomeUnicodeBuilder() #___________________________________________________________________ # Support functions for SomeString.no_nul diff --git a/pypy/translator/c/database.py b/pypy/translator/c/database.py --- a/pypy/translator/c/database.py +++ b/pypy/translator/c/database.py @@ -1,7 +1,7 @@ -from pypy.rpython.lltypesystem.lltype import ( - Primitive, Ptr, typeOf, RuntimeTypeInfo, Struct, Array, FuncType, PyObject, - Void, ContainerType, OpaqueType, FixedSizeArray, _uninitialized, Typedef) +from pypy.rpython.lltypesystem.lltype import (Primitive, Ptr, typeOf, + RuntimeTypeInfo, Struct, Array, FuncType, Void, ContainerType, OpaqueType, + FixedSizeArray, Typedef) from pypy.rpython.lltypesystem import lltype, rffi from pypy.rpython.lltypesystem.llmemory import WeakRef, _WeakRefType, GCREF from pypy.rpython.lltypesystem.rffi import CConstant @@ -14,7 +14,6 @@ from pypy.translator.c.support import cdecl, CNameManager from pypy.translator.c.support import log, barebonearray from pypy.translator.c.extfunc import do_the_getting -from pypy import conftest from pypy.translator.c import gc from pypy.tool.identity_dict import identity_dict @@ -120,8 +119,6 @@ if who_asks is not None: who_asks.dependencies[node] = True return node.gettype() - elif T == PyObject: - return 'PyObject @' elif isinstance(T, FuncType): resulttype = self.gettype(T.RESULT) argtypes = [] @@ -363,11 +360,8 @@ yield node def get_lltype_of_exception_value(self): - if self.translator is not None and self.translator.rtyper is not None: - exceptiondata = self.translator.rtyper.getexceptiondata() - return exceptiondata.lltype_of_exception_value - else: - return Ptr(PyObject) + exceptiondata = self.translator.rtyper.getexceptiondata() + return exceptiondata.lltype_of_exception_value def getstructdeflist(self): # return the StructDefNodes sorted according to dependencies diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py --- a/pypy/translator/c/funcgen.py +++ b/pypy/translator/c/funcgen.py @@ -3,14 +3,11 @@ from pypy.translator.c.support import cdecl from pypy.translator.c.support import llvalue_from_constant, gen_assignments from pypy.translator.c.support import c_string_constant, barebonearray -from pypy.objspace.flow.model import Variable, Constant, Block +from pypy.objspace.flow.model import Variable, Constant from pypy.objspace.flow.model import c_last_exception, copygraph -from pypy.rpython.lltypesystem.lltype import Ptr, PyObject, Void, Bool, Signed -from pypy.rpython.lltypesystem.lltype import Unsigned, SignedLongLong, Float -from pypy.rpython.lltypesystem.lltype import UnsignedLongLong, Char, UniChar -from pypy.rpython.lltypesystem.lltype import pyobjectptr, ContainerType -from pypy.rpython.lltypesystem.lltype import Struct, Array, FixedSizeArray -from pypy.rpython.lltypesystem.lltype import ForwardReference, FuncType +from pypy.rpython.lltypesystem.lltype import (Ptr, Void, Bool, Signed, Unsigned, + SignedLongLong, Float, UnsignedLongLong, Char, UniChar, ContainerType, + Array, FixedSizeArray, ForwardReference, FuncType) from pypy.rpython.lltypesystem.rffi import INT from pypy.rpython.lltypesystem.llmemory import Address from pypy.translator.backendopt.ssa import SSI_to_SSA @@ -18,7 +15,6 @@ from pypy.tool.identity_dict import identity_dict -PyObjPtr = Ptr(PyObject) LOCALVAR = 'l_%s' KEEP_INLINED_GRAPHS = False diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -2,9 +2,8 @@ import py import sys, os from pypy.rlib import exports -from pypy.rpython.lltypesystem import lltype from pypy.rpython.typesystem import getfunctionptr -from pypy.tool import isolate, runsubprocess +from pypy.tool import runsubprocess from pypy.tool.nullpath import NullPyPathLocal from pypy.tool.udir import udir from pypy.translator.c import gc @@ -12,7 +11,6 @@ from pypy.translator.c.extfunc import pre_include_code_lines from pypy.translator.c.support import log from pypy.translator.gensupp import uniquemodulename, NameManager -from pypy.translator.llsupport.wrapper import new_wrapper from pypy.translator.tool.cbuild import ExternalCompilationInfo _CYGWIN = sys.platform == 'cygwin' @@ -317,118 +315,6 @@ pass -class CExtModuleBuilder(CBuilder): - standalone = False - cpython_extension = True - _module = None - _wrapper = None - - def get_eci(self): - from distutils import sysconfig - python_inc = sysconfig.get_python_inc() - eci = ExternalCompilationInfo( - include_dirs=[python_inc], - includes=["Python.h", - ], - ) - return eci.merge(CBuilder.get_eci(self)) - - def getentrypointptr(self): # xxx - if self._wrapper is None: - self._wrapper = new_wrapper(self.entrypoint, self.translator) - return self._wrapper - - def compile(self): - assert self.c_source_filename - assert not self._compiled - export_symbols = [self.db.get(self.getentrypointptr()), - 'RPython_StartupCode', - ] - if self.config.translation.countmallocs: - export_symbols.append('malloc_counters') - extsymeci = ExternalCompilationInfo(export_symbols=export_symbols) - self.eci = self.eci.merge(extsymeci) - - if sys.platform == 'win32': - self.eci = self.eci.merge(ExternalCompilationInfo( - library_dirs = [py.path.local(sys.exec_prefix).join('LIBs'), - py.path.local(sys.executable).dirpath(), - ], - )) - - - files = [self.c_source_filename] + self.extrafiles - self.translator.platform.compile(files, self.eci, standalone=False) - self._compiled = True - - def _make_wrapper_module(self): - fname = 'wrap_' + self.c_source_filename.purebasename - modfile = self.c_source_filename.new(purebasename=fname, ext=".py") - - entrypoint_ptr = self.getentrypointptr() - wrapped_entrypoint_c_name = self.db.get(entrypoint_ptr) - - CODE = """ -import ctypes - -_lib = ctypes.PyDLL(r"%(so_name)s") - -_entry_point = getattr(_lib, "%(c_entrypoint_name)s") -_entry_point.restype = ctypes.py_object -_entry_point.argtypes = %(nargs)d*(ctypes.py_object,) - -def entrypoint(*args): - return _entry_point(*args) - -try: - _malloc_counters = _lib.malloc_counters -except AttributeError: - pass -else: - _malloc_counters.restype = ctypes.py_object - _malloc_counters.argtypes = 2*(ctypes.py_object,) - - def malloc_counters(): - return _malloc_counters(None, None) - -_rpython_startup = _lib.RPython_StartupCode -_rpython_startup() -""" % {'so_name': self.c_source_filename.new(ext=self.translator.platform.so_ext), - 'c_entrypoint_name': wrapped_entrypoint_c_name, - 'nargs': len(lltype.typeOf(entrypoint_ptr).TO.ARGS)} - modfile.write(CODE) - self._module_path = modfile - - def _import_module(self, isolated=False): - if self._module is not None: - return self._module - assert self._compiled - assert not self._module - self._make_wrapper_module() - if not isolated: - mod = ModuleWithCleanup(self._module_path.pyimport()) - else: - mod = isolate.Isolate((str(self._module_path.dirpath()), - self._module_path.purebasename)) - self._module = mod - return mod - - def get_entry_point(self, isolated=False): - self._import_module(isolated=isolated) - return getattr(self._module, "entrypoint") - - def get_malloc_counters(self, isolated=False): - self._import_module(isolated=isolated) - return self._module.malloc_counters - - def cleanup(self): - #assert self._module - if isinstance(self._module, isolate.Isolate): - isolate.close_isolate(self._module) - - def gen_makefile(self, targetdir, exe_name=None): - pass - class CStandaloneBuilder(CBuilder): standalone = True split = True diff --git a/pypy/translator/c/node.py b/pypy/translator/c/node.py --- a/pypy/translator/c/node.py +++ b/pypy/translator/c/node.py @@ -1,8 +1,7 @@ -from pypy.rpython.lltypesystem.lltype import \ - Struct, Array, FixedSizeArray, FuncType, PyObjectType, typeOf, \ - GcStruct, GcArray, RttiStruct, ContainerType, \ - parentlink, Ptr, PyObject, Void, OpaqueType, Float, \ - RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray +from pypy.rpython.lltypesystem.lltype import (Struct, Array, FixedSizeArray, + FuncType, typeOf, GcStruct, GcArray, RttiStruct, ContainerType, parentlink, + Ptr, Void, OpaqueType, Float, RuntimeTypeInfo, getRuntimeTypeInfo, Char, + _subarray) from pypy.rpython.lltypesystem import llmemory, llgroup from pypy.translator.c.funcgen import FunctionCodeGenerator from pypy.translator.c.external import CExternalFunctionCodeGenerator @@ -790,12 +789,7 @@ return lines else: comma = ',' - if typeOf(value) == Ptr(PyObject) and value: - # cannot just write 'gxxx' as a constant in a structure :-( - node = db.getcontainernode(value._obj) - expr = 'NULL /*%s*/' % node.name - node.where_to_copy_me.append('&%s' % access_expr) - elif typeOf(value) == Float and not isfinite(value): + if typeOf(value) == Float and not isfinite(value): db.late_initializations.append(('%s' % access_expr, db.get(value))) expr = '0.0 /* patched later by %sinfinity */' % ( '-+'[value > 0]) @@ -1005,54 +999,6 @@ raise Exception("don't know about %r" % (T,)) -class PyObjectNode(ContainerNode): - nodekind = 'pyobj' - globalcontainer = True - typename = 'PyObject @' - implementationtypename = 'PyObject *@' - _funccodegen_owner = None - - def __init__(self, db, T, obj): - # obj is a _pyobject here; obj.value is the underlying CPython object - self.db = db - self.T = T - self.obj = obj - value = obj.value - self.name = self._python_c_name(value) - self.exported_name = self.name - # a list of expressions giving places where this constant PyObject - # must be copied. Normally just in the global variable of the same - # name, but see also StructNode.initializationexpr() :-( - self.where_to_copy_me = [] - - def getptrname(self): - return self.name - - def _python_c_name(self, value): - # just some minimal cases: None and builtin exceptions - if value is None: - return 'Py_None' - import types, py - if isinstance(value, (type, types.ClassType)): - if (issubclass(value, BaseException) and - value.__module__ == 'exceptions'): - return 'PyExc_' + value.__name__ - if issubclass(value, AssertionError): - return 'PyExc_AssertionError' - if value is _StackOverflow: - return 'PyExc_RuntimeError' - raise Exception("don't know how to simply render py object: %r" % - (value, )) - - def forward_declaration(self): - return [] - - def enum_dependencies(self): - return [] - - def implementation(self): - return [] - def weakrefnode_factory(db, T, obj): assert isinstance(obj, llmemory._wref) ptarget = obj._dereference() @@ -1131,7 +1077,6 @@ FixedSizeArray: FixedSizeArrayNode, FuncType: FuncNode, OpaqueType: opaquenode_factory, - PyObjectType: PyObjectNode, llmemory._WeakRefType: weakrefnode_factory, llgroup.GroupType: GroupNode, - } +} diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py --- a/pypy/translator/driver.py +++ b/pypy/translator/driver.py @@ -172,19 +172,14 @@ def _maybe_skip(self): maybe_skip = [] if self._disabled: - for goal in self.backend_select_goals(self._disabled): + for goal in self.backend_select_goals(self._disabled): maybe_skip.extend(self._depending_on_closure(goal)) return dict.fromkeys(maybe_skip).keys() - def setup(self, entry_point, inputtypes, policy=None, extra={}, empty_translator=None): - standalone = inputtypes is None - self.standalone = standalone - - if standalone: - # the 'argv' parameter - inputtypes = [s_list_of_strings] - self.inputtypes = inputtypes + assert inputtypes is None + # the 'argv' parameter + self.inputtypes = [s_list_of_strings] if policy is None: policy = annpolicy.AnnotatorPolicy() @@ -322,7 +317,7 @@ s = None self.sanity_check_annotation() - if self.entry_point and self.standalone and s.knowntype != int: + if self.entry_point and s.knowntype != int: raise Exception("stand-alone program entry point must return an " "int (and not, e.g., None or always raise an " "exception).") @@ -469,15 +464,10 @@ if self.libdef is not None: cbuilder = self.libdef.getcbuilder(self.translator, self.config) - self.standalone = False standalone = False else: - standalone = self.standalone - - if standalone: - from pypy.translator.c.genc import CStandaloneBuilder as CBuilder - else: - from pypy.translator.c.genc import CExtModuleBuilder as CBuilder + from pypy.translator.c.genc import CStandaloneBuilder as CBuilder + standalone = True cbuilder = CBuilder(self.translator, self.entry_point, config=self.config, secondary_entrypoints=self.secondary_entrypoints) @@ -551,17 +541,13 @@ """ cbuilder = self.cbuilder kwds = {} - if self.standalone and self.exe_name is not None: + if self.exe_name is not None: kwds['exe_name'] = self.compute_exe_name().basename cbuilder.compile(**kwds) - if self.standalone: - self.c_entryp = cbuilder.executable_name - self.create_exe() - else: - isolated = self._backend_extra_options.get('c_isolated', False) - self.c_entryp = cbuilder.get_entry_point(isolated=isolated) - # + self.c_entryp = cbuilder.executable_name + self.create_exe() + task_compile_c = taskdef(task_compile_c, ['source_c'], "Compiling c source") def task_llinterpret_lltype(self): @@ -611,7 +597,7 @@ unpatch_os(self.old_cli_defs) self.log.info("Compiled %s" % filename) - if self.standalone and self.exe_name: + if self.exe_name: self.copy_cli_exe() task_compile_cli = taskdef(task_compile_cli, ['source_cli'], 'Compiling CLI source') @@ -678,8 +664,7 @@ from pypy.translator.jvm.node import EntryPoint entry_point_graph = self.translator.graphs[0] - is_func = not self.standalone - entry_point = EntryPoint(entry_point_graph, is_func, is_func) + entry_point = EntryPoint(entry_point_graph, False, False) self.gen = GenJvm(udir, self.translator, entry_point) self.jvmsource = self.gen.generate_source() self.log.info("Wrote JVM code") @@ -695,7 +680,7 @@ if hasattr(self, 'old_cli_defs'): unpatch_os(self.old_cli_defs) self.log.info("Compiled JVM source") - if self.standalone and self.exe_name: + if self.exe_name: self.copy_jvm_jar() task_compile_jvm = taskdef(task_compile_jvm, ['source_jvm'], 'Compiling JVM source') From noreply at buildbot.pypy.org Sun Oct 7 18:15:04 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 18:15:04 +0200 (CEST) Subject: [pypy-commit] cffi default: Fix this test to run from any current working dir. Message-ID: <20121007161504.73D071C03FB@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r984:660f8bb17cf7 Date: 2012-10-07 18:14 +0200 http://bitbucket.org/cffi/cffi/changeset/660f8bb17cf7/ Log: Fix this test to run from any current working dir. diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1187,7 +1187,8 @@ def test_callback_in_thread(): if sys.platform == 'win32': py.test.skip("pthread only") - import subprocess - g = subprocess.Popen([sys.executable, 'callback_in_thread.py']) + import os, subprocess + arg = os.path.join(os.path.dirname(__file__), 'callback_in_thread.py') + g = subprocess.Popen([sys.executable, arg]) result = g.wait() assert result == 0 From noreply at buildbot.pypy.org Sun Oct 7 18:19:23 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 18:19:23 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: kill some dead imports and style cleanups Message-ID: <20121007161923.5A2661C03FB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57826:a21178a973d3 Date: 2012-10-07 18:18 +0200 http://bitbucket.org/pypy/pypy/changeset/a21178a973d3/ Log: kill some dead imports and style cleanups diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -1,23 +1,18 @@ -import autopath, sys, os, py +import sys + +import py + from pypy.rpython.lltypesystem.lltype import * from pypy.annotation import model as annmodel from pypy.translator.translator import TranslationContext -from pypy.translator.c.database import LowLevelDatabase from pypy.translator.c import genc -from pypy.translator.c.gc import NoneGcPolicy -from pypy.objspace.flow.model import Constant, Variable, SpaceOperation -from pypy.objspace.flow.model import Block, Link, FunctionGraph -from pypy.tool.udir import udir -from pypy.translator.gensupp import uniquemodulename -from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.interactive import Translation from pypy.rlib.entrypoint import entrypoint from pypy.tool.nullpath import NullPyPathLocal + def compile(fn, argtypes, view=False, gcpolicy="ref", backendopt=True, annotatorpolicy=None): - if argtypes is not None and "__pypy__" in sys.builtin_module_names: - py.test.skip("requires building cpython extension modules") t = Translation(fn, argtypes, gc=gcpolicy, backend="c", policy=annotatorpolicy) if not backendopt: diff --git a/pypy/translator/interactive.py b/pypy/translator/interactive.py --- a/pypy/translator/interactive.py +++ b/pypy/translator/interactive.py @@ -44,7 +44,7 @@ self.ensure_setup() elif kind == 'post': pass - + def ensure_setup(self, argtypes=None, policy=None, standalone=False): if not self.driver_setup: if standalone: @@ -74,7 +74,8 @@ kwds.pop('policy', None) kwds.pop('standalone', None) gc = kwds.pop('gc', None) - if gc: self.config.translation.gc = gc + if gc: + self.config.translation.gc = gc self.config.translation.set(**kwds) def ensure_opt(self, name, value=None, fallback=None): @@ -88,13 +89,13 @@ if val is not None: return val raise Exception( - "the %r option should have been specified at this point" %name) + "the %r option should have been specified at this point" % name) def ensure_type_system(self, type_system=None): if self.config.translation.backend is not None: return self.ensure_opt('type_system') return self.ensure_opt('type_system', type_system, 'lltype') - + def ensure_backend(self, backend=None): backend = self.ensure_opt('backend', backend) self.ensure_type_system() @@ -121,20 +122,20 @@ def rtype(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) ts = self.ensure_type_system() - return getattr(self.driver, 'rtype_'+ts)() + return getattr(self.driver, 'rtype_' + ts)() def backendopt(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) ts = self.ensure_type_system('lltype') - return getattr(self.driver, 'backendopt_'+ts)() - + return getattr(self.driver, 'backendopt_' + ts)() + # backend depedent def source(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) backend = self.ensure_backend() - getattr(self.driver, 'source_'+backend)() - + getattr(self.driver, 'source_' + backend)() + def source_c(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) self.ensure_backend('c') @@ -148,15 +149,15 @@ def compile(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) backend = self.ensure_backend() - getattr(self.driver, 'compile_'+backend)() + getattr(self.driver, 'compile_' + backend)() return self.driver.c_entryp - + def compile_c(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) self.ensure_backend('c') self.driver.compile_c() return self.driver.c_entryp - + def compile_cli(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) self.ensure_backend('cli') From noreply at buildbot.pypy.org Sun Oct 7 18:25:55 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 18:25:55 +0200 (CEST) Subject: [pypy-commit] cffi default: Fix. Message-ID: <20121007162555.75B031C03FB@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r985:46d7c3ff4031 Date: 2012-10-07 18:25 +0200 http://bitbucket.org/cffi/cffi/changeset/46d7c3ff4031/ Log: Fix. diff --git a/testing/test_zdistutils.py b/testing/test_zdistutils.py --- a/testing/test_zdistutils.py +++ b/testing/test_zdistutils.py @@ -124,7 +124,6 @@ lib = ffi.verify(csrc, force_generic_engine=self.generic) assert lib.sin(12.3) == math.sin(12.3) assert isinstance(ffi.verifier, Verifier) - ffi.verifier.write_source() with open(ffi.verifier.sourcefilename, 'r') as f: data = f.read() assert csrc in data From noreply at buildbot.pypy.org Sun Oct 7 18:27:36 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 18:27:36 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Remove another pyobj usage. Message-ID: <20121007162736.3CC6A1C03FB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57827:0425059c3e0e Date: 2012-10-07 18:26 +0200 http://bitbucket.org/pypy/pypy/changeset/0425059c3e0e/ Log: Remove another pyobj usage. diff --git a/pypy/rpython/ootypesystem/rdict.py b/pypy/rpython/ootypesystem/rdict.py --- a/pypy/rpython/ootypesystem/rdict.py +++ b/pypy/rpython/ootypesystem/rdict.py @@ -7,6 +7,8 @@ from pypy.rpython.ootypesystem import ootype from pypy.rlib import objectmodel from pypy.rpython import rmodel, llinterp +# This is needed by other things, don't remove! +from pypy.rpython.rdict import rtype_newdict class DictRepr(AbstractDictRepr): diff --git a/pypy/rpython/rdict.py b/pypy/rpython/rdict.py --- a/pypy/rpython/rdict.py +++ b/pypy/rpython/rdict.py @@ -1,10 +1,5 @@ -from pypy.tool.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.objspace.flow.model import Constant from pypy.rpython.lltypesystem import lltype -from pypy.rlib.rarithmetic import r_uint -from pypy.rlib.objectmodel import hlinvoke -from pypy.rlib import objectmodel from pypy.rpython import rmodel @@ -58,9 +53,6 @@ def rtype_newdict(hop): hop.inputargs() # no arguments expected r_dict = hop.r_result - if r_dict == robject.pyobj_repr: # special case: SomeObject: SomeObject dicts! - cdict = hop.inputconst(robject.pyobj_repr, dict) - return hop.genop('simple_call', [cdict], resulttype = robject.pyobj_repr) cDICT = hop.inputconst(lltype.Void, r_dict.DICT) v_result = hop.gendirectcall(hop.rtyper.type_system.rdict.ll_newdict, cDICT) return v_result diff --git a/pypy/translator/interactive.py b/pypy/translator/interactive.py --- a/pypy/translator/interactive.py +++ b/pypy/translator/interactive.py @@ -1,9 +1,7 @@ -import optparse - -import autopath from pypy.translator.translator import TranslationContext from pypy.translator import driver + DEFAULTS = { 'translation.backend': None, 'translation.type_system': None, From noreply at buildbot.pypy.org Sun Oct 7 18:30:06 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 18:30:06 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Some files that should be removed. Message-ID: <20121007163006.E7BBF1C03FB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57828:3452112080a7 Date: 2012-10-07 18:29 +0200 http://bitbucket.org/pypy/pypy/changeset/3452112080a7/ Log: Some files that should be removed. diff --git a/pypy/rpython/test/test_robject.py b/pypy/rpython/test/test_robject.py deleted file mode 100644 --- a/pypy/rpython/test/test_robject.py +++ /dev/null @@ -1,59 +0,0 @@ -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.test.test_llinterp import interpret - - -def test_simple(): - def fn(obj): - return obj + 1 - _1L = pyobjectptr(1L) - res = interpret(fn, [_1L], someobjects=True) - assert res._obj.value == 2L - -def test_obj_obj_dict(): - def f(i, c): - d = {} - d[1] = 'a' - d['a'] = i - d['ab'] = c - d[i] = c - return len(d) - res = interpret(f, [2, 'c'], someobjects=True) - assert res == 4 - res = interpret(f, [3, 'c'], someobjects=True) - assert res == 4 - -def test_obj_list(): - def f(i, c): - lis = [1, 2, 3, 4] - lis[i] = c - lis.append(i) - return len(lis) - res = interpret(f, [2, 'c'], someobjects=True) - assert res == 5 - res = interpret(f, [3, 'c'], someobjects=True) - assert res == 5 - -def test_obj_iter(): - def f(flag): - if flag: - x = (1, 2) - else: - x = '34' - lst = [u for u in x] - return lst[flag] - res = interpret(f, [1], someobjects=True) - assert res._obj.value == 2 - res = interpret(f, [0], someobjects=True) - assert res._obj.value == '3' - -def test_listofobj_iter(): - def f(look): - lst = ['*', 2, 5] - for u in lst: - if u == look: - return True - return False - res = interpret(f, [1], someobjects=True) - assert res is False - res = interpret(f, [2], someobjects=True) - assert res is True diff --git a/pypy/translator/llsupport/test/test_wrapper.py b/pypy/translator/llsupport/test/test_wrapper.py deleted file mode 100644 --- a/pypy/translator/llsupport/test/test_wrapper.py +++ /dev/null @@ -1,60 +0,0 @@ -import py -from pypy import conftest -from pypy.translator.translator import TranslationContext -from pypy.translator.llsupport.wrapper import new_wrapper -from pypy.rpython.rmodel import PyObjPtr -from pypy.rpython.llinterp import LLInterpreter -from pypy.rpython.lltypesystem import lltype - - -class TestMakeWrapper: - - def getgraph(self, func, argtypes=None): - from pypy.config.pypyoption import get_pypy_config - config = get_pypy_config(translating=True) - config.translation.gc = "ref" - config.translation.simplifying = True - t = TranslationContext(config=config) - if argtypes is None: - argtypes = [] - a = t.buildannotator() - a.build_types(func, argtypes) - a.simplify() - t.buildrtyper().specialize() - wrapperptr = new_wrapper(func, t) - wrappergraph = wrapperptr._obj.graph - F = lltype.typeOf(wrapperptr).TO - assert F.ARGS == (PyObjPtr,) * len(wrappergraph.getargs()) - assert F.RESULT == PyObjPtr - - for inputarg in wrappergraph.getargs(): - assert inputarg.concretetype == PyObjPtr - assert wrappergraph.getreturnvar().concretetype == PyObjPtr - return t.graphs[0], wrappergraph, t - - def interpret(self, t, graph, *args): - interp = LLInterpreter(t.rtyper) - result = interp.eval_graph(graph, [lltype.pyobjectptr(arg) - for arg in args]) - return result._obj.value - - def test_simple(self): - def f(x): - return x * 3 - graph, wrappergraph, t = self.getgraph(f, [int]) - res = self.interpret(t, wrappergraph, 3) - assert res == 9 - - def test_manyargs(self): - def f(x, y, z): - return x * y + z - graph, wrappergraph, t = self.getgraph(f, [int, int, int]) - res = self.interpret(t, wrappergraph, 3, 4, 5) - assert res == 3 * 4 + 5 - - def test_returnnone(self): - def f(): - pass - graph, wrappergraph, t = self.getgraph(f) - res = self.interpret(t, wrappergraph) - assert res is None diff --git a/pypy/translator/llsupport/wrapper.py b/pypy/translator/llsupport/wrapper.py deleted file mode 100644 --- a/pypy/translator/llsupport/wrapper.py +++ /dev/null @@ -1,78 +0,0 @@ -from pypy.objspace.flow.model import Variable -from pypy.objspace.flow.model import Block, Link, FunctionGraph, checkgraph -from pypy.rpython.lltypesystem.lltype import \ - Ptr, PyObject, typeOf, Signed, FuncType, functionptr, nullptr, Void -from pypy.rpython.rtyper import LowLevelOpList -from pypy.rpython.rmodel import inputconst, PyObjPtr -from pypy.rpython.robject import pyobj_repr - -from pypy.rpython.typesystem import getfunctionptr - - - -def new_wrapper(func, translator, newname=None): - # The basic idea is to produce a flow graph from scratch, using the - # help of the rtyper for the conversion of the arguments after they - # have been decoded. - - bk = translator.annotator.bookkeeper - graph = bk.getdesc(func).getuniquegraph() - - f = getfunctionptr(graph) - FUNCTYPE = typeOf(f).TO - - newops = LowLevelOpList(translator.rtyper) - - varguments = [] - for var in graph.startblock.inputargs: - v = Variable(var) - v.concretetype = PyObjPtr - varguments.append(v) - - wrapper_inputargs = varguments[:] - # use the rtyper to produce the conversions - inputargs = f._obj.graph.getargs() - for i in range(len(varguments)): - if FUNCTYPE.ARGS[i] != PyObjPtr: - rtyper = translator.rtyper - r_arg = rtyper.bindingrepr(inputargs[i]) - # give the rtyper a chance to know which function we are wrapping - rtyper.set_wrapper_context(func) - varguments[i] = newops.convertvar(varguments[i], - r_from = pyobj_repr, - r_to = r_arg) - rtyper.set_wrapper_context(None) - - vlist = [inputconst(typeOf(f), f)] + varguments - vresult = newops.genop('direct_call', vlist, resulttype=FUNCTYPE.RESULT) - - if FUNCTYPE.RESULT != PyObjPtr: - # convert "result" back to a PyObject - rtyper = translator.rtyper - assert rtyper is not None, ( - "needs the rtyper to perform function result conversions") - r_result = rtyper.bindingrepr(f._obj.graph.getreturnvar()) - vresult = newops.convertvar(vresult, - r_from = r_result, - r_to = pyobj_repr) - - # "return result" - block = Block(wrapper_inputargs) - wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block) - translator.update_call_graph(wgraph, graph, object()) - translator.graphs.append(wgraph) - block.operations[:] = newops - block.closeblock(Link([vresult], wgraph.returnblock)) - wgraph.getreturnvar().concretetype = PyObjPtr - checkgraph(wgraph) - - # the above convertvar()s may have created and annotated new helpers - # that need to be specialized now - translator.rtyper.specialize_more_blocks() - - return functionptr(FuncType([PyObjPtr] * len(wrapper_inputargs), - PyObjPtr), - wgraph.name, - graph = wgraph, - exception_policy = "CPython") - From noreply at buildbot.pypy.org Sun Oct 7 18:35:41 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 18:35:41 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: another removal of pyobject Message-ID: <20121007163541.B57C41C041E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57829:f915493e9df0 Date: 2012-10-07 18:34 +0200 http://bitbucket.org/pypy/pypy/changeset/f915493e9df0/ Log: another removal of pyobject diff --git a/pypy/rpython/typesystem.py b/pypy/rpython/typesystem.py --- a/pypy/rpython/typesystem.py +++ b/pypy/rpython/typesystem.py @@ -119,7 +119,7 @@ return hop.genop('ptr_nonzero', vlist, resulttype=lltype.Bool) def getconcretetype(self, v): - return getattr(v, 'concretetype', lltype.Ptr(lltype.PyObject)) + return v.concretetype def null_callable(self, T): return lltype.nullptr(T.TO) From noreply at buildbot.pypy.org Sun Oct 7 18:39:25 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 18:39:25 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Make jit/codewriter tests up to date with the new APIs Message-ID: <20121007163925.A34841C041E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57830:dc0452a0abcd Date: 2012-10-07 18:38 +0200 http://bitbucket.org/pypy/pypy/changeset/dc0452a0abcd/ Log: Make jit/codewriter tests up to date with the new APIs diff --git a/pypy/jit/codewriter/call.py b/pypy/jit/codewriter/call.py --- a/pypy/jit/codewriter/call.py +++ b/pypy/jit/codewriter/call.py @@ -180,11 +180,8 @@ """ fnptr = self.rtyper.type_system.getcallable(graph) FUNC = get_functype(lltype.typeOf(fnptr)) - assert lltype.Ptr(lltype.PyObject) not in FUNC.ARGS - if self.rtyper.type_system.name == 'ootypesystem': - XXX - else: - fnaddr = llmemory.cast_ptr_to_adr(fnptr) + assert self.rtyper.type_system.name == "lltypesystem" + fnaddr = llmemory.cast_ptr_to_adr(fnptr) NON_VOID_ARGS = [ARG for ARG in FUNC.ARGS if ARG is not lltype.Void] calldescr = self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), FUNC.RESULT, EffectInfo.MOST_GENERAL) diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -641,11 +641,7 @@ self.bookkeeper._jit_annotation_cache[driver] = cache for key, s_value in kwds_s.items(): s_previous = cache.get(key, annmodel.s_ImpossibleValue) - s_value = annmodel.unionof(s_previous, s_value) - if annmodel.isdegenerated(s_value): - raise JitHintError("mixing incompatible types in argument %s" - " of jit_merge_point/can_enter_jit" % - key[2:]) + s_value = annmodel.unionof(s_previous, s_value) # where="mixing incompatible types in argument %s of jit_merge_point/can_enter_jit" % key[2:] cache[key] = s_value # add the attribute _dont_reach_me_in_del_ (see pypy.rpython.rclass) From noreply at buildbot.pypy.org Sun Oct 7 18:44:22 2012 From: noreply at buildbot.pypy.org (stefanor) Date: Sun, 7 Oct 2012 18:44:22 +0200 (CEST) Subject: [pypy-commit] pypy default: Not needing -fPIC on i386 is exception, not the norm. Don't expect all 32 bit archs to build shared libraries without it. Message-ID: <20121007164422.499021C041E@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r57831:c3d0f9f30426 Date: 2012-10-07 18:42 +0200 http://bitbucket.org/pypy/pypy/changeset/c3d0f9f30426/ Log: Not needing -fPIC on i386 is exception, not the norm. Don't expect all 32 bit archs to build shared libraries without it. diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py --- a/pypy/translator/platform/__init__.py +++ b/pypy/translator/platform/__init__.py @@ -240,12 +240,15 @@ if sys.platform.startswith('linux'): - from pypy.translator.platform.linux import Linux, Linux64 + from pypy.translator.platform.linux import Linux, LinuxPIC import platform - if platform.architecture()[0] == '32bit': + # Only required on armhf and mips{,el}, not armel. But there's no way to + # detect armhf without shelling out + if (platform.architecture()[0] == '64bit' + or platform.machine().startswith(('arm', 'mips'))): + host_factory = LinuxPIC + else: host_factory = Linux - else: - host_factory = Linux64 elif sys.platform == 'darwin': from pypy.translator.platform.darwin import Darwin_i386, Darwin_x86_64, Darwin_PowerPC import platform diff --git a/pypy/translator/platform/linux.py b/pypy/translator/platform/linux.py --- a/pypy/translator/platform/linux.py +++ b/pypy/translator/platform/linux.py @@ -48,5 +48,5 @@ shared_only = () # it seems that on 32-bit linux, compiling with -fPIC # gives assembler that asmgcc is not happy about. -class Linux64(BaseLinux): +class LinuxPIC(BaseLinux): pass From noreply at buildbot.pypy.org Sun Oct 7 18:44:23 2012 From: noreply at buildbot.pypy.org (stefanor) Date: Sun, 7 Oct 2012 18:44:23 +0200 (CEST) Subject: [pypy-commit] pypy default: Add GNU/kFreeBSD platform description. It needs -lrt Message-ID: <20121007164423.699231C041E@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r57832:db40e4d6a501 Date: 2012-10-07 18:43 +0200 http://bitbucket.org/pypy/pypy/changeset/db40e4d6a501/ Log: Add GNU/kFreeBSD platform description. It needs -lrt diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py --- a/pypy/translator/platform/__init__.py +++ b/pypy/translator/platform/__init__.py @@ -260,6 +260,13 @@ host_factory = Darwin_i386 else: host_factory = Darwin_x86_64 +elif "gnukfreebsd" in sys.platform: + from pypy.translator.platform.freebsd import GNUkFreebsd, GNUkFreebsd_64 + import platform + if platform.architecture()[0] == '32bit': + host_factory = GNUkFreebsd + else: + host_factory = GNUkFreebsd_64 elif "freebsd" in sys.platform: from pypy.translator.platform.freebsd import Freebsd, Freebsd_64 import platform diff --git a/pypy/translator/platform/freebsd.py b/pypy/translator/platform/freebsd.py --- a/pypy/translator/platform/freebsd.py +++ b/pypy/translator/platform/freebsd.py @@ -52,3 +52,9 @@ class Freebsd_64(Freebsd): shared_only = ('-fPIC',) + +class GNUkFreebsd(Freebsd): + extra_libs = ('-lrt',) + +class GNUkFreebsd_64(Freebsd_64): + extra_libs = ('-lrt',) From noreply at buildbot.pypy.org Sun Oct 7 18:54:11 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 18:54:11 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Write some of the JIT parameter handling code more sanely (also of course makes it work with the new lack of SomeObject) Message-ID: <20121007165411.3324F1C041E@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57833:70ea70d1e526 Date: 2012-10-07 18:53 +0200 http://bitbucket.org/pypy/pypy/changeset/70ea70d1e526/ Log: Write some of the JIT parameter handling code more sanely (also of course makes it work with the new lack of SomeObject) diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -430,7 +430,6 @@ 'enable_opts': 'all', } unroll_parameters = unrolling_iterable(PARAMETERS.items()) -DEFAULT = object() # ____________________________________________________________ @@ -552,7 +551,7 @@ def _set_param(driver, name, value): # special-cased by ExtRegistryEntry # (internal, must receive a constant 'name') - # if value is DEFAULT, sets the default value. + # if value is None, sets the default value. assert name in PARAMETERS @specialize.arg(0, 1) @@ -564,7 +563,7 @@ @specialize.arg(0, 1) def set_param_to_default(driver, name): """Reset one of the tunable JIT parameters to its default value.""" - _set_param(driver, name, DEFAULT) + _set_param(driver, name, None) def set_user_param(driver, text): """Set the tunable JIT parameters from a user-supplied string @@ -771,7 +770,7 @@ def compute_result_annotation(self, s_driver, s_name, s_value): from pypy.annotation import model as annmodel assert s_name.is_constant() - if not self.bookkeeper.immutablevalue(DEFAULT).contains(s_value): + if annmodel.s_None.contains(s_value): if s_name.const == 'enable_opts': assert annmodel.SomeString(can_be_None=True).contains(s_value) else: @@ -791,7 +790,7 @@ else: repr = lltype.Signed if (isinstance(hop.args_v[2], Constant) and - hop.args_v[2].value is DEFAULT): + hop.args_v[2].value is None): value = PARAMETERS[name] v_value = hop.inputconst(repr, value) else: From noreply at buildbot.pypy.org Sun Oct 7 19:27:15 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 19:27:15 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix bug with pow(x, BIGNUM, z). Message-ID: <20121007172715.46E781C03FB@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57834:2fd0ae547d86 Date: 2012-10-07 19:26 +0200 http://bitbucket.org/pypy/pypy/changeset/2fd0ae547d86/ Log: Fix bug with pow(x, BIGNUM, z). diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -644,8 +644,7 @@ # j = (m+) % SHIFT = (m+) - (i * SHIFT) # (computed without doing "i * SHIFT", which might overflow) j = size_b % 5 - if j != 0: - j = 5 - j + j = _jmapping[j] if not we_are_translated(): assert j == (size_b*SHIFT+4)//5*5 - size_b*SHIFT # @@ -866,6 +865,12 @@ ONENEGATIVERBIGINT = rbigint([ONEDIGIT], -1, 1) NULLRBIGINT = rbigint() +_jmapping = [(5 * SHIFT) % 5, + (4 * SHIFT) % 5, + (3 * SHIFT) % 5, + (2 * SHIFT) % 5, + (1 * SHIFT) % 5] + #_________________________________________________________________ # Helper Functions diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -396,6 +396,14 @@ v = two.pow(t, rbigint.fromint(n)) assert v.toint() == pow(2, t.tolong(), n) + def test_pow_lll_bug2(self): + x = rbigint.fromlong(2) + y = rbigint.fromlong(5100894665148900058249470019412564146962964987365857466751243988156579407594163282788332839328303748028644825680244165072186950517295679131100799612871613064597) + z = rbigint.fromlong(538564) + expected = rbigint.fromlong(163464) + got = x.pow(y, z) + assert got.eq(expected) + def test_pow_lln(self): x = 10L y = 2L From noreply at buildbot.pypy.org Sun Oct 7 19:27:42 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 19:27:42 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Remove more pyobj stuff Message-ID: <20121007172742.960761C03FB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57835:bf78aca59cc6 Date: 2012-10-07 19:26 +0200 http://bitbucket.org/pypy/pypy/changeset/bf78aca59cc6/ Log: Remove more pyobj stuff diff --git a/pypy/rpython/lltypesystem/test/test_lltype.py b/pypy/rpython/lltypesystem/test/test_lltype.py --- a/pypy/rpython/lltypesystem/test/test_lltype.py +++ b/pypy/rpython/lltypesystem/test/test_lltype.py @@ -718,10 +718,6 @@ gc.collect() repr(s) -def test_pyobject(): - p = pyobjectptr({42: 84}) - assert typeOf(p) == Ptr(PyObject) - def test_name_clash(): import re fn = lltype.__file__ diff --git a/pypy/rpython/memory/gctransform/support.py b/pypy/rpython/memory/gctransform/support.py --- a/pypy/rpython/memory/gctransform/support.py +++ b/pypy/rpython/memory/gctransform/support.py @@ -3,17 +3,6 @@ from pypy.annotation import model as annmodel import os -def var_ispyobj(var): - if hasattr(var, 'concretetype'): - if isinstance(var.concretetype, lltype.Ptr): - return var.concretetype.TO._gckind == 'cpy' - else: - return False - else: - # assume PyObjPtr - return True - -PyObjPtr = lltype.Ptr(lltype.PyObject) def find_gc_ptrs_in_type(TYPE): if isinstance(TYPE, lltype.Array): @@ -33,20 +22,6 @@ else: return [] -def type_contains_pyobjs(TYPE): - if isinstance(TYPE, lltype.Array): - return type_contains_pyobjs(TYPE.OF) - elif isinstance(TYPE, lltype.Struct): - result = [] - for name in TYPE._names: - if type_contains_pyobjs(TYPE._flds[name]): - return True - return False - elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'cpy': - return True - else: - return False - def get_rtti(TYPE): if isinstance(TYPE, lltype.RttiStruct): try: diff --git a/pypy/rpython/memory/gctransform/transform.py b/pypy/rpython/memory/gctransform/transform.py --- a/pypy/rpython/memory/gctransform/transform.py +++ b/pypy/rpython/memory/gctransform/transform.py @@ -1,4 +1,3 @@ -import py from pypy.rpython.lltypesystem import lltype, llmemory from pypy.objspace.flow.model import SpaceOperation, Variable, Constant, \ c_last_exception, checkgraph @@ -7,24 +6,18 @@ from pypy.translator.unsimplify import starts_with_empty_block from pypy.translator.backendopt.support import var_needsgc from pypy.translator.backendopt import inline -from pypy.translator.backendopt import graphanalyze from pypy.translator.backendopt.canraise import RaiseAnalyzer from pypy.translator.backendopt.ssa import DataFlowFamilyBuilder from pypy.translator.backendopt.constfold import constant_fold_graph from pypy.annotation import model as annmodel from pypy.rpython import rmodel -from pypy.rpython.memory import gc -from pypy.rpython.memory.gctransform.support import var_ispyobj from pypy.rpython.annlowlevel import MixLevelHelperAnnotator from pypy.rpython.rtyper import LowLevelOpList from pypy.rpython.rbuiltin import gen_cast from pypy.rlib.rarithmetic import ovfcheck -import sys -import os from pypy.rpython.lltypesystem.lloperation import llop -from pypy.translator.simplify import join_blocks, cleanup_graph +from pypy.translator.simplify import cleanup_graph -PyObjPtr = lltype.Ptr(lltype.PyObject) class GcHighLevelOp(object): def __init__(self, gct, op, index, llops): @@ -55,17 +48,9 @@ if var_needsgc(v_result): gct.livevars.append(v_result) - if var_ispyobj(v_result): - if opname in ('getfield', 'getarrayitem', 'same_as', - 'cast_pointer', 'getsubstruct', - 'getinteriorfield'): - # XXX more operations? - gct.push_alive(v_result, self.llops) - elif opname not in ('direct_call', 'indirect_call'): + if opname not in ('direct_call', 'indirect_call'): gct.push_alive(v_result, self.llops) - - def rename(self, newopname): self.llops.append( SpaceOperation(newopname, self.spaceop.args, self.spaceop.result)) @@ -85,8 +70,8 @@ def cast_result(self, var): v_result = self.spaceop.result - resulttype = getattr(v_result, 'concretetype', PyObjPtr) - curtype = getattr(var, 'concretetype', PyObjPtr) + resulttype = v_result.concretetype + curtype = var.concretetype if curtype == resulttype: self.genop('same_as', [var], resultvar=v_result) else: @@ -120,11 +105,8 @@ self.minimalgctransformer = None def get_lltype_of_exception_value(self): - if self.translator is not None: - exceptiondata = self.translator.rtyper.getexceptiondata() - return exceptiondata.lltype_of_exception_value - else: - return lltype.Ptr(lltype.PyObject) + exceptiondata = self.translator.rtyper.getexceptiondata() + return exceptiondata.lltype_of_exception_value def need_minimal_transform(self, graph): self.seen_graphs[graph] = True @@ -329,28 +311,11 @@ hop.rename('bare_' + opname) self.pop_alive(v_old, hop.llops) - def push_alive(self, var, llops): - if var_ispyobj(var): - self.push_alive_pyobj(var, llops) - else: - self.push_alive_nopyobj(var, llops) + self.push_alive_nopyobj(var, llops) def pop_alive(self, var, llops): - if var_ispyobj(var): - self.pop_alive_pyobj(var, llops) - else: - self.pop_alive_nopyobj(var, llops) - - def push_alive_pyobj(self, var, llops): - if hasattr(var, 'concretetype') and var.concretetype != PyObjPtr: - var = gen_cast(llops, PyObjPtr, var) - llops.genop("gc_push_alive_pyobj", [var]) - - def pop_alive_pyobj(self, var, llops): - if hasattr(var, 'concretetype') and var.concretetype != PyObjPtr: - var = gen_cast(llops, PyObjPtr, var) - llops.genop("gc_pop_alive_pyobj", [var]) + self.pop_alive_nopyobj(var, llops) def push_alive_nopyobj(self, var, llops): pass @@ -359,7 +324,7 @@ pass def var_needs_set_transform(self, var): - return var_ispyobj(var) + return False def default(self, hop): hop.llops.append(hop.spaceop) diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py --- a/pypy/translator/c/funcgen.py +++ b/pypy/translator/c/funcgen.py @@ -53,7 +53,7 @@ self.collect_var_and_types() for v in self.vars: - T = getattr(v, 'concretetype', PyObjPtr) + T = v.concretetype # obscure: skip forward references and hope for the best # (needed for delayed function pointers) if isinstance(T, Ptr) and T.TO.__class__ == ForwardReference: @@ -121,7 +121,7 @@ db = self.db lltypes = identity_dict() for v in self.vars: - T = getattr(v, 'concretetype', PyObjPtr) + T = v.concretetype typename = db.gettype(T) lltypes[v] = T, typename self.illtypes = lltypes @@ -221,12 +221,6 @@ if len(block.exits) == 0: assert len(block.inputargs) == 1 # regular return block - if self.exception_policy == "CPython": - assert self.lltypemap(self.graph.getreturnvar()) == PyObjPtr - yield 'if (RPyExceptionOccurred()) {' - yield '\tRPyConvertExceptionToCPython();' - yield '\treturn NULL;' - yield '}' retval = self.expr(block.inputargs[0]) if self.exception_policy != "exc_helper": yield 'RPY_DEBUG_RETURN();' @@ -241,20 +235,12 @@ assert block.exitswitch != c_last_exception # block ending in a switch on a value TYPE = self.lltypemap(block.exitswitch) - if TYPE in (Bool, PyObjPtr): + if TYPE == Bool: expr = self.expr(block.exitswitch) for link in block.exits[:0:-1]: assert link.exitcase in (False, True) - if TYPE == Bool: - if not link.exitcase: - expr = '!' + expr - elif TYPE == PyObjPtr: - yield 'assert(%s == Py_True || %s == Py_False);' % ( - expr, expr) - if link.exitcase: - expr = '%s == Py_True' % expr - else: - expr = '%s == Py_False' % expr + if not link.exitcase: + expr = '!' + expr yield 'if (%s) {' % expr for op in self.gen_link(link): yield '\t' + op From noreply at buildbot.pypy.org Sun Oct 7 19:34:37 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 19:34:37 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Remove a bunch of PyObject stuff from the GCs Message-ID: <20121007173437.4C4451C03FB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57836:d2c5a48866bd Date: 2012-10-07 19:33 +0200 http://bitbucket.org/pypy/pypy/changeset/d2c5a48866bd/ Log: Remove a bunch of PyObject stuff from the GCs diff --git a/pypy/rpython/memory/gcwrapper.py b/pypy/rpython/memory/gcwrapper.py --- a/pypy/rpython/memory/gcwrapper.py +++ b/pypy/rpython/memory/gcwrapper.py @@ -5,6 +5,7 @@ from pypy.rpython.memory import gctypelayout from pypy.objspace.flow.model import Constant + class GCManagedHeap(object): def __init__(self, llinterp, flowgraphs, gc_class, GC_PARAMS={}): @@ -152,9 +153,6 @@ else: return True - def pyobjectptr(self, klass): - raise NotImplementedError(klass) - # ____________________________________________________________ class LLInterpRootWalker: @@ -193,8 +191,7 @@ super(DirectRunLayoutBuilder, self).__init__(GCClass, lltype2vtable) def make_finalizer_funcptr_for_type(self, TYPE): - from pypy.rpython.memory.gctransform.support import get_rtti, \ - type_contains_pyobjs + from pypy.rpython.memory.gctransform.support import get_rtti rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): destrptr = rtti._obj.destructor_funcptr @@ -203,7 +200,6 @@ else: return None, False - assert not type_contains_pyobjs(TYPE), "not implemented" t = self.llinterp.typer.annotator.translator light = not FinalizerAnalyzer(t).analyze_light_finalizer(destrgraph) def ll_finalizer(addr, dummy): @@ -218,8 +214,7 @@ return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer), light def make_custom_trace_funcptr_for_type(self, TYPE): - from pypy.rpython.memory.gctransform.support import get_rtti, \ - type_contains_pyobjs + from pypy.rpython.memory.gctransform.support import get_rtti rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'custom_trace_funcptr'): return rtti._obj.custom_trace_funcptr diff --git a/pypy/rpython/memory/lltypelayout.py b/pypy/rpython/memory/lltypelayout.py --- a/pypy/rpython/memory/lltypelayout.py +++ b/pypy/rpython/memory/lltypelayout.py @@ -47,8 +47,6 @@ return "i" elif isinstance(TYPE, lltype.FuncType): return "i" - elif isinstance(TYPE, lltype.PyObjectType): - return "i" else: assert 0, "type %s not yet implemented" % (TYPE, ) @@ -71,8 +69,6 @@ return get_fixed_size(lltype.Unsigned) elif isinstance(TYPE, lltype.FuncType): return get_fixed_size(lltype.Unsigned) - elif isinstance(TYPE, lltype.PyObjectType): - return get_fixed_size(lltype.Unsigned) assert 0, "not yet implemented" def get_variable_size(TYPE): @@ -89,8 +85,6 @@ return 0 elif isinstance(TYPE, lltype.FuncType): return 0 - elif isinstance(TYPE, lltype.PyObjectType): - return 0 elif isinstance(TYPE, lltype.Ptr): return 0 else: From noreply at buildbot.pypy.org Sun Oct 7 19:38:40 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 7 Oct 2012 19:38:40 +0200 (CEST) Subject: [pypy-commit] pypy default: rpython supports the with statement Message-ID: <20121007173840.3DF491C0CD3@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r57837:52fdda6089af Date: 2012-10-07 10:38 -0700 http://bitbucket.org/pypy/pypy/changeset/52fdda6089af/ Log: rpython supports the with statement diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -41,9 +41,6 @@ llexternal functions. For a typical usage, see `pypy.rlib.rsocket.RSocket.getsockopt_int`. -- Support context managers and the `with` statement. This could be a workaround - before the previous point is available. - Extensible type system for llexternal ------------------------------------- From noreply at buildbot.pypy.org Sun Oct 7 19:43:19 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 19:43:19 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: remove more dead code about pyobjs Message-ID: <20121007174319.82C341C0D42@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57838:ec21db827d58 Date: 2012-10-07 19:42 +0200 http://bitbucket.org/pypy/pypy/changeset/ec21db827d58/ Log: remove more dead code about pyobjs diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py --- a/pypy/rpython/memory/gctransform/framework.py +++ b/pypy/rpython/memory/gctransform/framework.py @@ -5,8 +5,7 @@ from pypy.rpython.lltypesystem.lloperation import LL_OPERATIONS from pypy.rpython.memory import gctypelayout from pypy.rpython.memory.gctransform.log import log -from pypy.rpython.memory.gctransform.support import get_rtti, \ - ll_call_destructor, type_contains_pyobjs, var_ispyobj +from pypy.rpython.memory.gctransform.support import get_rtti, ll_call_destructor from pypy.rpython.memory.gctransform.transform import GCTransformer from pypy.rpython.memory.gctypelayout import ll_weakref_deref, WEAKREF, \ WEAKREFPTR @@ -19,6 +18,7 @@ TYPE_ID = llgroup.HALFWORD + class CollectAnalyzer(graphanalyze.BoolGraphAnalyzer): def analyze_direct_call(self, graph, seen=None): @@ -1184,11 +1184,9 @@ if self.gcdata.gc.moving_gc and not keep_current_args: # moving GCs don't borrow, so the caller does not need to keep # the arguments alive - livevars = [var for var in hop.livevars_after_op() - if not var_ispyobj(var)] + livevars = [var for var in hop.livevars_after_op()] else: livevars = hop.livevars_after_op() + hop.current_op_keeps_alive() - livevars = [var for var in livevars if not var_ispyobj(var)] return livevars def compute_borrowed_vars(self, graph): @@ -1244,7 +1242,6 @@ rtti = get_rtti(TYPE) destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] - assert not type_contains_pyobjs(TYPE), "not implemented" typename = TYPE.__name__ def ll_finalizer(addr, ignored): v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) diff --git a/pypy/rpython/memory/test/test_transformed_gc.py b/pypy/rpython/memory/test/test_transformed_gc.py --- a/pypy/rpython/memory/test/test_transformed_gc.py +++ b/pypy/rpython/memory/test/test_transformed_gc.py @@ -1,10 +1,9 @@ import py -import sys import inspect + from pypy.translator.c import gc from pypy.annotation import model as annmodel -from pypy.annotation import policy as annpolicy -from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi, llgroup +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, llgroup from pypy.rpython.memory.gctransform import framework, shadowstack from pypy.rpython.lltypesystem.lloperation import llop, void from pypy.rlib.objectmodel import compute_unique_id, we_are_translated @@ -25,7 +24,7 @@ t.config.translation.gc = gcname t.config.translation.gcremovetypeptr = True t.config.set(**extraconfigopts) - ann = t.buildannotator(policy=annpolicy.StrictAnnotatorPolicy()) + ann = t.buildannotator() ann.build_types(func, inputtypes) if specialize: From noreply at buildbot.pypy.org Sun Oct 7 19:46:02 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 19:46:02 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Remove naming that no longer makes sense. Message-ID: <20121007174602.B62ED1C0D6C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57839:f3367162aaed Date: 2012-10-07 19:45 +0200 http://bitbucket.org/pypy/pypy/changeset/f3367162aaed/ Log: Remove naming that no longer makes sense. diff --git a/pypy/rpython/memory/gctransform/boehm.py b/pypy/rpython/memory/gctransform/boehm.py --- a/pypy/rpython/memory/gctransform/boehm.py +++ b/pypy/rpython/memory/gctransform/boehm.py @@ -57,12 +57,6 @@ self.mixlevelannotator.finish() # for now self.mixlevelannotator.backend_optimize() - def push_alive_nopyobj(self, var, llops): - pass - - def pop_alive_nopyobj(self, var, llops): - pass - def gct_fv_gc_malloc(self, hop, flags, TYPE, c_size): # XXX same behavior for zero=True: in theory that's wrong if TYPE._is_atomic(): diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py --- a/pypy/rpython/memory/gctransform/framework.py +++ b/pypy/rpython/memory/gctransform/framework.py @@ -1174,12 +1174,6 @@ def var_needs_set_transform(self, var): return var_needsgc(var) - def push_alive_nopyobj(self, var, llops): - pass - - def pop_alive_nopyobj(self, var, llops): - pass - def get_livevars_for_roots(self, hop, keep_current_args=False): if self.gcdata.gc.moving_gc and not keep_current_args: # moving GCs don't borrow, so the caller does not need to keep diff --git a/pypy/rpython/memory/gctransform/refcounting.py b/pypy/rpython/memory/gctransform/refcounting.py --- a/pypy/rpython/memory/gctransform/refcounting.py +++ b/pypy/rpython/memory/gctransform/refcounting.py @@ -142,11 +142,11 @@ def var_needs_set_transform(self, var): return var_needsgc(var) - def push_alive_nopyobj(self, var, llops): + def push_alive(self, var, llops): v_adr = gen_cast(llops, llmemory.Address, var) llops.genop("direct_call", [self.increfptr, v_adr]) - def pop_alive_nopyobj(self, var, llops): + def pop_alive(self, var, llops): PTRTYPE = var.concretetype v_adr = gen_cast(llops, llmemory.Address, var) diff --git a/pypy/rpython/memory/gctransform/test/test_transform.py b/pypy/rpython/memory/gctransform/test/test_transform.py --- a/pypy/rpython/memory/gctransform/test/test_transform.py +++ b/pypy/rpython/memory/gctransform/test/test_transform.py @@ -5,11 +5,9 @@ from pypy.translator.translator import TranslationContext, graphof from pypy.translator.exceptiontransform import ExceptionTransformer from pypy.rpython.lltypesystem import lltype -from pypy.objspace.flow.model import Variable -from pypy.annotation import model as annmodel -from pypy.rpython.extregistry import ExtRegistryEntry from pypy import conftest + class LLInterpedTranformerTests: def llinterpreter_for_transformed_graph(self, f, args_s): @@ -93,12 +91,13 @@ res = llinterp.eval_graph(graph, [False]) assert res == f(False) + class _TestGCTransformer(BaseGCTransformer): - def push_alive_nopyobj(self, var, llops): + def push_alive(self, var, llops): llops.genop("gc_push_alive", [var]) - def pop_alive_nopyobj(self, var, llops): + def pop_alive(self, var, llops): llops.genop("gc_pop_alive", [var]) diff --git a/pypy/rpython/memory/gctransform/transform.py b/pypy/rpython/memory/gctransform/transform.py --- a/pypy/rpython/memory/gctransform/transform.py +++ b/pypy/rpython/memory/gctransform/transform.py @@ -312,15 +312,9 @@ self.pop_alive(v_old, hop.llops) def push_alive(self, var, llops): - self.push_alive_nopyobj(var, llops) + pass def pop_alive(self, var, llops): - self.pop_alive_nopyobj(var, llops) - - def push_alive_nopyobj(self, var, llops): - pass - - def pop_alive_nopyobj(self, var, llops): pass def var_needs_set_transform(self, var): From noreply at buildbot.pypy.org Sun Oct 7 19:47:45 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 19:47:45 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: style fixes Message-ID: <20121007174745.DDF831C0D6C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57840:f2d251283e6e Date: 2012-10-07 19:46 +0200 http://bitbucket.org/pypy/pypy/changeset/f2d251283e6e/ Log: style fixes diff --git a/pypy/rpython/memory/gctransform/test/test_transform.py b/pypy/rpython/memory/gctransform/test/test_transform.py --- a/pypy/rpython/memory/gctransform/test/test_transform.py +++ b/pypy/rpython/memory/gctransform/test/test_transform.py @@ -13,12 +13,11 @@ def llinterpreter_for_transformed_graph(self, f, args_s): from pypy.rpython.llinterp import LLInterpreter from pypy.translator.c.genc import CStandaloneBuilder - from pypy.translator.c import gc t = rtype(f, args_s) # XXX we shouldn't need an actual gcpolicy here. cbuild = CStandaloneBuilder(t, f, t.config, gcpolicy=self.gcpolicy) - db = cbuild.generate_graphs_for_llinterp() + cbuild.generate_graphs_for_llinterp() graph = cbuild.getentrypointptr()._obj.graph # arguments cannot be GC objects because nobody would put a # proper header on them @@ -30,7 +29,6 @@ t.view() return llinterp, graph - def test_simple(self): from pypy.annotation.model import SomeInteger @@ -65,7 +63,6 @@ r.append(x) return len(r) - llinterp, graph = self.llinterpreter_for_transformed_graph(f, [SomeInteger()]) res = llinterp.eval_graph(graph, [0]) @@ -83,7 +80,6 @@ x = 'brrrrrrr' return len(x + 'a') - llinterp, graph = self.llinterpreter_for_transformed_graph(f, [SomeBool()]) res = llinterp.eval_graph(graph, [True]) @@ -150,7 +146,7 @@ t.buildrtyper().specialize() if conftest.option.view: t.view() - return t + return t def rtype_and_transform(func, inputtypes, transformcls, specialize=True, check=True): t = rtype(func, inputtypes, specialize) @@ -198,7 +194,7 @@ c.x = 1 return c t, transformer = rtype_and_transform(f, [], _TestGCTransformer) - + def test_call_function(): class C: pass @@ -322,7 +318,7 @@ except ValueError: return 0 t, transformer = rtype_and_transform(g, [int], _TestGCTransformer) - + def test_no_livevars_with_exception(): def g(): raise TypeError @@ -337,7 +333,8 @@ def test_bare_setfield(): from pypy.rpython.lltypesystem.lloperation import llop class A: - def __init__(self, obj): self.x = obj + def __init__(self, obj): + self.x = obj def f(v): inst = A(v) llop.setfield(lltype.Void, inst, 'x', v) From noreply at buildbot.pypy.org Sun Oct 7 19:53:08 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 19:53:08 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Make OO tests run. Message-ID: <20121007175308.0BF4F1C0DB2@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57841:b895c022394a Date: 2012-10-07 19:52 +0200 http://bitbucket.org/pypy/pypy/changeset/b895c022394a/ Log: Make OO tests run. diff --git a/pypy/rpython/ootypesystem/test/test_ooclean.py b/pypy/rpython/ootypesystem/test/test_ooclean.py --- a/pypy/rpython/ootypesystem/test/test_ooclean.py +++ b/pypy/rpython/ootypesystem/test/test_ooclean.py @@ -1,25 +1,21 @@ -from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype from pypy.rpython.test.test_llinterp import get_interpreter import py -import sys def check_only_ootype(graph): def check_ootype(v): t = v.concretetype assert isinstance(t, ootype.Primitive) or isinstance(t, ootype.OOType) - for block in graph.iterblocks(): for var in block.getvariables(): check_ootype(var) for const in block.getconstants(): check_ootype(const) -def interpret(func, values, view=False, viewbefore=False, policy=None, - someobjects=False): +def interpret(func, values, view=False, viewbefore=False, policy=None): interp, graph = get_interpreter(func, values, view, viewbefore, policy, - someobjects, type_system='ootype') + type_system='ootype') for g in interp.typer.annotator.translator.graphs: check_only_ootype(g) return interp.eval_graph(graph, values) From noreply at buildbot.pypy.org Sun Oct 7 19:56:27 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 7 Oct 2012 19:56:27 +0200 (CEST) Subject: [pypy-commit] pypy numpy-reintroduce-zjit-tests: in-progress, waiting for some other branch Message-ID: <20121007175627.745AF1C0DDC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: numpy-reintroduce-zjit-tests Changeset: r57842:330b40485c02 Date: 2012-10-07 11:04 +0200 http://bitbucket.org/pypy/pypy/changeset/330b40485c02/ Log: in-progress, waiting for some other branch diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -2524,6 +2524,36 @@ s = a.build_types(f, []) assert s.const == 2 + def test_mixin_staticmethod(self): + class A(object): + _mixin_ = True + + def __init__(self, v): + self.v = v + + @staticmethod + def x(foo): + return len(foo) + + def m(self): + return self.x(self.v) + + class B(A): + pass + + class C(A): + pass + + def f(i): + if i: + return B([1, 2, 3]).m() + else: + return C("xyz").m() + + a = self.RPythonAnnotator() + s = a.build_types(f, [int]) + assert isinstance(s, annmodel.SomeInteger) + def test___class___attribute(self): class Base(object): pass class A(Base): pass 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 @@ -122,9 +122,10 @@ # XXX deal with the bridge at some point self.check_simple_loop({'raw_load':2, 'float_add': 1, 'raw_store': 1, 'getarrayitem_gc': 3, - 'getarrayitem_gc_pure': 1, 'int_add': 2, - 'int_sub': 1, 'setfield_gc': 1, + 'getarrayitem_gc_pure': 1, 'int_add': 3, + 'int_sub': 1, 'setfield_gc': 2, 'int_lt': 1, 'guard_true': 1, + 'jump': 1, 'setarrayitem_gc': 1}) def define_max(): @@ -139,7 +140,8 @@ assert result == 128 self.check_simple_loop({"raw_load": 1, "float_gt": 1, "guard_false": 2, "int_add": 1, - "int_ge": 1, "setfield_gc": 1}) + "int_ge": 1, "setfield_gc": 1, + 'jump': 1}) def define_any(): return """ diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -257,8 +257,8 @@ @specialize.argtype(1) def box(self, value): - box = Primitive.box(self, value) - if box.value: + value = lookup_type_dict(lltype.typeOf(value)).for_computation(value) + if value: return self.True else: return self.False @@ -276,7 +276,8 @@ def str_format(self, box): return "True" if self.unbox(box) else "False" - def for_computation(self, v): + @staticmethod + def for_computation(v): return int(v) def default_fromstring(self, space): @@ -311,7 +312,8 @@ def str_format(self, box): return str(self.for_computation(self.unbox(box))) - def for_computation(self, v): + @staticmethod + def for_computation(v): return widen(v) def default_fromstring(self, space): @@ -556,7 +558,8 @@ return float2string(self.for_computation(self.unbox(box)), "g", rfloat.DTSF_STR_PRECISION) - def for_computation(self, v): + @staticmethod + def for_computation(v): return float(v) def default_fromstring(self, space): @@ -986,10 +989,18 @@ break del tp +TYPE_DICT = {} + def _setup(): # compute alignment for tp in globals().values(): if isinstance(tp, type) and hasattr(tp, 'T'): tp.alignment = clibffi.cast_type_to_ffitype(tp.T).c_alignment + TYPE_DICT[tp.T] = tp + + at specialize.memo() +def lookup_type_dict(T): + return TYPE_DICT[T] + _setup() del _setup From noreply at buildbot.pypy.org Sun Oct 7 19:56:28 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 7 Oct 2012 19:56:28 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: in-progress Message-ID: <20121007175628.C875F1C0DDC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57843:d37368dbd72a Date: 2012-10-07 19:49 +0200 http://bitbucket.org/pypy/pypy/changeset/d37368dbd72a/ Log: in-progress diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -276,44 +276,6 @@ extrafiles.append(fn) return extrafiles -class ModuleWithCleanup(object): - def __init__(self, mod): - self.__dict__['mod'] = mod - - def __getattr__(self, name): - mod = self.__dict__['mod'] - obj = getattr(mod, name) - parentself = self - if callable(obj) and getattr(obj, '__module__', None) == mod.__name__: - # The module must be kept alive with the function. - # This wrapper avoids creating a cycle. - class Wrapper: - def __init__(self, obj): - self.myself = parentself - self.func = obj - def __call__(self, *args, **kwargs): - return self.func(*args, **kwargs) - obj = Wrapper(obj) - return obj - - def __setattr__(self, name, val): - mod = self.__dict__['mod'] - setattr(mod, name, val) - - def __del__(self): - import sys - if sys.platform == "win32": - from _ctypes import FreeLibrary as dlclose - else: - from _ctypes import dlclose - # XXX fish fish fish - mod = self.__dict__['mod'] - dlclose(mod._lib._handle) - try: - del sys.modules[mod.__name__] - except KeyError: - pass - class CStandaloneBuilder(CBuilder): standalone = True diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -44,19 +44,11 @@ def test_simple(): def f(x): return x*2 - t = TranslationContext() - t.buildannotator().build_types(f, [int]) - t.buildrtyper().specialize() - t.config.translation.countmallocs = True - builder = genc.CExtModuleBuilder(t, f, config=t.config) - builder.generate_source() - builder.compile() - f1 = builder.get_entry_point() + f1 = compile(f, [int]) assert f1(5) == 10 assert f1(-123) == -246 - assert builder.get_malloc_counters()() == (0, 0) py.test.raises(Exception, f1, "world") # check that it's really typed From noreply at buildbot.pypy.org Sun Oct 7 19:56:29 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 7 Oct 2012 19:56:29 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (agaynor, fijal, arigo, crazy hg hackery) backout driver changes, dlltool Message-ID: <20121007175629.E75D91C0DDC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57844:40f5bd151095 Date: 2012-10-07 19:54 +0200 http://bitbucket.org/pypy/pypy/changeset/40f5bd151095/ Log: (agaynor, fijal, arigo, crazy hg hackery) backout driver changes, dlltool make standalone=False diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py --- a/pypy/translator/driver.py +++ b/pypy/translator/driver.py @@ -172,14 +172,19 @@ def _maybe_skip(self): maybe_skip = [] if self._disabled: - for goal in self.backend_select_goals(self._disabled): + for goal in self.backend_select_goals(self._disabled): maybe_skip.extend(self._depending_on_closure(goal)) return dict.fromkeys(maybe_skip).keys() + def setup(self, entry_point, inputtypes, policy=None, extra={}, empty_translator=None): - assert inputtypes is None - # the 'argv' parameter - self.inputtypes = [s_list_of_strings] + standalone = inputtypes is None + self.standalone = standalone + + if standalone: + # the 'argv' parameter + inputtypes = [s_list_of_strings] + self.inputtypes = inputtypes if policy is None: policy = annpolicy.AnnotatorPolicy() @@ -317,7 +322,7 @@ s = None self.sanity_check_annotation() - if self.entry_point and s.knowntype != int: + if self.entry_point and self.standalone and s.knowntype != int: raise Exception("stand-alone program entry point must return an " "int (and not, e.g., None or always raise an " "exception).") @@ -464,10 +469,15 @@ if self.libdef is not None: cbuilder = self.libdef.getcbuilder(self.translator, self.config) + self.standalone = False standalone = False else: - from pypy.translator.c.genc import CStandaloneBuilder as CBuilder - standalone = True + standalone = self.standalone + + if standalone: + from pypy.translator.c.genc import CStandaloneBuilder as CBuilder + else: + from pypy.translator.c.genc import CExtModuleBuilder as CBuilder cbuilder = CBuilder(self.translator, self.entry_point, config=self.config, secondary_entrypoints=self.secondary_entrypoints) @@ -541,13 +551,17 @@ """ cbuilder = self.cbuilder kwds = {} - if self.exe_name is not None: + if self.standalone and self.exe_name is not None: kwds['exe_name'] = self.compute_exe_name().basename cbuilder.compile(**kwds) - self.c_entryp = cbuilder.executable_name - self.create_exe() - + if self.standalone: + self.c_entryp = cbuilder.executable_name + self.create_exe() + else: + isolated = self._backend_extra_options.get('c_isolated', False) + self.c_entryp = cbuilder.get_entry_point(isolated=isolated) + # task_compile_c = taskdef(task_compile_c, ['source_c'], "Compiling c source") def task_llinterpret_lltype(self): @@ -597,7 +611,7 @@ unpatch_os(self.old_cli_defs) self.log.info("Compiled %s" % filename) - if self.exe_name: + if self.standalone and self.exe_name: self.copy_cli_exe() task_compile_cli = taskdef(task_compile_cli, ['source_cli'], 'Compiling CLI source') @@ -664,7 +678,8 @@ from pypy.translator.jvm.node import EntryPoint entry_point_graph = self.translator.graphs[0] - entry_point = EntryPoint(entry_point_graph, False, False) + is_func = not self.standalone + entry_point = EntryPoint(entry_point_graph, is_func, is_func) self.gen = GenJvm(udir, self.translator, entry_point) self.jvmsource = self.gen.generate_source() self.log.info("Wrote JVM code") @@ -680,7 +695,7 @@ if hasattr(self, 'old_cli_defs'): unpatch_os(self.old_cli_defs) self.log.info("Compiled JVM source") - if self.exe_name: + if self.standalone and self.exe_name: self.copy_jvm_jar() task_compile_jvm = taskdef(task_compile_jvm, ['source_jvm'], 'Compiling JVM source') From noreply at buildbot.pypy.org Sun Oct 7 19:56:31 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 7 Oct 2012 19:56:31 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121007175631.252AF1C0DDC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57845:4766f06dd382 Date: 2012-10-07 19:55 +0200 http://bitbucket.org/pypy/pypy/changeset/4766f06dd382/ Log: merge diff --git a/pypy/jit/codewriter/call.py b/pypy/jit/codewriter/call.py --- a/pypy/jit/codewriter/call.py +++ b/pypy/jit/codewriter/call.py @@ -180,11 +180,8 @@ """ fnptr = self.rtyper.type_system.getcallable(graph) FUNC = get_functype(lltype.typeOf(fnptr)) - assert lltype.Ptr(lltype.PyObject) not in FUNC.ARGS - if self.rtyper.type_system.name == 'ootypesystem': - XXX - else: - fnaddr = llmemory.cast_ptr_to_adr(fnptr) + assert self.rtyper.type_system.name == "lltypesystem" + fnaddr = llmemory.cast_ptr_to_adr(fnptr) NON_VOID_ARGS = [ARG for ARG in FUNC.ARGS if ARG is not lltype.Void] calldescr = self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), FUNC.RESULT, EffectInfo.MOST_GENERAL) diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -430,7 +430,6 @@ 'enable_opts': 'all', } unroll_parameters = unrolling_iterable(PARAMETERS.items()) -DEFAULT = object() # ____________________________________________________________ @@ -552,7 +551,7 @@ def _set_param(driver, name, value): # special-cased by ExtRegistryEntry # (internal, must receive a constant 'name') - # if value is DEFAULT, sets the default value. + # if value is None, sets the default value. assert name in PARAMETERS @specialize.arg(0, 1) @@ -564,7 +563,7 @@ @specialize.arg(0, 1) def set_param_to_default(driver, name): """Reset one of the tunable JIT parameters to its default value.""" - _set_param(driver, name, DEFAULT) + _set_param(driver, name, None) def set_user_param(driver, text): """Set the tunable JIT parameters from a user-supplied string @@ -641,11 +640,7 @@ self.bookkeeper._jit_annotation_cache[driver] = cache for key, s_value in kwds_s.items(): s_previous = cache.get(key, annmodel.s_ImpossibleValue) - s_value = annmodel.unionof(s_previous, s_value) - if annmodel.isdegenerated(s_value): - raise JitHintError("mixing incompatible types in argument %s" - " of jit_merge_point/can_enter_jit" % - key[2:]) + s_value = annmodel.unionof(s_previous, s_value) # where="mixing incompatible types in argument %s of jit_merge_point/can_enter_jit" % key[2:] cache[key] = s_value # add the attribute _dont_reach_me_in_del_ (see pypy.rpython.rclass) @@ -775,7 +770,7 @@ def compute_result_annotation(self, s_driver, s_name, s_value): from pypy.annotation import model as annmodel assert s_name.is_constant() - if not self.bookkeeper.immutablevalue(DEFAULT).contains(s_value): + if annmodel.s_None.contains(s_value): if s_name.const == 'enable_opts': assert annmodel.SomeString(can_be_None=True).contains(s_value) else: @@ -795,7 +790,7 @@ else: repr = lltype.Signed if (isinstance(hop.args_v[2], Constant) and - hop.args_v[2].value is DEFAULT): + hop.args_v[2].value is None): value = PARAMETERS[name] v_value = hop.inputconst(repr, value) else: diff --git a/pypy/rpython/lltypesystem/test/test_lltype.py b/pypy/rpython/lltypesystem/test/test_lltype.py --- a/pypy/rpython/lltypesystem/test/test_lltype.py +++ b/pypy/rpython/lltypesystem/test/test_lltype.py @@ -718,10 +718,6 @@ gc.collect() repr(s) -def test_pyobject(): - p = pyobjectptr({42: 84}) - assert typeOf(p) == Ptr(PyObject) - def test_name_clash(): import re fn = lltype.__file__ diff --git a/pypy/rpython/memory/gctransform/support.py b/pypy/rpython/memory/gctransform/support.py --- a/pypy/rpython/memory/gctransform/support.py +++ b/pypy/rpython/memory/gctransform/support.py @@ -3,17 +3,6 @@ from pypy.annotation import model as annmodel import os -def var_ispyobj(var): - if hasattr(var, 'concretetype'): - if isinstance(var.concretetype, lltype.Ptr): - return var.concretetype.TO._gckind == 'cpy' - else: - return False - else: - # assume PyObjPtr - return True - -PyObjPtr = lltype.Ptr(lltype.PyObject) def find_gc_ptrs_in_type(TYPE): if isinstance(TYPE, lltype.Array): @@ -33,20 +22,6 @@ else: return [] -def type_contains_pyobjs(TYPE): - if isinstance(TYPE, lltype.Array): - return type_contains_pyobjs(TYPE.OF) - elif isinstance(TYPE, lltype.Struct): - result = [] - for name in TYPE._names: - if type_contains_pyobjs(TYPE._flds[name]): - return True - return False - elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'cpy': - return True - else: - return False - def get_rtti(TYPE): if isinstance(TYPE, lltype.RttiStruct): try: diff --git a/pypy/rpython/memory/gctransform/transform.py b/pypy/rpython/memory/gctransform/transform.py --- a/pypy/rpython/memory/gctransform/transform.py +++ b/pypy/rpython/memory/gctransform/transform.py @@ -1,4 +1,3 @@ -import py from pypy.rpython.lltypesystem import lltype, llmemory from pypy.objspace.flow.model import SpaceOperation, Variable, Constant, \ c_last_exception, checkgraph @@ -7,24 +6,18 @@ from pypy.translator.unsimplify import starts_with_empty_block from pypy.translator.backendopt.support import var_needsgc from pypy.translator.backendopt import inline -from pypy.translator.backendopt import graphanalyze from pypy.translator.backendopt.canraise import RaiseAnalyzer from pypy.translator.backendopt.ssa import DataFlowFamilyBuilder from pypy.translator.backendopt.constfold import constant_fold_graph from pypy.annotation import model as annmodel from pypy.rpython import rmodel -from pypy.rpython.memory import gc -from pypy.rpython.memory.gctransform.support import var_ispyobj from pypy.rpython.annlowlevel import MixLevelHelperAnnotator from pypy.rpython.rtyper import LowLevelOpList from pypy.rpython.rbuiltin import gen_cast from pypy.rlib.rarithmetic import ovfcheck -import sys -import os from pypy.rpython.lltypesystem.lloperation import llop -from pypy.translator.simplify import join_blocks, cleanup_graph +from pypy.translator.simplify import cleanup_graph -PyObjPtr = lltype.Ptr(lltype.PyObject) class GcHighLevelOp(object): def __init__(self, gct, op, index, llops): @@ -55,17 +48,9 @@ if var_needsgc(v_result): gct.livevars.append(v_result) - if var_ispyobj(v_result): - if opname in ('getfield', 'getarrayitem', 'same_as', - 'cast_pointer', 'getsubstruct', - 'getinteriorfield'): - # XXX more operations? - gct.push_alive(v_result, self.llops) - elif opname not in ('direct_call', 'indirect_call'): + if opname not in ('direct_call', 'indirect_call'): gct.push_alive(v_result, self.llops) - - def rename(self, newopname): self.llops.append( SpaceOperation(newopname, self.spaceop.args, self.spaceop.result)) @@ -85,8 +70,8 @@ def cast_result(self, var): v_result = self.spaceop.result - resulttype = getattr(v_result, 'concretetype', PyObjPtr) - curtype = getattr(var, 'concretetype', PyObjPtr) + resulttype = v_result.concretetype + curtype = var.concretetype if curtype == resulttype: self.genop('same_as', [var], resultvar=v_result) else: @@ -120,11 +105,8 @@ self.minimalgctransformer = None def get_lltype_of_exception_value(self): - if self.translator is not None: - exceptiondata = self.translator.rtyper.getexceptiondata() - return exceptiondata.lltype_of_exception_value - else: - return lltype.Ptr(lltype.PyObject) + exceptiondata = self.translator.rtyper.getexceptiondata() + return exceptiondata.lltype_of_exception_value def need_minimal_transform(self, graph): self.seen_graphs[graph] = True @@ -329,28 +311,11 @@ hop.rename('bare_' + opname) self.pop_alive(v_old, hop.llops) - def push_alive(self, var, llops): - if var_ispyobj(var): - self.push_alive_pyobj(var, llops) - else: - self.push_alive_nopyobj(var, llops) + self.push_alive_nopyobj(var, llops) def pop_alive(self, var, llops): - if var_ispyobj(var): - self.pop_alive_pyobj(var, llops) - else: - self.pop_alive_nopyobj(var, llops) - - def push_alive_pyobj(self, var, llops): - if hasattr(var, 'concretetype') and var.concretetype != PyObjPtr: - var = gen_cast(llops, PyObjPtr, var) - llops.genop("gc_push_alive_pyobj", [var]) - - def pop_alive_pyobj(self, var, llops): - if hasattr(var, 'concretetype') and var.concretetype != PyObjPtr: - var = gen_cast(llops, PyObjPtr, var) - llops.genop("gc_pop_alive_pyobj", [var]) + self.pop_alive_nopyobj(var, llops) def push_alive_nopyobj(self, var, llops): pass @@ -359,7 +324,7 @@ pass def var_needs_set_transform(self, var): - return var_ispyobj(var) + return False def default(self, hop): hop.llops.append(hop.spaceop) diff --git a/pypy/rpython/memory/gcwrapper.py b/pypy/rpython/memory/gcwrapper.py --- a/pypy/rpython/memory/gcwrapper.py +++ b/pypy/rpython/memory/gcwrapper.py @@ -5,6 +5,7 @@ from pypy.rpython.memory import gctypelayout from pypy.objspace.flow.model import Constant + class GCManagedHeap(object): def __init__(self, llinterp, flowgraphs, gc_class, GC_PARAMS={}): @@ -152,9 +153,6 @@ else: return True - def pyobjectptr(self, klass): - raise NotImplementedError(klass) - # ____________________________________________________________ class LLInterpRootWalker: @@ -193,8 +191,7 @@ super(DirectRunLayoutBuilder, self).__init__(GCClass, lltype2vtable) def make_finalizer_funcptr_for_type(self, TYPE): - from pypy.rpython.memory.gctransform.support import get_rtti, \ - type_contains_pyobjs + from pypy.rpython.memory.gctransform.support import get_rtti rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): destrptr = rtti._obj.destructor_funcptr @@ -203,7 +200,6 @@ else: return None, False - assert not type_contains_pyobjs(TYPE), "not implemented" t = self.llinterp.typer.annotator.translator light = not FinalizerAnalyzer(t).analyze_light_finalizer(destrgraph) def ll_finalizer(addr, dummy): @@ -218,8 +214,7 @@ return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer), light def make_custom_trace_funcptr_for_type(self, TYPE): - from pypy.rpython.memory.gctransform.support import get_rtti, \ - type_contains_pyobjs + from pypy.rpython.memory.gctransform.support import get_rtti rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'custom_trace_funcptr'): return rtti._obj.custom_trace_funcptr diff --git a/pypy/rpython/memory/lltypelayout.py b/pypy/rpython/memory/lltypelayout.py --- a/pypy/rpython/memory/lltypelayout.py +++ b/pypy/rpython/memory/lltypelayout.py @@ -47,8 +47,6 @@ return "i" elif isinstance(TYPE, lltype.FuncType): return "i" - elif isinstance(TYPE, lltype.PyObjectType): - return "i" else: assert 0, "type %s not yet implemented" % (TYPE, ) @@ -71,8 +69,6 @@ return get_fixed_size(lltype.Unsigned) elif isinstance(TYPE, lltype.FuncType): return get_fixed_size(lltype.Unsigned) - elif isinstance(TYPE, lltype.PyObjectType): - return get_fixed_size(lltype.Unsigned) assert 0, "not yet implemented" def get_variable_size(TYPE): @@ -89,8 +85,6 @@ return 0 elif isinstance(TYPE, lltype.FuncType): return 0 - elif isinstance(TYPE, lltype.PyObjectType): - return 0 elif isinstance(TYPE, lltype.Ptr): return 0 else: diff --git a/pypy/rpython/ootypesystem/rdict.py b/pypy/rpython/ootypesystem/rdict.py --- a/pypy/rpython/ootypesystem/rdict.py +++ b/pypy/rpython/ootypesystem/rdict.py @@ -7,6 +7,8 @@ from pypy.rpython.ootypesystem import ootype from pypy.rlib import objectmodel from pypy.rpython import rmodel, llinterp +# This is needed by other things, don't remove! +from pypy.rpython.rdict import rtype_newdict class DictRepr(AbstractDictRepr): diff --git a/pypy/rpython/rdict.py b/pypy/rpython/rdict.py --- a/pypy/rpython/rdict.py +++ b/pypy/rpython/rdict.py @@ -1,10 +1,5 @@ -from pypy.tool.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.objspace.flow.model import Constant from pypy.rpython.lltypesystem import lltype -from pypy.rlib.rarithmetic import r_uint -from pypy.rlib.objectmodel import hlinvoke -from pypy.rlib import objectmodel from pypy.rpython import rmodel @@ -58,9 +53,6 @@ def rtype_newdict(hop): hop.inputargs() # no arguments expected r_dict = hop.r_result - if r_dict == robject.pyobj_repr: # special case: SomeObject: SomeObject dicts! - cdict = hop.inputconst(robject.pyobj_repr, dict) - return hop.genop('simple_call', [cdict], resulttype = robject.pyobj_repr) cDICT = hop.inputconst(lltype.Void, r_dict.DICT) v_result = hop.gendirectcall(hop.rtyper.type_system.rdict.ll_newdict, cDICT) return v_result diff --git a/pypy/rpython/test/test_robject.py b/pypy/rpython/test/test_robject.py deleted file mode 100644 --- a/pypy/rpython/test/test_robject.py +++ /dev/null @@ -1,59 +0,0 @@ -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.test.test_llinterp import interpret - - -def test_simple(): - def fn(obj): - return obj + 1 - _1L = pyobjectptr(1L) - res = interpret(fn, [_1L], someobjects=True) - assert res._obj.value == 2L - -def test_obj_obj_dict(): - def f(i, c): - d = {} - d[1] = 'a' - d['a'] = i - d['ab'] = c - d[i] = c - return len(d) - res = interpret(f, [2, 'c'], someobjects=True) - assert res == 4 - res = interpret(f, [3, 'c'], someobjects=True) - assert res == 4 - -def test_obj_list(): - def f(i, c): - lis = [1, 2, 3, 4] - lis[i] = c - lis.append(i) - return len(lis) - res = interpret(f, [2, 'c'], someobjects=True) - assert res == 5 - res = interpret(f, [3, 'c'], someobjects=True) - assert res == 5 - -def test_obj_iter(): - def f(flag): - if flag: - x = (1, 2) - else: - x = '34' - lst = [u for u in x] - return lst[flag] - res = interpret(f, [1], someobjects=True) - assert res._obj.value == 2 - res = interpret(f, [0], someobjects=True) - assert res._obj.value == '3' - -def test_listofobj_iter(): - def f(look): - lst = ['*', 2, 5] - for u in lst: - if u == look: - return True - return False - res = interpret(f, [1], someobjects=True) - assert res is False - res = interpret(f, [2], someobjects=True) - assert res is True diff --git a/pypy/rpython/typesystem.py b/pypy/rpython/typesystem.py --- a/pypy/rpython/typesystem.py +++ b/pypy/rpython/typesystem.py @@ -119,7 +119,7 @@ return hop.genop('ptr_nonzero', vlist, resulttype=lltype.Bool) def getconcretetype(self, v): - return getattr(v, 'concretetype', lltype.Ptr(lltype.PyObject)) + return v.concretetype def null_callable(self, T): return lltype.nullptr(T.TO) diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py --- a/pypy/translator/c/funcgen.py +++ b/pypy/translator/c/funcgen.py @@ -53,7 +53,7 @@ self.collect_var_and_types() for v in self.vars: - T = getattr(v, 'concretetype', PyObjPtr) + T = v.concretetype # obscure: skip forward references and hope for the best # (needed for delayed function pointers) if isinstance(T, Ptr) and T.TO.__class__ == ForwardReference: @@ -121,7 +121,7 @@ db = self.db lltypes = identity_dict() for v in self.vars: - T = getattr(v, 'concretetype', PyObjPtr) + T = v.concretetype typename = db.gettype(T) lltypes[v] = T, typename self.illtypes = lltypes @@ -221,12 +221,6 @@ if len(block.exits) == 0: assert len(block.inputargs) == 1 # regular return block - if self.exception_policy == "CPython": - assert self.lltypemap(self.graph.getreturnvar()) == PyObjPtr - yield 'if (RPyExceptionOccurred()) {' - yield '\tRPyConvertExceptionToCPython();' - yield '\treturn NULL;' - yield '}' retval = self.expr(block.inputargs[0]) if self.exception_policy != "exc_helper": yield 'RPY_DEBUG_RETURN();' @@ -241,20 +235,12 @@ assert block.exitswitch != c_last_exception # block ending in a switch on a value TYPE = self.lltypemap(block.exitswitch) - if TYPE in (Bool, PyObjPtr): + if TYPE == Bool: expr = self.expr(block.exitswitch) for link in block.exits[:0:-1]: assert link.exitcase in (False, True) - if TYPE == Bool: - if not link.exitcase: - expr = '!' + expr - elif TYPE == PyObjPtr: - yield 'assert(%s == Py_True || %s == Py_False);' % ( - expr, expr) - if link.exitcase: - expr = '%s == Py_True' % expr - else: - expr = '%s == Py_False' % expr + if not link.exitcase: + expr = '!' + expr yield 'if (%s) {' % expr for op in self.gen_link(link): yield '\t' + op diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -276,44 +276,6 @@ extrafiles.append(fn) return extrafiles -class ModuleWithCleanup(object): - def __init__(self, mod): - self.__dict__['mod'] = mod - - def __getattr__(self, name): - mod = self.__dict__['mod'] - obj = getattr(mod, name) - parentself = self - if callable(obj) and getattr(obj, '__module__', None) == mod.__name__: - # The module must be kept alive with the function. - # This wrapper avoids creating a cycle. - class Wrapper: - def __init__(self, obj): - self.myself = parentself - self.func = obj - def __call__(self, *args, **kwargs): - return self.func(*args, **kwargs) - obj = Wrapper(obj) - return obj - - def __setattr__(self, name, val): - mod = self.__dict__['mod'] - setattr(mod, name, val) - - def __del__(self): - import sys - if sys.platform == "win32": - from _ctypes import FreeLibrary as dlclose - else: - from _ctypes import dlclose - # XXX fish fish fish - mod = self.__dict__['mod'] - dlclose(mod._lib._handle) - try: - del sys.modules[mod.__name__] - except KeyError: - pass - class CStandaloneBuilder(CBuilder): standalone = True diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -1,23 +1,18 @@ -import autopath, sys, os, py +import sys + +import py + from pypy.rpython.lltypesystem.lltype import * from pypy.annotation import model as annmodel from pypy.translator.translator import TranslationContext -from pypy.translator.c.database import LowLevelDatabase from pypy.translator.c import genc -from pypy.translator.c.gc import NoneGcPolicy -from pypy.objspace.flow.model import Constant, Variable, SpaceOperation -from pypy.objspace.flow.model import Block, Link, FunctionGraph -from pypy.tool.udir import udir -from pypy.translator.gensupp import uniquemodulename -from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.interactive import Translation from pypy.rlib.entrypoint import entrypoint from pypy.tool.nullpath import NullPyPathLocal + def compile(fn, argtypes, view=False, gcpolicy="ref", backendopt=True, annotatorpolicy=None): - if argtypes is not None and "__pypy__" in sys.builtin_module_names: - py.test.skip("requires building cpython extension modules") t = Translation(fn, argtypes, gc=gcpolicy, backend="c", policy=annotatorpolicy) if not backendopt: @@ -49,19 +44,11 @@ def test_simple(): def f(x): return x*2 - t = TranslationContext() - t.buildannotator().build_types(f, [int]) - t.buildrtyper().specialize() - t.config.translation.countmallocs = True - builder = genc.CExtModuleBuilder(t, f, config=t.config) - builder.generate_source() - builder.compile() - f1 = builder.get_entry_point() + f1 = compile(f, [int]) assert f1(5) == 10 assert f1(-123) == -246 - assert builder.get_malloc_counters()() == (0, 0) py.test.raises(Exception, f1, "world") # check that it's really typed diff --git a/pypy/translator/interactive.py b/pypy/translator/interactive.py --- a/pypy/translator/interactive.py +++ b/pypy/translator/interactive.py @@ -1,9 +1,7 @@ -import optparse - -import autopath from pypy.translator.translator import TranslationContext from pypy.translator import driver + DEFAULTS = { 'translation.backend': None, 'translation.type_system': None, @@ -44,7 +42,7 @@ self.ensure_setup() elif kind == 'post': pass - + def ensure_setup(self, argtypes=None, policy=None, standalone=False): if not self.driver_setup: if standalone: @@ -74,7 +72,8 @@ kwds.pop('policy', None) kwds.pop('standalone', None) gc = kwds.pop('gc', None) - if gc: self.config.translation.gc = gc + if gc: + self.config.translation.gc = gc self.config.translation.set(**kwds) def ensure_opt(self, name, value=None, fallback=None): @@ -88,13 +87,13 @@ if val is not None: return val raise Exception( - "the %r option should have been specified at this point" %name) + "the %r option should have been specified at this point" % name) def ensure_type_system(self, type_system=None): if self.config.translation.backend is not None: return self.ensure_opt('type_system') return self.ensure_opt('type_system', type_system, 'lltype') - + def ensure_backend(self, backend=None): backend = self.ensure_opt('backend', backend) self.ensure_type_system() @@ -121,20 +120,20 @@ def rtype(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) ts = self.ensure_type_system() - return getattr(self.driver, 'rtype_'+ts)() + return getattr(self.driver, 'rtype_' + ts)() def backendopt(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) ts = self.ensure_type_system('lltype') - return getattr(self.driver, 'backendopt_'+ts)() - + return getattr(self.driver, 'backendopt_' + ts)() + # backend depedent def source(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) backend = self.ensure_backend() - getattr(self.driver, 'source_'+backend)() - + getattr(self.driver, 'source_' + backend)() + def source_c(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) self.ensure_backend('c') @@ -148,15 +147,15 @@ def compile(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) backend = self.ensure_backend() - getattr(self.driver, 'compile_'+backend)() + getattr(self.driver, 'compile_' + backend)() return self.driver.c_entryp - + def compile_c(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) self.ensure_backend('c') self.driver.compile_c() return self.driver.c_entryp - + def compile_cli(self, argtypes=None, **kwds): self.update_options(argtypes, kwds) self.ensure_backend('cli') diff --git a/pypy/translator/llsupport/test/test_wrapper.py b/pypy/translator/llsupport/test/test_wrapper.py deleted file mode 100644 --- a/pypy/translator/llsupport/test/test_wrapper.py +++ /dev/null @@ -1,60 +0,0 @@ -import py -from pypy import conftest -from pypy.translator.translator import TranslationContext -from pypy.translator.llsupport.wrapper import new_wrapper -from pypy.rpython.rmodel import PyObjPtr -from pypy.rpython.llinterp import LLInterpreter -from pypy.rpython.lltypesystem import lltype - - -class TestMakeWrapper: - - def getgraph(self, func, argtypes=None): - from pypy.config.pypyoption import get_pypy_config - config = get_pypy_config(translating=True) - config.translation.gc = "ref" - config.translation.simplifying = True - t = TranslationContext(config=config) - if argtypes is None: - argtypes = [] - a = t.buildannotator() - a.build_types(func, argtypes) - a.simplify() - t.buildrtyper().specialize() - wrapperptr = new_wrapper(func, t) - wrappergraph = wrapperptr._obj.graph - F = lltype.typeOf(wrapperptr).TO - assert F.ARGS == (PyObjPtr,) * len(wrappergraph.getargs()) - assert F.RESULT == PyObjPtr - - for inputarg in wrappergraph.getargs(): - assert inputarg.concretetype == PyObjPtr - assert wrappergraph.getreturnvar().concretetype == PyObjPtr - return t.graphs[0], wrappergraph, t - - def interpret(self, t, graph, *args): - interp = LLInterpreter(t.rtyper) - result = interp.eval_graph(graph, [lltype.pyobjectptr(arg) - for arg in args]) - return result._obj.value - - def test_simple(self): - def f(x): - return x * 3 - graph, wrappergraph, t = self.getgraph(f, [int]) - res = self.interpret(t, wrappergraph, 3) - assert res == 9 - - def test_manyargs(self): - def f(x, y, z): - return x * y + z - graph, wrappergraph, t = self.getgraph(f, [int, int, int]) - res = self.interpret(t, wrappergraph, 3, 4, 5) - assert res == 3 * 4 + 5 - - def test_returnnone(self): - def f(): - pass - graph, wrappergraph, t = self.getgraph(f) - res = self.interpret(t, wrappergraph) - assert res is None diff --git a/pypy/translator/llsupport/wrapper.py b/pypy/translator/llsupport/wrapper.py deleted file mode 100644 --- a/pypy/translator/llsupport/wrapper.py +++ /dev/null @@ -1,78 +0,0 @@ -from pypy.objspace.flow.model import Variable -from pypy.objspace.flow.model import Block, Link, FunctionGraph, checkgraph -from pypy.rpython.lltypesystem.lltype import \ - Ptr, PyObject, typeOf, Signed, FuncType, functionptr, nullptr, Void -from pypy.rpython.rtyper import LowLevelOpList -from pypy.rpython.rmodel import inputconst, PyObjPtr -from pypy.rpython.robject import pyobj_repr - -from pypy.rpython.typesystem import getfunctionptr - - - -def new_wrapper(func, translator, newname=None): - # The basic idea is to produce a flow graph from scratch, using the - # help of the rtyper for the conversion of the arguments after they - # have been decoded. - - bk = translator.annotator.bookkeeper - graph = bk.getdesc(func).getuniquegraph() - - f = getfunctionptr(graph) - FUNCTYPE = typeOf(f).TO - - newops = LowLevelOpList(translator.rtyper) - - varguments = [] - for var in graph.startblock.inputargs: - v = Variable(var) - v.concretetype = PyObjPtr - varguments.append(v) - - wrapper_inputargs = varguments[:] - # use the rtyper to produce the conversions - inputargs = f._obj.graph.getargs() - for i in range(len(varguments)): - if FUNCTYPE.ARGS[i] != PyObjPtr: - rtyper = translator.rtyper - r_arg = rtyper.bindingrepr(inputargs[i]) - # give the rtyper a chance to know which function we are wrapping - rtyper.set_wrapper_context(func) - varguments[i] = newops.convertvar(varguments[i], - r_from = pyobj_repr, - r_to = r_arg) - rtyper.set_wrapper_context(None) - - vlist = [inputconst(typeOf(f), f)] + varguments - vresult = newops.genop('direct_call', vlist, resulttype=FUNCTYPE.RESULT) - - if FUNCTYPE.RESULT != PyObjPtr: - # convert "result" back to a PyObject - rtyper = translator.rtyper - assert rtyper is not None, ( - "needs the rtyper to perform function result conversions") - r_result = rtyper.bindingrepr(f._obj.graph.getreturnvar()) - vresult = newops.convertvar(vresult, - r_from = r_result, - r_to = pyobj_repr) - - # "return result" - block = Block(wrapper_inputargs) - wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block) - translator.update_call_graph(wgraph, graph, object()) - translator.graphs.append(wgraph) - block.operations[:] = newops - block.closeblock(Link([vresult], wgraph.returnblock)) - wgraph.getreturnvar().concretetype = PyObjPtr - checkgraph(wgraph) - - # the above convertvar()s may have created and annotated new helpers - # that need to be specialized now - translator.rtyper.specialize_more_blocks() - - return functionptr(FuncType([PyObjPtr] * len(wrapper_inputargs), - PyObjPtr), - wgraph.name, - graph = wgraph, - exception_policy = "CPython") - From noreply at buildbot.pypy.org Sun Oct 7 19:56:32 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 7 Oct 2012 19:56:32 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121007175632.5AE041C0DDC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57846:4bd09f2bcf13 Date: 2012-10-07 19:55 +0200 http://bitbucket.org/pypy/pypy/changeset/4bd09f2bcf13/ Log: merge diff --git a/pypy/rpython/memory/gctransform/boehm.py b/pypy/rpython/memory/gctransform/boehm.py --- a/pypy/rpython/memory/gctransform/boehm.py +++ b/pypy/rpython/memory/gctransform/boehm.py @@ -57,12 +57,6 @@ self.mixlevelannotator.finish() # for now self.mixlevelannotator.backend_optimize() - def push_alive_nopyobj(self, var, llops): - pass - - def pop_alive_nopyobj(self, var, llops): - pass - def gct_fv_gc_malloc(self, hop, flags, TYPE, c_size): # XXX same behavior for zero=True: in theory that's wrong if TYPE._is_atomic(): diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py --- a/pypy/rpython/memory/gctransform/framework.py +++ b/pypy/rpython/memory/gctransform/framework.py @@ -5,8 +5,7 @@ from pypy.rpython.lltypesystem.lloperation import LL_OPERATIONS from pypy.rpython.memory import gctypelayout from pypy.rpython.memory.gctransform.log import log -from pypy.rpython.memory.gctransform.support import get_rtti, \ - ll_call_destructor, type_contains_pyobjs, var_ispyobj +from pypy.rpython.memory.gctransform.support import get_rtti, ll_call_destructor from pypy.rpython.memory.gctransform.transform import GCTransformer from pypy.rpython.memory.gctypelayout import ll_weakref_deref, WEAKREF, \ WEAKREFPTR @@ -19,6 +18,7 @@ TYPE_ID = llgroup.HALFWORD + class CollectAnalyzer(graphanalyze.BoolGraphAnalyzer): def analyze_direct_call(self, graph, seen=None): @@ -1174,21 +1174,13 @@ def var_needs_set_transform(self, var): return var_needsgc(var) - def push_alive_nopyobj(self, var, llops): - pass - - def pop_alive_nopyobj(self, var, llops): - pass - def get_livevars_for_roots(self, hop, keep_current_args=False): if self.gcdata.gc.moving_gc and not keep_current_args: # moving GCs don't borrow, so the caller does not need to keep # the arguments alive - livevars = [var for var in hop.livevars_after_op() - if not var_ispyobj(var)] + livevars = [var for var in hop.livevars_after_op()] else: livevars = hop.livevars_after_op() + hop.current_op_keeps_alive() - livevars = [var for var in livevars if not var_ispyobj(var)] return livevars def compute_borrowed_vars(self, graph): @@ -1244,7 +1236,6 @@ rtti = get_rtti(TYPE) destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] - assert not type_contains_pyobjs(TYPE), "not implemented" typename = TYPE.__name__ def ll_finalizer(addr, ignored): v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) diff --git a/pypy/rpython/memory/gctransform/refcounting.py b/pypy/rpython/memory/gctransform/refcounting.py --- a/pypy/rpython/memory/gctransform/refcounting.py +++ b/pypy/rpython/memory/gctransform/refcounting.py @@ -142,11 +142,11 @@ def var_needs_set_transform(self, var): return var_needsgc(var) - def push_alive_nopyobj(self, var, llops): + def push_alive(self, var, llops): v_adr = gen_cast(llops, llmemory.Address, var) llops.genop("direct_call", [self.increfptr, v_adr]) - def pop_alive_nopyobj(self, var, llops): + def pop_alive(self, var, llops): PTRTYPE = var.concretetype v_adr = gen_cast(llops, llmemory.Address, var) diff --git a/pypy/rpython/memory/gctransform/test/test_transform.py b/pypy/rpython/memory/gctransform/test/test_transform.py --- a/pypy/rpython/memory/gctransform/test/test_transform.py +++ b/pypy/rpython/memory/gctransform/test/test_transform.py @@ -5,22 +5,19 @@ from pypy.translator.translator import TranslationContext, graphof from pypy.translator.exceptiontransform import ExceptionTransformer from pypy.rpython.lltypesystem import lltype -from pypy.objspace.flow.model import Variable -from pypy.annotation import model as annmodel -from pypy.rpython.extregistry import ExtRegistryEntry from pypy import conftest + class LLInterpedTranformerTests: def llinterpreter_for_transformed_graph(self, f, args_s): from pypy.rpython.llinterp import LLInterpreter from pypy.translator.c.genc import CStandaloneBuilder - from pypy.translator.c import gc t = rtype(f, args_s) # XXX we shouldn't need an actual gcpolicy here. cbuild = CStandaloneBuilder(t, f, t.config, gcpolicy=self.gcpolicy) - db = cbuild.generate_graphs_for_llinterp() + cbuild.generate_graphs_for_llinterp() graph = cbuild.getentrypointptr()._obj.graph # arguments cannot be GC objects because nobody would put a # proper header on them @@ -32,7 +29,6 @@ t.view() return llinterp, graph - def test_simple(self): from pypy.annotation.model import SomeInteger @@ -67,7 +63,6 @@ r.append(x) return len(r) - llinterp, graph = self.llinterpreter_for_transformed_graph(f, [SomeInteger()]) res = llinterp.eval_graph(graph, [0]) @@ -85,7 +80,6 @@ x = 'brrrrrrr' return len(x + 'a') - llinterp, graph = self.llinterpreter_for_transformed_graph(f, [SomeBool()]) res = llinterp.eval_graph(graph, [True]) @@ -93,12 +87,13 @@ res = llinterp.eval_graph(graph, [False]) assert res == f(False) + class _TestGCTransformer(BaseGCTransformer): - def push_alive_nopyobj(self, var, llops): + def push_alive(self, var, llops): llops.genop("gc_push_alive", [var]) - def pop_alive_nopyobj(self, var, llops): + def pop_alive(self, var, llops): llops.genop("gc_pop_alive", [var]) @@ -151,7 +146,7 @@ t.buildrtyper().specialize() if conftest.option.view: t.view() - return t + return t def rtype_and_transform(func, inputtypes, transformcls, specialize=True, check=True): t = rtype(func, inputtypes, specialize) @@ -199,7 +194,7 @@ c.x = 1 return c t, transformer = rtype_and_transform(f, [], _TestGCTransformer) - + def test_call_function(): class C: pass @@ -323,7 +318,7 @@ except ValueError: return 0 t, transformer = rtype_and_transform(g, [int], _TestGCTransformer) - + def test_no_livevars_with_exception(): def g(): raise TypeError @@ -338,7 +333,8 @@ def test_bare_setfield(): from pypy.rpython.lltypesystem.lloperation import llop class A: - def __init__(self, obj): self.x = obj + def __init__(self, obj): + self.x = obj def f(v): inst = A(v) llop.setfield(lltype.Void, inst, 'x', v) diff --git a/pypy/rpython/memory/gctransform/transform.py b/pypy/rpython/memory/gctransform/transform.py --- a/pypy/rpython/memory/gctransform/transform.py +++ b/pypy/rpython/memory/gctransform/transform.py @@ -312,15 +312,9 @@ self.pop_alive(v_old, hop.llops) def push_alive(self, var, llops): - self.push_alive_nopyobj(var, llops) + pass def pop_alive(self, var, llops): - self.pop_alive_nopyobj(var, llops) - - def push_alive_nopyobj(self, var, llops): - pass - - def pop_alive_nopyobj(self, var, llops): pass def var_needs_set_transform(self, var): diff --git a/pypy/rpython/memory/test/test_transformed_gc.py b/pypy/rpython/memory/test/test_transformed_gc.py --- a/pypy/rpython/memory/test/test_transformed_gc.py +++ b/pypy/rpython/memory/test/test_transformed_gc.py @@ -1,10 +1,9 @@ import py -import sys import inspect + from pypy.translator.c import gc from pypy.annotation import model as annmodel -from pypy.annotation import policy as annpolicy -from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi, llgroup +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, llgroup from pypy.rpython.memory.gctransform import framework, shadowstack from pypy.rpython.lltypesystem.lloperation import llop, void from pypy.rlib.objectmodel import compute_unique_id, we_are_translated @@ -25,7 +24,7 @@ t.config.translation.gc = gcname t.config.translation.gcremovetypeptr = True t.config.set(**extraconfigopts) - ann = t.buildannotator(policy=annpolicy.StrictAnnotatorPolicy()) + ann = t.buildannotator() ann.build_types(func, inputtypes) if specialize: diff --git a/pypy/rpython/ootypesystem/test/test_ooclean.py b/pypy/rpython/ootypesystem/test/test_ooclean.py --- a/pypy/rpython/ootypesystem/test/test_ooclean.py +++ b/pypy/rpython/ootypesystem/test/test_ooclean.py @@ -1,25 +1,21 @@ -from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype from pypy.rpython.test.test_llinterp import get_interpreter import py -import sys def check_only_ootype(graph): def check_ootype(v): t = v.concretetype assert isinstance(t, ootype.Primitive) or isinstance(t, ootype.OOType) - for block in graph.iterblocks(): for var in block.getvariables(): check_ootype(var) for const in block.getconstants(): check_ootype(const) -def interpret(func, values, view=False, viewbefore=False, policy=None, - someobjects=False): +def interpret(func, values, view=False, viewbefore=False, policy=None): interp, graph = get_interpreter(func, values, view, viewbefore, policy, - someobjects, type_system='ootype') + type_system='ootype') for g in interp.typer.annotator.translator.graphs: check_only_ootype(g) return interp.eval_graph(graph, values) From noreply at buildbot.pypy.org Sun Oct 7 20:01:31 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 20:01:31 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: more code quality cleanup Message-ID: <20121007180131.C3B7D1C0DE0@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57847:5b5c78c68248 Date: 2012-10-07 20:00 +0200 http://bitbucket.org/pypy/pypy/changeset/5b5c78c68248/ Log: more code quality cleanup diff --git a/pypy/translator/c/dlltool.py b/pypy/translator/c/dlltool.py --- a/pypy/translator/c/dlltool.py +++ b/pypy/translator/c/dlltool.py @@ -1,9 +1,10 @@ from pypy.translator.driver import TranslationDriver -from pypy.translator.c.genc import CBuilder, CCompilerDriver +from pypy.translator.c.genc import CBuilder from pypy.rpython.typesystem import getfunctionptr from pypy.translator.tool.cbuild import ExternalCompilationInfo + class CLibraryBuilder(CBuilder): standalone = False split = True @@ -38,6 +39,7 @@ def get_entry_point(self, isolated=False): return self.so_name + class DLLDef(object): def __init__(self, name, functions=[], policy=None, config=None): self.name = name From noreply at buildbot.pypy.org Sun Oct 7 20:03:46 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 20:03:46 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, fijal, arigato) kill cpython_extension Message-ID: <20121007180346.89CFB1C0DE6@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57848:662707d28356 Date: 2012-10-07 20:03 +0200 http://bitbucket.org/pypy/pypy/changeset/662707d28356/ Log: (alex, fijal, arigato) kill cpython_extension diff --git a/pypy/translator/c/database.py b/pypy/translator/c/database.py --- a/pypy/translator/c/database.py +++ b/pypy/translator/c/database.py @@ -27,13 +27,11 @@ gctransformer = None def __init__(self, translator=None, standalone=False, - cpython_extension=False, gcpolicyclass=None, thread_enabled=False, sandbox=False): self.translator = translator self.standalone = standalone - self.cpython_extension = cpython_extension self.sandbox = sandbox if gcpolicyclass is None: gcpolicyclass = gc.RefcountingGcPolicy diff --git a/pypy/translator/c/extfunc.py b/pypy/translator/c/extfunc.py --- a/pypy/translator/c/extfunc.py +++ b/pypy/translator/c/extfunc.py @@ -105,8 +105,6 @@ yield ('RPYTHON_EXCEPTION_MATCH', exceptiondata.fn_exception_match) yield ('RPYTHON_TYPE_OF_EXC_INST', exceptiondata.fn_type_of_exc_inst) yield ('RPYTHON_RAISE_OSERROR', exceptiondata.fn_raise_OSError) - if db.cpython_extension: - yield ('RPYTHON_PYEXCCLASS2EXC', exceptiondata.fn_pyexcclass2exc) yield ('RPyExceptionOccurred1', exctransformer.rpyexc_occured_ptr.value) yield ('RPyFetchExceptionType', exctransformer.rpyexc_fetch_type_ptr.value) diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -118,8 +118,7 @@ _compiled = False modulename = None split = False - cpython_extension = False - + def __init__(self, translator, entrypoint, config, gcpolicy=None, secondary_entrypoints=()): self.translator = translator @@ -146,7 +145,6 @@ raise NotImplementedError("--gcrootfinder=asmgcc requires standalone") db = LowLevelDatabase(translator, standalone=self.standalone, - cpython_extension=self.cpython_extension, gcpolicyclass=gcpolicyclass, thread_enabled=self.config.translation.thread, sandbox=self.config.translation.sandbox) @@ -244,8 +242,6 @@ CBuilder.have___thread = self.translator.platform.check___thread() if not self.standalone: assert not self.config.translation.instrument - if self.cpython_extension: - defines['PYPY_CPYTHON_EXTENSION'] = 1 else: defines['PYPY_STANDALONE'] = db.get(pf) if self.config.translation.instrument: From noreply at buildbot.pypy.org Sun Oct 7 20:19:47 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 7 Oct 2012 20:19:47 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, arigo, fijal) kill kill kill Message-ID: <20121007181947.72BE01C0C02@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57849:e8aee8a86867 Date: 2012-10-07 20:17 +0200 http://bitbucket.org/pypy/pypy/changeset/e8aee8a86867/ Log: (alex, arigo, fijal) kill kill kill diff --git a/pypy/translator/c/extfunc.py b/pypy/translator/c/extfunc.py --- a/pypy/translator/c/extfunc.py +++ b/pypy/translator/c/extfunc.py @@ -105,8 +105,6 @@ yield ('RPYTHON_EXCEPTION_MATCH', exceptiondata.fn_exception_match) yield ('RPYTHON_TYPE_OF_EXC_INST', exceptiondata.fn_type_of_exc_inst) yield ('RPYTHON_RAISE_OSERROR', exceptiondata.fn_raise_OSError) - if db.cpython_extension: - yield ('RPYTHON_PYEXCCLASS2EXC', exceptiondata.fn_pyexcclass2exc) yield ('RPyExceptionOccurred1', exctransformer.rpyexc_occured_ptr.value) yield ('RPyFetchExceptionType', exctransformer.rpyexc_fetch_type_ptr.value) @@ -115,8 +113,7 @@ yield ('RPyRaiseException', exctransformer.rpyexc_raise_ptr.value) for pyexccls in exceptiondata.standardexceptions: - exc_llvalue = exceptiondata.fn_pyexcclass2exc( - lltype.pyobjectptr(pyexccls)) + exc_llvalue = exceptiondata # strange naming here because the macro name must be # a substring of PyExc_%s name = pyexccls.__name__ diff --git a/pypy/translator/c/src/g_include.h b/pypy/translator/c/src/g_include.h --- a/pypy/translator/c/src/g_include.h +++ b/pypy/translator/c/src/g_include.h @@ -23,10 +23,6 @@ #define PY_LONG_LONG long long #endif -#ifndef PYPY_STANDALONE -# include "src/pyobj.h" -#endif - #include "src/int.h" #include "src/char.h" #include "src/float.h" diff --git a/pypy/translator/c/src/mem.h b/pypy/translator/c/src/mem.h --- a/pypy/translator/c/src/mem.h +++ b/pypy/translator/c/src/mem.h @@ -103,7 +103,6 @@ r = (restype) PyObject_Malloc(size); \ if (r != NULL) { \ memset((void*)r, 0, size); \ - COUNT_MALLOC; \ } \ } @@ -111,14 +110,11 @@ #define OP_RAW_MALLOC(size, r, restype) { \ r = (restype) PyObject_Malloc(size); \ - if (r != NULL) { \ - COUNT_MALLOC; \ - } \ } #endif -#define OP_RAW_FREE(p, r) PyObject_Free(p); COUNT_FREE; +#define OP_RAW_FREE(p, r) PyObject_Free(p); #define OP_RAW_MEMCLEAR(p, size, r) memset((void*)p, 0, size) @@ -139,31 +135,6 @@ #define OP_FREE(p) OP_RAW_FREE(p, do_not_use) -/*------------------------------------------------------------*/ -#ifndef COUNT_OP_MALLOCS -/*------------------------------------------------------------*/ - -#define COUNT_MALLOC /* nothing */ -#define COUNT_FREE /* nothing */ - -/*------------------------------------------------------------*/ -#else /*COUNT_OP_MALLOCS*/ -/*------------------------------------------------------------*/ - -static int count_mallocs=0, count_frees=0; - -#define COUNT_MALLOC count_mallocs++ -#define COUNT_FREE count_frees++ - -PyObject* malloc_counters(PyObject* self, PyObject* args) -{ - return Py_BuildValue("ii", count_mallocs, count_frees); -} - -/*------------------------------------------------------------*/ -#endif /*COUNT_OP_MALLOCS*/ -/*------------------------------------------------------------*/ - /* for Boehm GC */ #ifdef USING_BOEHM_GC diff --git a/pypy/translator/c/src/support.h b/pypy/translator/c/src/support.h --- a/pypy/translator/c/src/support.h +++ b/pypy/translator/c/src/support.h @@ -20,18 +20,6 @@ #define FAIL_OVF(msg) FAIL_EXCEPTION(PyExc_OverflowError, msg) #define FAIL_VAL(msg) FAIL_EXCEPTION(PyExc_ValueError, msg) #define FAIL_ZER(msg) FAIL_EXCEPTION(PyExc_ZeroDivisionError, msg) -#define CFAIL() RPyConvertExceptionFromCPython() - -/* the following macros are used by rpython/lltypesystem/rstr.py */ -#define PyString_FromRPyString(rpystr) \ - PyString_FromStringAndSize(_RPyString_AsString(rpystr), RPyString_Size(rpystr)) - -#define PyUnicode_FromRPyUnicode(rpystr) \ - _PyUnicode_FromRPyUnicode(_RPyUnicode_AsUnicode(rpystr), RPyUnicode_Size(rpystr)) - -#define PyString_ToRPyString(s, rpystr) \ - memcpy(_RPyString_AsString(rpystr), PyString_AS_STRING(s), \ - RPyString_Size(rpystr)) /* Extra checks can be enabled with the RPY_ASSERT or RPY_LL_ASSERT * macros. They differ in the level at which the tests are made. @@ -104,416 +92,4 @@ # define RPyBareItem(array, index) ((array)[index]) #endif -#ifdef PYPY_CPYTHON_EXTENSION - -/* prototypes */ - -PyObject * gencfunc_descr_get(PyObject *func, PyObject *obj, PyObject *type); -PyObject* PyList_Pack(int n, ...); -PyObject* PyDict_Pack(int n, ...); -#if PY_VERSION_HEX < 0x02040000 /* 2.4 */ -PyObject* PyTuple_Pack(int n, ...); -#endif -#if PY_VERSION_HEX >= 0x02030000 /* 2.3 */ -# define PyObject_GetItem1 PyObject_GetItem -# define PyObject_SetItem1 PyObject_SetItem -#else -PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index); -PyObject* PyObject_SetItem1(PyObject* obj, PyObject* index, PyObject* v); -#endif -PyObject* CallWithShape(PyObject* callable, PyObject* shape, ...); -PyObject* decode_arg(PyObject* fname, int position, PyObject* name, - PyObject* vargs, PyObject* vkwds, PyObject* def); -int check_no_more_arg(PyObject* fname, int n, PyObject* vargs); -int check_self_nonzero(PyObject* fname, PyObject* self); -PyObject *PyTuple_GetItem_WithIncref(PyObject *tuple, int index); -int PyTuple_SetItem_WithIncref(PyObject *tuple, int index, PyObject *o); -int PySequence_Contains_with_exc(PyObject *seq, PyObject *ob); -PyObject* _PyUnicode_FromRPyUnicode(wchar_t *items, long length); - -/* implementations */ - -#ifndef PYPY_NOT_MAIN_FILE - -/* we need a subclass of 'builtin_function_or_method' which can be used - as methods: builtin function objects that can be bound on instances */ -PyObject * -gencfunc_descr_get(PyObject *func, PyObject *obj, PyObject *type) -{ - if (obj == Py_None) - obj = NULL; - return PyMethod_New(func, obj, type); -} -static PyTypeObject PyGenCFunction_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "pypy_generated_function", - sizeof(PyCFunctionObject), - 0, - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - /*&PyCFunction_Type set below*/ 0, /* tp_base */ - 0, /* tp_dict */ - gencfunc_descr_get, /* tp_descr_get */ - 0, /* tp_descr_set */ -}; - - -/*** misc support functions ***/ - -PyObject* PyList_Pack(int n, ...) -{ - int i; - PyObject *o; - PyObject *result; - va_list vargs; - - va_start(vargs, n); - result = PyList_New(n); - if (result == NULL) { - return NULL; - } - for (i = 0; i < n; i++) { - o = va_arg(vargs, PyObject *); - Py_INCREF(o); - PyList_SET_ITEM(result, i, o); - } - va_end(vargs); - return result; -} - -PyObject* PyDict_Pack(int n, ...) -{ - int i; - PyObject *key, *val; - PyObject *result; - va_list vargs; - - va_start(vargs, n); - result = PyDict_New(); - if (result == NULL) { - return NULL; - } - for (i = 0; i < n; i++) { - key = va_arg(vargs, PyObject *); - val = va_arg(vargs, PyObject *); - if (PyDict_SetItem(result, key, val) < 0) { - Py_DECREF(result); - return NULL; - } - } - va_end(vargs); - return result; -} - -#if PY_VERSION_HEX < 0x02040000 /* 2.4 */ -PyObject* PyTuple_Pack(int n, ...) -{ - int i; - PyObject *o; - PyObject *result; - PyObject **items; - va_list vargs; - - va_start(vargs, n); - result = PyTuple_New(n); - if (result == NULL) { - return NULL; - } - items = ((PyTupleObject *)result)->ob_item; - for (i = 0; i < n; i++) { - o = va_arg(vargs, PyObject *); - Py_INCREF(o); - items[i] = o; - } - va_end(vargs); - return result; -} -#endif - -#if PY_VERSION_HEX < 0x02030000 /* 2.3 */ -/* for Python 2.2 only */ -PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index) -{ - int start, stop, step; - if (!PySlice_Check(index)) { - return PyObject_GetItem(obj, index); - } - if (((PySliceObject*) index)->start == Py_None) { - start = -INT_MAX-1; - } else { - start = PyInt_AsLong(((PySliceObject*) index)->start); - if (start == -1 && PyErr_Occurred()) { - return NULL; - } - } - if (((PySliceObject*) index)->stop == Py_None) { - stop = INT_MAX; - } else { - stop = PyInt_AsLong(((PySliceObject*) index)->stop); - if (stop == -1 && PyErr_Occurred()) { - return NULL; - } - } - if (((PySliceObject*) index)->step != Py_None) { - step = PyInt_AsLong(((PySliceObject*) index)->step); - if (step == -1 && PyErr_Occurred()) { - return NULL; - } - if (step != 1) { - PyErr_SetString(PyExc_ValueError, - "obj[slice]: no step allowed"); - return NULL; - } - } - return PySequence_GetSlice(obj, start, stop); -} - -PyObject* PyObject_SetItem1(PyObject* obj, PyObject* index, PyObject* v) -{ - int start, stop, step; - if (!PySlice_Check(index)) { - return PyObject_SetItem(obj, index, v); - } - if (((PySliceObject*) index)->start == Py_None) { - start = -INT_MAX-1; - } else { - start = PyInt_AsLong(((PySliceObject*) index)->start); - if (start == -1 && PyErr_Occurred()) { - return NULL; - } - } - if (((PySliceObject*) index)->stop == Py_None) { - stop = INT_MAX; - } else { - stop = PyInt_AsLong(((PySliceObject*) index)->stop); - if (stop == -1 && PyErr_Occurred()) { - return NULL; - } - } - if (((PySliceObject*) index)->step != Py_None) { - step = PyInt_AsLong(((PySliceObject*) index)->step); - if (step == -1 && PyErr_Occurred()) { - return NULL; - } - if (step != 1) { - PyErr_SetString(PyExc_ValueError, - "obj[slice]: no step allowed"); - return NULL; - } - } - return PySequence_SetSlice(obj, start, stop, v); -} -#endif - -PyObject* CallWithShape(PyObject* callable, PyObject* shape, ...) -{ - /* XXX the 'shape' argument is a tuple as specified by - XXX pypy.interpreter.argument.fromshape(). This code should - XXX we made independent on the format of the 'shape' later... */ - PyObject* result = NULL; - PyObject* t = NULL; - PyObject* d = NULL; - PyObject* o; - PyObject* key; - PyObject* t2; - int i, nargs, nkwds, starflag, starstarflag; - va_list vargs; - - if (!PyTuple_Check(shape) || - PyTuple_GET_SIZE(shape) != 4 || - !PyInt_Check(PyTuple_GET_ITEM(shape, 0)) || - !PyTuple_Check(PyTuple_GET_ITEM(shape, 1)) || - !PyInt_Check(PyTuple_GET_ITEM(shape, 2)) || - !PyInt_Check(PyTuple_GET_ITEM(shape, 3))) { - Py_FatalError("in genc.h: invalid 'shape' argument"); - } - nargs = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 0)); - nkwds = PyTuple_GET_SIZE(PyTuple_GET_ITEM(shape, 1)); - starflag = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 2)); - starstarflag = PyInt_AS_LONG(PyTuple_GET_ITEM(shape, 3)); - - va_start(vargs, shape); - t = PyTuple_New(nargs); - if (t == NULL) - goto finally; - for (i = 0; i < nargs; i++) { - o = va_arg(vargs, PyObject *); - Py_INCREF(o); - PyTuple_SET_ITEM(t, i, o); - } - if (nkwds) { - d = PyDict_New(); - if (d == NULL) - goto finally; - for (i = 0; i < nkwds; i++) { - o = va_arg(vargs, PyObject *); - key = PyTuple_GET_ITEM(PyTuple_GET_ITEM(shape, 1), i); - if (PyDict_SetItem(d, key, o) < 0) - goto finally; - } - } - if (starflag) { - o = va_arg(vargs, PyObject *); - o = PySequence_Tuple(o); - if (o == NULL) - goto finally; - t2 = PySequence_Concat(t, o); - Py_DECREF(o); - Py_DECREF(t); - t = t2; - if (t == NULL) - goto finally; - } - if (starstarflag) { - int len1, len2, len3; - o = va_arg(vargs, PyObject *); - len1 = PyDict_Size(d); - len2 = PyDict_Size(o); - if (len1 < 0 || len2 < 0) - goto finally; - if (PyDict_Update(d, o) < 0) - goto finally; - len3 = PyDict_Size(d); - if (len1 + len2 != len3) { - PyErr_SetString(PyExc_TypeError, - "genc.h: duplicate keyword arguments"); - goto finally; - } - } - va_end(vargs); - - result = PyObject_Call(callable, t, d); - - finally: - Py_XDECREF(d); - Py_XDECREF(t); - return result; -} - -PyObject* decode_arg(PyObject* fname, int position, PyObject* name, - PyObject* vargs, PyObject* vkwds, PyObject* def) -{ - PyObject* result; - int size = PyTuple_Size(vargs); - if (size < 0) - return NULL; - if (vkwds != NULL) { - result = PyDict_GetItem(vkwds, name); - if (result != NULL) { - if (position < size) { - PyErr_Format(PyExc_TypeError, - "%s() got duplicate value for " - "its '%s' argument", - PyString_AS_STRING(fname), - PyString_AS_STRING(name)); - return NULL; - } - Py_INCREF(result); - return result; - } - } - if (position < size) { - /* common case */ - result = PyTuple_GET_ITEM(vargs, position); - Py_INCREF(result); - return result; - } - if (def != NULL) { - Py_INCREF(def); - return def; - } - PyErr_Format(PyExc_TypeError, "%s() got only %d argument(s)", - PyString_AS_STRING(fname), - position); - return NULL; -} - -int check_no_more_arg(PyObject* fname, int n, PyObject* vargs) -{ - int size = PyTuple_Size(vargs); - if (size < 0) - return -1; - if (size > n) { - PyErr_Format(PyExc_TypeError, - "%s() got %d argument(s), expected %d", - PyString_AS_STRING(fname), - size, n); - return -1; - } - return 0; -} - -int check_self_nonzero(PyObject* fname, PyObject* self) -{ - if (!self) { - PyErr_Format(PyExc_TypeError, - "%s() expects instance first arg", - PyString_AS_STRING(fname)); - return -1; - } - return 0; -} - -/************************************************************/ - -PyObject *PyTuple_GetItem_WithIncref(PyObject *tuple, int index) -{ - PyObject *result = PyTuple_GetItem(tuple, index); - Py_XINCREF(result); - return result; -} - -int PyTuple_SetItem_WithIncref(PyObject *tuple, int index, PyObject *o) -{ - Py_INCREF(o); - return PyTuple_SetItem(tuple, index, o); -} - -int PySequence_Contains_with_exc(PyObject *seq, PyObject *ob) -{ - int ret = PySequence_Contains(seq, ob); - - if (ret < 0) - CFAIL(); - return ret; -} - -PyObject* _PyUnicode_FromRPyUnicode(wchar_t *items, long length) -{ - PyObject *u = PyUnicode_FromUnicode(NULL, length); - long i; - for (i=0; i Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57850:4b69b6e90f73 Date: 2012-10-07 20:19 +0200 http://bitbucket.org/pypy/pypy/changeset/4b69b6e90f73/ Log: merge diff --git a/pypy/translator/c/database.py b/pypy/translator/c/database.py --- a/pypy/translator/c/database.py +++ b/pypy/translator/c/database.py @@ -27,13 +27,11 @@ gctransformer = None def __init__(self, translator=None, standalone=False, - cpython_extension=False, gcpolicyclass=None, thread_enabled=False, sandbox=False): self.translator = translator self.standalone = standalone - self.cpython_extension = cpython_extension self.sandbox = sandbox if gcpolicyclass is None: gcpolicyclass = gc.RefcountingGcPolicy diff --git a/pypy/translator/c/dlltool.py b/pypy/translator/c/dlltool.py --- a/pypy/translator/c/dlltool.py +++ b/pypy/translator/c/dlltool.py @@ -1,9 +1,10 @@ from pypy.translator.driver import TranslationDriver -from pypy.translator.c.genc import CBuilder, CCompilerDriver +from pypy.translator.c.genc import CBuilder from pypy.rpython.typesystem import getfunctionptr from pypy.translator.tool.cbuild import ExternalCompilationInfo + class CLibraryBuilder(CBuilder): standalone = False split = True @@ -38,6 +39,7 @@ def get_entry_point(self, isolated=False): return self.so_name + class DLLDef(object): def __init__(self, name, functions=[], policy=None, config=None): self.name = name diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -118,8 +118,7 @@ _compiled = False modulename = None split = False - cpython_extension = False - + def __init__(self, translator, entrypoint, config, gcpolicy=None, secondary_entrypoints=()): self.translator = translator @@ -146,7 +145,6 @@ raise NotImplementedError("--gcrootfinder=asmgcc requires standalone") db = LowLevelDatabase(translator, standalone=self.standalone, - cpython_extension=self.cpython_extension, gcpolicyclass=gcpolicyclass, thread_enabled=self.config.translation.thread, sandbox=self.config.translation.sandbox) @@ -244,8 +242,6 @@ CBuilder.have___thread = self.translator.platform.check___thread() if not self.standalone: assert not self.config.translation.instrument - if self.cpython_extension: - defines['PYPY_CPYTHON_EXTENSION'] = 1 else: defines['PYPY_STANDALONE'] = db.get(pf) if self.config.translation.instrument: From noreply at buildbot.pypy.org Sun Oct 7 20:24:55 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 7 Oct 2012 20:24:55 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: kill a hack that is a few hours old, for a change Message-ID: <20121007182455.B27401C0C02@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57851:dfd843e24933 Date: 2012-10-07 20:24 +0200 http://bitbucket.org/pypy/pypy/changeset/dfd843e24933/ Log: kill a hack that is a few hours old, for a change diff --git a/pypy/rpython/exceptiondata.py b/pypy/rpython/exceptiondata.py --- a/pypy/rpython/exceptiondata.py +++ b/pypy/rpython/exceptiondata.py @@ -39,6 +39,7 @@ self.r_exception_value = r_instance self.lltype_of_exception_type = r_type.lowleveltype self.lltype_of_exception_value = r_instance.lowleveltype + self.rtyper = rtyper def make_standard_exceptions(self, rtyper): bk = rtyper.annotator.bookkeeper @@ -51,28 +52,6 @@ classdef = bk.getuniqueclassdef(cls) rclass.getclassrepr(rtyper, classdef).setup() - def make_raise_noarg(self, rtyper): - def ll_raise_noarg(classname): - if classname == 'OverflowError': - raise OverflowError - if classname == 'ValueError': - raise ValueError - if classname == 'ZeroDivisionError': - raise ZeroDivisionError - if classname == 'MemoryError': - raise MemoryError - if classname == 'IOError': - raise IOError - if classname == 'StopIteration': - raise StopIteration - if classname == 'KeyError': - raise KeyError - if classname == 'IndexError': - raise IndexError - raise NotImplementedError # we did not special-case this so far - helper_fn = rtyper.annotate_helper_fn(ll_raise_noarg, [annmodel.SomeString()]) - return helper_fn - def make_raise_OSError(self, rtyper): # ll_raise_OSError(errno) def ll_raise_OSError(errno): @@ -86,5 +65,8 @@ example = r_inst.get_reusable_prebuilt_instance() example = self.cast_exception(self.lltype_of_exception_value, example) return example - + def get_standard_ll_exc_instance_by_class(self, exceptionclass): + clsdef = self.rtyper.annotator.bookkeeper.getuniqueclassdef( + exceptionclass) + return self.get_standard_ll_exc_instance(self.rtyper, clsdef) diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -459,11 +459,11 @@ exdata = typer.getexceptiondata() if isinstance(exc, OSError): self.op_direct_call(exdata.fn_raise_OSError, exc.errno) + assert False, "op_direct_call above should have raised" else: - exc_class = exc.__class__.__name__ - llname = typer.type_system.rstr.string_repr.convert_const(exc_class) - self.op_direct_call(exdata.fn_raise_noarg, llname) - assert False, "op_direct_call above should have raised" + evalue = exdata.get_standard_ll_exc_instance_by_class(exc.__class__) + etype = self.op_direct_call(exdata.fn_type_of_exc_inst, evalue) + raise LLException(etype, evalue, *extraargs) def invoke_callable_with_pyexceptions(self, fptr, *args): obj = self.llinterpreter.typer.type_system.deref(fptr) diff --git a/pypy/rpython/lltypesystem/exceptiondata.py b/pypy/rpython/lltypesystem/exceptiondata.py --- a/pypy/rpython/lltypesystem/exceptiondata.py +++ b/pypy/rpython/lltypesystem/exceptiondata.py @@ -14,7 +14,6 @@ self.fn_exception_match = self.make_exception_matcher(rtyper) self.fn_type_of_exc_inst = self.make_type_of_exc_inst(rtyper) self.fn_raise_OSError = self.make_raise_OSError(rtyper) - self.fn_raise_noarg = self.make_raise_noarg(rtyper) def make_exception_matcher(self, rtyper): # ll_exception_matcher(real_exception_vtable, match_exception_vtable) diff --git a/pypy/rpython/ootypesystem/exceptiondata.py b/pypy/rpython/ootypesystem/exceptiondata.py --- a/pypy/rpython/ootypesystem/exceptiondata.py +++ b/pypy/rpython/ootypesystem/exceptiondata.py @@ -23,7 +23,6 @@ self.fn_exception_match = self.make_exception_matcher(rtyper) self.fn_type_of_exc_inst = self.make_type_of_exc_inst(rtyper) self.fn_raise_OSError = self.make_raise_OSError(rtyper) - self.fn_raise_noarg = self.make_raise_noarg(rtyper) def make_exception_matcher(self, rtyper): # ll_exception_matcher(real_exception_class, match_exception_class) From noreply at buildbot.pypy.org Sun Oct 7 20:25:30 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 20:25:30 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: kill tests using someobjects Message-ID: <20121007182530.C9B0D1C0C02@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57852:998d083319fe Date: 2012-10-07 20:24 +0200 http://bitbucket.org/pypy/pypy/changeset/998d083319fe/ Log: kill tests using someobjects diff --git a/pypy/rpython/test/test_rbuiltin.py b/pypy/rpython/test/test_rbuiltin.py --- a/pypy/rpython/test/test_rbuiltin.py +++ b/pypy/rpython/test/test_rbuiltin.py @@ -562,31 +562,6 @@ class TestLLtype(BaseTestRbuiltin, LLRtypeMixin): - - def test_isinstance_obj(self): - _1 = lltype.pyobjectptr(1) - def f(x): - return isinstance(x, int) - res = self.interpret(f, [_1], someobjects=True) - assert res is True - _1_0 = lltype.pyobjectptr(1.0) - res = self.interpret(f, [_1_0], someobjects=True) - assert res is False - - def test_hasattr(self): - class A(object): - def __init__(self): - self.x = 42 - def f(i): - a = A() - if i==0: return int(hasattr(A, '__init__')) - if i==1: return int(hasattr(A, 'y')) - if i==2: return int(hasattr(42, 'x')) - for x, y in zip(range(3), (1, 0, 0)): - res = self.interpret(f, [x], someobjects=True) - assert res._obj.value == y - # hmm, would like to test against PyObj, is this the wrong place/way? - def test_cast(self): def llfn(v): return rffi.cast(rffi.VOIDP, v) @@ -607,7 +582,8 @@ res = self.interpret(llfn, [lltype.nullptr(rffi.VOIDP.TO)]) assert res == 0 assert isinstance(res, r_ulonglong) - + + class TestOOtype(BaseTestRbuiltin, OORtypeMixin): def test_instantiate_multiple_meta(self): From noreply at buildbot.pypy.org Sun Oct 7 20:25:32 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 20:25:32 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121007182532.044D81C0C02@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57853:c45ce704a9b2 Date: 2012-10-07 20:25 +0200 http://bitbucket.org/pypy/pypy/changeset/c45ce704a9b2/ Log: merge diff --git a/pypy/rpython/exceptiondata.py b/pypy/rpython/exceptiondata.py --- a/pypy/rpython/exceptiondata.py +++ b/pypy/rpython/exceptiondata.py @@ -39,6 +39,7 @@ self.r_exception_value = r_instance self.lltype_of_exception_type = r_type.lowleveltype self.lltype_of_exception_value = r_instance.lowleveltype + self.rtyper = rtyper def make_standard_exceptions(self, rtyper): bk = rtyper.annotator.bookkeeper @@ -51,28 +52,6 @@ classdef = bk.getuniqueclassdef(cls) rclass.getclassrepr(rtyper, classdef).setup() - def make_raise_noarg(self, rtyper): - def ll_raise_noarg(classname): - if classname == 'OverflowError': - raise OverflowError - if classname == 'ValueError': - raise ValueError - if classname == 'ZeroDivisionError': - raise ZeroDivisionError - if classname == 'MemoryError': - raise MemoryError - if classname == 'IOError': - raise IOError - if classname == 'StopIteration': - raise StopIteration - if classname == 'KeyError': - raise KeyError - if classname == 'IndexError': - raise IndexError - raise NotImplementedError # we did not special-case this so far - helper_fn = rtyper.annotate_helper_fn(ll_raise_noarg, [annmodel.SomeString()]) - return helper_fn - def make_raise_OSError(self, rtyper): # ll_raise_OSError(errno) def ll_raise_OSError(errno): @@ -86,5 +65,8 @@ example = r_inst.get_reusable_prebuilt_instance() example = self.cast_exception(self.lltype_of_exception_value, example) return example - + def get_standard_ll_exc_instance_by_class(self, exceptionclass): + clsdef = self.rtyper.annotator.bookkeeper.getuniqueclassdef( + exceptionclass) + return self.get_standard_ll_exc_instance(self.rtyper, clsdef) diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -459,11 +459,11 @@ exdata = typer.getexceptiondata() if isinstance(exc, OSError): self.op_direct_call(exdata.fn_raise_OSError, exc.errno) + assert False, "op_direct_call above should have raised" else: - exc_class = exc.__class__.__name__ - llname = typer.type_system.rstr.string_repr.convert_const(exc_class) - self.op_direct_call(exdata.fn_raise_noarg, llname) - assert False, "op_direct_call above should have raised" + evalue = exdata.get_standard_ll_exc_instance_by_class(exc.__class__) + etype = self.op_direct_call(exdata.fn_type_of_exc_inst, evalue) + raise LLException(etype, evalue, *extraargs) def invoke_callable_with_pyexceptions(self, fptr, *args): obj = self.llinterpreter.typer.type_system.deref(fptr) diff --git a/pypy/rpython/lltypesystem/exceptiondata.py b/pypy/rpython/lltypesystem/exceptiondata.py --- a/pypy/rpython/lltypesystem/exceptiondata.py +++ b/pypy/rpython/lltypesystem/exceptiondata.py @@ -14,7 +14,6 @@ self.fn_exception_match = self.make_exception_matcher(rtyper) self.fn_type_of_exc_inst = self.make_type_of_exc_inst(rtyper) self.fn_raise_OSError = self.make_raise_OSError(rtyper) - self.fn_raise_noarg = self.make_raise_noarg(rtyper) def make_exception_matcher(self, rtyper): # ll_exception_matcher(real_exception_vtable, match_exception_vtable) diff --git a/pypy/rpython/ootypesystem/exceptiondata.py b/pypy/rpython/ootypesystem/exceptiondata.py --- a/pypy/rpython/ootypesystem/exceptiondata.py +++ b/pypy/rpython/ootypesystem/exceptiondata.py @@ -23,7 +23,6 @@ self.fn_exception_match = self.make_exception_matcher(rtyper) self.fn_type_of_exc_inst = self.make_type_of_exc_inst(rtyper) self.fn_raise_OSError = self.make_raise_OSError(rtyper) - self.fn_raise_noarg = self.make_raise_noarg(rtyper) def make_exception_matcher(self, rtyper): # ll_exception_matcher(real_exception_class, match_exception_class) From noreply at buildbot.pypy.org Sun Oct 7 20:26:31 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 20:26:31 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix rpython test_rbool Message-ID: <20121007182631.43C9D1C0C02@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57854:8791b8217074 Date: 2012-10-07 20:26 +0200 http://bitbucket.org/pypy/pypy/changeset/8791b8217074/ Log: fix rpython test_rbool diff --git a/pypy/rpython/test/test_rbool.py b/pypy/rpython/test/test_rbool.py --- a/pypy/rpython/test/test_rbool.py +++ b/pypy/rpython/test/test_rbool.py @@ -1,11 +1,10 @@ from pypy.translator.translator import TranslationContext -from pypy.rpython.lltypesystem.lltype import pyobjectptr from pypy.annotation import model as annmodel from pypy.rpython.test import snippet from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin + class TestSnippet(object): - def _test(self, func, types): t = TranslationContext() t.buildannotator().build_types(func, types) From noreply at buildbot.pypy.org Sun Oct 7 20:31:10 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 20:31:10 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: kill tons of pyobj code Message-ID: <20121007183110.751401C0CD8@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57855:e101d8f7ba51 Date: 2012-10-07 20:30 +0200 http://bitbucket.org/pypy/pypy/changeset/e101d8f7ba51/ Log: kill tons of pyobj code diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -846,12 +846,6 @@ def op_gc_deallocate(self, TYPE, addr): raise NotImplementedError("gc_deallocate") - def op_gc_push_alive_pyobj(self, pyobj): - raise NotImplementedError("gc_push_alive_pyobj") - - def op_gc_pop_alive_pyobj(self, pyobj): - raise NotImplementedError("gc_pop_alive_pyobj") - def op_gc_reload_possibly_moved(self, v_newaddr, v_ptr): assert v_newaddr.concretetype is llmemory.Address assert isinstance(v_ptr.concretetype, lltype.Ptr) @@ -938,28 +932,6 @@ def op_stack_current(self): return 0 - # operations on pyobjects! - for opname in lloperation.opimpls.keys(): - exec py.code.Source(""" - def op_%(opname)s(self, *pyobjs): - for pyo in pyobjs: - assert lltype.typeOf(pyo) == lltype.Ptr(lltype.PyObject) - func = lloperation.opimpls[%(opname)r] - try: - pyo = func(*[pyo._obj.value for pyo in pyobjs]) - except Exception: - self.make_llexception() - return self.heap.pyobjectptr(pyo) - """ % locals()).compile() - del opname - - def op_simple_call(self, f, *args): - assert lltype.typeOf(f) == lltype.Ptr(lltype.PyObject) - for pyo in args: - assert lltype.typeOf(pyo) == lltype.Ptr(lltype.PyObject) - res = f._obj.value(*[pyo._obj.value for pyo in args]) - return self.heap.pyobjectptr(res) - # __________________________________________________________ # operations on addresses @@ -980,7 +952,7 @@ return llmemory.raw_malloc_usage(size) def op_raw_free(self, addr): - checkadr(addr) + checkadr(addr) llmemory.raw_free(addr) def op_raw_memclear(self, addr, size): diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py --- a/pypy/rpython/lltypesystem/lloperation.py +++ b/pypy/rpython/lltypesystem/lloperation.py @@ -8,7 +8,7 @@ class LLOp(object): def __init__(self, sideeffects=True, canfold=False, canraise=(), - pyobj=False, canmallocgc=False, canrun=False, oo=False, + canmallocgc=False, canrun=False, oo=False, tryfold=False): # self.opname = ... (set afterwards) @@ -32,9 +32,6 @@ assert not canraise or not canfold - # The operation manipulates PyObjects - self.pyobj = pyobj - # The operation can go a GC malloc self.canmallocgc = canmallocgc if canmallocgc: @@ -476,8 +473,6 @@ 'gc_restore_exception': LLOp(), 'gc_call_rtti_destructor': LLOp(), 'gc_deallocate': LLOp(), - 'gc_push_alive_pyobj': LLOp(), - 'gc_pop_alive_pyobj': LLOp(), 'gc_reload_possibly_moved': LLOp(), # see rlib/objectmodel for gc_identityhash and gc_id 'gc_identityhash': LLOp(sideeffects=False, canmallocgc=True), @@ -602,17 +597,6 @@ } # ***** Run test_lloperation after changes. ***** - - # __________ operations on PyObjects __________ - -from pypy.objspace.flow.operation import FunctionByName -opimpls = FunctionByName.copy() -opimpls['is_true'] = bool -for opname in opimpls: - LL_OPERATIONS[opname] = LLOp(canraise=(Exception,), pyobj=True) -LL_OPERATIONS['simple_call'] = LLOp(canraise=(Exception,), pyobj=True) -del opname, FunctionByName - # ____________________________________________________________ # Post-processing diff --git a/pypy/rpython/memory/gctransform/boehm.py b/pypy/rpython/memory/gctransform/boehm.py --- a/pypy/rpython/memory/gctransform/boehm.py +++ b/pypy/rpython/memory/gctransform/boehm.py @@ -1,12 +1,12 @@ from pypy.rpython.memory.gctransform.transform import GCTransformer, mallocHelpers -from pypy.rpython.memory.gctransform.support import type_contains_pyobjs, \ - get_rtti, _static_deallocator_body_for_type, LLTransformerOp, ll_call_destructor +from pypy.rpython.memory.gctransform.support import (get_rtti, + _static_deallocator_body_for_type, LLTransformerOp, ll_call_destructor) from pypy.rpython.lltypesystem import lltype, llmemory from pypy.objspace.flow.model import Constant from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rpython.lltypesystem import rffi from pypy.rpython import rmodel + class BoehmGCTransformer(GCTransformer): malloc_zero_filled = True FINALIZER_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void)) @@ -99,20 +99,7 @@ destrptr = None DESTR_ARG = None - if type_contains_pyobjs(TYPE): - if destrptr: - raise Exception("can't mix PyObjects and __del__ with Boehm") - - static_body = '\n'.join(_static_deallocator_body_for_type('v', TYPE)) - d = {'pop_alive': LLTransformerOp(self.pop_alive), - 'PTR_TYPE':lltype.Ptr(TYPE), - 'cast_adr_to_ptr': llmemory.cast_adr_to_ptr} - src = ("def ll_finalizer(addr):\n" - " v = cast_adr_to_ptr(addr, PTR_TYPE)\n" - "%s\n")%(static_body,) - exec src in d - fptr = self.annotate_finalizer(d['ll_finalizer'], [llmemory.Address], lltype.Void) - elif destrptr: + if destrptr: EXC_INSTANCE_TYPE = self.translator.rtyper.exceptiondata.lltype_of_exception_value typename = TYPE.__name__ def ll_finalizer(addr): diff --git a/pypy/translator/c/test/test_boehm.py b/pypy/translator/c/test/test_boehm.py --- a/pypy/translator/c/test/test_boehm.py +++ b/pypy/translator/c/test/test_boehm.py @@ -2,11 +2,11 @@ from pypy.translator.translator import TranslationContext from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rpython.memory.test import snippet from pypy.translator.c.genc import CExtModuleBuilder from pypy.rlib.objectmodel import keepalive_until_here from pypy import conftest + def setup_module(mod): from pypy.rpython.tool.rffi_platform import configure_boehm from pypy.translator.platform import CompilationError @@ -69,7 +69,6 @@ fn() def test__del__(self): - from pypy.rpython.lltypesystem.lloperation import llop class State: pass s = State() @@ -105,7 +104,6 @@ def test_id_is_weak(self): # test that compute_unique_id(obj) does not keep obj alive - from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.objectmodel import compute_unique_id class State: pass @@ -155,7 +153,6 @@ assert 0 < res2 <= 5 def test_del_raises(self): - from pypy.rpython.lltypesystem.lloperation import llop class A(object): def __del__(self): s.dels += 1 @@ -199,31 +196,6 @@ fn = self.getcompiled(f) res = fn() assert res == 10 - - # this test shows if we have a problem with refcounting PyObject - def test_refcount_pyobj(self): - from pypy.rpython.lltypesystem.lloperation import llop - def prob_with_pyobj(b): - return 3, b - def collect(): - llop.gc__collect(lltype.Void) - f = self.getcompiled(prob_with_pyobj, [object]) - c = self.getcompiled(collect, []) - from sys import getrefcount as g - obj = None - before = g(obj) - f(obj) - f(obj) - f(obj) - f(obj) - f(obj) - c() - c() - c() - c() - c() - after = g(obj) - assert abs(before - after) < 5 def test_zero_malloc(self): T = lltype.GcStruct("C", ('x', lltype.Signed)) From noreply at buildbot.pypy.org Sun Oct 7 20:36:30 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 20:36:30 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: more pyobj death Message-ID: <20121007183630.5E60C1C0CF4@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57856:201d2c6d8098 Date: 2012-10-07 20:35 +0200 http://bitbucket.org/pypy/pypy/changeset/201d2c6d8098/ Log: more pyobj death diff --git a/pypy/rpython/memory/gctransform/test/test_boehm.py b/pypy/rpython/memory/gctransform/test/test_boehm.py --- a/pypy/rpython/memory/gctransform/test/test_boehm.py +++ b/pypy/rpython/memory/gctransform/test/test_boehm.py @@ -5,8 +5,7 @@ from pypy.translator.translator import graphof from pypy.translator.c.gc import BoehmGcPolicy from pypy.rpython.memory.gctransform.test.test_transform import LLInterpedTranformerTests -from pypy import conftest -import py + class TestLLInterpedBoehm(LLInterpedTranformerTests): gcpolicy = BoehmGcPolicy @@ -34,11 +33,6 @@ f, t = make_boehm_finalizer(S) assert f is None -def test_boehm_finalizer_pyobj(): - S = lltype.GcStruct("S", ('x', lltype.Ptr(lltype.PyObject))) - f, t = make_boehm_finalizer(S) - assert f is not None - def test_boehm_finalizer___del__(): S = lltype.GcStruct("S", ('x', lltype.Signed), rtti=True) def f(s): @@ -53,24 +47,6 @@ lltype.Void), "destructor_funcptr", _callable=f) - pinf = lltype.attachRuntimeTypeInfo(S, qp, destrptr=dp) + lltype.attachRuntimeTypeInfo(S, qp, destrptr=dp) f, t = make_boehm_finalizer(S) assert f is not None - -def test_boehm_finalizer_nomix___del___and_pyobj(): - S = lltype.GcStruct("S", ('x', lltype.Signed), - ('y', lltype.Ptr(lltype.PyObject)), rtti=True) - def f(s): - s.x = 1 - def type_info_S(p): - return lltype.getRuntimeTypeInfo(S) - qp = lltype.functionptr(lltype.FuncType([lltype.Ptr(S)], - lltype.Ptr(lltype.RuntimeTypeInfo)), - "type_info_S", - _callable=type_info_S) - dp = lltype.functionptr(lltype.FuncType([lltype.Ptr(S)], - lltype.Void), - "destructor_funcptr", - _callable=f) - pinf = lltype.attachRuntimeTypeInfo(S, qp, destrptr=dp) - py.test.raises(Exception, "make_boehm_finalizer(S)") diff --git a/pypy/rpython/memory/gctransform/test/test_transform.py b/pypy/rpython/memory/gctransform/test/test_transform.py --- a/pypy/rpython/memory/gctransform/test/test_transform.py +++ b/pypy/rpython/memory/gctransform/test/test_transform.py @@ -1,6 +1,5 @@ from pypy.rpython.memory.gctransform.transform import BaseGCTransformer from pypy.objspace.flow.model import c_last_exception, Variable -from pypy.rpython.memory.gctransform.support import var_ispyobj from pypy.translator.backendopt.support import var_needsgc from pypy.translator.translator import TranslationContext, graphof from pypy.translator.exceptiontransform import ExceptionTransformer @@ -110,22 +109,13 @@ and not is_borrowed(v)]) push_alives = len([op for op in block.operations if op.opname == 'gc_push_alive']) - pyobj_push_alives = len([op for op in block.operations - if op.opname == 'gc_push_alive_pyobj']) - # implicit_pyobj_pushalives included calls to things that return pyobject* - implicit_pyobj_pushalives = len([op for op in block.operations - if var_ispyobj(op.result) - and op.opname not in ('getfield', 'getarrayitem', 'same_as')]) - nonpyobj_gc_returning_calls = len([op for op in block.operations - if op.opname in ('direct_call', 'indirect_call') - and var_needsgc(op.result) - and not var_ispyobj(op.result)]) + gc_returning_calls = len([op for op in block.operations + if op.opname in ('direct_call', 'indirect_call') + and var_needsgc(op.result)]) pop_alives = len([op for op in block.operations if op.opname == 'gc_pop_alive']) - pyobj_pop_alives = len([op for op in block.operations - if op.opname == 'gc_pop_alive_pyobj']) if pop_alives == len(block.operations): # it's a block we inserted return @@ -135,9 +125,8 @@ for v2 in link.target.inputargs: if var_needsgc(v2) and not is_borrowed(v2): refs_out += 1 - pyobj_pushes = pyobj_push_alives + implicit_pyobj_pushalives - nonpyobj_pushes = push_alives + nonpyobj_gc_returning_calls - assert refs_in + pyobj_pushes + nonpyobj_pushes == pop_alives + pyobj_pop_alives + refs_out + pushes = push_alives + gc_returning_calls + assert refs_in + pushes == pop_alives + refs_out def rtype(func, inputtypes, specialize=True): t = TranslationContext() @@ -229,55 +218,6 @@ return a.x + b.x t, transformer = rtype_and_transform(f, [int], _TestGCTransformer) -def test_pyobj(): - def f(x): - if x: - a = 1 - else: - a = "1" - return int(a) - t, transformer = rtype_and_transform(f, [int], _TestGCTransformer) - fgraph = graphof(t, f) - gcops = [op for op in fgraph.startblock.exits[0].target.operations - if op.opname.startswith("gc_")] - for op in gcops: - assert op.opname.endswith("_pyobj") - -def test_call_return_pyobj(): - def g(factory): - return factory() - def f(factory): - g(factory) - t, transformer = rtype_and_transform(f, [object], _TestGCTransformer) - fgraph = graphof(t, f) - ops = getops(fgraph) - calls = ops['direct_call'] - for call in calls: - if call.result.concretetype is not lltype.Bool: #RPyExceptionOccurred() - assert var_ispyobj(call.result) - -def test_getfield_pyobj(): - class S: - pass - def f(thing): - s = S() - s.x = thing - return s.x - t, transformer = rtype_and_transform(f, [object], _TestGCTransformer) - fgraph = graphof(t, f) - pyobj_getfields = 0 - pyobj_setfields = 0 - for b in fgraph.iterblocks(): - for op in b.operations: - if op.opname == 'getfield' and var_ispyobj(op.result): - pyobj_getfields += 1 - elif op.opname == 'bare_setfield' and var_ispyobj(op.args[2]): - pyobj_setfields += 1 - # although there's only one explicit getfield in the code, a - # setfield on a pyobj must get the old value out and decref it - assert pyobj_getfields >= 2 - assert pyobj_setfields >= 1 - def test_pass_gc_pointer(): S = lltype.GcStruct("S", ('x', lltype.Signed)) def f(s): From noreply at buildbot.pypy.org Sun Oct 7 20:38:40 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 20:38:40 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: kill more pyobj stuff Message-ID: <20121007183840.48B511C0CF4@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57857:a16325a0a786 Date: 2012-10-07 20:38 +0200 http://bitbucket.org/pypy/pypy/changeset/a16325a0a786/ Log: kill more pyobj stuff diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -1,9 +1,6 @@ -import sys - import py from pypy.rpython.lltypesystem.lltype import * -from pypy.annotation import model as annmodel from pypy.translator.translator import TranslationContext from pypy.translator.c import genc from pypy.translator.interactive import Translation @@ -133,16 +130,6 @@ assert f1(-5) == -42 -def test_rptr_array(): - A = GcArray(Ptr(PyObject)) - def f(i, x): - p = malloc(A, i) - p[1] = x - return p[1] - f1 = compile(f, [int, annmodel.SomePtr(Ptr(PyObject))]) - assert f1(5, 123) == 123 - assert f1(12, "hello") == "hello" - def test_empty_string(): A = Array(Char, hints={'nolength': True}) p = malloc(A, 1, immortal=True) @@ -343,61 +330,12 @@ def f(): x = [1] y = ['b'] - objectmodel.keepalive_until_here(x,y) + objectmodel.keepalive_until_here(x, y) return 1 f1 = compile(f, []) assert f1() == 1 -def test_refcount_pyobj(): - def prob_with_pyobj(b): - return 3, b - - f = compile(prob_with_pyobj, [object]) - from sys import getrefcount as g - obj = None - import gc; gc.collect() - before = g(obj) - f(obj) - after = g(obj) - assert before == after - -def test_refcount_pyobj_setfield(): - import weakref, gc - class S(object): - def __init__(self): - self.p = None - def foo(wref, objfact): - s = S() - b = objfact() - s.p = b - wr = wref(b) - s.p = None - return wr - f = compile(foo, [object, object], backendopt=False) - class C(object): - pass - wref = f(weakref.ref, C) - gc.collect() - assert not wref() - -def test_refcount_pyobj_setfield_increfs(): - class S(object): - def __init__(self): - self.p = None - def goo(objfact): - s = S() - b = objfact() - s.p = b - return s - def foo(objfact): - s = goo(objfact) - return s.p - f = compile(foo, [object], backendopt=False) - class C(object): - pass - print f(C) - def test_print(): def f(): for i in range(10): @@ -414,7 +352,7 @@ t = Translation(f, [], backend="c") t.annotate() - compiled_fn = t.compile_c() + t.compile_c() if py.test.config.option.view: t.view() assert 'pypy_xyz_f' in t.driver.cbuilder.c_source_filename.read() @@ -430,7 +368,7 @@ t = Translation(f, [], backend="c", secondaryentrypoints="test_entrypoints42") t.annotate() - compiled_fn = t.compile_c() + t.compile_c() if py.test.config.option.view: t.view() assert 'foobar' in t.driver.cbuilder.c_source_filename.read() @@ -445,7 +383,7 @@ export_struct("BarStruct", foo._obj) t = Translation(f, [], backend="c") t.annotate() - compiled_fn = t.compile_c() + t.compile_c() if py.test.config.option.view: t.view() assert ' BarStruct ' in t.driver.cbuilder.c_source_filename.read() @@ -455,7 +393,6 @@ from pypy.rpython.annlowlevel import llhelper from pypy.rpython.lltypesystem import lltype from pypy.rlib.objectmodel import specialize - from pypy.rlib.nonconst import NonConstant FT = lltype.ForwardReference() FTPTR = lltype.Ptr(FT) STRUCT = lltype.Struct("foo", ("bar", FTPTR)) @@ -503,7 +440,6 @@ assert fn(True) def test_inhibit_tail_call(): - from pypy.rpython.lltypesystem import lltype def foobar_fn(n): return 42 foobar_fn._dont_inline_ = True From noreply at buildbot.pypy.org Sun Oct 7 20:41:55 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 7 Oct 2012 20:41:55 +0200 (CEST) Subject: [pypy-commit] pypy length-hint: fix mishandling of bad length hints in zip, add some related asserts Message-ID: <20121007184155.C5DB01C03FB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: length-hint Changeset: r57858:c40b559e03ca Date: 2012-10-05 11:28 -0700 http://bitbucket.org/pypy/pypy/changeset/c40b559e03ca/ Log: fix mishandling of bad length hints in zip, add some related asserts diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py --- a/pypy/module/__builtin__/app_functional.py +++ b/pypy/module/__builtin__/app_functional.py @@ -222,6 +222,8 @@ hint = operator._length_hint(seq, min_hint) if min_hint == -1 or hint < min_hint: min_hint = hint + if min_hint == -1: + min_hint = 0 with _ManagedNewlistHint(min_hint) as result: while True: diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py --- a/pypy/module/__builtin__/test/test_functional.py +++ b/pypy/module/__builtin__/test/test_functional.py @@ -87,6 +87,15 @@ def test_three_lists(self): assert zip([1,2,3], [1,2], [1,2,3]) == [(1,1,1), (2,2,2)] + def test_bad_length_hint(self): + class Foo(object): + def __length_hint__(self): + return NotImplemented + def __iter__(self): + if False: + yield None + assert zip(Foo()) == [] + class AppTestReduce: def test_None(self): raises(TypeError, reduce, lambda x, y: x+y, [1,2,3], None) 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 @@ -449,6 +449,7 @@ pass def _resize_hint(self, w_list, hint): + assert hint >= 0 if hint: w_list.strategy = SizeListStrategy(self.space, hint) @@ -536,6 +537,7 @@ ListStrategy.__init__(self, space) def _resize_hint(self, w_list, hint): + assert hint >= 0 self.sizehint = hint class RangeListStrategy(ListStrategy): @@ -572,7 +574,7 @@ def _resize_hint(self, w_list, hint): # XXX: this could be supported - pass + assert hint >= 0 def copy_into(self, w_list, w_other): w_other.strategy = self diff --git a/pypy/rpython/lltypesystem/rlist.py b/pypy/rpython/lltypesystem/rlist.py --- a/pypy/rpython/lltypesystem/rlist.py +++ b/pypy/rpython/lltypesystem/rlist.py @@ -222,6 +222,7 @@ list to the newsize (and after the operation incase the initial guess lied). """ + 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) From noreply at buildbot.pypy.org Sun Oct 7 20:41:56 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 7 Oct 2012 20:41:56 +0200 (CEST) Subject: [pypy-commit] pypy length-hint: another __length_hint__ impl for the generic reversed Message-ID: <20121007184156.E04801C03FB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: length-hint Changeset: r57859:ad1264e5637a Date: 2012-10-07 11:40 -0700 http://bitbucket.org/pypy/pypy/changeset/ad1264e5637a/ Log: another __length_hint__ impl for the generic reversed diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -270,6 +270,9 @@ def descr___iter__(self, space): return space.wrap(self) + def descr_length(self, space): + return space.wrap(0 if self.remaining == -1 else self.remaining + 1) + def descr_next(self, space): if self.remaining >= 0: w_index = space.wrap(self.remaining) @@ -296,9 +299,10 @@ return space.newtuple([w_new_inst, w_info]) W_ReversedIterator.typedef = TypeDef("reversed", - __iter__=interp2app(W_ReversedIterator.descr___iter__), - next=interp2app(W_ReversedIterator.descr_next), - __reduce__=interp2app(W_ReversedIterator.descr___reduce__), + __iter__ = interp2app(W_ReversedIterator.descr___iter__), + __length_hint__ = interp2app(W_ReversedIterator.descr_length), + next = interp2app(W_ReversedIterator.descr_next), + __reduce__ = interp2app(W_ReversedIterator.descr___reduce__), ) # exported through _pickle_support diff --git a/pypy/objspace/std/test/test_lengthhint.py b/pypy/objspace/std/test/test_lengthhint.py --- a/pypy/objspace/std/test/test_lengthhint.py +++ b/pypy/objspace/std/test/test_lengthhint.py @@ -65,6 +65,24 @@ self._test_length_hint(self.space.newtuple(self.ITEMS)) def test_reversed(self): + # test the generic reversed iterator (w_foo lacks __reversed__) + space = self.space + w_foo = space.appexec([], """(): + class Foo(object): + def __len__(self): + return %r + def __getitem__(self, index): + if 0 <= index < %r: + return index + raise IndexError() + return Foo() + """ % (self.SIZE, self.SIZE)) + w_reversed = space.call_method(space.builtin, 'reversed', w_foo) + assert space.int_w( + space.call_method(w_reversed, '__length_hint__')) == self.SIZE + self._test_length_hint(w_reversed) + + def test_reversedsequenceiterator(self): space = self.space w_reversed = space.call_method(space.builtin, 'reversed', space.wrap(self.ITEMS)) From noreply at buildbot.pypy.org Sun Oct 7 20:41:58 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 7 Oct 2012 20:41:58 +0200 (CEST) Subject: [pypy-commit] pypy length-hint: update per the final PEP Message-ID: <20121007184158.20D6D1C03FB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: length-hint Changeset: r57860:47941daac5ab Date: 2012-10-07 11:40 -0700 http://bitbucket.org/pypy/pypy/changeset/47941daac5ab/ Log: update per the final PEP diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -942,7 +942,11 @@ if self.is_w(w_hint, self.w_NotImplemented): return default - return max(self.int_w(w_hint), 0) + hint = self.int_w(w_hint) + if hint < 0: + raise OperationError(self.w_ValueError, self.wrap( + "__length_hint__() should return >= 0")) + return hint def fixedview(self, w_iterable, expected_length=-1): """ A fixed list view of w_iterable. Don't modify the result diff --git a/pypy/objspace/std/test/test_lengthhint.py b/pypy/objspace/std/test/test_lengthhint.py --- a/pypy/objspace/std/test/test_lengthhint.py +++ b/pypy/objspace/std/test/test_lengthhint.py @@ -1,3 +1,4 @@ +from pypy.interpreter.error import OperationError from pypy.module._collections.interp_deque import W_Deque from pypy.module.itertools.interp_itertools import W_Repeat @@ -122,8 +123,22 @@ """) assert space.length_hint(w_foo, 3) == 3 + def test_invalid_hint(self): + space = self.space + w_foo = space.appexec([], """(): + class Foo(object): + def __length_hint__(self): + return -1 + return Foo() + """) + try: + space.length_hint(w_foo, 3) + except OperationError, e: + assert e.match(space, space.w_ValueError) + else: + assert False, 'ValueError expected' + def test_exc(self): - from pypy.interpreter.error import OperationError space = self.space w_foo = space.appexec([], """(): class Foo(object): From noreply at buildbot.pypy.org Sun Oct 7 20:47:54 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 20:47:54 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: remove some references to cpy, the old allocation flavor for PyObject Message-ID: <20121007184754.8E5391C03FB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57861:5881a4cad188 Date: 2012-10-07 20:41 +0200 http://bitbucket.org/pypy/pypy/changeset/5881a4cad188/ Log: remove some references to cpy, the old allocation flavor for PyObject diff --git a/pypy/rpython/memory/gctransform/refcounting.py b/pypy/rpython/memory/gctransform/refcounting.py --- a/pypy/rpython/memory/gctransform/refcounting.py +++ b/pypy/rpython/memory/gctransform/refcounting.py @@ -201,9 +201,7 @@ return self.static_deallocator_funcptrs[TYPE] #print_call_chain(self) - if TYPE._gckind == 'cpy': - return # you don't really have an RPython deallocator for PyObjects - rtti = get_rtti(TYPE) + rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] @@ -266,7 +264,6 @@ return fptr def dynamic_deallocation_funcptr_for_type(self, TYPE): - assert TYPE._gckind != 'cpy' if TYPE in self.dynamic_deallocator_funcptrs: return self.dynamic_deallocator_funcptrs[TYPE] #print_call_chain(self) diff --git a/pypy/rpython/memory/gctransform/transform.py b/pypy/rpython/memory/gctransform/transform.py --- a/pypy/rpython/memory/gctransform/transform.py +++ b/pypy/rpython/memory/gctransform/transform.py @@ -505,7 +505,6 @@ if add_flags: flags.update(add_flags) flavor = flags['flavor'] - assert flavor != 'cpy', "cannot malloc CPython objects directly" meth = getattr(self, 'gct_fv_%s_malloc_varsize' % flavor, None) assert meth, "%s has no support for malloc_varsize with flavor %r" % (self, flavor) return self.varsize_malloc_helper(hop, flags, meth, []) @@ -583,7 +582,6 @@ flags = op.args[1].value flavor = flags['flavor'] v = op.args[0] - assert flavor != 'cpy', "cannot free CPython objects directly" if flavor == 'raw': v = hop.genop("cast_ptr_to_adr", [v], resulttype=llmemory.Address) if flags.get('track_allocation', True): diff --git a/pypy/rpython/rmodel.py b/pypy/rpython/rmodel.py --- a/pypy/rpython/rmodel.py +++ b/pypy/rpython/rmodel.py @@ -172,16 +172,15 @@ isinstance(T.TO, (lltype.Struct, lltype.Array, lltype.ForwardReference))): - assert T.TO._gckind != 'cpy' return DummyValueBuilder(rtyper, T.TO) else: return None def rtype_bltn_list(self, hop): - raise TyperError, 'no list() support for %r' % self + raise TyperError('no list() support for %r' % self) def rtype_unichr(self, hop): - raise TyperError, 'no unichr() support for %r' % self + raise TyperError('no unichr() support for %r' % self) # default implementation of some operations From noreply at buildbot.pypy.org Sun Oct 7 21:00:04 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 7 Oct 2012 21:00:04 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (arigo, fijal, alex) kill more stuff, start passing C tests Message-ID: <20121007190004.1F2541C03FB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57862:1dd0eec7c927 Date: 2012-10-07 20:58 +0200 http://bitbucket.org/pypy/pypy/changeset/1dd0eec7c927/ Log: (arigo, fijal, alex) kill more stuff, start passing C tests diff --git a/pypy/translator/c/extfunc.py b/pypy/translator/c/extfunc.py --- a/pypy/translator/c/extfunc.py +++ b/pypy/translator/c/extfunc.py @@ -112,13 +112,14 @@ yield ('RPyClearException', exctransformer.rpyexc_clear_ptr.value) yield ('RPyRaiseException', exctransformer.rpyexc_raise_ptr.value) - for pyexccls in exceptiondata.standardexceptions: - exc_llvalue = exceptiondata + for exccls in exceptiondata.standardexceptions: + exc_llvalue = exceptiondata.get_standard_ll_exc_instance_by_class( + exccls) # strange naming here because the macro name must be # a substring of PyExc_%s - name = pyexccls.__name__ - if pyexccls.__module__ != 'exceptions': - name = '%s_%s' % (pyexccls.__module__.replace('.', '__'), name) + name = exccls.__name__ + if exccls.__module__ != 'exceptions': + name = '%s_%s' % (exccls.__module__.replace('.', '__'), name) yield ('RPyExc_%s' % name, exc_llvalue) diff --git a/pypy/translator/c/src/exception.h b/pypy/translator/c/src/exception.h --- a/pypy/translator/c/src/exception.h +++ b/pypy/translator/c/src/exception.h @@ -2,6 +2,8 @@ /************************************************************/ /*** C header subsection: exceptions ***/ +#ifdef HAVE_RTYPER // shrug, hopefully dies with PYPY_NOT_MAIN_FILE + /* just a renaming, unless DO_LOG_EXC is set */ #define RPyExceptionOccurred RPyExceptionOccurred1 #define RPY_DEBUG_RETURN() /* nothing */ @@ -64,3 +66,5 @@ RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc); } #endif /* PYPY_NOT_MAIN_FILE */ + +#endif diff --git a/pypy/translator/c/src/support.h b/pypy/translator/c/src/support.h --- a/pypy/translator/c/src/support.h +++ b/pypy/translator/c/src/support.h @@ -91,5 +91,3 @@ # define RPyNLenItem(array, index) ((array)->items[index]) # define RPyBareItem(array, index) ((array)[index]) #endif - -#endif /* PYPY_NOT_MAIN_FILE */ diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -1,6 +1,7 @@ import sys import py +import ctypes from pypy.rpython.lltypesystem.lltype import * from pypy.annotation import model as annmodel @@ -10,7 +11,6 @@ from pypy.rlib.entrypoint import entrypoint from pypy.tool.nullpath import NullPyPathLocal - def compile(fn, argtypes, view=False, gcpolicy="ref", backendopt=True, annotatorpolicy=None): t = Translation(fn, argtypes, gc=gcpolicy, backend="c", @@ -20,26 +20,20 @@ t.annotate() # XXX fish t.driver.config.translation.countmallocs = True - compiled_fn = t.compile_c() + so_name = t.compile_c() try: if py.test.config.option.view: t.view() except AttributeError: pass - malloc_counters = t.driver.cbuilder.get_malloc_counters() - def checking_fn(*args, **kwds): - if 'expected_extra_mallocs' in kwds: - expected_extra_mallocs = kwds.pop('expected_extra_mallocs') - else: - expected_extra_mallocs = 0 - res = compiled_fn(*args, **kwds) - mallocs, frees = malloc_counters() - if isinstance(expected_extra_mallocs, int): - assert mallocs - frees == expected_extra_mallocs - else: - assert mallocs - frees in expected_extra_mallocs - return res - return checking_fn + def f(*args): + assert len(args) == len(argtypes) + for arg, argtype in zip(args, argtypes): + assert isinstance(arg, argtype) + dll = ctypes.CDLL(str(so_name)) + return getattr(dll, 'pypy_g_' + fn.__name__)(*args) + f.__name__ = fn.__name__ + return f def test_simple(): def f(x): @@ -62,46 +56,13 @@ t.config.translation.countmallocs = True t.config.translation.dont_write_c_files = True - builder = genc.CExtModuleBuilder(t, f, config=t.config) + builder = genc.CStandaloneBuilder(t, f, config=t.config) builder.generate_source() assert isinstance(builder.targetdir, NullPyPathLocal) - assert builder.targetdir.listdir() == [] + for f in builder.targetdir.listdir(): + assert not str(f).endswith('.c') -def test_simple_lambda(): - f = lambda x: x*2 - t = TranslationContext() - t.buildannotator().build_types(f, [int]) - t.buildrtyper().specialize() - - t.config.translation.countmallocs = True - builder = genc.CExtModuleBuilder(t, f, config=t.config) - builder.generate_source() - builder.compile() - f1 = builder.get_entry_point() - - assert f1(5) == 10 - -def test_py_capi_exc(): - def f(x): - if x: - l = None - else: - l = [2] - x = x*2 - return l[0] - t = TranslationContext() - t.buildannotator().build_types(f, [int]) - t.buildrtyper().specialize() - - builder = genc.CExtModuleBuilder(t, f, config=t.config) - builder.generate_source() - builder.compile() - f1 = builder.get_entry_point(isolated=True) - - x = py.test.raises(Exception, f1, "world") - assert not isinstance(x.value, EOFError) # EOFError === segfault - def test_rlist(): def f(x): l = [x] diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py --- a/pypy/translator/driver.py +++ b/pypy/translator/driver.py @@ -563,8 +563,7 @@ self.c_entryp = cbuilder.executable_name self.create_exe() else: - isolated = self._backend_extra_options.get('c_isolated', False) - self.c_entryp = cbuilder.get_entry_point(isolated=isolated) + self.c_entryp = cbuilder.get_entry_point() # task_compile_c = taskdef(task_compile_c, ['source_c'], "Compiling c source") From noreply at buildbot.pypy.org Sun Oct 7 21:00:05 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 7 Oct 2012 21:00:05 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121007190005.50EE91C03FB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57863:9f74be6a89fd Date: 2012-10-07 20:59 +0200 http://bitbucket.org/pypy/pypy/changeset/9f74be6a89fd/ Log: merge diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -846,12 +846,6 @@ def op_gc_deallocate(self, TYPE, addr): raise NotImplementedError("gc_deallocate") - def op_gc_push_alive_pyobj(self, pyobj): - raise NotImplementedError("gc_push_alive_pyobj") - - def op_gc_pop_alive_pyobj(self, pyobj): - raise NotImplementedError("gc_pop_alive_pyobj") - def op_gc_reload_possibly_moved(self, v_newaddr, v_ptr): assert v_newaddr.concretetype is llmemory.Address assert isinstance(v_ptr.concretetype, lltype.Ptr) @@ -938,28 +932,6 @@ def op_stack_current(self): return 0 - # operations on pyobjects! - for opname in lloperation.opimpls.keys(): - exec py.code.Source(""" - def op_%(opname)s(self, *pyobjs): - for pyo in pyobjs: - assert lltype.typeOf(pyo) == lltype.Ptr(lltype.PyObject) - func = lloperation.opimpls[%(opname)r] - try: - pyo = func(*[pyo._obj.value for pyo in pyobjs]) - except Exception: - self.make_llexception() - return self.heap.pyobjectptr(pyo) - """ % locals()).compile() - del opname - - def op_simple_call(self, f, *args): - assert lltype.typeOf(f) == lltype.Ptr(lltype.PyObject) - for pyo in args: - assert lltype.typeOf(pyo) == lltype.Ptr(lltype.PyObject) - res = f._obj.value(*[pyo._obj.value for pyo in args]) - return self.heap.pyobjectptr(res) - # __________________________________________________________ # operations on addresses @@ -980,7 +952,7 @@ return llmemory.raw_malloc_usage(size) def op_raw_free(self, addr): - checkadr(addr) + checkadr(addr) llmemory.raw_free(addr) def op_raw_memclear(self, addr, size): diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py --- a/pypy/rpython/lltypesystem/lloperation.py +++ b/pypy/rpython/lltypesystem/lloperation.py @@ -8,7 +8,7 @@ class LLOp(object): def __init__(self, sideeffects=True, canfold=False, canraise=(), - pyobj=False, canmallocgc=False, canrun=False, oo=False, + canmallocgc=False, canrun=False, oo=False, tryfold=False): # self.opname = ... (set afterwards) @@ -32,9 +32,6 @@ assert not canraise or not canfold - # The operation manipulates PyObjects - self.pyobj = pyobj - # The operation can go a GC malloc self.canmallocgc = canmallocgc if canmallocgc: @@ -476,8 +473,6 @@ 'gc_restore_exception': LLOp(), 'gc_call_rtti_destructor': LLOp(), 'gc_deallocate': LLOp(), - 'gc_push_alive_pyobj': LLOp(), - 'gc_pop_alive_pyobj': LLOp(), 'gc_reload_possibly_moved': LLOp(), # see rlib/objectmodel for gc_identityhash and gc_id 'gc_identityhash': LLOp(sideeffects=False, canmallocgc=True), @@ -602,17 +597,6 @@ } # ***** Run test_lloperation after changes. ***** - - # __________ operations on PyObjects __________ - -from pypy.objspace.flow.operation import FunctionByName -opimpls = FunctionByName.copy() -opimpls['is_true'] = bool -for opname in opimpls: - LL_OPERATIONS[opname] = LLOp(canraise=(Exception,), pyobj=True) -LL_OPERATIONS['simple_call'] = LLOp(canraise=(Exception,), pyobj=True) -del opname, FunctionByName - # ____________________________________________________________ # Post-processing diff --git a/pypy/rpython/memory/gctransform/boehm.py b/pypy/rpython/memory/gctransform/boehm.py --- a/pypy/rpython/memory/gctransform/boehm.py +++ b/pypy/rpython/memory/gctransform/boehm.py @@ -1,12 +1,12 @@ from pypy.rpython.memory.gctransform.transform import GCTransformer, mallocHelpers -from pypy.rpython.memory.gctransform.support import type_contains_pyobjs, \ - get_rtti, _static_deallocator_body_for_type, LLTransformerOp, ll_call_destructor +from pypy.rpython.memory.gctransform.support import (get_rtti, + _static_deallocator_body_for_type, LLTransformerOp, ll_call_destructor) from pypy.rpython.lltypesystem import lltype, llmemory from pypy.objspace.flow.model import Constant from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rpython.lltypesystem import rffi from pypy.rpython import rmodel + class BoehmGCTransformer(GCTransformer): malloc_zero_filled = True FINALIZER_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void)) @@ -99,20 +99,7 @@ destrptr = None DESTR_ARG = None - if type_contains_pyobjs(TYPE): - if destrptr: - raise Exception("can't mix PyObjects and __del__ with Boehm") - - static_body = '\n'.join(_static_deallocator_body_for_type('v', TYPE)) - d = {'pop_alive': LLTransformerOp(self.pop_alive), - 'PTR_TYPE':lltype.Ptr(TYPE), - 'cast_adr_to_ptr': llmemory.cast_adr_to_ptr} - src = ("def ll_finalizer(addr):\n" - " v = cast_adr_to_ptr(addr, PTR_TYPE)\n" - "%s\n")%(static_body,) - exec src in d - fptr = self.annotate_finalizer(d['ll_finalizer'], [llmemory.Address], lltype.Void) - elif destrptr: + if destrptr: EXC_INSTANCE_TYPE = self.translator.rtyper.exceptiondata.lltype_of_exception_value typename = TYPE.__name__ def ll_finalizer(addr): diff --git a/pypy/rpython/memory/gctransform/refcounting.py b/pypy/rpython/memory/gctransform/refcounting.py --- a/pypy/rpython/memory/gctransform/refcounting.py +++ b/pypy/rpython/memory/gctransform/refcounting.py @@ -201,9 +201,7 @@ return self.static_deallocator_funcptrs[TYPE] #print_call_chain(self) - if TYPE._gckind == 'cpy': - return # you don't really have an RPython deallocator for PyObjects - rtti = get_rtti(TYPE) + rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] @@ -266,7 +264,6 @@ return fptr def dynamic_deallocation_funcptr_for_type(self, TYPE): - assert TYPE._gckind != 'cpy' if TYPE in self.dynamic_deallocator_funcptrs: return self.dynamic_deallocator_funcptrs[TYPE] #print_call_chain(self) diff --git a/pypy/rpython/memory/gctransform/test/test_boehm.py b/pypy/rpython/memory/gctransform/test/test_boehm.py --- a/pypy/rpython/memory/gctransform/test/test_boehm.py +++ b/pypy/rpython/memory/gctransform/test/test_boehm.py @@ -5,8 +5,7 @@ from pypy.translator.translator import graphof from pypy.translator.c.gc import BoehmGcPolicy from pypy.rpython.memory.gctransform.test.test_transform import LLInterpedTranformerTests -from pypy import conftest -import py + class TestLLInterpedBoehm(LLInterpedTranformerTests): gcpolicy = BoehmGcPolicy @@ -34,11 +33,6 @@ f, t = make_boehm_finalizer(S) assert f is None -def test_boehm_finalizer_pyobj(): - S = lltype.GcStruct("S", ('x', lltype.Ptr(lltype.PyObject))) - f, t = make_boehm_finalizer(S) - assert f is not None - def test_boehm_finalizer___del__(): S = lltype.GcStruct("S", ('x', lltype.Signed), rtti=True) def f(s): @@ -53,24 +47,6 @@ lltype.Void), "destructor_funcptr", _callable=f) - pinf = lltype.attachRuntimeTypeInfo(S, qp, destrptr=dp) + lltype.attachRuntimeTypeInfo(S, qp, destrptr=dp) f, t = make_boehm_finalizer(S) assert f is not None - -def test_boehm_finalizer_nomix___del___and_pyobj(): - S = lltype.GcStruct("S", ('x', lltype.Signed), - ('y', lltype.Ptr(lltype.PyObject)), rtti=True) - def f(s): - s.x = 1 - def type_info_S(p): - return lltype.getRuntimeTypeInfo(S) - qp = lltype.functionptr(lltype.FuncType([lltype.Ptr(S)], - lltype.Ptr(lltype.RuntimeTypeInfo)), - "type_info_S", - _callable=type_info_S) - dp = lltype.functionptr(lltype.FuncType([lltype.Ptr(S)], - lltype.Void), - "destructor_funcptr", - _callable=f) - pinf = lltype.attachRuntimeTypeInfo(S, qp, destrptr=dp) - py.test.raises(Exception, "make_boehm_finalizer(S)") diff --git a/pypy/rpython/memory/gctransform/test/test_transform.py b/pypy/rpython/memory/gctransform/test/test_transform.py --- a/pypy/rpython/memory/gctransform/test/test_transform.py +++ b/pypy/rpython/memory/gctransform/test/test_transform.py @@ -1,6 +1,5 @@ from pypy.rpython.memory.gctransform.transform import BaseGCTransformer from pypy.objspace.flow.model import c_last_exception, Variable -from pypy.rpython.memory.gctransform.support import var_ispyobj from pypy.translator.backendopt.support import var_needsgc from pypy.translator.translator import TranslationContext, graphof from pypy.translator.exceptiontransform import ExceptionTransformer @@ -110,22 +109,13 @@ and not is_borrowed(v)]) push_alives = len([op for op in block.operations if op.opname == 'gc_push_alive']) - pyobj_push_alives = len([op for op in block.operations - if op.opname == 'gc_push_alive_pyobj']) - # implicit_pyobj_pushalives included calls to things that return pyobject* - implicit_pyobj_pushalives = len([op for op in block.operations - if var_ispyobj(op.result) - and op.opname not in ('getfield', 'getarrayitem', 'same_as')]) - nonpyobj_gc_returning_calls = len([op for op in block.operations - if op.opname in ('direct_call', 'indirect_call') - and var_needsgc(op.result) - and not var_ispyobj(op.result)]) + gc_returning_calls = len([op for op in block.operations + if op.opname in ('direct_call', 'indirect_call') + and var_needsgc(op.result)]) pop_alives = len([op for op in block.operations if op.opname == 'gc_pop_alive']) - pyobj_pop_alives = len([op for op in block.operations - if op.opname == 'gc_pop_alive_pyobj']) if pop_alives == len(block.operations): # it's a block we inserted return @@ -135,9 +125,8 @@ for v2 in link.target.inputargs: if var_needsgc(v2) and not is_borrowed(v2): refs_out += 1 - pyobj_pushes = pyobj_push_alives + implicit_pyobj_pushalives - nonpyobj_pushes = push_alives + nonpyobj_gc_returning_calls - assert refs_in + pyobj_pushes + nonpyobj_pushes == pop_alives + pyobj_pop_alives + refs_out + pushes = push_alives + gc_returning_calls + assert refs_in + pushes == pop_alives + refs_out def rtype(func, inputtypes, specialize=True): t = TranslationContext() @@ -229,55 +218,6 @@ return a.x + b.x t, transformer = rtype_and_transform(f, [int], _TestGCTransformer) -def test_pyobj(): - def f(x): - if x: - a = 1 - else: - a = "1" - return int(a) - t, transformer = rtype_and_transform(f, [int], _TestGCTransformer) - fgraph = graphof(t, f) - gcops = [op for op in fgraph.startblock.exits[0].target.operations - if op.opname.startswith("gc_")] - for op in gcops: - assert op.opname.endswith("_pyobj") - -def test_call_return_pyobj(): - def g(factory): - return factory() - def f(factory): - g(factory) - t, transformer = rtype_and_transform(f, [object], _TestGCTransformer) - fgraph = graphof(t, f) - ops = getops(fgraph) - calls = ops['direct_call'] - for call in calls: - if call.result.concretetype is not lltype.Bool: #RPyExceptionOccurred() - assert var_ispyobj(call.result) - -def test_getfield_pyobj(): - class S: - pass - def f(thing): - s = S() - s.x = thing - return s.x - t, transformer = rtype_and_transform(f, [object], _TestGCTransformer) - fgraph = graphof(t, f) - pyobj_getfields = 0 - pyobj_setfields = 0 - for b in fgraph.iterblocks(): - for op in b.operations: - if op.opname == 'getfield' and var_ispyobj(op.result): - pyobj_getfields += 1 - elif op.opname == 'bare_setfield' and var_ispyobj(op.args[2]): - pyobj_setfields += 1 - # although there's only one explicit getfield in the code, a - # setfield on a pyobj must get the old value out and decref it - assert pyobj_getfields >= 2 - assert pyobj_setfields >= 1 - def test_pass_gc_pointer(): S = lltype.GcStruct("S", ('x', lltype.Signed)) def f(s): diff --git a/pypy/rpython/memory/gctransform/transform.py b/pypy/rpython/memory/gctransform/transform.py --- a/pypy/rpython/memory/gctransform/transform.py +++ b/pypy/rpython/memory/gctransform/transform.py @@ -505,7 +505,6 @@ if add_flags: flags.update(add_flags) flavor = flags['flavor'] - assert flavor != 'cpy', "cannot malloc CPython objects directly" meth = getattr(self, 'gct_fv_%s_malloc_varsize' % flavor, None) assert meth, "%s has no support for malloc_varsize with flavor %r" % (self, flavor) return self.varsize_malloc_helper(hop, flags, meth, []) @@ -583,7 +582,6 @@ flags = op.args[1].value flavor = flags['flavor'] v = op.args[0] - assert flavor != 'cpy', "cannot free CPython objects directly" if flavor == 'raw': v = hop.genop("cast_ptr_to_adr", [v], resulttype=llmemory.Address) if flags.get('track_allocation', True): diff --git a/pypy/rpython/rmodel.py b/pypy/rpython/rmodel.py --- a/pypy/rpython/rmodel.py +++ b/pypy/rpython/rmodel.py @@ -172,16 +172,15 @@ isinstance(T.TO, (lltype.Struct, lltype.Array, lltype.ForwardReference))): - assert T.TO._gckind != 'cpy' return DummyValueBuilder(rtyper, T.TO) else: return None def rtype_bltn_list(self, hop): - raise TyperError, 'no list() support for %r' % self + raise TyperError('no list() support for %r' % self) def rtype_unichr(self, hop): - raise TyperError, 'no unichr() support for %r' % self + raise TyperError('no unichr() support for %r' % self) # default implementation of some operations diff --git a/pypy/rpython/test/test_rbool.py b/pypy/rpython/test/test_rbool.py --- a/pypy/rpython/test/test_rbool.py +++ b/pypy/rpython/test/test_rbool.py @@ -1,11 +1,10 @@ from pypy.translator.translator import TranslationContext -from pypy.rpython.lltypesystem.lltype import pyobjectptr from pypy.annotation import model as annmodel from pypy.rpython.test import snippet from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin + class TestSnippet(object): - def _test(self, func, types): t = TranslationContext() t.buildannotator().build_types(func, types) diff --git a/pypy/rpython/test/test_rbuiltin.py b/pypy/rpython/test/test_rbuiltin.py --- a/pypy/rpython/test/test_rbuiltin.py +++ b/pypy/rpython/test/test_rbuiltin.py @@ -562,31 +562,6 @@ class TestLLtype(BaseTestRbuiltin, LLRtypeMixin): - - def test_isinstance_obj(self): - _1 = lltype.pyobjectptr(1) - def f(x): - return isinstance(x, int) - res = self.interpret(f, [_1], someobjects=True) - assert res is True - _1_0 = lltype.pyobjectptr(1.0) - res = self.interpret(f, [_1_0], someobjects=True) - assert res is False - - def test_hasattr(self): - class A(object): - def __init__(self): - self.x = 42 - def f(i): - a = A() - if i==0: return int(hasattr(A, '__init__')) - if i==1: return int(hasattr(A, 'y')) - if i==2: return int(hasattr(42, 'x')) - for x, y in zip(range(3), (1, 0, 0)): - res = self.interpret(f, [x], someobjects=True) - assert res._obj.value == y - # hmm, would like to test against PyObj, is this the wrong place/way? - def test_cast(self): def llfn(v): return rffi.cast(rffi.VOIDP, v) @@ -607,7 +582,8 @@ res = self.interpret(llfn, [lltype.nullptr(rffi.VOIDP.TO)]) assert res == 0 assert isinstance(res, r_ulonglong) - + + class TestOOtype(BaseTestRbuiltin, OORtypeMixin): def test_instantiate_multiple_meta(self): diff --git a/pypy/translator/c/test/test_boehm.py b/pypy/translator/c/test/test_boehm.py --- a/pypy/translator/c/test/test_boehm.py +++ b/pypy/translator/c/test/test_boehm.py @@ -2,11 +2,11 @@ from pypy.translator.translator import TranslationContext from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rpython.memory.test import snippet from pypy.translator.c.genc import CExtModuleBuilder from pypy.rlib.objectmodel import keepalive_until_here from pypy import conftest + def setup_module(mod): from pypy.rpython.tool.rffi_platform import configure_boehm from pypy.translator.platform import CompilationError @@ -69,7 +69,6 @@ fn() def test__del__(self): - from pypy.rpython.lltypesystem.lloperation import llop class State: pass s = State() @@ -105,7 +104,6 @@ def test_id_is_weak(self): # test that compute_unique_id(obj) does not keep obj alive - from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.objectmodel import compute_unique_id class State: pass @@ -155,7 +153,6 @@ assert 0 < res2 <= 5 def test_del_raises(self): - from pypy.rpython.lltypesystem.lloperation import llop class A(object): def __del__(self): s.dels += 1 @@ -199,31 +196,6 @@ fn = self.getcompiled(f) res = fn() assert res == 10 - - # this test shows if we have a problem with refcounting PyObject - def test_refcount_pyobj(self): - from pypy.rpython.lltypesystem.lloperation import llop - def prob_with_pyobj(b): - return 3, b - def collect(): - llop.gc__collect(lltype.Void) - f = self.getcompiled(prob_with_pyobj, [object]) - c = self.getcompiled(collect, []) - from sys import getrefcount as g - obj = None - before = g(obj) - f(obj) - f(obj) - f(obj) - f(obj) - f(obj) - c() - c() - c() - c() - c() - after = g(obj) - assert abs(before - after) < 5 def test_zero_malloc(self): T = lltype.GcStruct("C", ('x', lltype.Signed)) diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -1,10 +1,7 @@ -import sys - import py import ctypes from pypy.rpython.lltypesystem.lltype import * -from pypy.annotation import model as annmodel from pypy.translator.translator import TranslationContext from pypy.translator.c import genc from pypy.translator.interactive import Translation @@ -94,16 +91,6 @@ assert f1(-5) == -42 -def test_rptr_array(): - A = GcArray(Ptr(PyObject)) - def f(i, x): - p = malloc(A, i) - p[1] = x - return p[1] - f1 = compile(f, [int, annmodel.SomePtr(Ptr(PyObject))]) - assert f1(5, 123) == 123 - assert f1(12, "hello") == "hello" - def test_empty_string(): A = Array(Char, hints={'nolength': True}) p = malloc(A, 1, immortal=True) @@ -304,61 +291,12 @@ def f(): x = [1] y = ['b'] - objectmodel.keepalive_until_here(x,y) + objectmodel.keepalive_until_here(x, y) return 1 f1 = compile(f, []) assert f1() == 1 -def test_refcount_pyobj(): - def prob_with_pyobj(b): - return 3, b - - f = compile(prob_with_pyobj, [object]) - from sys import getrefcount as g - obj = None - import gc; gc.collect() - before = g(obj) - f(obj) - after = g(obj) - assert before == after - -def test_refcount_pyobj_setfield(): - import weakref, gc - class S(object): - def __init__(self): - self.p = None - def foo(wref, objfact): - s = S() - b = objfact() - s.p = b - wr = wref(b) - s.p = None - return wr - f = compile(foo, [object, object], backendopt=False) - class C(object): - pass - wref = f(weakref.ref, C) - gc.collect() - assert not wref() - -def test_refcount_pyobj_setfield_increfs(): - class S(object): - def __init__(self): - self.p = None - def goo(objfact): - s = S() - b = objfact() - s.p = b - return s - def foo(objfact): - s = goo(objfact) - return s.p - f = compile(foo, [object], backendopt=False) - class C(object): - pass - print f(C) - def test_print(): def f(): for i in range(10): @@ -375,7 +313,7 @@ t = Translation(f, [], backend="c") t.annotate() - compiled_fn = t.compile_c() + t.compile_c() if py.test.config.option.view: t.view() assert 'pypy_xyz_f' in t.driver.cbuilder.c_source_filename.read() @@ -391,7 +329,7 @@ t = Translation(f, [], backend="c", secondaryentrypoints="test_entrypoints42") t.annotate() - compiled_fn = t.compile_c() + t.compile_c() if py.test.config.option.view: t.view() assert 'foobar' in t.driver.cbuilder.c_source_filename.read() @@ -406,7 +344,7 @@ export_struct("BarStruct", foo._obj) t = Translation(f, [], backend="c") t.annotate() - compiled_fn = t.compile_c() + t.compile_c() if py.test.config.option.view: t.view() assert ' BarStruct ' in t.driver.cbuilder.c_source_filename.read() @@ -416,7 +354,6 @@ from pypy.rpython.annlowlevel import llhelper from pypy.rpython.lltypesystem import lltype from pypy.rlib.objectmodel import specialize - from pypy.rlib.nonconst import NonConstant FT = lltype.ForwardReference() FTPTR = lltype.Ptr(FT) STRUCT = lltype.Struct("foo", ("bar", FTPTR)) @@ -464,7 +401,6 @@ assert fn(True) def test_inhibit_tail_call(): - from pypy.rpython.lltypesystem import lltype def foobar_fn(n): return 42 foobar_fn._dont_inline_ = True From noreply at buildbot.pypy.org Sun Oct 7 21:05:23 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 7 Oct 2012 21:05:23 +0200 (CEST) Subject: [pypy-commit] pypy length-hint: workaround (potentially) for parsing extend_from_iterable's trace Message-ID: <20121007190523.849621C03FB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: length-hint Changeset: r57864:3126105cd7ea Date: 2012-10-07 12:05 -0700 http://bitbucket.org/pypy/pypy/changeset/3126105cd7ea/ Log: workaround (potentially) for parsing extend_from_iterable's trace diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py --- a/pypy/module/pypyjit/test_pypy_c/model.py +++ b/pypy/module/pypyjit/test_pypy_c/model.py @@ -104,6 +104,9 @@ yield subchunk def compute_ids(self, ids): + # XXX: valid? + if not self.code: + return # # 1. compute the ids of self, i.e. the outer function id2opcodes = find_ids(self.code) From noreply at buildbot.pypy.org Sun Oct 7 21:33:35 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 7 Oct 2012 21:33:35 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Add a gc_collect() in test_weakref Message-ID: <20121007193335.1297E1C041E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57865:f714fade7395 Date: 2012-10-07 10:13 +0200 http://bitbucket.org/pypy/pypy/changeset/f714fade7395/ Log: Add a gc_collect() in test_weakref diff --git a/lib-python/3.2/test/test_socket.py b/lib-python/3.2/test/test_socket.py --- a/lib-python/3.2/test/test_socket.py +++ b/lib-python/3.2/test/test_socket.py @@ -273,6 +273,7 @@ self.assertEqual(p.fileno(), s.fileno()) s.close() s = None + support.gc_collect() try: p.fileno() except ReferenceError: From noreply at buildbot.pypy.org Sun Oct 7 21:33:36 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 7 Oct 2012 21:33:36 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix keyword argument in socket.getaddrinfo() Message-ID: <20121007193336.556951C041E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57866:74a4e30fc988 Date: 2012-10-07 10:19 +0200 http://bitbucket.org/pypy/pypy/changeset/74a4e30fc988/ Log: Fix keyword argument in socket.getaddrinfo() diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -244,14 +244,15 @@ space.wrap(str(e))) return space.wrap(ip) - at unwrap_spec(family=int, socktype=int, proto=int, flags=int) + at unwrap_spec(family=int, type=int, proto=int, flags=int) def getaddrinfo(space, w_host, w_port, - family=rsocket.AF_UNSPEC, socktype=0, proto=0, flags=0): - """getaddrinfo(host, port [, family, socktype, proto, flags]) - -> list of (family, socktype, proto, canonname, sockaddr) + family=rsocket.AF_UNSPEC, type=0, proto=0, flags=0): + """getaddrinfo(host, port [, family, type, proto, flags]) + -> list of (family, type, proto, canonname, sockaddr) Resolve host and port into addrinfo struct. """ + socktype = type # host can be None, string or unicode if space.is_w(w_host, space.w_None): host = None From noreply at buildbot.pypy.org Sun Oct 7 21:33:37 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 7 Oct 2012 21:33:37 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Improve error message when the buffer interface is not supported. Message-ID: <20121007193337.76FB91C041E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57867:bfaa20565278 Date: 2012-10-07 10:49 +0200 http://bitbucket.org/pypy/pypy/changeset/bfaa20565278/ Log: Improve error message when the buffer interface is not supported. diff --git a/pypy/interpreter/test/test_buffer.py b/pypy/interpreter/test/test_buffer.py --- a/pypy/interpreter/test/test_buffer.py +++ b/pypy/interpreter/test/test_buffer.py @@ -19,7 +19,9 @@ assert space.bufferstr_w(w_hello) == 'hello world' assert space.bufferstr_w(space.buffer(w_hello)) == 'hello world' space.raises_w(space.w_TypeError, space.buffer_w, space.wrap(5)) - space.raises_w(space.w_TypeError, space.buffer, space.wrap(5)) + e = space.raises_w(space.w_TypeError, space.buffer, space.wrap(5)) + message = space.unwrap(e.value.get_w_value(space)) + assert "'int' does not support the buffer interface" == message def test_file_write(self): space = self.space diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -473,6 +473,15 @@ else: return space.isinstance(w_inst, w_type) + def buffer(space, w_obj): + w_impl = space.lookup(w_obj, '__buffer__') + if w_impl is None: + typename = space.type(w_obj).getname(space) + raise operationerrfmt( + space.w_TypeError, + "'%s' does not support the buffer interface", typename) + return space.get_and_call_function(w_impl, w_obj) + # helpers From noreply at buildbot.pypy.org Sun Oct 7 21:33:38 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 7 Oct 2012 21:33:38 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Oops, fix translation of _ssl module. Message-ID: <20121007193338.ACEF51C041E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57868:5702ff1929a4 Date: 2012-10-07 10:49 +0200 http://bitbucket.org/pypy/pypy/changeset/5702ff1929a4/ Log: Oops, fix translation of _ssl module. 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 @@ -160,10 +160,11 @@ def get_options_w(self, space): return space.wrap(libssl_SSL_CTX_get_options(self.ctx)) - def set_options_w(self, space, value): + def set_options_w(self, space, w_value): + value = space.int_w(w_value) opts = libssl_SSL_CTX_get_options(self.ctx) - clear = opts & ~new_opts - set = ~opts & new_opts + clear = opts & ~value + set = ~opts & value if clear: if HAVE_SSL_CTX_CLEAR_OPTIONS: libssl_SSL_CTX_clear_options(self.ctx, clear) diff --git a/pypy/rlib/ropenssl.py b/pypy/rlib/ropenssl.py --- a/pypy/rlib/ropenssl.py +++ b/pypy/rlib/ropenssl.py @@ -183,6 +183,7 @@ OBJ_NAME = rffi.CArrayPtr(OBJ_NAME_st) HAVE_OPENSSL_RAND = OPENSSL_VERSION_NUMBER >= 0x0090500f +HAVE_SSL_CTX_CLEAR_OPTIONS = OPENSSL_VERSION_NUMBER >= 0x009080df def external(name, argtypes, restype, **kw): kw['compilation_info'] = eci @@ -218,7 +219,9 @@ ssl_external('SSLv23_method', [], SSL_METHOD) ssl_external('SSL_CTX_use_PrivateKey_file', [SSL_CTX, rffi.CCHARP, rffi.INT], rffi.INT) ssl_external('SSL_CTX_use_certificate_chain_file', [SSL_CTX, rffi.CCHARP], rffi.INT) +ssl_external('SSL_CTX_get_options', [SSL_CTX], rffi.INT, macro=True) ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.INT], rffi.INT, macro=True) +ssl_external('SSL_CTX_clear_options', [SSL_CTX, rffi.INT], rffi.INT, macro=True) ssl_external('SSL_CTX_ctrl', [SSL_CTX, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT) ssl_external('SSL_CTX_set_verify', [SSL_CTX, rffi.INT, rffi.VOIDP], lltype.Void) ssl_external('SSL_CTX_get_verify_mode', [SSL_CTX], rffi.INT) From noreply at buildbot.pypy.org Sun Oct 7 21:33:39 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 7 Oct 2012 21:33:39 +0200 (CEST) Subject: [pypy-commit] pypy py3k: CPython defines OP_ALL differently, see CPython Issue #13885. Message-ID: <20121007193339.EE6031C041E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57869:02860bde5a0f Date: 2012-10-07 10:56 +0200 http://bitbucket.org/pypy/pypy/changeset/02860bde5a0f/ Log: CPython defines OP_ALL differently, see CPython Issue #13885. 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 @@ -61,7 +61,7 @@ constants["PROTOCOL_TLSv1"] = PY_SSL_VERSION_TLS1 # protocol options -constants["OP_ALL"] = SSL_OP_ALL +constants["OP_ALL"] = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS constants["OP_NO_SSLv2"] = SSL_OP_NO_SSLv2 constants["OP_NO_SSLv3"] = SSL_OP_NO_SSLv3 constants["OP_NO_TLSv1"] = SSL_OP_NO_TLSv1 From noreply at buildbot.pypy.org Sun Oct 7 21:33:41 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 7 Oct 2012 21:33:41 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix exception type, a test relies on it. Message-ID: <20121007193341.1C8F21C041E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57870:0f2251687b05 Date: 2012-10-07 10:59 +0200 http://bitbucket.org/pypy/pypy/changeset/0f2251687b05/ Log: Fix exception type, a test relies on it. 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 @@ -219,7 +219,7 @@ else: capath = space.str_w(w_capath) if cafile is None and capath is None: - raise OperationError(space.w_ValueError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( "cafile and capath cannot be both omitted")) ret = libssl_SSL_CTX_load_verify_locations( self.ctx, cafile, capath) From noreply at buildbot.pypy.org Sun Oct 7 23:46:37 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 7 Oct 2012 23:46:37 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: make this a new type Message-ID: <20121007214637.9DCE11C03FB@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57871:700c1b33a2f5 Date: 2012-10-07 23:46 +0200 http://bitbucket.org/pypy/pypy/changeset/700c1b33a2f5/ Log: make this a new type diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py --- a/pypy/rpython/lltypesystem/opimpl.py +++ b/pypy/rpython/lltypesystem/opimpl.py @@ -1,8 +1,6 @@ -import sys -import math from pypy.tool.sourcetools import func_with_new_name from pypy.rpython.lltypesystem import lltype, llmemory -from pypy.rpython.lltypesystem.lloperation import opimpls +from pypy.rpython.lltypesystem.lloperation import FunctionByName from pypy.rlib import debug from pypy.rlib.rarithmetic import is_valid_int @@ -49,11 +47,11 @@ def get_primitive_op_src(fullopname): assert '_' in fullopname, "%s: not a primitive op" % (fullopname,) typname, opname = fullopname.split('_', 1) - if opname not in opimpls and (opname + '_') in opimpls: - func = opimpls[opname + '_'] # or_, and_ + if opname not in FunctionByName and (opname + '_') in FunctionByName: + func = FunctionByName[opname + '_'] # or_, and_ else: - assert opname in opimpls, "%s: not a primitive op" % (fullopname,) - func = opimpls[opname] + assert opname in FunctionByName, "%s: not a primitive op" % (fullopname,) + func = FunctionByName[opname] if typname == 'char': # char_lt, char_eq, ... From noreply at buildbot.pypy.org Mon Oct 8 00:09:59 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 8 Oct 2012 00:09:59 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix some test_ztranslation failures, Message-ID: <20121007220959.0F09D1C041E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57872:4d836b33546a Date: 2012-10-07 23:08 +0200 http://bitbucket.org/pypy/pypy/changeset/4d836b33546a/ Log: Fix some test_ztranslation failures, functions with unwrap_spec(str) could not be analyzed. diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -41,6 +41,7 @@ def str_w(self, space): return NonConstant("foobar") + identifier_w = bytes_w = str_w def unicode_w(self, space): return NonConstant(u"foobar") From noreply at buildbot.pypy.org Mon Oct 8 00:31:37 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 8 Oct 2012 00:31:37 +0200 (CEST) Subject: [pypy-commit] pypy length-hint: cleanup Message-ID: <20121007223137.E1A221C041E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: length-hint Changeset: r57873:61217b655c79 Date: 2012-10-07 15:24 -0700 http://bitbucket.org/pypy/pypy/changeset/61217b655c79/ Log: cleanup diff --git a/pypy/objspace/std/test/test_lengthhint.py b/pypy/objspace/std/test/test_lengthhint.py --- a/pypy/objspace/std/test/test_lengthhint.py +++ b/pypy/objspace/std/test/test_lengthhint.py @@ -1,4 +1,3 @@ -from pypy.interpreter.error import OperationError from pypy.module._collections.interp_deque import W_Deque from pypy.module.itertools.interp_itertools import W_Repeat @@ -131,12 +130,7 @@ return -1 return Foo() """) - try: - space.length_hint(w_foo, 3) - except OperationError, e: - assert e.match(space, space.w_ValueError) - else: - assert False, 'ValueError expected' + space.raises_w(space.w_ValueError, space.length_hint, w_foo, 3) def test_exc(self): space = self.space @@ -146,9 +140,4 @@ 1 / 0 return Foo() """) - try: - space.length_hint(w_foo, 3) - except OperationError, e: - assert e.match(space, space.w_ZeroDivisionError) - else: - assert False, 'ZeroDivisionError expected' + space.raises_w(space.w_ZeroDivisionError, space.length_hint, w_foo, 3) From noreply at buildbot.pypy.org Mon Oct 8 00:31:39 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 8 Oct 2012 00:31:39 +0200 (CEST) Subject: [pypy-commit] pypy length-hint: fix itertools length_hint returning a negative length Message-ID: <20121007223139.1CA711C041E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: length-hint Changeset: r57874:2ec86d638139 Date: 2012-10-07 15:27 -0700 http://bitbucket.org/pypy/pypy/changeset/2ec86d638139/ Log: fix itertools length_hint returning a negative length diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -92,7 +92,7 @@ self.count = 0 else: self.counting = True - self.count = self.space.int_w(w_times) + self.count = max(self.space.int_w(w_times), 0) def next_w(self): if self.counting: diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -90,11 +90,15 @@ def test_repeat_len(self): import itertools + import operator r = itertools.repeat('a', 15) r.next() raises(TypeError, "len(itertools.repeat('xkcd'))") + r = itertools.repeat('a', -3) + assert operator._length_hint(r, 3) == 0 + def test_takewhile(self): import itertools From noreply at buildbot.pypy.org Mon Oct 8 09:38:24 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 09:38:24 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: a bit of test cleanup Message-ID: <20121008073824.A60F91C0CD3@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57875:c947278ffa5d Date: 2012-10-08 09:37 +0200 http://bitbucket.org/pypy/pypy/changeset/c947278ffa5d/ Log: a bit of test cleanup diff --git a/pypy/rlib/parsing/test/test_deterministic.py b/pypy/rlib/parsing/test/test_deterministic.py --- a/pypy/rlib/parsing/test/test_deterministic.py +++ b/pypy/rlib/parsing/test/test_deterministic.py @@ -1,6 +1,6 @@ from pypy.rlib.parsing.deterministic import * +from pypy.translator.interactive import Translation -from sets import Set def test_DFA_simple(): a = DFA() @@ -24,11 +24,8 @@ assert py.test.raises(LexerError, "recognize('xzya')") assert recognize("aaaacb") + def test_compile_recognizer(): - try: - from pypy.translator.interactive import Translation - except ImportError: - py.test.skip("pypy not found on path") a = DFA() s0 = a.add_state("start") s1 = a.add_state() @@ -45,6 +42,7 @@ assert cfn("b") assert cfn("aaaacb") + def test_NFA_simple(): a = NFA() z0 = a.add_state("z0", start=True) diff --git a/pypy/rlib/test/test_jit.py b/pypy/rlib/test/test_jit.py --- a/pypy/rlib/test/test_jit.py +++ b/pypy/rlib/test/test_jit.py @@ -1,18 +1,21 @@ import py + from pypy.conftest import option -from pypy.rlib.jit import hint, we_are_jitted, JitDriver, elidable_promote -from pypy.rlib.jit import JitHintError, oopspec, isconstant +from pypy.annotation.model import UnionError +from pypy.rlib.jit import (hint, we_are_jitted, JitDriver, elidable_promote, + JitHintError, oopspec, isconstant) from pypy.rlib.rarithmetic import r_uint -from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rpython.lltypesystem import lltype + def test_oopspec(): @oopspec('foobar') def fn(): pass assert fn.oopspec == 'foobar' - + + class BaseTestJIT(BaseRtypingTest): def test_hint(self): def f(): @@ -91,7 +94,7 @@ for graph in t.graphs: if getattr(graph, 'func', None) is func: return [v.concretetype for v in graph.getargs()] - raise Exception, 'function %r has not been annotated' % func + raise Exception('function %r has not been annotated' % func) get_printable_location_args = getargs(get_printable_location) assert get_printable_location_args == [lltype.Float] @@ -108,15 +111,17 @@ def test_annotate_typeerror(self): myjitdriver = JitDriver(greens=['m'], reds=['n']) - class A(object): pass - class B(object): pass + class A(object): + pass + class B(object): + pass def fn(n): while n > 0: myjitdriver.can_enter_jit(m=A(), n=n) myjitdriver.jit_merge_point(m=B(), n=n) n -= 1 return n - py.test.raises(JitHintError, self.gengraph, fn, [int]) + py.test.raises(UnionError, self.gengraph, fn, [int]) def test_green_field(self): def get_printable_location(xfoo): diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py --- a/pypy/rpython/lltypesystem/opimpl.py +++ b/pypy/rpython/lltypesystem/opimpl.py @@ -1,9 +1,8 @@ -from pypy.tool.sourcetools import func_with_new_name -from pypy.rpython.lltypesystem import lltype, llmemory -from pypy.rpython.lltypesystem.lloperation import FunctionByName +from pypy.objspace.flow.operation import FunctionByName from pypy.rlib import debug from pypy.rlib.rarithmetic import is_valid_int - +from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.tool.sourcetools import func_with_new_name # ____________________________________________________________ # Implementation of the 'canfold' operations @@ -27,8 +26,8 @@ else: r_longlong_arg = r_longlong r_longlong_result = r_longlong - - + + r_longlonglong_arg = r_longlonglong r_longlonglong_result = r_longlonglong From noreply at buildbot.pypy.org Mon Oct 8 09:50:06 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 09:50:06 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: remove references to policy=annpolicy.StrictAnnotatorPolicy(), Message-ID: <20121008075006.4ED281C0274@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57876:69cf2b314c06 Date: 2012-10-08 09:49 +0200 http://bitbucket.org/pypy/pypy/changeset/69cf2b314c06/ Log: remove references to policy=annpolicy.StrictAnnotatorPolicy(), diff --git a/pypy/jit/backend/arm/test/test_zrpy_gc.py b/pypy/jit/backend/arm/test/test_zrpy_gc.py --- a/pypy/jit/backend/arm/test/test_zrpy_gc.py +++ b/pypy/jit/backend/arm/test/test_zrpy_gc.py @@ -96,7 +96,7 @@ t.config.translation.gcremovetypeptr = True for name, value in kwds.items(): setattr(t.config.translation, name, value) - ann = t.buildannotator(policy=annpolicy.StrictAnnotatorPolicy()) + ann = t.buildannotator() ann.build_types(f, [s_list_of_strings], main_entry_point=True) t.buildrtyper().specialize() diff --git a/pypy/jit/backend/x86/test/test_zrpy_gc.py b/pypy/jit/backend/x86/test/test_zrpy_gc.py --- a/pypy/jit/backend/x86/test/test_zrpy_gc.py +++ b/pypy/jit/backend/x86/test/test_zrpy_gc.py @@ -93,7 +93,7 @@ t.config.translation.gcremovetypeptr = True for name, value in kwds.items(): setattr(t.config.translation, name, value) - ann = t.buildannotator(policy=annpolicy.StrictAnnotatorPolicy()) + ann = t.buildannotator() ann.build_types(f, [s_list_of_strings], main_entry_point=True) t.buildrtyper().specialize() diff --git a/pypy/translator/c/test/test_newgc.py b/pypy/translator/c/test/test_newgc.py --- a/pypy/translator/c/test/test_newgc.py +++ b/pypy/translator/c/test/test_newgc.py @@ -39,7 +39,6 @@ return 0 t = Translation(main, standalone=True, gc=cls.gcpolicy, - policy=annpolicy.StrictAnnotatorPolicy(), taggedpointers=cls.taggedpointers, gcremovetypeptr=cls.removetypeptr) t.disable(['backendopt']) From noreply at buildbot.pypy.org Mon Oct 8 09:51:39 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 09:51:39 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: remove import of CExtModuleBuilder so the tests will import (even if they fail) Message-ID: <20121008075139.4CE921C0CD3@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57877:b276dfeb927d Date: 2012-10-08 09:51 +0200 http://bitbucket.org/pypy/pypy/changeset/b276dfeb927d/ Log: remove import of CExtModuleBuilder so the tests will import (even if they fail) diff --git a/pypy/translator/c/test/test_boehm.py b/pypy/translator/c/test/test_boehm.py --- a/pypy/translator/c/test/test_boehm.py +++ b/pypy/translator/c/test/test_boehm.py @@ -2,7 +2,6 @@ from pypy.translator.translator import TranslationContext from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.lltypesystem.lloperation import llop -from pypy.translator.c.genc import CExtModuleBuilder from pypy.rlib.objectmodel import keepalive_until_here from pypy import conftest @@ -15,20 +14,21 @@ except CompilationError: py.test.skip("Boehm GC not present") + class AbstractGCTestClass(object): gcpolicy = "boehm" use_threads = False - + # deal with cleanups def setup_method(self, meth): self._cleanups = [] + def teardown_method(self, meth): while self._cleanups: #print "CLEANUP" self._cleanups.pop()() - def getcompiled(self, func, argstypelist = [], - annotatorpolicy=None): + def getcompiled(self, func, argstypelist=[], annotatorpolicy=None): from pypy.config.pypyoption import get_pypy_config config = get_pypy_config(translating=True) config.translation.gc = self.gcpolicy From noreply at buildbot.pypy.org Mon Oct 8 10:04:30 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 10:04:30 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix flow tests Message-ID: <20121008080430.7304B1C0CD3@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57878:3d1b217354aa Date: 2012-10-08 10:04 +0200 http://bitbucket.org/pypy/pypy/changeset/3d1b217354aa/ Log: fix flow tests diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py --- a/pypy/objspace/flow/model.py +++ b/pypy/objspace/flow/model.py @@ -1,6 +1,6 @@ # The model produced by the flowobjspace # this is to be used by the translator mainly. -# +# # the below object/attribute model evolved from # a discussion in Berlin, 4th of october 2003 import py @@ -19,7 +19,7 @@ Var/Const/SpaceOp 205 MB 325 MB + Link 189 MB 311 MB + Block 185 MB 304 MB - + Dropping Variable.instances and using just an instancenames dict brought annotation down to 160 MB. @@ -55,13 +55,19 @@ @property def source(self): + if hasattr(self, "_source"): + return self._source from pypy.tool.sourcetools import getsource - func = self.func # can raise AttributeError + self.func # can raise AttributeError src = getsource(self.func) if src is None: raise AttributeError('source not found') return src + @source.setter + def source(self, value): + self._source = value + @property def startline(self): return self.func.func_code.co_firstlineno diff --git a/pypy/objspace/flow/test/test_model.py b/pypy/objspace/flow/test/test_model.py --- a/pypy/objspace/flow/test/test_model.py +++ b/pypy/objspace/flow/test/test_model.py @@ -57,7 +57,7 @@ assert graph.returnblock is pieces.headerblock.exits[0].target assert graph.getargs() == [pieces.i] assert [graph.getreturnvar()] == graph.returnblock.inputargs - assert graph.getsource() == inspect.getsource(sample_function) + assert graph.source == inspect.getsource(sample_function) def test_iterblocks(): assert list(graph.iterblocks()) == [pieces.startblock, From noreply at buildbot.pypy.org Mon Oct 8 10:18:07 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 10:18:07 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix one more test Message-ID: <20121008081807.D21881C027A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57879:98cb49867043 Date: 2012-10-08 10:17 +0200 http://bitbucket.org/pypy/pypy/changeset/98cb49867043/ Log: fix one more test diff --git a/pypy/translator/c/src/g_include.h b/pypy/translator/c/src/g_include.h --- a/pypy/translator/c/src/g_include.h +++ b/pypy/translator/c/src/g_include.h @@ -2,19 +2,9 @@ /************************************************************/ /*** C header file for code produced by genc.py ***/ -#ifdef PYPY_CPYTHON_EXTENSION -# include "Python.h" -# include "compile.h" -# include "frameobject.h" -# include "structmember.h" -# include "traceback.h" -# include "marshal.h" -# include "eval.h" -#else -# include -# include -# include -#endif +#include +#include +#include #include "src/mem.h" #include "src/exception.h" @@ -46,8 +36,8 @@ # include "src/ll_strtod.h" #endif +# include "src/allocator.h" #ifdef PYPY_STANDALONE -# include "src/allocator.h" # include "src/main.h" #endif diff --git a/pypy/translator/c/src/g_prerequisite.h b/pypy/translator/c/src/g_prerequisite.h --- a/pypy/translator/c/src/g_prerequisite.h +++ b/pypy/translator/c/src/g_prerequisite.h @@ -3,9 +3,7 @@ /*** this is included before any code produced by genc.py ***/ -#ifdef PYPY_STANDALONE -# include "src/commondefs.h" -#endif +#include "src/commondefs.h" #ifdef _WIN32 # include /* needed, otherwise _lseeki64 truncates to 32-bits (??) */ From noreply at buildbot.pypy.org Mon Oct 8 10:19:27 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 10:19:27 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Cleaned up test_newgc Message-ID: <20121008081927.C52F51C027A@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57880:0e6f30e1005b Date: 2012-10-08 10:18 +0200 http://bitbucket.org/pypy/pypy/changeset/0e6f30e1005b/ Log: Cleaned up test_newgc diff --git a/pypy/translator/c/test/test_newgc.py b/pypy/translator/c/test/test_newgc.py --- a/pypy/translator/c/test/test_newgc.py +++ b/pypy/translator/c/test/test_newgc.py @@ -1,17 +1,20 @@ +import gc +import inspect +import os +import sys + import py -import sys, os, inspect -from pypy.objspace.flow.model import summary -from pypy.rpython.lltypesystem import lltype, llmemory +from pypy import conftest +from pypy.rlib import rgc +from pypy.rlib.objectmodel import keepalive_until_here, compute_hash, compute_identity_hash +from pypy.rlib.rstring import StringBuilder +from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.memory.test import snippet -from pypy.rlib import rgc -from pypy.rlib.objectmodel import keepalive_until_here -from pypy.rlib.rstring import StringBuilder, UnicodeBuilder from pypy.tool.udir import udir from pypy.translator.interactive import Translation -from pypy.annotation import policy as annpolicy -from pypy import conftest + class TestUsingFramework(object): gcpolicy = "marksweep" @@ -57,7 +60,6 @@ return run - def setup_class(cls): funcs0 = [] funcs1 = [] @@ -74,12 +76,12 @@ prefix, name = fullname.split('_', 1) definefunc = getattr(cls, fullname) func = definefunc.im_func(cls) - func.func_name = 'f_'+name + func.func_name = 'f_' + name if prefix == 'definestr': funcsstr.append(func) funcs0.append(None) funcs1.append(None) - else: + else: numargs = len(inspect.getargspec(func)[0]) funcsstr.append(None) if numargs == 0: @@ -91,6 +93,7 @@ funcs1.append(func) assert name not in name_to_func name_to_func[name] = len(name_to_func) + def allfuncs(name, arg): num = name_to_func[name] func0 = funcs0[num] @@ -236,10 +239,10 @@ a[j] = lltype.malloc(T) a[j].y = i a[j].s = lltype.malloc(S) - a[j].s.x = 2*i + a[j].s.x = 2 * i r += a[j].y + a[j].s.x a[j].s = lltype.malloc(S) - a[j].s.x = 3*i + a[j].s.x = 3 * i r -= a[j].s.x for j in range(i): r += a[j].y @@ -269,7 +272,7 @@ def test_framework_using_lists(self): N = 1000 res = self.run('framework_using_lists') - assert res == N*(N - 1)/2 + assert res == N * (N - 1) / 2 def define_framework_static_roots(cls): class A(object): @@ -318,10 +321,9 @@ res = self.run('framework_void_array') assert res == 44 - def define_framework_malloc_failure(cls): def f(): - a = [1] * (sys.maxint//2) + a = [1] * (sys.maxint // 2) return len(a) + a[0] return f @@ -397,7 +399,6 @@ assert res == 6 def define_del_catches(cls): - import os def g(): pass class A(object): @@ -442,7 +443,6 @@ def define_custom_trace(cls): from pypy.rpython.annlowlevel import llhelper - from pypy.rpython.lltypesystem import llmemory # S = lltype.GcStruct('S', ('x', llmemory.Address), rtti=True) offset_of_x = llmemory.offsetof(S, 'x') @@ -530,9 +530,9 @@ a = refs[i]() rgc.collect() if a is None: - result += (i+1) + result += (i + 1) else: - result += a.hello * (i+1) + result += a.hello * (i + 1) return result return fn @@ -624,7 +624,7 @@ res = self.run('object_alignment') from pypy.rpython.tool import rffi_platform expected_alignment = rffi_platform.memory_alignment() - assert (res & (expected_alignment-1)) == 0 + assert (res & (expected_alignment - 1)) == 0 def define_void_list(cls): class E: @@ -664,8 +664,6 @@ def define_callback_with_collect(cls): from pypy.rlib.clibffi import ffi_type_pointer, cast_type_to_ffitype,\ CDLL, ffi_type_void, CallbackFuncPtr, ffi_type_sint - from pypy.rpython.lltypesystem import rffi, ll2ctypes - import gc ffi_size_t = cast_type_to_ffitype(rffi.SIZE_T) from pypy.rlib.clibffi import get_libc_name @@ -702,7 +700,7 @@ qsort.push_arg(rffi.cast(rffi.SIZE_T, rffi.sizeof(lltype.Signed))) qsort.push_arg(rffi.cast(rffi.VOIDP, ptr.ll_closure)) qsort.call(lltype.Void) - result = [to_sort[i] for i in range(4)] == [1,2,3,4] + result = [to_sort[i] for i in range(4)] == [1, 2, 3, 4] lltype.free(to_sort, flavor='raw') keepalive_until_here(ptr) return int(result) @@ -732,7 +730,7 @@ assert not rgc.can_move(a) return 1 return 0 - except Exception, e: + except Exception: return 2 return func @@ -767,9 +765,6 @@ assert res == expected def define_hash_preservation(cls): - from pypy.rlib.objectmodel import compute_hash - from pypy.rlib.objectmodel import compute_identity_hash - from pypy.rlib.objectmodel import current_object_addr_as_int class C: pass class D(C): @@ -784,17 +779,23 @@ h_s = compute_identity_hash(s) # varsized: hash not saved/restored # def f(): - if compute_hash(c) != compute_identity_hash(c): return 12 - if compute_hash(d) != h_d: return 13 - if compute_hash(("Hi", None, (7.5, 2, d))) != h_t: return 14 + if compute_hash(c) != compute_identity_hash(c): + return 12 + if compute_hash(d) != h_d: + return 13 + if compute_hash(("Hi", None, (7.5, 2, d))) != h_t: + return 14 c2 = C() h_c2 = compute_hash(c2) - if compute_hash(c2) != h_c2: return 15 - if compute_identity_hash(s) == h_s: return 16 # unlikely + if compute_hash(c2) != h_c2: + return 15 + if compute_identity_hash(s) == h_s: + return 16 # unlikely i = 0 while i < 6: rgc.collect() - if compute_hash(c2) != h_c2: return i + if compute_hash(c2) != h_c2: + return i i += 1 return 42 return f @@ -804,7 +805,6 @@ assert res == 42 def define_hash_overflow(self): - from pypy.rlib.objectmodel import compute_identity_hash class X(object): pass @@ -848,16 +848,16 @@ build(x1, n) # can collect! check(x1, n, 1) build(x3, 3) - x2 = g(n//2) # allocate more and try again - build(x2, n//2) + x2 = g(n // 2) # allocate more and try again + build(x2, n // 2) check(x1, n, 11) - check(x2, n//2, 12) + check(x2, n // 2, 12) build(x4, 3) check(x3, 3, 13) # check these old objects too check(x4, 3, 14) # check these old objects too rgc.collect() check(x1, n, 21) - check(x2, n//2, 22) + check(x2, n // 2, 22) check(x3, 3, 23) check(x4, 3, 24) @@ -890,7 +890,6 @@ res = self.run('hash_varsized') assert res != 0 - def define_arraycopy_writebarrier_int(cls): TP = lltype.GcArray(lltype.Signed) S = lltype.GcStruct('S') @@ -1062,10 +1061,10 @@ assert 8 <= int1 <= 32 gcref2 = lltype.cast_opaque_ptr(llmemory.GCREF, s.u) int2 = rgc.get_rpy_memory_usage(gcref2) - assert 4*9 <= int2 <= 8*12 + assert 4 * 9 <= int2 <= 8 * 12 gcref3 = lltype.cast_opaque_ptr(llmemory.GCREF, a) int3 = rgc.get_rpy_memory_usage(gcref3) - assert 4*1001 <= int3 <= 8*1010 + assert 4 * 1001 <= int3 <= 8 * 1010 return 0 return fn @@ -1234,7 +1233,7 @@ # the semispace size starts at 8MB for now, so setting a # smaller limit has no effect # set to more than 32MB -- which should be rounded down to 32MB - rgc.set_max_heap_size(32*1024*1024 + 20000) + rgc.set_max_heap_size(32 * 1024 * 1024 + 20000) s1 = s2 = s3 = None try: s1 = g(400000) # ~ 400 KB @@ -1299,7 +1298,6 @@ assert res == "aabcbdddd" def definestr_string_builder_over_allocation(cls): - import gc def fn(_): s = StringBuilder(4) s.append("abcd") @@ -1318,7 +1316,6 @@ assert res[1000] == 'y' def definestr_string_builder_multiple_builds(cls): - import gc def fn(_): s = StringBuilder(4) got = [] @@ -1335,7 +1332,6 @@ for length in range(1, 51)]) def define_nursery_hash_base(cls): - from pypy.rlib.objectmodel import compute_identity_hash class A: pass def fn(): @@ -1362,6 +1358,7 @@ gcpolicy = "generation" should_be_moving = True + class TestHybridGC(TestGenerationalGC): gcpolicy = "hybrid" should_be_moving = True @@ -1371,7 +1368,6 @@ py.test.skip("not implemented") - class TestHybridGCRemoveTypePtr(TestHybridGC): removetypeptr = True @@ -1436,6 +1432,7 @@ res = self.run("adding_a_hash") assert res == 0 + class TestMiniMarkGC(TestSemiSpaceGC): gcpolicy = "minimark" should_be_moving = True @@ -1466,7 +1463,7 @@ am3 = am2 am2 = am1 am1 = A(i * 4) - am1.buf[0] = rffi.cast(rffi.INT, i-50000) + am1.buf[0] = rffi.cast(rffi.INT, i - 50000) return res return f @@ -1477,7 +1474,6 @@ def define_nongc_opaque_attached_to_gc(cls): from pypy.module._hashlib.interp_hashlib import HASH_MALLOC_SIZE from pypy.rlib import rgc, ropenssl - from pypy.rpython.lltypesystem import rffi class A: def __init__(self): @@ -1594,8 +1590,10 @@ class TestHybridTaggedPointers(TaggedPointersTest, TestHybridGC): pass + class TestMarkCompactGCMostCompact(TaggedPointersTest, TestMarkCompactGC): removetypeptr = True + class TestMiniMarkGCMostCompact(TaggedPointersTest, TestMiniMarkGC): removetypeptr = True From noreply at buildbot.pypy.org Mon Oct 8 10:19:29 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 10:19:29 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121008081929.0EB4E1C027A@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57881:800018e02513 Date: 2012-10-08 10:19 +0200 http://bitbucket.org/pypy/pypy/changeset/800018e02513/ Log: merge diff --git a/pypy/translator/c/src/g_include.h b/pypy/translator/c/src/g_include.h --- a/pypy/translator/c/src/g_include.h +++ b/pypy/translator/c/src/g_include.h @@ -2,19 +2,9 @@ /************************************************************/ /*** C header file for code produced by genc.py ***/ -#ifdef PYPY_CPYTHON_EXTENSION -# include "Python.h" -# include "compile.h" -# include "frameobject.h" -# include "structmember.h" -# include "traceback.h" -# include "marshal.h" -# include "eval.h" -#else -# include -# include -# include -#endif +#include +#include +#include #include "src/mem.h" #include "src/exception.h" @@ -46,8 +36,8 @@ # include "src/ll_strtod.h" #endif +# include "src/allocator.h" #ifdef PYPY_STANDALONE -# include "src/allocator.h" # include "src/main.h" #endif diff --git a/pypy/translator/c/src/g_prerequisite.h b/pypy/translator/c/src/g_prerequisite.h --- a/pypy/translator/c/src/g_prerequisite.h +++ b/pypy/translator/c/src/g_prerequisite.h @@ -3,9 +3,7 @@ /*** this is included before any code produced by genc.py ***/ -#ifdef PYPY_STANDALONE -# include "src/commondefs.h" -#endif +#include "src/commondefs.h" #ifdef _WIN32 # include /* needed, otherwise _lseeki64 truncates to 32-bits (??) */ From noreply at buildbot.pypy.org Mon Oct 8 10:20:27 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 10:20:27 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, fijal) kill a now unused debug option Message-ID: <20121008082027.F38E71C027A@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57882:f19e44d300a7 Date: 2012-10-08 10:20 +0200 http://bitbucket.org/pypy/pypy/changeset/f19e44d300a7/ Log: (alex, fijal) kill a now unused debug option diff --git a/pypy/translator/goal/translate.py b/pypy/translator/goal/translate.py --- a/pypy/translator/goal/translate.py +++ b/pypy/translator/goal/translate.py @@ -83,11 +83,6 @@ goal_options()), ]) - -OVERRIDES = { - 'translation.debug': False, -} - import optparse from pypy.tool.ansi_print import ansi_log log = py.log.Producer("translation") From noreply at buildbot.pypy.org Mon Oct 8 10:39:27 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 10:39:27 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: some cleanup of boehm tests Message-ID: <20121008083927.27B621C0274@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57883:08560cea9cd4 Date: 2012-10-08 10:39 +0200 http://bitbucket.org/pypy/pypy/changeset/08560cea9cd4/ Log: some cleanup of boehm tests diff --git a/pypy/translator/c/test/test_boehm.py b/pypy/translator/c/test/test_boehm.py --- a/pypy/translator/c/test/test_boehm.py +++ b/pypy/translator/c/test/test_boehm.py @@ -1,9 +1,15 @@ +import weakref + import py -from pypy.translator.translator import TranslationContext + +from pypy import conftest +from pypy.rlib import rgc +from pypy.rlib.objectmodel import (keepalive_until_here, compute_unique_id, + compute_hash, current_object_addr_as_int) from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rlib.objectmodel import keepalive_until_here -from pypy import conftest +from pypy.rpython.lltypesystem.rstr import STR +from pypy.translator.translator import TranslationContext def setup_module(mod): @@ -104,7 +110,6 @@ def test_id_is_weak(self): # test that compute_unique_id(obj) does not keep obj alive - from pypy.rlib.objectmodel import compute_unique_id class State: pass s = State() @@ -232,9 +237,6 @@ assert res == 2 def test_weakref(self): - import weakref - from pypy.rlib import rgc - class A: pass @@ -268,8 +270,6 @@ assert 3500 <= res <= 6000 def test_prebuilt_weakref(self): - import weakref - from pypy.rlib import rgc class A: pass a = A() @@ -296,8 +296,6 @@ assert res == -5 def test_weakref_to_prebuilt(self): - import weakref - from pypy.rlib import rgc class A: pass a = A() @@ -311,7 +309,6 @@ c_fn(100) def test_nested_finalizers(self): - from pypy.rlib import rgc class State: pass state = State() @@ -345,7 +342,6 @@ assert res == 0 def test_can_move(self): - from pypy.rlib import rgc class A: pass def fn(): @@ -355,8 +351,6 @@ assert c_fn() == False def test_heap_stats(self): - from pypy.rlib import rgc - def fn(): return bool(rgc._heap_stats()) @@ -367,23 +361,19 @@ TP = lltype.GcArray(lltype.Char) def func(): try: - from pypy.rlib import rgc a = rgc.malloc_nonmovable(TP, 3) rgc.collect() if a: assert not rgc.can_move(a) return 0 return 1 - except Exception, e: + except Exception: return 2 run = self.getcompiled(func) assert run() == 0 def test_shrink_array(self): - from pypy.rpython.lltypesystem.rstr import STR - from pypy.rlib import rgc - def f(): ptr = lltype.malloc(STR, 3) ptr.hash = 0x62 @@ -409,11 +399,9 @@ llmemory.cast_ptr_to_adr(s)) return True run = self.getcompiled(f) - assert run() == True + assert run() == True def test_hash_preservation(self): - from pypy.rlib.objectmodel import compute_hash - from pypy.rlib.objectmodel import current_object_addr_as_int class C: pass class D(C): @@ -429,7 +417,7 @@ compute_hash(c), compute_hash(d), compute_hash(("Hi", None, (7.5, 2, d)))) - + f = self.getcompiled(fn) res = f() From noreply at buildbot.pypy.org Mon Oct 8 11:05:34 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 11:05:34 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Merged default in. Message-ID: <20121008090534.0589E1C0CD8@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57884:bf2fa5d5c6d1 Date: 2012-10-08 11:05 +0200 http://bitbucket.org/pypy/pypy/changeset/bf2fa5d5c6d1/ Log: Merged default in. diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -41,9 +41,6 @@ llexternal functions. For a typical usage, see `pypy.rlib.rsocket.RSocket.getsockopt_int`. -- Support context managers and the `with` statement. This could be a workaround - before the previous point is available. - Extensible type system for llexternal ------------------------------------- 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 @@ -185,7 +185,7 @@ return stream.readline() else: # very inefficient unless there is a peek() - result = [] + result = StringBuilder() while size > 0: # "peeks" on the underlying stream to see how many chars # we can safely read without reading past an end-of-line @@ -200,7 +200,7 @@ if c.endswith('\n'): break size -= len(c) - return ''.join(result) + return result.build() @unwrap_spec(size=int) def direct_readlines(self, size=0): 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 @@ -428,6 +428,18 @@ pass assert f.subclass_closed + def test_readline_unbuffered_should_read_one_line_only(self): + import posix + + with self.file(self.temppath, 'w') as f: + f.write('foo\nbar\n') + + with self.file(self.temppath, 'r', 0) as f: + s = f.readline() + assert s == 'foo\n' + s = posix.read(f.fileno(), 10) + assert s == 'bar\n' + def test_flush_at_exit(): from pypy import conftest from pypy.tool.option import make_config, make_objspace diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -644,8 +644,7 @@ # j = (m+) % SHIFT = (m+) - (i * SHIFT) # (computed without doing "i * SHIFT", which might overflow) j = size_b % 5 - if j != 0: - j = 5 - j + j = _jmapping[j] if not we_are_translated(): assert j == (size_b*SHIFT+4)//5*5 - size_b*SHIFT # @@ -866,6 +865,12 @@ ONENEGATIVERBIGINT = rbigint([ONEDIGIT], -1, 1) NULLRBIGINT = rbigint() +_jmapping = [(5 * SHIFT) % 5, + (4 * SHIFT) % 5, + (3 * SHIFT) % 5, + (2 * SHIFT) % 5, + (1 * SHIFT) % 5] + #_________________________________________________________________ # Helper Functions diff --git a/pypy/rlib/rsre/rsre_re.py b/pypy/rlib/rsre/rsre_re.py --- a/pypy/rlib/rsre/rsre_re.py +++ b/pypy/rlib/rsre/rsre_re.py @@ -75,7 +75,7 @@ else: item = match.groups("") matchlist.append(item) - return matchlist + return matchlist def finditer(self, string, pos=0, endpos=sys.maxint): return iter(self.scanner(string, pos, endpos).search, None) diff --git a/pypy/rlib/streamio.py b/pypy/rlib/streamio.py --- a/pypy/rlib/streamio.py +++ b/pypy/rlib/streamio.py @@ -41,6 +41,7 @@ from pypy.rlib.objectmodel import specialize, we_are_translated from pypy.rlib.rarithmetic import r_longlong, intmask from pypy.rlib import rposix +from pypy.rlib.rstring import StringBuilder from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC O_BINARY = getattr(os, "O_BINARY", 0) @@ -141,8 +142,7 @@ def construct_stream_tower(stream, buffering, universal, reading, writing, binary): if buffering == 0: # no buffering - if reading: # force some minimal buffering for readline() - stream = ReadlineInputStream(stream) + pass elif buffering == 1: # line-buffering if writing: stream = LineBufferingOutputStream(stream) @@ -303,6 +303,26 @@ raise # else try again + def readline(self): + # mostly inefficient, but not as laughably bad as with the default + # readline() from Stream + result = StringBuilder() + while True: + try: + c = os.read(self.fd, 1) + except OSError, e: + if e.errno != errno.EINTR: + raise + else: + continue # try again + if not c: + break + c = c[0] + result.append(c) + if c == '\n': + break + return result.build() + def write(self, data): while data: try: @@ -700,113 +720,6 @@ flush_buffers=False) -class ReadlineInputStream(Stream): - - """Minimal buffering input stream. - - Only does buffering for readline(). The other kinds of reads, and - all writes, are not buffered at all. - """ - - bufsize = 2**13 # 8 K - - def __init__(self, base, bufsize=-1): - self.base = base - self.do_read = base.read # function to fill buffer some more - self.do_seek = base.seek # seek to a byte offset - if bufsize == -1: # Get default from the class - bufsize = self.bufsize - self.bufsize = bufsize # buffer size (hint only) - self.buf = None # raw data (may contain "\n") - self.bufstart = 0 - - def flush_buffers(self): - if self.buf is not None: - try: - self.do_seek(self.bufstart-len(self.buf), 1) - except (MyNotImplementedError, OSError): - pass - else: - self.buf = None - self.bufstart = 0 - - def readline(self): - if self.buf is not None: - i = self.buf.find('\n', self.bufstart) - else: - self.buf = '' - i = -1 - # - if i < 0: - self.buf = self.buf[self.bufstart:] - self.bufstart = 0 - while True: - bufsize = max(self.bufsize, len(self.buf) >> 2) - data = self.do_read(bufsize) - if not data: - result = self.buf # end-of-file reached - self.buf = None - return result - startsearch = len(self.buf) # there is no '\n' in buf so far - self.buf += data - i = self.buf.find('\n', startsearch) - if i >= 0: - break - # - i += 1 - result = self.buf[self.bufstart:i] - self.bufstart = i - return result - - def peek(self): - if self.buf is None: - return '' - if self.bufstart > 0: - self.buf = self.buf[self.bufstart:] - self.bufstart = 0 - return self.buf - - def tell(self): - pos = self.base.tell() - if self.buf is not None: - pos -= (len(self.buf) - self.bufstart) - return pos - - def readall(self): - result = self.base.readall() - if self.buf is not None: - result = self.buf[self.bufstart:] + result - self.buf = None - self.bufstart = 0 - return result - - def read(self, n): - if self.buf is None: - return self.do_read(n) - else: - m = n - (len(self.buf) - self.bufstart) - start = self.bufstart - if m > 0: - result = self.buf[start:] + self.do_read(m) - self.buf = None - self.bufstart = 0 - return result - elif n >= 0: - self.bufstart = start + n - return self.buf[start : self.bufstart] - else: - return '' - - seek = PassThrough("seek", flush_buffers=True) - write = PassThrough("write", flush_buffers=True) - truncate = PassThrough("truncate", flush_buffers=True) - flush = PassThrough("flush", flush_buffers=True) - flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) - try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", - flush_buffers=False) - - class BufferingOutputStream(Stream): """Standard buffering output stream. diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -396,6 +396,14 @@ v = two.pow(t, rbigint.fromint(n)) assert v.toint() == pow(2, t.tolong(), n) + def test_pow_lll_bug2(self): + x = rbigint.fromlong(2) + y = rbigint.fromlong(5100894665148900058249470019412564146962964987365857466751243988156579407594163282788332839328303748028644825680244165072186950517295679131100799612871613064597) + z = rbigint.fromlong(538564) + expected = rbigint.fromlong(163464) + got = x.pow(y, z) + assert got.eq(expected) + def test_pow_lln(self): x = 10L y = 2L diff --git a/pypy/rlib/test/test_streamio.py b/pypy/rlib/test/test_streamio.py --- a/pypy/rlib/test/test_streamio.py +++ b/pypy/rlib/test/test_streamio.py @@ -1026,7 +1026,7 @@ base.tell = f if not seek: base.seek = f - return streamio.ReadlineInputStream(base, bufsize) + return base def test_readline(self): for file in [self.makeStream(), self.makeStream(bufsize=2)]: diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -545,7 +545,7 @@ localpath = py.path.local(g.filename) pypkgpath = localpath.pypkgpath() if pypkgpath: - relpypath = localpath.relto(pypkgpath) + relpypath = localpath.relto(pypkgpath.dirname) return relpypath.replace('.py', '.c') return None if hasattr(node.obj, 'graph'): diff --git a/pypy/translator/c/test/test_dlltool.py b/pypy/translator/c/test/test_dlltool.py --- a/pypy/translator/c/test/test_dlltool.py +++ b/pypy/translator/c/test/test_dlltool.py @@ -28,4 +28,4 @@ d = DLLDef('lib', [(f, [int]), (b, [int])]) so = d.compile() dirpath = py.path.local(so).dirpath() - assert dirpath.join('translator_c_test_test_dlltool.c').check() + assert dirpath.join('pypy_translator_c_test_test_dlltool.c').check() diff --git a/pypy/translator/c/test/test_standalone.py b/pypy/translator/c/test/test_standalone.py --- a/pypy/translator/c/test/test_standalone.py +++ b/pypy/translator/c/test/test_standalone.py @@ -57,9 +57,9 @@ # Verify that the generated C files have sane names: gen_c_files = [str(f) for f in cbuilder.extrafiles] - for expfile in ('rlib_rposix.c', - 'rpython_lltypesystem_rstr.c', - 'translator_c_test_test_standalone.c'): + for expfile in ('pypy_rlib_rposix.c', + 'pypy_rpython_lltypesystem_rstr.c', + 'pypy_translator_c_test_test_standalone.c'): assert cbuilder.targetdir.join(expfile) in gen_c_files def test_print(self): diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py --- a/pypy/translator/platform/__init__.py +++ b/pypy/translator/platform/__init__.py @@ -240,12 +240,15 @@ if sys.platform.startswith('linux'): - from pypy.translator.platform.linux import Linux, Linux64 + from pypy.translator.platform.linux import Linux, LinuxPIC import platform - if platform.architecture()[0] == '32bit': + # Only required on armhf and mips{,el}, not armel. But there's no way to + # detect armhf without shelling out + if (platform.architecture()[0] == '64bit' + or platform.machine().startswith(('arm', 'mips'))): + host_factory = LinuxPIC + else: host_factory = Linux - else: - host_factory = Linux64 elif sys.platform == 'darwin': from pypy.translator.platform.darwin import Darwin_i386, Darwin_x86_64, Darwin_PowerPC import platform @@ -257,6 +260,13 @@ host_factory = Darwin_i386 else: host_factory = Darwin_x86_64 +elif "gnukfreebsd" in sys.platform: + from pypy.translator.platform.freebsd import GNUkFreebsd, GNUkFreebsd_64 + import platform + if platform.architecture()[0] == '32bit': + host_factory = GNUkFreebsd + else: + host_factory = GNUkFreebsd_64 elif "freebsd" in sys.platform: from pypy.translator.platform.freebsd import Freebsd, Freebsd_64 import platform diff --git a/pypy/translator/platform/freebsd.py b/pypy/translator/platform/freebsd.py --- a/pypy/translator/platform/freebsd.py +++ b/pypy/translator/platform/freebsd.py @@ -52,3 +52,9 @@ class Freebsd_64(Freebsd): shared_only = ('-fPIC',) + +class GNUkFreebsd(Freebsd): + extra_libs = ('-lrt',) + +class GNUkFreebsd_64(Freebsd_64): + extra_libs = ('-lrt',) diff --git a/pypy/translator/platform/linux.py b/pypy/translator/platform/linux.py --- a/pypy/translator/platform/linux.py +++ b/pypy/translator/platform/linux.py @@ -48,5 +48,5 @@ shared_only = () # it seems that on 32-bit linux, compiling with -fPIC # gives assembler that asmgcc is not happy about. -class Linux64(BaseLinux): +class LinuxPIC(BaseLinux): pass From noreply at buildbot.pypy.org Mon Oct 8 11:12:38 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 11:12:38 +0200 (CEST) Subject: [pypy-commit] buildbot default: A random ordering change attempt. Message-ID: <20121008091238.020221C0274@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r705:b51c79475fcb Date: 2012-10-08 11:12 +0200 http://bitbucket.org/pypy/buildbot/changeset/b51c79475fcb/ Log: A random ordering change attempt. diff --git a/bot2/pypybuildbot/summary.py b/bot2/pypybuildbot/summary.py --- a/bot2/pypybuildbot/summary.py +++ b/bot2/pypybuildbot/summary.py @@ -804,6 +804,8 @@ branch_key = (len(self.branch_order_prefixes)+1, branch) for i, catprefix in enumerate(self.categories): if category.startswith(catprefix): + # kill '-' to make 'linux32' sort before 'linux-armel' + category = category.replace('-', '') break else: i = len(self.categories) From noreply at buildbot.pypy.org Mon Oct 8 11:15:31 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 11:15:31 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: cleanup of this test file Message-ID: <20121008091531.051EA1C0274@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57885:d7c2e61a1da2 Date: 2012-10-08 11:14 +0200 http://bitbucket.org/pypy/pypy/changeset/d7c2e61a1da2/ Log: cleanup of this test file diff --git a/pypy/translator/c/test/test_typed.py b/pypy/translator/c/test/test_typed.py --- a/pypy/translator/c/test/test_typed.py +++ b/pypy/translator/c/test/test_typed.py @@ -1,15 +1,19 @@ from __future__ import with_statement -import autopath + +import math import sys -import math + import py from py.test import raises from pypy import conftest +from pypy.rlib.objectmodel import compute_hash, current_object_addr_as_int +from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask, longlongmask +from pypy.rpython.lltypesystem import rffi, lltype from pypy.translator.test import snippet from pypy.translator.translator import TranslationContext -from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask + class CompilationTestCase: @@ -78,7 +82,7 @@ def test_nested_whiles(self): nested_whiles = self.getcompiled(snippet.nested_whiles, [int, int]) - assert nested_whiles(5,3) == '!!!!!' + assert nested_whiles(5, 3) == '!!!!!' def test_call_unpack_56(self): call_unpack_56 = self.getcompiled(snippet.call_unpack_56, []) @@ -99,10 +103,10 @@ def tuple_repr(x, y): z = x, y while x: - x = x-1 + x = x - 1 return z fn = self.getcompiled(tuple_repr, [int, str]) - assert fn(6,'a') == (6,'a') + assert fn(6, 'a') == (6, 'a') def test_classattribute(self): fn = self.getcompiled(snippet.classattribute, [int]) @@ -117,7 +121,7 @@ def type_conversion(n): if n > 3: while n > 0: - n = n-1 + n = n - 1 if n == 5: n += 3.1416 return n @@ -129,15 +133,15 @@ def test_do_try_raise_choose(self): fn = self.getcompiled(snippet.try_raise_choose, [int]) result = [] - for n in [-1,0,1,2]: + for n in [-1, 0, 1, 2]: result.append(fn(n)) - assert result == [-1,0,1,2] + assert result == [-1, 0, 1, 2] def test_is_perfect_number(self): fn = self.getcompiled(snippet.is_perfect_number, [int]) for i in range(1, 33): perfect = fn(i) - assert perfect is (i in (6,28)) + assert perfect is (i in (6, 28)) def test_prime(self): fn = self.getcompiled(snippet.prime, [int]) @@ -172,13 +176,13 @@ def test_memoryerror(self): def f(i): - lst = [0]*i + lst = [0] * i lst[-1] = 5 return lst[0] fn = self.getcompiled(f, [int]) assert fn(1) == 5 assert fn(2) == 0 - py.test.raises(MemoryError, fn, sys.maxint//2+1) + py.test.raises(MemoryError, fn, sys.maxint // 2 + 1) py.test.raises(MemoryError, fn, sys.maxint) def test_chr(self): @@ -231,14 +235,14 @@ def test_long_long(self): def f(i): - return 4*i + return 4 * i fn = self.getcompiled(f, [r_ulonglong], view=False) - assert fn(2147483647) == 4*2147483647 + assert fn(2147483647) == 4 * 2147483647 def g(i): - return 4*i + return 4 * i gn = self.getcompiled(g, [r_longlong], view=False) - assert gn(2147483647) == 4*2147483647 + assert gn(2147483647) == 4 * 2147483647 def g(i): return i << 12 @@ -253,7 +257,7 @@ def g(i): return i >> 12 gn = self.getcompiled(g, [r_ulonglong]) - assert gn(2**64 - 12345678) == (2**64 - 12345678) >> 12 + assert gn(2 ** 64 - 12345678) == (2 ** 64 - 12345678) >> 12 def test_specializing_int_functions(self): def f(i): @@ -266,8 +270,8 @@ return f(0) fn = self.getcompiled(g, [int]) - assert g(0) == 1 - assert g(1) == 1 + assert fn(0) == 1 + assert fn(1) == 1 def test_downcast_int(self): def f(i): @@ -276,7 +280,6 @@ assert fn(0) == 0 def test_upcast_int(self): - from pypy.rpython.lltypesystem import rffi def f(v): v = rffi.cast(rffi.USHORT, v) return intmask(v) @@ -312,7 +315,7 @@ def get_set_del_nonneg_slice(): # no neg slices for now! l = [ord('a'), ord('b'), ord('c'), ord('d'), ord('e'), ord('f'), ord('g'), ord('h'), ord('i'), ord('j')] del l[:1] - bound = len(l)-1 + bound = len(l) - 1 if bound >= 0: del l[bound:] del l[2:4] @@ -321,7 +324,7 @@ #assert bound >= 0 #l[bound:] = [9] no setting slice into lists for now #l[2:4] = [8,11] - l[0], l[-1], l[2], l[3] =3, 9, 8, 11 + l[0], l[-1], l[2], l[3] = 3, 9, 8, 11 list_3_c = l[:2] list_9 = l[5:] @@ -371,7 +374,7 @@ for j in range(6): res = fn(i, j) assert res is testfn(i, j) - + def testfn(i, j): s1 = ['one', 'two'] s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar'] @@ -381,7 +384,7 @@ for j in range(6): res = fn(i, j) assert res is testfn(i, j) - + def testfn(i, j): s1 = ['one', 'two'] s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar'] @@ -391,7 +394,7 @@ for j in range(6): res = fn(i, j) assert res is testfn(i, j) - + def testfn(i, j): s1 = ['one', 'two'] s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar'] @@ -401,7 +404,7 @@ for j in range(6): res = fn(i, j) assert res is testfn(i, j) - + def testfn(i, j): s1 = ['one', 'two'] s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar'] @@ -411,7 +414,7 @@ for j in range(6): res = fn(i, j) assert res is testfn(i, j) - + def test_str_methods(self): def testfn(i, j): s1 = ['one', 'two'] @@ -434,15 +437,15 @@ def test_str_join(self): def testfn(i, j): - s1 = [ '', ',', ' and '] - s2 = [ [], ['foo'], ['bar', 'baz', 'bazz']] + s1 = ['', ',', ' and '] + s2 = [[], ['foo'], ['bar', 'baz', 'bazz']] return s1[i].join(s2[j]) fn = self.getcompiled(testfn, [int, int]) for i in range(3): for j in range(3): res = fn(i, j) assert res == fn(i, j) - + def test_unichr_eq(self): l = list(u'Hello world') def f(i, j): @@ -450,9 +453,9 @@ fn = self.getcompiled(f, [int, int]) for i in range(len(l)): for j in range(len(l)): - res = fn(i,j) - assert res == f(i,j) - + res = fn(i, j) + assert res == f(i, j) + def test_unichr_ne(self): l = list(u'Hello world') def f(i, j): @@ -460,8 +463,8 @@ fn = self.getcompiled(f, [int, int]) for i in range(len(l)): for j in range(len(l)): - res = fn(i,j) - assert res == f(i,j) + res = fn(i, j) + assert res == f(i, j) def test_unichr_ord(self): l = list(u'Hello world') @@ -512,14 +515,13 @@ def test_int_unary_ovf(self): fn = self.getcompiled(snippet.unary_func, [int]) - for i in range(-3,3): - assert fn(i) == (-(i), abs(i-1)) - raises (OverflowError, fn, -sys.maxint-1) - raises (OverflowError, fn, -sys.maxint) + for i in range(-3, 3): + assert fn(i) == (-(i), abs(i - 1)) + raises(OverflowError, fn, -sys.maxint - 1) + raises(OverflowError, fn, -sys.maxint) - # floats + # floats def test_float_operations(self): - import math def func(x, y): z = x + y / 2.1 * x z = math.fmod(z, 60.0) @@ -551,10 +553,9 @@ res = self.getcompiled(fn)() assert res == 0 - def test_stringformatting(self): def fn(i): - return "you said %d, you did"%i + return "you said %d, you did" % i f = self.getcompiled(fn, [int]) assert f(1) == fn(1) @@ -570,11 +571,11 @@ f = self.getcompiled(fn, [float]) res = f(1.0) assert type(res) is str and float(res) == 1.0 - + def test_uint_arith(self): def fn(i): try: - return ~(i*(i+1))/(i-1) + return ~(i * (i + 1)) / (i - 1) except ZeroDivisionError: return r_uint(91872331) f = self.getcompiled(fn, [r_uint]) @@ -589,8 +590,6 @@ assert f(255) == 255 def test_hash_preservation(self): - from pypy.rlib.objectmodel import compute_hash - from pypy.rlib.objectmodel import current_object_addr_as_int class C: pass class D(C): @@ -606,7 +605,7 @@ compute_hash(c), compute_hash(d), compute_hash(("Hi", None, (7.5, 2, d)))) - + f = self.getcompiled(fn) res = f() @@ -618,20 +617,20 @@ def test_list_basic_ops(self): def list_basic_ops(i, j): - l = [1,2,3] + l = [1, 2, 3] l.insert(0, 42) del l[1] l.append(i) listlen = len(l) - l.extend(l) + l.extend(l) del l[listlen:] - l += [5,6] + l += [5, 6] l[1] = i return l[j] f = self.getcompiled(list_basic_ops, [int, int]) - for i in range(6): - for j in range(6): - assert f(i,j) == list_basic_ops(i,j) + for i in range(6): + for j in range(6): + assert f(i, j) == list_basic_ops(i, j) def test_range2list(self): def fn(): @@ -646,7 +645,8 @@ r = range(10, 37, 4) try: return r[idx] - except: raise + except: + raise f = self.getcompiled(fn, [int]) assert f(0) == fn(0) assert f(-1) == fn(-1) @@ -697,7 +697,7 @@ if len(self.l): break return did_loop - + a1 = A() def f(): for ii in range(1): @@ -711,7 +711,7 @@ if n == 0: return 1 else: - return n*f(n-1) + return n * f(n - 1) fn = self.getcompiled(f, [int]) assert fn(7) == 5040 assert fn(7) == 5040 # detection must work several times, too @@ -721,7 +721,7 @@ def test_infinite_recursion(self): def f(x): if x: - return 1+f(x) + return 1 + f(x) return 1 def g(x): try: @@ -735,7 +735,7 @@ def test_r_dict_exceptions(self): from pypy.rlib.objectmodel import r_dict - + def raising_hash(obj): if obj.startswith("bla"): raise TypeError @@ -786,7 +786,7 @@ return float(s) except ValueError: return -999.0 - + fn = self.getcompiled(f, [int]) for i in range(len(ex)): @@ -799,14 +799,14 @@ a = [] b = range(10) while b: - item = b.pop() + b.pop() a.extend(b) tmp = a a = b b = tmp del a[:] - - f = self.getcompiled(func_swap, []) + + self.getcompiled(func_swap, []) def test_returns_unicode(self): def func(i): @@ -838,13 +838,13 @@ x += 1 assert f(x - frac) == -666 - x = -sys.maxint-1 - while int(x - frac) < -sys.maxint-1: + x = -sys.maxint - 1 + while int(x - frac) < -sys.maxint - 1: x += 1 assert f(x - frac) == int(x - frac) - x = -sys.maxint-1 - while int(x + frac) >= -sys.maxint-1: + x = -sys.maxint - 1 + while int(x + frac) >= -sys.maxint- 1: x -= 1 assert f(x + frac) == -666 @@ -887,7 +887,6 @@ assert res == 'acquire, hello, raised, release' def test_longlongmask(self): - from pypy.rlib.rarithmetic import longlongmask, r_ulonglong def func(n): m = r_ulonglong(n) m *= 100000 @@ -897,7 +896,6 @@ assert res == -200000000000000 def test_int128(self): - from pypy.rpython.lltypesystem import rffi if not hasattr(rffi, '__INT128_T'): py.test.skip("no '__int128_t'") def func(n): @@ -912,7 +910,6 @@ assert res == 305123851 def test_bool_2(self): - from pypy.rpython.lltypesystem import lltype, rffi def func(n): x = rffi.cast(lltype.Bool, n) return int(x) From noreply at buildbot.pypy.org Mon Oct 8 11:20:00 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 11:20:00 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: remove a reference to a removed var and general cleanup Message-ID: <20121008092001.000E71C0274@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57886:269cdc5bd620 Date: 2012-10-08 11:19 +0200 http://bitbucket.org/pypy/pypy/changeset/269cdc5bd620/ Log: remove a reference to a removed var and general cleanup diff --git a/pypy/translator/goal/translate.py b/pypy/translator/goal/translate.py --- a/pypy/translator/goal/translate.py +++ b/pypy/translator/goal/translate.py @@ -4,9 +4,11 @@ See below """ -import sys, os, new -import autopath +import os +import sys + +import autopath import py # clean up early pypy/_cache try: @@ -14,25 +16,24 @@ except Exception: pass -from pypy.config.config import to_optparse, OptionDescription, BoolOption, \ - ArbitraryOption, StrOption, IntOption, Config, \ - ChoiceOption, OptHelpFormatter -from pypy.config.translationoption import get_combined_translation_config -from pypy.config.translationoption import set_opt_level, final_check_config -from pypy.config.translationoption import OPT_LEVELS, DEFAULT_OPT_LEVEL -from pypy.config.translationoption import PLATFORMS, set_platform +from pypy.config.config import (to_optparse, OptionDescription, BoolOption, + ArbitraryOption, StrOption, IntOption, Config, ChoiceOption, OptHelpFormatter) +from pypy.config.translationoption import (get_combined_translation_config, + set_opt_level, final_check_config, OPT_LEVELS, DEFAULT_OPT_LEVEL, set_platform) -GOALS= [ - ("annotate", "do type inference", "-a --annotate", ""), - ("rtype", "do rtyping", "-t --rtype", ""), - ("pyjitpl", "JIT generation step", "--pyjitpl", ""), - ("jittest", "JIT test with llgraph backend", "--jittest", ""), - ("backendopt", "do backend optimizations", "--backendopt", ""), - ("source", "create source", "-s --source", ""), - ("compile", "compile", "-c --compile", " (default goal)"), - ("llinterpret", "interpret the rtyped flow graphs", "--llinterpret", ""), - ] +GOALS = [ + ("annotate", "do type inference", "-a --annotate", ""), + ("rtype", "do rtyping", "-t --rtype", ""), + ("pyjitpl", "JIT generation step", "--pyjitpl", ""), + ("jittest", "JIT test with llgraph backend", "--jittest", ""), + ("backendopt", "do backend optimizations", "--backendopt", ""), + ("source", "create source", "-s --source", ""), + ("compile", "compile", "-c --compile", " (default goal)"), + ("llinterpret", "interpret the rtyped flow graphs", "--llinterpret", ""), +] + + def goal_options(): result = [] for name, doc, cmdline, extra in GOALS: @@ -40,12 +41,12 @@ if name.startswith('?'): optional = True name = name[1:] - yesdoc = doc[0].upper()+doc[1:]+extra + yesdoc = doc[0].upper() + doc[1:] + extra result.append(BoolOption(name, yesdoc, default=False, cmdline=cmdline, negation=False)) if not optional: - result.append(BoolOption("no_%s" % name, "Don't "+doc, default=False, - cmdline="--no-"+name, negation=False)) + result.append(BoolOption("no_%s" % name, "Don't " + doc, default=False, + cmdline="--no-" + name, negation=False)) return result translate_optiondescr = OptionDescription("translate", "XXX", [ @@ -79,8 +80,8 @@ ArbitraryOption("skipped_goals", "XXX", defaultfactory=list), OptionDescription("goal_options", - "Goals that should be reached during translation", - goal_options()), + "Goals that should be reached during translation", + goal_options()), ]) import optparse @@ -109,8 +110,7 @@ opt_parser.disable_interspersed_args() - config = get_combined_translation_config( - overrides=OVERRIDES, translating=True) + config = get_combined_translation_config(translating=True) to_optparse(config, parser=opt_parser, useoptions=['translation.*']) translateconfig = Config(translate_optiondescr) to_optparse(translateconfig, parser=opt_parser) @@ -125,17 +125,17 @@ if getattr(translateconfig.goal_options, name): if name not in translateconfig.goals: translateconfig.goals.append(name) - if getattr(translateconfig.goal_options, 'no_'+name): + if getattr(translateconfig.goal_options, 'no_' + name): if name not in translateconfig.skipped_goals: if not reset: translateconfig.skipped_goals[:] = [] reset = True translateconfig.skipped_goals.append(name) - + if args: arg = args[0] args = args[1:] - if os.path.isfile(arg+'.py'): + if os.path.isfile(arg + '.py'): assert not os.path.isfile(arg), ( "ambiguous file naming, please rename %s" % arg) translateconfig.targetspec = arg @@ -182,7 +182,7 @@ print "\n\nFor detailed descriptions of the command line options see" print "http://pypy.readthedocs.org/en/latest/config/commandline.html" sys.exit(0) - + return targetspec_dic, translateconfig, config, args def log_options(options, header="options in effect"): @@ -192,8 +192,8 @@ optnames.sort() for name in optnames: optvalue = getattr(options, name) - log('%25s: %s' %(name, optvalue)) - + log('%25s: %s' % (name, optvalue)) + def log_config(config, header="config used"): log('%s:' % header) log(str(config)) @@ -225,7 +225,7 @@ prof.disable() statfilename = 'prof.dump' log.info('Dumping profiler stats to: %s' % statfilename) - prof.dump_stats(statfilename) + prof.dump_stats(statfilename) def debug(got_error): tb = None @@ -248,7 +248,7 @@ if translateconfig.batch: log.event("batch mode, not calling interactive helpers") return - + log.event("start debugger...") if translateconfig.view: @@ -295,7 +295,7 @@ samefile = this_exe.samefile(exe_name) assert not samefile, ( 'Output file %s is the currently running ' - 'interpreter (use --output=...)'% exe_name) + 'interpreter (use --output=...)' % exe_name) except EnvironmentError: pass From noreply at buildbot.pypy.org Mon Oct 8 11:52:31 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 11:52:31 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Remove some import * from tests Message-ID: <20121008095231.53C241C0D26@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57887:7e43c5977f39 Date: 2012-10-08 11:52 +0200 http://bitbucket.org/pypy/pypy/changeset/7e43c5977f39/ Log: Remove some import * from tests diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py --- a/pypy/rpython/lltypesystem/lltype.py +++ b/pypy/rpython/lltypesystem/lltype.py @@ -1,9 +1,7 @@ -import py from pypy.rlib.rarithmetic import (r_int, r_uint, intmask, r_singlefloat, r_ulonglong, r_longlong, r_longfloat, r_longlonglong, base_int, normalizedinttype, longlongmask, longlonglongmask) from pypy.rlib.objectmodel import Symbolic -from pypy.tool.uid import Hashable from pypy.tool.identity_dict import identity_dict from pypy.tool import leakfinder from types import NoneType diff --git a/pypy/rpython/test/test_rlist.py b/pypy/rpython/test/test_rlist.py --- a/pypy/rpython/test/test_rlist.py +++ b/pypy/rpython/test/test_rlist.py @@ -1,31 +1,32 @@ import sys import re + import py -from pypy.translator.translator import TranslationContext + +from pypy.rlib.debug import ll_assert from pypy.rpython.error import TyperError -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.ootypesystem import ootype -from pypy.rpython.rlist import * +from pypy.rpython.llinterp import LLException +from pypy.rpython.lltypesystem import rlist as ll_rlist from pypy.rpython.lltypesystem.rlist import ListRepr, FixedSizeListRepr, ll_newlist, ll_fixed_newlist -from pypy.rpython.lltypesystem import rlist as ll_rlist -from pypy.rpython.llinterp import LLException from pypy.rpython.ootypesystem import rlist as oo_rlist from pypy.rpython.rint import signed_repr -from pypy.objspace.flow.model import Constant, Variable +from pypy.rpython.rlist import * from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rlib.debug import ll_assert +from pypy.translator.translator import TranslationContext + # undo the specialization parameter for n1 in 'get set del'.split(): - for n2 in '','_nonneg': + for n2 in '', '_nonneg': name = 'll_%sitem%s' % (n1, n2) - globals()['_'+name] = globals()[name] + globals()['_' + name] = globals()[name] exec """if 1: def %s(*args): return _%s(dum_checkidx, *args) """ % (name, name) del n1, n2, name + class BaseTestListImpl: def check_list(self, l1, expected): @@ -88,8 +89,6 @@ class TestListImpl(BaseTestListImpl): - - def sample_list(self): # [42, 43, 44, 45] rlist = ListRepr(None, signed_repr) rlist.setup() @@ -134,8 +133,8 @@ del expected[start:stop] self.check_list(l, expected) + class TestFixedSizeListImpl(BaseTestListImpl): - def sample_list(self): # [42, 43, 44, 45] rlist = FixedSizeListRepr(None, signed_repr) rlist.setup() @@ -207,7 +206,7 @@ l.append(90) return len(l), l[0], l[-1] res = self.interpret(dummyfn, []) - assert res.item0 == 5 + assert res.item0 == 5 assert res.item1 == 50 assert res.item2 == 90 @@ -271,7 +270,6 @@ res = self.interpret(dummyfn, []) assert res == 25 - def test_recursive(self): def dummyfn(N): l = [] @@ -294,14 +292,14 @@ def test_add(self): def dummyfn(): l = [5] - l += [6,7] + l += [6, 7] return l + [8] res = self.interpret(dummyfn, []) assert self.ll_to_list(res) == [5, 6, 7, 8] def dummyfn(): l = [5] - l += [6,7] + l += [6, 7] l2 = l + [8] l2.append(9) return l2 @@ -369,7 +367,7 @@ return len(l) res = self.interpret(dummyfn, []) assert res == 0 - + def test_setslice(self): def dummyfn(): l = [10, 9, 8, 7] @@ -417,9 +415,11 @@ for resize2 in [False, True]: def dummyfn(): l1 = [42] - if resize1: l1.append(43) + if resize1: + l1.append(43) l2 = list(l1) - if resize2: l2.append(44) + if resize2: + l2.append(44) l2[0] = 0 return l1[0] res = self.interpret(dummyfn, ()) @@ -443,9 +443,9 @@ def test_list_index_simple(self): def dummyfn(i): - l = [5,6,7,8] + l = [5, 6, 7, 8] return l.index(i) - + res = self.interpret(dummyfn, (6,)) assert res == 1 self.interpret_raises(ValueError, dummyfn, [42]) @@ -460,7 +460,7 @@ l.pop(-1) l.pop() return l[-1] - res = self.interpret(dummyfn, ())#, view=True) + res = self.interpret(dummyfn, ()) assert res == 42 def test_insert_bug(self): @@ -492,7 +492,7 @@ res = self.interpret(f, [1]) assert self.class_name(res) == 'A' #''.join(res.super.typeptr.name) == 'A\00' - + def test_reverse(self): def dummyfn(): l = [5, 3, 2] @@ -881,7 +881,7 @@ i += 1 return str(l) res = self.ll_to_string(self.interpret(fn, [])) - res = res.replace('pypy.rpython.test.test_rlist.', '') + res = res.replace('pypy.rpython.test.test_rlist.', '') res = re.sub(' at 0x[a-z0-9]+', '', res) assert res == '[, , , , ]' @@ -990,12 +990,12 @@ del l[1] l.append(i) listlen = len(l) - l.extend(l) + l.extend(l) del l[listlen:] - l += [5,6] + l += [5,6] l[1] = i return l[j] - for i in range(6): + for i in range(6): for j in range(6): res = self.interpret(list_basic_ops, [i, j]) assert res == list_basic_ops(i, j) @@ -1138,7 +1138,7 @@ res = self.interpret(f, [0]) assert res == 1 res = self.interpret(f, [1]) - assert res == -1 + assert res == -1 def f(x): l = [1] @@ -1161,7 +1161,7 @@ res = self.interpret(f, [0]) assert res == 1 - + def test_getitem_exc_2(self): def f(x): l = [1] @@ -1189,7 +1189,7 @@ res = self.interpret(f, [0]) assert res == 1 res = self.interpret(f, [1]) - assert res == -1 + assert res == -1 def f(x): l = [1] @@ -1449,7 +1449,7 @@ r_A_list = rtyper.getrepr(s_A_list) assert isinstance(r_A_list, self.rlist.FixedSizeListRepr) r_B_list = rtyper.getrepr(s_B_list) - assert isinstance(r_B_list, self.rlist.FixedSizeListRepr) + assert isinstance(r_B_list, self.rlist.FixedSizeListRepr) assert r_A_list.lowleveltype == r_B_list.lowleveltype diff --git a/pypy/rpython/test/test_rpbc.py b/pypy/rpython/test/test_rpbc.py --- a/pypy/rpython/test/test_rpbc.py +++ b/pypy/rpython/test/test_rpbc.py @@ -1,9 +1,9 @@ import py -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.rtyper import RPythonTyper -from pypy.rpython.ootypesystem import ootype + +from pypy.annotation import policy, specialize +from pypy.rpython.lltypesystem.lltype import typeOf from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.annotation import policy, specialize + class MyBase: def m(self, x): diff --git a/pypy/rpython/test/test_rptr.py b/pypy/rpython/test/test_rptr.py --- a/pypy/rpython/test/test_rptr.py +++ b/pypy/rpython/test/test_rptr.py @@ -1,11 +1,13 @@ -import py, sys +import sys + +import py + +from pypy.annotation import model as annmodel from pypy.annotation.annrpython import RPythonAnnotator +from pypy.rlib.rarithmetic import is_valid_int from pypy.rpython.annlowlevel import annotate_lowlevel_helper, LowLevelAnnotatorPolicy -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.lltypesystem import llmemory +from pypy.rpython.lltypesystem import llmemory, lltype from pypy.rpython.rtyper import RPythonTyper -from pypy.annotation import model as annmodel -from pypy.rlib.rarithmetic import is_valid_int # ____________________________________________________________ @@ -22,29 +24,29 @@ return s, t def test_cast_pointer(): - S = GcStruct('s', ('x', Signed)) - S1 = GcStruct('s1', ('sub', S)) - S2 = GcStruct('s2', ('sub', S1)) - PS = Ptr(S) - PS2 = Ptr(S2) + S = lltype.GcStruct('s', ('x', lltype.Signed)) + S1 = lltype.GcStruct('s1', ('sub', S)) + S2 = lltype.GcStruct('s2', ('sub', S1)) + PS = lltype.Ptr(S) + PS2 = lltype.Ptr(S2) def lldown(p): - return cast_pointer(PS, p) + return lltype.cast_pointer(PS, p) s, t = ll_rtype(lldown, [annmodel.SomePtr(PS2)]) assert s.ll_ptrtype == PS def llup(p): - return cast_pointer(PS2, p) + return lltype.cast_pointer(PS2, p) s, t = ll_rtype(llup, [annmodel.SomePtr(PS)]) assert s.ll_ptrtype == PS2 def test_runtime_type_info(): - S = GcStruct('s', ('x', Signed), rtti=True) + S = lltype.GcStruct('s', ('x', lltype.Signed), rtti=True) def ll_example(p): - return (runtime_type_info(p), - runtime_type_info(p) == getRuntimeTypeInfo(S)) + return (lltype.runtime_type_info(p), + lltype.runtime_type_info(p) == lltype.getRuntimeTypeInfo(S)) - assert ll_example(malloc(S)) == (getRuntimeTypeInfo(S), True) - s, t = ll_rtype(ll_example, [annmodel.SomePtr(Ptr(S))]) - assert s == annmodel.SomeTuple([annmodel.SomePtr(Ptr(RuntimeTypeInfo)), + assert ll_example(lltype.malloc(S)) == (lltype.getRuntimeTypeInfo(S), True) + s, t = ll_rtype(ll_example, [annmodel.SomePtr(lltype.Ptr(S))]) + assert s == annmodel.SomeTuple([annmodel.SomePtr(lltype.Ptr(lltype.RuntimeTypeInfo)), annmodel.SomeBool()]) from pypy.rpython.test.test_llinterp import interpret, gengraph @@ -53,9 +55,9 @@ policy = LowLevelAnnotatorPolicy() def h_newstruct(): - return malloc(S) - - S = GcStruct('s', ('x', Signed), + return lltype.malloc(S) + + S = lltype.GcStruct('s', ('x', lltype.Signed), adtmeths={"h_newstruct": h_newstruct}) def f(): @@ -63,14 +65,14 @@ s = interpret(f, [], policy=policy) - assert typeOf(s) == Ptr(S) + assert lltype.typeOf(s) == lltype.Ptr(S) def h_alloc(n): - return malloc(A, n) + return lltype.malloc(A, n) def h_length(a): return len(a) - A = GcArray(Signed, + A = lltype.GcArray(lltype.Signed, adtmeths={"h_alloc": h_alloc, "h_length": h_length, 'flag': True}) @@ -80,9 +82,9 @@ a = interpret(f, [], policy=policy) - assert typeOf(a) == Ptr(A) + assert lltype.typeOf(a) == lltype.Ptr(A) assert len(a) == 10 - + def f(): a = A.h_alloc(10) @@ -97,72 +99,72 @@ assert res def test_odd_ints(): - T = GcStruct('T') - S = GcStruct('S', ('t', T)) - PT = Ptr(T) - PS = Ptr(S) + T = lltype.GcStruct('T') + S = lltype.GcStruct('S', ('t', T)) + PT = lltype.Ptr(T) + PS = lltype.Ptr(S) def fn(n): - s = cast_int_to_ptr(PS, n) - assert typeOf(s) == PS - assert cast_ptr_to_int(s) == n - t = cast_pointer(PT, s) - assert typeOf(t) == PT - assert cast_ptr_to_int(t) == n - assert s == cast_pointer(PS, t) + s = lltype.cast_int_to_ptr(PS, n) + assert lltype.typeOf(s) == PS + assert lltype.cast_ptr_to_int(s) == n + t = lltype.cast_pointer(PT, s) + assert lltype.typeOf(t) == PT + assert lltype.cast_ptr_to_int(t) == n + assert s == lltype.cast_pointer(PS, t) interpret(fn, [11521]) def test_odd_ints_opaque(): - T = GcStruct('T') - Q = GcOpaqueType('Q') - PT = Ptr(T) - PQ = Ptr(Q) + T = lltype.GcStruct('T') + Q = lltype.GcOpaqueType('Q') + PT = lltype.Ptr(T) + PQ = lltype.Ptr(Q) def fn(n): - t = cast_int_to_ptr(PT, n) - assert typeOf(t) == PT - assert cast_ptr_to_int(t) == n - o = cast_opaque_ptr(PQ, t) - assert cast_ptr_to_int(o) == n + t = lltype.cast_int_to_ptr(PT, n) + assert lltype.typeOf(t) == PT + assert lltype.cast_ptr_to_int(t) == n + o = lltype.cast_opaque_ptr(PQ, t) + assert lltype.cast_ptr_to_int(o) == n fn(13) interpret(fn, [11521]) -def test_Ptr(): - S = GcStruct('s') +def test_ptr(): + S = lltype.GcStruct('s') def ll_example(): - return malloc(Ptr(S).TO) - + return lltype.malloc(lltype.Ptr(S).TO) + p = interpret(ll_example, []) - assert typeOf(p) == Ptr(S) + assert lltype.typeOf(p) == lltype.Ptr(S) def test_cast_opaque_ptr(): - O = GcOpaqueType('O') - Q = GcOpaqueType('Q') - S = GcStruct('S', ('x', Signed)) + O = lltype.GcOpaqueType('O') + Q = lltype.GcOpaqueType('Q') + S = lltype.GcStruct('S', ('x', lltype.Signed)) def fn(): - s = malloc(S) - o = cast_opaque_ptr(Ptr(O), s) - q = cast_opaque_ptr(Ptr(Q), o) - p = cast_opaque_ptr(Ptr(S), q) + s = lltype.malloc(S) + o = lltype.cast_opaque_ptr(lltype.Ptr(O), s) + q = lltype.cast_opaque_ptr(lltype.Ptr(Q), o) + p = lltype.cast_opaque_ptr(lltype.Ptr(S), q) return p == s res = interpret(fn, []) assert res is True - O1 = OpaqueType('O') - S1 = Struct('S1', ('x', Signed)) - s1 = malloc(S1, immortal=True) + O1 = lltype.OpaqueType('O') + S1 = lltype.Struct('S1', ('x', lltype.Signed)) + s1 = lltype.malloc(S1, immortal=True) def fn1(): - o1 = cast_opaque_ptr(Ptr(O1), s1) - p1 = cast_opaque_ptr(Ptr(S1), o1) + o1 = lltype.cast_opaque_ptr(lltype.Ptr(O1), s1) + p1 = lltype.cast_opaque_ptr(lltype.Ptr(S1), o1) return p1 == s1 res = interpret(fn1, []) assert res is True def test_address(): - S = GcStruct('S') - p1 = nullptr(S) - p2 = malloc(S) - + S = lltype.GcStruct('S') + p1 = lltype.nullptr(S) + p2 = lltype.malloc(S) + def g(p): return bool(llmemory.cast_ptr_to_adr(p)) def fn(n): @@ -177,8 +179,8 @@ assert res is True def test_cast_adr_to_int(): - S = Struct('S') - p = malloc(S, immortal=True) + S = lltype.Struct('S') + p = lltype.malloc(S, immortal=True) def fn(n): a = llmemory.cast_ptr_to_adr(p) if n == 2: @@ -190,7 +192,7 @@ res = interpret(fn, [2]) assert is_valid_int(res) - assert res == cast_ptr_to_int(p) + assert res == lltype.cast_ptr_to_int(p) # res = interpret(fn, [4]) assert isinstance(res, llmemory.AddressAsInt) @@ -199,60 +201,60 @@ res = interpret(fn, [6]) assert is_valid_int(res) from pypy.rpython.lltypesystem import rffi - assert res == rffi.cast(Signed, p) + assert res == rffi.cast(lltype.Signed, p) def test_flavored_malloc(): - T = GcStruct('T', ('y', Signed)) + T = lltype.GcStruct('T', ('y', lltype.Signed)) def fn(n): - p = malloc(T, flavor='gc') + p = lltype.malloc(T, flavor='gc') p.y = n return p.y res = interpret(fn, [232]) assert res == 232 - S = Struct('S', ('x', Signed)) + S = lltype.Struct('S', ('x', lltype.Signed)) def fn(n): - p = malloc(S, flavor='raw') + p = lltype.malloc(S, flavor='raw') p.x = n result = p.x - free(p, flavor='raw') - return n + lltype.free(p, flavor='raw') + return result res = interpret(fn, [23]) assert res == 23 - S = Struct('S', ('x', Signed)) + S = lltype.Struct('S', ('x', lltype.Signed)) def fn(n): - p = malloc(S, flavor='raw', track_allocation=False) + p = lltype.malloc(S, flavor='raw', track_allocation=False) p.x = n result = p.x - return n + return result res = interpret(fn, [23]) assert res == 23 - S = Struct('S', ('x', Signed)) + S = lltype.Struct('S', ('x', lltype.Signed)) def fn(n): - p = malloc(S, flavor='raw', track_allocation=False) + p = lltype.malloc(S, flavor='raw', track_allocation=False) p.x = n result = p.x - free(p, flavor='raw', track_allocation=False) - return n + lltype.free(p, flavor='raw', track_allocation=False) + return result res = interpret(fn, [23]) assert res == 23 def test_memoryerror(): - A = Array(Signed) + A = lltype.Array(lltype.Signed) def fn(n): try: - a = malloc(A, n, flavor='raw') + a = lltype.malloc(A, n, flavor='raw') except MemoryError: return -42 else: res = len(a) - free(a, flavor='raw') + lltype.free(a, flavor='raw') return res res = interpret(fn, [123]) @@ -263,23 +265,23 @@ def test_call_ptr(): - def f(x,y,z): + def f(x, y, z): return x+y+z - FTYPE = FuncType([Signed, Signed, Signed], Signed) - fptr = functionptr(FTYPE, "f", _callable=f) + FTYPE = lltype.FuncType([lltype.Signed, lltype.Signed, lltype.Signed], lltype.Signed) + fptr = lltype.functionptr(FTYPE, "f", _callable=f) - def g(x,y,z): + def g(x, y, z): tot = 0 - tot += fptr(x,y,z) - tot += fptr(*(x,y,z)) - tot += fptr(x, *(x,z)) + tot += fptr(x, y, z) + tot += fptr(*(x, y, z)) + tot += fptr(x, *(x, z)) return tot - res = interpret(g, [1,2,4]) - assert res == g(1,2,4) + res = interpret(g, [1, 2, 4]) + assert res == g(1, 2, 4) - def wrong(x,y): - fptr(*(x,y)) + def wrong(x, y): + fptr(*(x, y)) py.test.raises(TypeError, "interpret(wrong, [1, 2])") @@ -288,8 +290,8 @@ def f(): return str(p) - S = GcStruct('S', ('x', Signed)) - p = malloc(S) + S = lltype.GcStruct('S', ('x', lltype.Signed)) + p = lltype.malloc(S) res = interpret(f, []) assert res.chars[0] == '0' @@ -297,10 +299,10 @@ def test_first_subfield_access_is_cast_pointer(): - B = GcStruct("B", ('x', Signed)) - C = GcStruct("C", ('super', B), ('y', Signed)) + B = lltype.GcStruct("B", ('x', lltype.Signed)) + C = lltype.GcStruct("C", ('super', B), ('y', lltype.Signed)) def f(): - c = malloc(C) + c = lltype.malloc(C) c.super.x = 1 c.y = 2 return c.super.x + c.y @@ -311,73 +313,73 @@ graphsum = summary(graph) assert 'getsubstruct' not in graphsum assert 'cast_pointer' in graphsum - - + + def test_interior_ptr(): - S = Struct("S", ('x', Signed)) - T = GcStruct("T", ('s', S)) + S = lltype.Struct("S", ('x', lltype.Signed)) + T = lltype.GcStruct("T", ('s', S)) def f(): - t = malloc(T) + t = lltype.malloc(T) t.s.x = 1 return t.s.x res = interpret(f, []) assert res == 1 def test_interior_ptr_with_index(): - S = Struct("S", ('x', Signed)) - T = GcArray(S) + S = lltype.Struct("S", ('x', lltype.Signed)) + T = lltype.GcArray(S) def f(): - t = malloc(T, 1) + t = lltype.malloc(T, 1) t[0].x = 1 return t[0].x res = interpret(f, []) assert res == 1 def test_interior_ptr_with_field_and_index(): - S = Struct("S", ('x', Signed)) - T = GcStruct("T", ('items', Array(S))) + S = lltype.Struct("S", ('x', lltype.Signed)) + T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(): - t = malloc(T, 1) + t = lltype.malloc(T, 1) t.items[0].x = 1 return t.items[0].x res = interpret(f, []) assert res == 1 def test_interior_ptr_with_index_and_field(): - S = Struct("S", ('x', Signed)) - T = Struct("T", ('s', S)) - U = GcArray(T) + S = lltype.Struct("S", ('x', lltype.Signed)) + T = lltype.Struct("T", ('s', S)) + U = lltype.GcArray(T) def f(): - u = malloc(U, 1) + u = lltype.malloc(U, 1) u[0].s.x = 1 return u[0].s.x res = interpret(f, []) assert res == 1 def test_interior_ptr_len(): - S = Struct("S", ('x', Signed)) - T = GcStruct("T", ('items', Array(S))) + S = lltype.Struct("S", ('x', lltype.Signed)) + T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(): - t = malloc(T, 1) + t = lltype.malloc(T, 1) return len(t.items) res = interpret(f, []) assert res == 1 def test_interior_ptr_with_setitem(): - T = GcStruct("T", ('s', Array(Signed))) + T = lltype.GcStruct("T", ('s', lltype.Array(lltype.Signed))) def f(): - t = malloc(T, 1) + t = lltype.malloc(T, 1) t.s[0] = 1 return t.s[0] res = interpret(f, []) assert res == 1 - -def test_isinstance_Ptr(): - S = GcStruct("S", ('x', Signed)) + +def test_isinstance_ptr(): + S = lltype.GcStruct("S", ('x', lltype.Signed)) def f(n): - x = isinstance(Signed, Ptr) - return x + (typeOf(x) is Ptr(S)) + len(n) + x = isinstance(lltype.Signed, lltype.Ptr) + return x + (lltype.typeOf(x) is lltype.Ptr(S)) + len(n) def lltest(): f([]) return f([1]) @@ -385,10 +387,10 @@ assert s.is_constant() == False def test_staticadtmeths(): - ll_func = staticAdtMethod(lambda x: x + 42) - S = GcStruct('S', adtmeths={'ll_func': ll_func}) + ll_func = lltype.staticAdtMethod(lambda x: x + 42) + S = lltype.GcStruct('S', adtmeths={'ll_func': ll_func}) def f(): - return malloc(S).ll_func(5) + return lltype.malloc(S).ll_func(5) s, t = ll_rtype(f, []) graphf = t.graphs[0] for op in graphf.startblock.operations: diff --git a/pypy/rpython/test/test_rrange.py b/pypy/rpython/test/test_rrange.py --- a/pypy/rpython/test/test_rrange.py +++ b/pypy/rpython/test/test_rrange.py @@ -1,6 +1,6 @@ -from pypy.rpython.rrange import * +from pypy.rlib.rarithmetic import intmask +from pypy.rpython.rrange import ll_rangelen, ll_rangeitem, ll_rangeitem_nonneg, dum_nocheck from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rlib.rarithmetic import intmask class BaseTestRrange(BaseRtypingTest): @@ -14,7 +14,7 @@ step = l.step else: RANGE = self.rrange.RangeRepr(step).RANGE - l = self.rrange.ll_newrange(RANGE,start,stop) + l = self.rrange.ll_newrange(RANGE, start, stop) assert ll_rangelen(l, step) == length lst = [ll_rangeitem(dum_nocheck, l, i, step) for i in range(length)] assert lst == expected diff --git a/pypy/rpython/test/test_rstr.py b/pypy/rpython/test/test_rstr.py --- a/pypy/rpython/test/test_rstr.py +++ b/pypy/rpython/test/test_rstr.py @@ -1,12 +1,14 @@ import random -from pypy.rpython.lltypesystem.lltype import * + +import py + +from pypy.objspace.flow.model import summary +from pypy.rpython.lltypesystem.lltype import typeOf, Signed, malloc +from pypy.rpython.lltypesystem.rstr import LLHelpers, STR from pypy.rpython.rstr import AbstractLLHelpers -from pypy.rpython.lltypesystem.rstr import LLHelpers, STR -from pypy.rpython.ootypesystem.ootype import make_string -from pypy.rpython.rtyper import RPythonTyper, TyperError +from pypy.rpython.rtyper import TyperError from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rpython.llinterp import LLException -from pypy.objspace.flow.model import summary + def test_parse_fmt(): parse = AbstractLLHelpers.parse_fmt_string @@ -14,6 +16,7 @@ assert parse('%s') == [('s',)] assert parse("name '%s' is not defined") == ["name '", ("s",), "' is not defined"] + class AbstractTestRstr(BaseRtypingTest): def test_simple(self): const = self.const diff --git a/pypy/rpython/test/test_rtuple.py b/pypy/rpython/test/test_rtuple.py --- a/pypy/rpython/test/test_rtuple.py +++ b/pypy/rpython/test/test_rtuple.py @@ -1,11 +1,10 @@ +from pypy.rpython.lltypesystem import rtupletype +from pypy.rpython.lltypesystem.lltype import Signed, Bool +from pypy.rpython.rbool import bool_repr +from pypy.rpython.rint import signed_repr +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.translator.translator import TranslationContext -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.lltypesystem import rtupletype -from pypy.rpython.ootypesystem import ootype -from pypy.rpython.rint import signed_repr -from pypy.rpython.rbool import bool_repr -from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -import py + def test_rtuple(): from pypy.rpython.lltypesystem.rtuple import TupleRepr @@ -18,9 +17,9 @@ def test_simple(self): def dummyfn(x): - l = (10,x,30) + l = (10, x, 30) return l[2] - res = self.interpret(dummyfn,[4]) + res = self.interpret(dummyfn, [4]) assert res == 30 def test_len(self): From noreply at buildbot.pypy.org Mon Oct 8 12:00:47 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 12:00:47 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: remove some import * and other general cleanups Message-ID: <20121008100047.6E5B81C0D26@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57888:ff4dd9fb4bad Date: 2012-10-08 12:00 +0200 http://bitbucket.org/pypy/pypy/changeset/ff4dd9fb4bad/ Log: remove some import * and other general cleanups diff --git a/pypy/rpython/test/test_exception.py b/pypy/rpython/test/test_exception.py --- a/pypy/rpython/test/test_exception.py +++ b/pypy/rpython/test/test_exception.py @@ -1,10 +1,11 @@ import py + from pypy.translator.translator import TranslationContext -from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rpython.llinterp import LLException from pypy.rpython.error import MissingRTypeOperation + class MyException(Exception): pass diff --git a/pypy/rpython/test/test_llann.py b/pypy/rpython/test/test_llann.py --- a/pypy/rpython/test/test_llann.py +++ b/pypy/rpython/test/test_llann.py @@ -1,20 +1,18 @@ import py + +from pypy.annotation import model as annmodel +from pypy.conftest import option +from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.rpython.annlowlevel import (annotate_lowlevel_helper, + MixLevelHelperAnnotator, PseudoHighLevelCallable, llhelper, + cast_instance_to_base_ptr, cast_base_ptr_to_instance, base_ptr_lltype) +from pypy.rpython.llinterp import LLInterpreter from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.ootypesystem import ootype -from pypy.rpython.lltypesystem.rclass import OBJECTPTR from pypy.rpython.rclass import fishllattr +from pypy.rpython.test.test_llinterp import interpret from pypy.translator.translator import TranslationContext -from pypy.annotation import model as annmodel -from pypy.rpython.annlowlevel import annotate_lowlevel_helper -from pypy.rpython.annlowlevel import MixLevelHelperAnnotator -from pypy.rpython.annlowlevel import PseudoHighLevelCallable -from pypy.rpython.annlowlevel import llhelper, cast_instance_to_base_ptr -from pypy.rpython.annlowlevel import cast_base_ptr_to_instance -from pypy.rpython.annlowlevel import base_ptr_lltype -from pypy.rpython.llinterp import LLInterpreter -from pypy.rpython.test.test_llinterp import interpret -from pypy.objspace.flow.objspace import FlowObjSpace -from pypy.conftest import option + # helpers @@ -24,15 +22,17 @@ if op.opname in ops: yield op + def derived(op, orig): if op.args[0].value.__name__.startswith(orig): return op.args[0].value else: return None + class TestLowLevelAnnotateTestCase: - def setup_class(cls): - cls.space = FlowObjSpace() + def setup_class(cls): + cls.space = FlowObjSpace() from pypy.annotation.annrpython import RPythonAnnotator @@ -53,7 +53,7 @@ def test_simple2(self): S = Struct("s", ('v', Signed)) - S2 = GcStruct("s2", ('a',S), ('b',S)) + S2 = GcStruct("s2", ('a', S), ('b', S)) def llf(): s = malloc(S2) return s.a.v+s.b.v @@ -93,8 +93,8 @@ a[0] = 3 return a[0] s = self.annotate(llf, []) - assert s.knowntype == int - + assert s.knowntype == int + def test_cast_simple_widening(self): S2 = Struct("s2", ('a', Signed)) S1 = Struct("s1", ('sub1', S2), ('sub2', S2)) @@ -141,7 +141,7 @@ return p12, p13, p21, p23, p31, p32 s = self.annotate(llf, []) assert [x.ll_ptrtype for x in s.items] == [PS1, PS1, PS2, PS2, PS3, PS3] - + def test_array_length(self): A = GcArray(('v', Signed)) @@ -158,7 +158,7 @@ return p(0) s = self.annotate(llf, [annmodel.SomePtr(PF)]) assert s.knowntype == int - + def test_ll_calling_ll(self): A = GcArray(Float) @@ -194,13 +194,13 @@ if (func, T) in seen: continue seen[func, T] = True - + desc = a.bookkeeper.getdesc(func) g = desc.specialize([a.binding(x) for x in call.args[1:]]) args = g.getargs() rv = g.getreturnvar() - if func is ll_get: + if func is ll_get: vT, vp, vi = args assert a.binding(vT) == a.bookkeeper.immutablevalue(T) assert a.binding(vi).knowntype == int @@ -218,7 +218,7 @@ assert len(seen) == 4 return a, vTs # reused by a test in test_rtyper - + def test_ll_calling_ll2(self): A = GcArray(Float) B = GcArray(Signed) @@ -252,7 +252,7 @@ return s.const else: return s.ll_ptrtype - + vTs = [] for call in annotated_calls(a): @@ -359,7 +359,7 @@ s = self.annotate(llf, [annmodel.SomePtr(Ptr(S))]) assert isinstance(s, annmodel.SomePtr) assert s.ll_ptrtype == Ptr(RuntimeTypeInfo) - + def test_cast_primitive(self): def llf(u): return cast_primitive(Signed, u) @@ -454,7 +454,7 @@ F = Ptr(FuncType([Ptr(S), Signed], Signed)) G = Ptr(FuncType([Ptr(S)], Signed)) - + def h(x, y, z): s = malloc(S) s.x = x @@ -479,7 +479,7 @@ F = ootype.StaticMethod([S, Signed], Signed) G = ootype.StaticMethod([S], Signed) - + def h(x, y, z): s = ootype.new(S) s.x = x diff --git a/pypy/rpython/test/test_rbuilder.py b/pypy/rpython/test/test_rbuilder.py --- a/pypy/rpython/test/test_rbuilder.py +++ b/pypy/rpython/test/test_rbuilder.py @@ -1,10 +1,11 @@ from __future__ import with_statement + import py from pypy.rlib.rstring import StringBuilder, UnicodeBuilder from pypy.rpython.annlowlevel import llstr, hlstr from pypy.rpython.lltypesystem import rffi -from pypy.rpython.lltypesystem.rbuilder import * +from pypy.rpython.lltypesystem.rbuilder import StringBuilderRepr from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin @@ -23,6 +24,7 @@ StringBuilderRepr.ll_append(sb, llstr("abc")) assert StringBuilderRepr.ll_build(sb) == sb.buf + class BaseTestStringBuilder(BaseRtypingTest): def test_simple(self): def func(): diff --git a/pypy/rpython/test/test_rclass.py b/pypy/rpython/test/test_rclass.py --- a/pypy/rpython/test/test_rclass.py +++ b/pypy/rpython/test/test_rclass.py @@ -1,14 +1,18 @@ +import sys + import py -import sys + +from pypy.objspace.flow.model import summary +from pypy.rlib.rarithmetic import r_longlong +from pypy.rpython.lltypesystem.lltype import (typeOf, Signed, getRuntimeTypeInfo, + identityhash) +from pypy.rpython.ootypesystem import ootype +from pypy.rpython.error import TyperError +from pypy.rpython.rclass import (IR_IMMUTABLE, IR_IMMUTABLE_ARRAY, + IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY) +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.translator.translator import TranslationContext, graphof -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.ootypesystem import ootype -from pypy.rlib.rarithmetic import r_longlong -from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rpython.rclass import IR_IMMUTABLE, IR_IMMUTABLE_ARRAY -from pypy.rpython.rclass import IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY -from pypy.rpython.error import TyperError -from pypy.objspace.flow.model import summary + class EmptyBase(object): pass diff --git a/pypy/rpython/test/test_rtyper.py b/pypy/rpython/test/test_rtyper.py --- a/pypy/rpython/test/test_rtyper.py +++ b/pypy/rpython/test/test_rtyper.py @@ -1,26 +1,26 @@ -from pypy.annotation import model as annmodel -from pypy.objspace.flow.model import Constant -from pypy.translator.translator import TranslationContext, graphof -from pypy.annotation import annrpython -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.test.test_llinterp import interpret -from pypy.rpython.rtyper import RPythonTyper -from pypy.rpython import rmodel import py +from pypy.annotation import model as annmodel, annrpython +from pypy.objspace.flow.model import Constant +from pypy.rpython import rmodel +from pypy.rpython.lltypesystem.lltype import Signed, Void +from pypy.rpython.rtyper import RPythonTyper +from pypy.rpython.test.test_llinterp import interpret +from pypy.translator.translator import TranslationContext, graphof -def setup_module(mod): + +def setup_module(mod): mod.logstate = py.log._getstate() py.log.setconsumer("rtyper", py.log.STDOUT) - py.log.setconsumer("annrpython", None) + py.log.setconsumer("annrpython", None) -def teardown_module(mod): - py.log._setstate(mod.logstate) +def teardown_module(mod): + py.log._setstate(mod.logstate) def test_reprkeys_dont_clash(): - stup1 = annmodel.SomeTuple((annmodel.SomeFloat(), + stup1 = annmodel.SomeTuple((annmodel.SomeFloat(), annmodel.SomeInteger())) - stup2 = annmodel.SomeTuple((annmodel.SomeString(), + stup2 = annmodel.SomeTuple((annmodel.SomeString(), annmodel.SomeInteger())) rtyper = RPythonTyper(annrpython.RPythonAnnotator(None)) key1 = rtyper.makekey(stup1) @@ -41,7 +41,7 @@ return g(1, x) res = interpret(f, [4]) - assert res == -3 + assert res == -3 def test_retval(): def f(x): @@ -82,7 +82,7 @@ rt = RPythonTyper(a) rt.specialize() assert [vT.concretetype for vT in vTs] == [Void] * 3 - + def test_getgcflavor(): class A: @@ -111,7 +111,7 @@ raise else: return default - + assert rmodel.getgcflavor(DummyClsDescDef(A)) == 'gc' assert rmodel.getgcflavor(DummyClsDescDef(B)) == 'gc' assert rmodel.getgcflavor(DummyClsDescDef(R)) == 'raw' From noreply at buildbot.pypy.org Mon Oct 8 12:06:59 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 12:06:59 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: more test file cleanup Message-ID: <20121008100659.4D0001C0D37@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57889:10ba881818be Date: 2012-10-08 12:05 +0200 http://bitbucket.org/pypy/pypy/changeset/10ba881818be/ Log: more test file cleanup diff --git a/pypy/rpython/test/test_rbuiltin.py b/pypy/rpython/test/test_rbuiltin.py --- a/pypy/rpython/test/test_rbuiltin.py +++ b/pypy/rpython/test/test_rbuiltin.py @@ -1,21 +1,22 @@ -from pypy.translator.translator import graphof -from pypy.rpython.test import test_llinterp -from pypy.rlib.objectmodel import instantiate, we_are_translated -from pypy.rlib.objectmodel import running_on_llinterp -from pypy.rlib.debug import llinterpcall -from pypy.rpython.lltypesystem import lltype -from pypy.tool import udir -from pypy.rlib.rarithmetic import intmask, longlongmask, r_int64, is_valid_int -from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong -from pypy.annotation.builtin import * -from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rpython.lltypesystem import rffi -from pypy.rpython import extfunc +import math +import os + import py +from pypy.rlib.debug import llinterpcall +from pypy.rlib.objectmodel import instantiate, running_on_llinterp, compute_unique_id, current_object_addr_as_int +from pypy.rlib.rarithmetic import (intmask, longlongmask, r_int64, is_valid_int, + r_int, r_uint, r_longlong, r_ulonglong) +from pypy.rlib.rstring import StringBuilder, UnicodeBuilder +from pypy.rpython.annlowlevel import hlstr, LowLevelAnnotatorPolicy +from pypy.rpython.lltypesystem import lltype, rffi +from pypy.rpython.test import test_llinterp +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin +from pypy.tool import udir +from pypy.translator.translator import graphof + def enum_direct_calls(translator, func): - blocks = [] graph = graphof(translator, func) for block in graph.iterblocks(): for op in block.operations: @@ -90,28 +91,28 @@ assert type(res) is r_int64 and res == 5 def test_rbuiltin_list(self): - def f(): - l=list((1,2,3)) + def f(): + l = list((1,2,3)) return l == [1,2,3] def g(): - l=list(('he','llo')) - return l == ['he','llo'] + l = list(('he', 'llo')) + return l == ['he', 'llo'] def r(): l = ['he','llo'] - l1=list(l) + l1 = list(l) return l == l1 and l is not l1 - result = self.interpret(f,[]) + result = self.interpret(f, []) assert result - result = self.interpret(g,[]) + result = self.interpret(g, []) assert result - result = self.interpret(r,[]) - assert result + result = self.interpret(r, []) + assert result def test_int_min(self): def fn(i, j): - return min(i,j) + return min(i ,j) ev_fun = self.interpret(fn, [0, 0]) assert self.interpret(fn, (1, 2)) == 1 assert self.interpret(fn, (1, -1)) == -1 @@ -145,28 +146,24 @@ assert self.interpret(fn, (1.1, -1)) == 1.1 def test_builtin_math_floor(self): - import math def fn(f): return math.floor(f) - import random for i in range(5): - rv = 1000 * float(i-10) #random.random() + rv = 1000 * float(i-10) res = self.interpret(fn, [rv]) - assert fn(rv) == res + assert fn(rv) == res def test_builtin_math_fmod(self): - import math def fn(f,y): return math.fmod(f,y) for i in range(10): for j in range(10): - rv = 1000 * float(i-10) + rv = 1000 * float(i-10) ry = 100 * float(i-10) +0.1 assert self.float_eq(fn(rv,ry), self.interpret(fn, (rv, ry))) def test_builtin_math_frexp(self): - import math def fn(f): return math.frexp(f) for x in (.5, 1, 1.5, 10/3.0): @@ -177,14 +174,12 @@ self.float_eq(res.item1, exponent)) def test_builtin_math_ldexp(self): - import math def fn(a, b): return math.ldexp(a, b) assert self.interpret(fn, [1, 2]) == 4 self.interpret_raises(OverflowError, fn, [1, 100000]) def test_builtin_math_modf(self): - import math def fn(f): return math.modf(f) res = self.interpret(fn, [10/3.0]) @@ -192,15 +187,13 @@ assert self.float_eq(res.item0, intpart) and self.float_eq(res.item1, fracpart) def test_os_getcwd(self): - import os def fn(): return os.getcwd() - res = self.interpret(fn, []) + res = self.interpret(fn, []) assert self.ll_to_string(res) == fn() - + def test_os_write(self): tmpdir = str(udir.udir.join("os_write_test")) - import os def wr_open(fname): fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777) os.write(fd, "hello world") @@ -213,11 +206,10 @@ assert hello == "hello world" fd = os.open(tmpdir, os.O_WRONLY|os.O_CREAT, 777) os.close(fd) - raises(OSError, os.write, fd, "hello world") + raises(OSError, os.write, fd, "hello world") def test_os_write_single_char(self): tmpdir = str(udir.udir.join("os_write_test_char")) - import os def wr_open(fname): fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777) os.write(fd, "x") @@ -230,7 +222,6 @@ assert hello == "x" def test_os_read(self): - import os tmpfile = str(udir.udir.join("os_read_test")) f = file(tmpfile, 'w') f.write('hello world') @@ -243,7 +234,6 @@ def test_os_lseek(self): self._skip_llinterpreter("os.lseek", skipOO=False) - import os tmpfile = str(udir.udir.join("os_lseek_test")) f = file(tmpfile, 'w') f.write('0123456789') @@ -269,7 +259,6 @@ assert res1 == res2 def test_os_dup(self): - import os def fn(fd): return os.dup(fd) res = self.interpret(fn, [0]) @@ -286,7 +275,6 @@ def test_os_open(self): tmpdir = str(udir.udir.join("os_open_test")) - import os def wr_open(fname): return os.open(fname, os.O_WRONLY|os.O_CREAT, 0777) def f(): @@ -302,9 +290,7 @@ def test_os_path_exists(self): self._skip_llinterpreter("os.stat()") - from pypy.rpython.annlowlevel import hlstr - - import os + def f(fn): fn = hlstr(fn) return os.path.exists(fn) @@ -315,9 +301,7 @@ def test_os_isdir(self): self._skip_llinterpreter("os.stat()") - from pypy.rpython.annlowlevel import hlstr - - import os + def f(fn): fn = hlstr(fn) return os.path.isdir(fn) @@ -332,14 +316,14 @@ def g(obj): return bool(obj) - def fn(neg): + def fn(neg): c = C.f return g(c) assert self.interpret(fn, [True]) - def fn(neg): + def fn(neg): c = None return g(c) - assert not self.interpret(fn, [True]) + assert not self.interpret(fn, [True]) def test_const_isinstance(self): class B(object): @@ -417,7 +401,6 @@ def test_os_path_join(self): self._skip_llinterpreter("os path oofakeimpl", skipLL=False) - import os.path def fn(a, b): return os.path.join(a, b) res = self.ll_to_string(self.interpret(fn, ['a', 'b'])) @@ -454,8 +437,6 @@ assert res == 321 def test_id(self): - from pypy.rlib.objectmodel import compute_unique_id - from pypy.rlib.objectmodel import current_object_addr_as_int class A: pass def fn(): @@ -477,8 +458,6 @@ assert x3 == intmask(x2) def test_id_on_builtins(self): - from pypy.rlib.objectmodel import compute_unique_id - from pypy.rlib.rstring import StringBuilder, UnicodeBuilder def fn(): return (compute_unique_id("foo"), compute_unique_id(u"bar"), @@ -491,7 +470,6 @@ assert isinstance(id, (int, r_longlong)) def test_uniqueness_of_id_on_strings(self): - from pypy.rlib.objectmodel import compute_unique_id def fn(s1, s2): return (compute_unique_id(s1), compute_unique_id(s2)) @@ -502,7 +480,6 @@ assert i1 != i2 def test_cast_primitive(self): - from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy def llf(u): return lltype.cast_primitive(lltype.Signed, u) res = self.interpret(llf, [r_uint(-1)], policy=LowLevelAnnotatorPolicy()) From noreply at buildbot.pypy.org Mon Oct 8 12:24:11 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 12:24:11 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: more test cleanup Message-ID: <20121008102411.947D41C0274@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57890:f75ab7745a08 Date: 2012-10-08 12:23 +0200 http://bitbucket.org/pypy/pypy/changeset/f75ab7745a08/ Log: more test cleanup diff --git a/pypy/rpython/lltypesystem/test/test_llarena.py b/pypy/rpython/lltypesystem/test/test_llarena.py --- a/pypy/rpython/lltypesystem/test/test_llarena.py +++ b/pypy/rpython/lltypesystem/test/test_llarena.py @@ -1,16 +1,15 @@ import py + from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.lltypesystem.llarena import (arena_malloc, arena_reset, + arena_reserve, arena_free, round_up_for_allocation, ArenaError, + arena_new_view, arena_shrink_obj, arena_protect, has_protect) from pypy.rpython.lltypesystem.llmemory import cast_adr_to_ptr -from pypy.rpython.lltypesystem.llarena import arena_malloc, arena_reset -from pypy.rpython.lltypesystem.llarena import arena_reserve, arena_free -from pypy.rpython.lltypesystem.llarena import round_up_for_allocation -from pypy.rpython.lltypesystem.llarena import ArenaError, arena_new_view -from pypy.rpython.lltypesystem.llarena import arena_shrink_obj -from pypy.rpython.lltypesystem.llarena import arena_protect, has_protect from pypy.translator.c.test import test_genc, test_standalone + def test_arena(): - S = lltype.Struct('S', ('x',lltype.Signed)) + S = lltype.Struct('S', ('x', lltype.Signed)) SPTR = lltype.Ptr(S) ssize = llmemory.raw_malloc_usage(llmemory.sizeof(S)) myarenasize = 2*ssize+1 @@ -303,8 +302,6 @@ class TestStandalone(test_standalone.StandaloneTests): def test_compiled_arena_protect(self): - import os - from pypy.translator.c.test.test_genc import compile S = lltype.Struct('S', ('x', lltype.Signed)) # def fn(argv): From noreply at buildbot.pypy.org Mon Oct 8 13:08:50 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 13:08:50 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: cleanup Message-ID: <20121008110850.B050D1C0D37@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57891:fb687ee9b75b Date: 2012-10-08 13:08 +0200 http://bitbucket.org/pypy/pypy/changeset/fb687ee9b75b/ Log: cleanup diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -7,31 +7,31 @@ """ -import types, sys, os -from pypy.tool.compat import md5 +import sys +import os +import types + +import py NoneNotWrapped = object() -from pypy.tool.sourcetools import func_with_new_name +from pypy.interpreter import eval +from pypy.interpreter.argument import Arguments, Signature +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, + SpaceCache, DescrMismatch) from pypy.interpreter.error import OperationError -from pypy.interpreter import eval -from pypy.interpreter.function import Function, Method, ClassMethod -from pypy.interpreter.function import FunctionWithFixedCode -from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable -from pypy.interpreter.baseobjspace import Wrappable, SpaceCache, DescrMismatch -from pypy.interpreter.argument import Arguments, Signature -from pypy.tool.sourcetools import NiceCompile, compile2 -from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from pypy.rlib import rstackovf from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.tool.sourcetools import func_with_new_name, compile2 + # internal non-translatable parts: -import py - class SignatureBuilder(object): "NOT_RPYTHON" def __init__(self, func=None, argnames=None, varargname=None, - kwargname=None, name = None): + kwargname=None, name=None): self.func = func if func is not None: self.name = func.__name__ @@ -81,8 +81,8 @@ for el in unwrap_spec: dispatch(el, *extra) + class UnwrapSpecEmit(UnwrapSpecRecipe): - def __init__(self): self.n = 0 self.miniglobals = {} @@ -99,8 +99,8 @@ #________________________________________________________________ + class UnwrapSpec_Check(UnwrapSpecRecipe): - # checks for checking interp2app func argument names wrt unwrap_spec # and synthetizing an app-level signature @@ -168,8 +168,8 @@ app_sig.append(argname[2:]) def visit__Arguments(self, el, app_sig): - argname = self.orig_arg() - assert app_sig.varargname is None,( + self.orig_arg() + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = 'args' app_sig.kwargname = 'keywords' @@ -179,7 +179,7 @@ assert argname.endswith('_w'), ( "rest arguments arg %s of built-in function %r should end in '_w'" % (argname, self.func)) - assert app_sig.varargname is None,( + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = argname[:-2] @@ -188,7 +188,7 @@ assert argname.startswith('w_'), ( "rest arguments arg %s of built-in function %r should start 'w_'" % (argname, self.func)) - assert app_sig.varargname is None,( + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = argname[2:] @@ -320,15 +320,16 @@ def _run(self, space, scope_w): """Subclasses with behavior specific for an unwrap spec are generated""" - raise TypeError, "abstract" + raise TypeError("abstract") #________________________________________________________________ + class FastFuncNotSupported(Exception): pass + class UnwrapSpec_FastFunc_Unwrap(UnwrapSpecEmit): - def __init__(self): UnwrapSpecEmit.__init__(self) self.args = [] @@ -439,6 +440,7 @@ return narg, fastfunc make_fastfunc = staticmethod(make_fastfunc) + def int_unwrapping_space_method(typ): assert typ in (int, str, float, unicode, r_longlong, r_uint, r_ulonglong, bool) if typ is r_int is r_longlong: @@ -466,6 +468,7 @@ return func return decorator + def build_unwrap_spec(func, argnames, self_type=None): """build the list of parameter unwrap spec for the function. """ @@ -505,6 +508,7 @@ return unwrap_spec + class BuiltinCode(eval.Code): "The code object implementing a built-in (interpreter-level) hook." _immutable_ = True @@ -517,8 +521,7 @@ NOT_RPYTHON_ATTRIBUTES = ['_bltin', '_unwrap_spec'] - def __init__(self, func, unwrap_spec = None, self_type = None, - descrmismatch=None): + def __init__(self, func, unwrap_spec=None, self_type=None, descrmismatch=None): "NOT_RPYTHON" # 'implfunc' is the interpreter-level function. # Note that this uses a lot of (construction-time) introspection. @@ -548,7 +551,7 @@ unwrap_spec = build_unwrap_spec(func, argnames, self_type) if self_type: - assert unwrap_spec[0] == 'self',"self_type without 'self' spec element" + assert unwrap_spec[0] == 'self', "self_type without 'self' spec element" unwrap_spec = list(unwrap_spec) if descrmismatch is not None: assert issubclass(self_type, Wrappable) @@ -561,13 +564,10 @@ assert descrmismatch is None, ( "descrmismatch without a self-type specified") - orig_sig = SignatureBuilder(func, argnames, varargname, kwargname) app_sig = SignatureBuilder(func) - UnwrapSpec_Check(orig_sig).apply_over(unwrap_spec, - app_sig #to populate - ) + UnwrapSpec_Check(orig_sig).apply_over(unwrap_spec, app_sig) self.sig = argnames, varargname, kwargname = app_sig.signature() self.minargs = len(argnames) @@ -598,8 +598,8 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) builtin_code = mod.get('builtin_code') return space.newtuple([builtin_code, space.newtuple([space.wrap(self.identifier)])]) @@ -658,6 +658,7 @@ # (verbose) performance hack below + class BuiltinCodePassThroughArguments0(BuiltinCode): _immutable_ = True @@ -677,6 +678,7 @@ w_result = space.w_None return w_result + class BuiltinCodePassThroughArguments1(BuiltinCode): _immutable_ = True fast_natural_arity = eval.Code.PASSTHROUGHARGS1 @@ -697,6 +699,7 @@ w_result = space.w_None return w_result + class BuiltinCode0(BuiltinCode): _immutable_ = True fast_natural_arity = 0 @@ -714,6 +717,7 @@ w_result = space.w_None return w_result + class BuiltinCode1(BuiltinCode): _immutable_ = True fast_natural_arity = 1 @@ -722,10 +726,10 @@ try: w_result = self.fastfunc_1(space, w1) except DescrMismatch: - return w1.descr_call_mismatch(space, - self.descrmismatch_op, - self.descr_reqcls, - Arguments(space, [w1])) + return w1.descr_call_mismatch(space, + self.descrmismatch_op, + self.descr_reqcls, + Arguments(space, [w1])) except Exception, e: self.handle_exception(space, e) w_result = None @@ -733,6 +737,7 @@ w_result = space.w_None return w_result + class BuiltinCode2(BuiltinCode): _immutable_ = True fast_natural_arity = 2 @@ -741,10 +746,10 @@ try: w_result = self.fastfunc_2(space, w1, w2) except DescrMismatch: - return w1.descr_call_mismatch(space, - self.descrmismatch_op, - self.descr_reqcls, - Arguments(space, [w1, w2])) + return w1.descr_call_mismatch(space, + self.descrmismatch_op, + self.descr_reqcls, + Arguments(space, [w1, w2])) except Exception, e: self.handle_exception(space, e) w_result = None @@ -752,6 +757,7 @@ w_result = space.w_None return w_result + class BuiltinCode3(BuiltinCode): _immutable_ = True fast_natural_arity = 3 @@ -760,10 +766,10 @@ try: w_result = self.fastfunc_3(space, w1, w2, w3) except DescrMismatch: - return w1.descr_call_mismatch(space, - self.descrmismatch_op, - self.descr_reqcls, - Arguments(space, [w1, w2, w3])) + return w1.descr_call_mismatch(space, + self.descrmismatch_op, + self.descr_reqcls, + Arguments(space, [w1, w2, w3])) except Exception, e: self.handle_exception(space, e) w_result = None @@ -771,6 +777,7 @@ w_result = space.w_None return w_result + class BuiltinCode4(BuiltinCode): _immutable_ = True fast_natural_arity = 4 @@ -779,11 +786,11 @@ try: w_result = self.fastfunc_4(space, w1, w2, w3, w4) except DescrMismatch: - return w1.descr_call_mismatch(space, - self.descrmismatch_op, - self.descr_reqcls, - Arguments(space, - [w1, w2, w3, w4])) + return w1.descr_call_mismatch(space, + self.descrmismatch_op, + self.descr_reqcls, + Arguments(space, + [w1, w2, w3, w4])) except Exception, e: self.handle_exception(space, e) w_result = None @@ -808,8 +815,8 @@ instancecache = {} - def __new__(cls, f, app_name=None, unwrap_spec = None, - descrmismatch=None, as_classmethod=False): + def __new__(cls, f, app_name=None, unwrap_spec=None, descrmismatch=None, + as_classmethod=False): "NOT_RPYTHON" # f must be a function whose name does NOT start with 'app_' @@ -818,10 +825,10 @@ self_type = f.im_class f = f.im_func if not isinstance(f, types.FunctionType): - raise TypeError, "function expected, got %r instead" % f + raise TypeError("function expected, got %r instead" % f) if app_name is None: if f.func_name.startswith('app_'): - raise ValueError, ("function name %r suspiciously starts " + raise ValueError("function name %r suspiciously starts " "with 'app_'" % f.func_name) app_name = f.func_name @@ -837,7 +844,7 @@ self = Wrappable.__new__(cls) cls.instancecache[key] = self self._code = BuiltinCode(f, unwrap_spec=unwrap_spec, - self_type = self_type, + self_type=self_type, descrmismatch=descrmismatch) self.__name__ = f.func_name self.name = app_name @@ -875,7 +882,7 @@ space = cache.space defs = gateway._getdefaults(space) # needs to be implemented by subclass code = gateway._code - fn = FunctionWithFixedCode(space, code, None, defs, forcename = gateway.name) + fn = FunctionWithFixedCode(space, code, None, defs, forcename=gateway.name) if not space.config.translating: fn.add_to_table() if gateway.as_classmethod: @@ -995,6 +1002,7 @@ # ____________________________________________________________ + def appdef(source, applevel=ApplevelClass, filename=None): """ NOT_RPYTHON: build an app-level helper function, like for example: myfunc = appdef('''myfunc(x, y): @@ -1015,7 +1023,7 @@ funcname = source[:p].strip() source = source[p:] assert source.strip() - funcsource = "def %s%s\n" % (funcname, source) + funcsource = "def %s%s\n" % (funcname, source) #for debugging of wrong source code: py.std.parser.suite(funcsource) a = applevel(funcsource, filename=filename) return a.interphook(funcname) From noreply at buildbot.pypy.org Mon Oct 8 13:12:45 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 13:12:45 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: kill dead imports Message-ID: <20121008111245.28CC81C0274@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57892:abfd57f6777a Date: 2012-10-08 13:12 +0200 http://bitbucket.org/pypy/pypy/changeset/abfd57f6777a/ Log: kill dead imports diff --git a/pypy/rpython/normalizecalls.py b/pypy/rpython/normalizecalls.py --- a/pypy/rpython/normalizecalls.py +++ b/pypy/rpython/normalizecalls.py @@ -1,16 +1,11 @@ -import py -import types, sys -import inspect -from pypy.objspace.flow.model import Variable, Constant, Block, Link -from pypy.objspace.flow.model import checkgraph, FunctionGraph, SpaceOperation -from pypy.annotation import model as annmodel -from pypy.annotation import description -from pypy.tool.sourcetools import has_varargs, valid_identifier -from pypy.tool.sourcetools import func_with_new_name +from pypy.annotation import model as annmodel, description +from pypy.interpreter.argument import Signature +from pypy.objspace.flow.model import (Variable, Constant, Block, Link, + checkgraph, FunctionGraph, SpaceOperation) +from pypy.rlib.objectmodel import ComputedIntSymbolic from pypy.rpython.error import TyperError from pypy.rpython.rmodel import getgcflavor -from pypy.rlib.objectmodel import instantiate, ComputedIntSymbolic -from pypy.interpreter.argument import Signature +from pypy.tool.sourcetools import valid_identifier def normalize_call_familes(annotator): @@ -42,7 +37,7 @@ assert not callfamily.normalized, "change in call family normalisation" if nshapes != 1: raise_call_table_too_complex_error(callfamily, annotator) - while True: + while True: progress = False for shape, table in callfamily.calltables.items(): for row in table: @@ -96,7 +91,7 @@ break else: return False # nothing to do, all signatures already match - + shape_cnt, shape_keys, shape_star, shape_stst = shape assert not shape_star, "XXX not implemented" assert not shape_stst, "XXX not implemented" @@ -155,7 +150,7 @@ newdefaults = newdefaults[i:] break graph.defaults = tuple(newdefaults) - graph.signature = Signature([argnames[j] for j in argorder], + graph.signature = Signature([argnames[j] for j in argorder], None, None) # finished checkgraph(graph) @@ -278,14 +273,14 @@ # build the 'instantiate() -> instance of C' functions for the vtables needs_generic_instantiate = annotator.bookkeeper.needs_generic_instantiate - + for classdef in needs_generic_instantiate: assert getgcflavor(classdef) == 'gc' # only gc-case create_instantiate_function(annotator, classdef) def create_instantiate_function(annotator, classdef): # build the graph of a function that looks like - # + # # def my_instantiate(): # return instantiate(cls) # @@ -294,7 +289,7 @@ v = Variable() block = Block([]) block.operations.append(SpaceOperation('instantiate1', [], v)) - name = valid_identifier('instantiate_'+classdef.name) + name = valid_identifier('instantiate_' + classdef.name) graph = FunctionGraph(name, block) block.closeblock(Link([v], graph.returnblock)) annotator.setbinding(v, annmodel.SomeInstance(classdef)) @@ -325,6 +320,7 @@ # see pypy.jit.metainterp.pyjitpl.opimpl_int_between def __sub__(self, other): return self.compute_fn() - other + def __rsub__(self, other): return other - self.compute_fn() From noreply at buildbot.pypy.org Mon Oct 8 13:14:51 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 13:14:51 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, arigo, fijal) fix the argtypes to ctypes Message-ID: <20121008111451.D000D1C0274@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57893:b3393134a743 Date: 2012-10-08 10:32 +0200 http://bitbucket.org/pypy/pypy/changeset/b3393134a743/ Log: (alex, arigo, fijal) fix the argtypes to ctypes diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -1,20 +1,28 @@ import py import ctypes +from pypy.annotation import model, signature from pypy.rpython.lltypesystem.lltype import * +from pypy.rpython.lltypesystem import ll2ctypes from pypy.translator.translator import TranslationContext from pypy.translator.c import genc from pypy.translator.interactive import Translation from pypy.rlib.entrypoint import entrypoint from pypy.tool.nullpath import NullPyPathLocal + +def cast_to_ctypes(type): + s_tp = signature.annotation(type) + ll_tp = model.annotation_to_lltype(s_tp) + return ll2ctypes.get_ctypes_type(ll_tp) + def compile(fn, argtypes, view=False, gcpolicy="ref", backendopt=True, annotatorpolicy=None): t = Translation(fn, argtypes, gc=gcpolicy, backend="c", policy=annotatorpolicy) if not backendopt: t.disable(["backendopt_lltype"]) - t.annotate() + s_res = t.annotate() # XXX fish t.driver.config.translation.countmallocs = True so_name = t.compile_c() @@ -28,7 +36,10 @@ for arg, argtype in zip(args, argtypes): assert isinstance(arg, argtype) dll = ctypes.CDLL(str(so_name)) - return getattr(dll, 'pypy_g_' + fn.__name__)(*args) + func = getattr(dll, 'pypy_g_' + fn.__name__) + func.argtypes = [cast_to_ctypes(arg) for arg in argtypes] + func.restype = cast_to_ctypes(s_res) + return func(*args) f.__name__ = fn.__name__ return f From noreply at buildbot.pypy.org Mon Oct 8 13:14:53 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 13:14:53 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (arigo, fijal) clean up the interactive a bit Message-ID: <20121008111453.0F3B31C0274@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57894:37013e47fdbc Date: 2012-10-08 13:12 +0200 http://bitbucket.org/pypy/pypy/changeset/37013e47fdbc/ Log: (arigo, fijal) clean up the interactive a bit diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -1,31 +1,39 @@ import py import ctypes -from pypy.annotation import model, signature from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.lltypesystem import ll2ctypes -from pypy.translator.translator import TranslationContext +from pypy.translator.translator import TranslationContext, graphof from pypy.translator.c import genc from pypy.translator.interactive import Translation from pypy.rlib.entrypoint import entrypoint from pypy.tool.nullpath import NullPyPathLocal +from pypy.rlib.unroll import unrolling_iterable - -def cast_to_ctypes(type): - s_tp = signature.annotation(type) - ll_tp = model.annotation_to_lltype(s_tp) - return ll2ctypes.get_ctypes_type(ll_tp) - -def compile(fn, argtypes, view=False, gcpolicy="ref", backendopt=True, +def compile(fn, argtypes, view=False, gcpolicy="none", backendopt=True, annotatorpolicy=None): - t = Translation(fn, argtypes, gc=gcpolicy, backend="c", + argtypes_unroll = unrolling_iterable(enumerate(argtypes)) + + def entry_point(argv): + args = () + for i, argtype in argtypes_unroll: + if argtype is int: + args = args + (int(argv[i + 1]),) + elif argtype is float: + args = args + (float(argv[i + 1]),) + else: + assert argtype is str + args = args + (argv[i + 1],) + res = fn(*args) + print "THE RESULT IS:", res, ";" + return 0 + + t = Translation(entry_point, None, gc=gcpolicy, backend="c", policy=annotatorpolicy) if not backendopt: t.disable(["backendopt_lltype"]) - s_res = t.annotate() - # XXX fish - t.driver.config.translation.countmallocs = True - so_name = t.compile_c() + t.annotate() + t.compile_c() + ll_res = graphof(t.context, fn).getreturnvar().concretetype try: if py.test.config.option.view: t.view() @@ -35,11 +43,20 @@ assert len(args) == len(argtypes) for arg, argtype in zip(args, argtypes): assert isinstance(arg, argtype) - dll = ctypes.CDLL(str(so_name)) - func = getattr(dll, 'pypy_g_' + fn.__name__) - func.argtypes = [cast_to_ctypes(arg) for arg in argtypes] - func.restype = cast_to_ctypes(s_res) - return func(*args) + stdout = t.driver.cbuilder.cmdexec(" ".join([str(arg) for arg in args])) + assert stdout.endswith(' ;\n') + pos = stdout.rindex('THE RESULT IS: ') + res = stdout[pos + len('THE RESULT IS: '):-3] + if ll_res == Signed: + return int(res) + elif ll_res == Char: + assert len(res) == 1 + return res + elif ll_res == Float: + return float(res) + elif ll_res == Void: + return None + raise NotImplementedError("parsing %s" % (ll_res,)) f.__name__ = fn.__name__ return f @@ -110,50 +127,6 @@ f1 = compile(f, []) assert f1() == '\x00' -def test_runtime_type_info(): - S = GcStruct('s', ('is_actually_s1', Bool), rtti=True) - S1 = GcStruct('s1', ('sub', S), rtti=True) - def rtti_S(p): - if p.is_actually_s1: - return getRuntimeTypeInfo(S1) - else: - return getRuntimeTypeInfo(S) - def rtti_S1(p): - return getRuntimeTypeInfo(S1) - def does_stuff(): - p = malloc(S) - p.is_actually_s1 = False - p1 = malloc(S1) - p1.sub.is_actually_s1 = True - # and no crash when p and p1 are decref'ed - return None - t = TranslationContext() - t.buildannotator().build_types(does_stuff, []) - rtyper = t.buildrtyper() - rtyper.attachRuntimeTypeInfoFunc(S, rtti_S) - rtyper.attachRuntimeTypeInfoFunc(S1, rtti_S1) - rtyper.specialize() - #t.view() - - from pypy.translator.c import genc - t.config.translation.countmallocs = True - builder = genc.CExtModuleBuilder(t, does_stuff, config=t.config) - builder.generate_source() - builder.compile() - f1 = builder.get_entry_point() - f1() - mallocs, frees = builder.get_malloc_counters()() - assert mallocs == frees - - -def test_str(): - def call_str(o): - return str(o) - f1 = compile(call_str, [object]) - lst = (1, [5], "'hello'", lambda x: x+1) - res = f1(lst) - assert res == str(lst) - def test_rstr(): def fn(i): @@ -287,15 +260,19 @@ s1 = 'hello' s2 = ''.join([chr(i) for i in range(256)]) s3 = 'abcd'*17 - s4 = open(__file__, 'rb').read() + s4 = open(__file__, 'rb').read(2049) choices = [s1, s2, s3, s4] def f(i, j): return choices[i][j] f1 = compile(f, [int, int]) for i, s in enumerate(choices): - for j, c in enumerate(s): + j = 0 + while j < len(s): + c = s[j] assert f1(i, j) == c - + j += 1 + if j > 100: + j += 10 def test_keepalive(): from pypy.rlib import objectmodel @@ -314,7 +291,7 @@ print "xxx" fn = compile(f, []) - fn(expected_extra_mallocs=1) + fn() def test_name(): def f(): @@ -327,7 +304,7 @@ t.compile_c() if py.test.config.option.view: t.view() - assert 'pypy_xyz_f' in t.driver.cbuilder.c_source_filename.read() + assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'pypy_xyz_f') def test_entrypoints(): def f(): @@ -343,7 +320,7 @@ t.compile_c() if py.test.config.option.view: t.view() - assert 'foobar' in t.driver.cbuilder.c_source_filename.read() + assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'foobar') def test_exportstruct(): from pypy.rlib.exports import export_struct diff --git a/pypy/translator/interactive.py b/pypy/translator/interactive.py --- a/pypy/translator/interactive.py +++ b/pypy/translator/interactive.py @@ -18,14 +18,10 @@ self.context = TranslationContext(config=self.config) # hook into driver events - driver_own_event = self.driver._event - def _event(kind, goal, func): - self.driver_event(kind, goal, func) - driver_own_event(kind, goal, func) - self.driver._event = _event self.driver_setup = False self.update_options(argtypes, kwds) + self.ensure_setup(argtypes, kwds.pop('policy', None)) # for t.view() to work just after construction graph = self.context.buildflowgraph(entry_point) self.context._prebuilt_graphs[entry_point] = graph @@ -36,14 +32,8 @@ def viewcg(self): self.context.viewcg() - def driver_event(self, kind, goal, func): - if kind == 'pre': - #print goal - self.ensure_setup() - elif kind == 'post': - pass - - def ensure_setup(self, argtypes=None, policy=None, standalone=False): + def ensure_setup(self, argtypes=None, policy=None): + standalone = argtypes is None if not self.driver_setup: if standalone: assert argtypes is None @@ -66,11 +56,6 @@ raise Exception("inconsistent annotation polish supplied") def update_options(self, argtypes, kwds): - if argtypes or kwds.get('policy') or kwds.get('standalone'): - self.ensure_setup(argtypes, kwds.get('policy'), - kwds.get('standalone')) - kwds.pop('policy', None) - kwds.pop('standalone', None) gc = kwds.pop('gc', None) if gc: self.config.translation.gc = gc From noreply at buildbot.pypy.org Mon Oct 8 13:14:54 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 13:14:54 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121008111454.707641C0274@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57895:2c75f24c71f9 Date: 2012-10-08 13:12 +0200 http://bitbucket.org/pypy/pypy/changeset/2c75f24c71f9/ Log: merge diff too long, truncating to 2000 out of 3344 lines diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -41,9 +41,6 @@ llexternal functions. For a typical usage, see `pypy.rlib.rsocket.RSocket.getsockopt_int`. -- Support context managers and the `with` statement. This could be a workaround - before the previous point is available. - Extensible type system for llexternal ------------------------------------- diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -7,31 +7,31 @@ """ -import types, sys, os -from pypy.tool.compat import md5 +import sys +import os +import types + +import py NoneNotWrapped = object() -from pypy.tool.sourcetools import func_with_new_name +from pypy.interpreter import eval +from pypy.interpreter.argument import Arguments, Signature +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, + SpaceCache, DescrMismatch) from pypy.interpreter.error import OperationError -from pypy.interpreter import eval -from pypy.interpreter.function import Function, Method, ClassMethod -from pypy.interpreter.function import FunctionWithFixedCode -from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable -from pypy.interpreter.baseobjspace import Wrappable, SpaceCache, DescrMismatch -from pypy.interpreter.argument import Arguments, Signature -from pypy.tool.sourcetools import NiceCompile, compile2 -from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from pypy.rlib import rstackovf from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.tool.sourcetools import func_with_new_name, compile2 + # internal non-translatable parts: -import py - class SignatureBuilder(object): "NOT_RPYTHON" def __init__(self, func=None, argnames=None, varargname=None, - kwargname=None, name = None): + kwargname=None, name=None): self.func = func if func is not None: self.name = func.__name__ @@ -81,8 +81,8 @@ for el in unwrap_spec: dispatch(el, *extra) + class UnwrapSpecEmit(UnwrapSpecRecipe): - def __init__(self): self.n = 0 self.miniglobals = {} @@ -99,8 +99,8 @@ #________________________________________________________________ + class UnwrapSpec_Check(UnwrapSpecRecipe): - # checks for checking interp2app func argument names wrt unwrap_spec # and synthetizing an app-level signature @@ -168,8 +168,8 @@ app_sig.append(argname[2:]) def visit__Arguments(self, el, app_sig): - argname = self.orig_arg() - assert app_sig.varargname is None,( + self.orig_arg() + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = 'args' app_sig.kwargname = 'keywords' @@ -179,7 +179,7 @@ assert argname.endswith('_w'), ( "rest arguments arg %s of built-in function %r should end in '_w'" % (argname, self.func)) - assert app_sig.varargname is None,( + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = argname[:-2] @@ -188,7 +188,7 @@ assert argname.startswith('w_'), ( "rest arguments arg %s of built-in function %r should start 'w_'" % (argname, self.func)) - assert app_sig.varargname is None,( + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = argname[2:] @@ -320,15 +320,16 @@ def _run(self, space, scope_w): """Subclasses with behavior specific for an unwrap spec are generated""" - raise TypeError, "abstract" + raise TypeError("abstract") #________________________________________________________________ + class FastFuncNotSupported(Exception): pass + class UnwrapSpec_FastFunc_Unwrap(UnwrapSpecEmit): - def __init__(self): UnwrapSpecEmit.__init__(self) self.args = [] @@ -439,6 +440,7 @@ return narg, fastfunc make_fastfunc = staticmethod(make_fastfunc) + def int_unwrapping_space_method(typ): assert typ in (int, str, float, unicode, r_longlong, r_uint, r_ulonglong, bool) if typ is r_int is r_longlong: @@ -466,6 +468,7 @@ return func return decorator + def build_unwrap_spec(func, argnames, self_type=None): """build the list of parameter unwrap spec for the function. """ @@ -505,6 +508,7 @@ return unwrap_spec + class BuiltinCode(eval.Code): "The code object implementing a built-in (interpreter-level) hook." _immutable_ = True @@ -517,8 +521,7 @@ NOT_RPYTHON_ATTRIBUTES = ['_bltin', '_unwrap_spec'] - def __init__(self, func, unwrap_spec = None, self_type = None, - descrmismatch=None): + def __init__(self, func, unwrap_spec=None, self_type=None, descrmismatch=None): "NOT_RPYTHON" # 'implfunc' is the interpreter-level function. # Note that this uses a lot of (construction-time) introspection. @@ -548,7 +551,7 @@ unwrap_spec = build_unwrap_spec(func, argnames, self_type) if self_type: - assert unwrap_spec[0] == 'self',"self_type without 'self' spec element" + assert unwrap_spec[0] == 'self', "self_type without 'self' spec element" unwrap_spec = list(unwrap_spec) if descrmismatch is not None: assert issubclass(self_type, Wrappable) @@ -561,13 +564,10 @@ assert descrmismatch is None, ( "descrmismatch without a self-type specified") - orig_sig = SignatureBuilder(func, argnames, varargname, kwargname) app_sig = SignatureBuilder(func) - UnwrapSpec_Check(orig_sig).apply_over(unwrap_spec, - app_sig #to populate - ) + UnwrapSpec_Check(orig_sig).apply_over(unwrap_spec, app_sig) self.sig = argnames, varargname, kwargname = app_sig.signature() self.minargs = len(argnames) @@ -598,8 +598,8 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) builtin_code = mod.get('builtin_code') return space.newtuple([builtin_code, space.newtuple([space.wrap(self.identifier)])]) @@ -658,6 +658,7 @@ # (verbose) performance hack below + class BuiltinCodePassThroughArguments0(BuiltinCode): _immutable_ = True @@ -677,6 +678,7 @@ w_result = space.w_None return w_result + class BuiltinCodePassThroughArguments1(BuiltinCode): _immutable_ = True fast_natural_arity = eval.Code.PASSTHROUGHARGS1 @@ -697,6 +699,7 @@ w_result = space.w_None return w_result + class BuiltinCode0(BuiltinCode): _immutable_ = True fast_natural_arity = 0 @@ -714,6 +717,7 @@ w_result = space.w_None return w_result + class BuiltinCode1(BuiltinCode): _immutable_ = True fast_natural_arity = 1 @@ -722,10 +726,10 @@ try: w_result = self.fastfunc_1(space, w1) except DescrMismatch: - return w1.descr_call_mismatch(space, - self.descrmismatch_op, - self.descr_reqcls, - Arguments(space, [w1])) + return w1.descr_call_mismatch(space, + self.descrmismatch_op, + self.descr_reqcls, + Arguments(space, [w1])) except Exception, e: self.handle_exception(space, e) w_result = None @@ -733,6 +737,7 @@ w_result = space.w_None return w_result + class BuiltinCode2(BuiltinCode): _immutable_ = True fast_natural_arity = 2 @@ -741,10 +746,10 @@ try: w_result = self.fastfunc_2(space, w1, w2) except DescrMismatch: - return w1.descr_call_mismatch(space, - self.descrmismatch_op, - self.descr_reqcls, - Arguments(space, [w1, w2])) + return w1.descr_call_mismatch(space, + self.descrmismatch_op, + self.descr_reqcls, + Arguments(space, [w1, w2])) except Exception, e: self.handle_exception(space, e) w_result = None @@ -752,6 +757,7 @@ w_result = space.w_None return w_result + class BuiltinCode3(BuiltinCode): _immutable_ = True fast_natural_arity = 3 @@ -760,10 +766,10 @@ try: w_result = self.fastfunc_3(space, w1, w2, w3) except DescrMismatch: - return w1.descr_call_mismatch(space, - self.descrmismatch_op, - self.descr_reqcls, - Arguments(space, [w1, w2, w3])) + return w1.descr_call_mismatch(space, + self.descrmismatch_op, + self.descr_reqcls, + Arguments(space, [w1, w2, w3])) except Exception, e: self.handle_exception(space, e) w_result = None @@ -771,6 +777,7 @@ w_result = space.w_None return w_result + class BuiltinCode4(BuiltinCode): _immutable_ = True fast_natural_arity = 4 @@ -779,11 +786,11 @@ try: w_result = self.fastfunc_4(space, w1, w2, w3, w4) except DescrMismatch: - return w1.descr_call_mismatch(space, - self.descrmismatch_op, - self.descr_reqcls, - Arguments(space, - [w1, w2, w3, w4])) + return w1.descr_call_mismatch(space, + self.descrmismatch_op, + self.descr_reqcls, + Arguments(space, + [w1, w2, w3, w4])) except Exception, e: self.handle_exception(space, e) w_result = None @@ -808,8 +815,8 @@ instancecache = {} - def __new__(cls, f, app_name=None, unwrap_spec = None, - descrmismatch=None, as_classmethod=False): + def __new__(cls, f, app_name=None, unwrap_spec=None, descrmismatch=None, + as_classmethod=False): "NOT_RPYTHON" # f must be a function whose name does NOT start with 'app_' @@ -818,10 +825,10 @@ self_type = f.im_class f = f.im_func if not isinstance(f, types.FunctionType): - raise TypeError, "function expected, got %r instead" % f + raise TypeError("function expected, got %r instead" % f) if app_name is None: if f.func_name.startswith('app_'): - raise ValueError, ("function name %r suspiciously starts " + raise ValueError("function name %r suspiciously starts " "with 'app_'" % f.func_name) app_name = f.func_name @@ -837,7 +844,7 @@ self = Wrappable.__new__(cls) cls.instancecache[key] = self self._code = BuiltinCode(f, unwrap_spec=unwrap_spec, - self_type = self_type, + self_type=self_type, descrmismatch=descrmismatch) self.__name__ = f.func_name self.name = app_name @@ -875,7 +882,7 @@ space = cache.space defs = gateway._getdefaults(space) # needs to be implemented by subclass code = gateway._code - fn = FunctionWithFixedCode(space, code, None, defs, forcename = gateway.name) + fn = FunctionWithFixedCode(space, code, None, defs, forcename=gateway.name) if not space.config.translating: fn.add_to_table() if gateway.as_classmethod: @@ -995,6 +1002,7 @@ # ____________________________________________________________ + def appdef(source, applevel=ApplevelClass, filename=None): """ NOT_RPYTHON: build an app-level helper function, like for example: myfunc = appdef('''myfunc(x, y): @@ -1015,7 +1023,7 @@ funcname = source[:p].strip() source = source[p:] assert source.strip() - funcsource = "def %s%s\n" % (funcname, source) + funcsource = "def %s%s\n" % (funcname, source) #for debugging of wrong source code: py.std.parser.suite(funcsource) a = applevel(funcsource, filename=filename) return a.interphook(funcname) 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 @@ -185,7 +185,7 @@ return stream.readline() else: # very inefficient unless there is a peek() - result = [] + result = StringBuilder() while size > 0: # "peeks" on the underlying stream to see how many chars # we can safely read without reading past an end-of-line @@ -200,7 +200,7 @@ if c.endswith('\n'): break size -= len(c) - return ''.join(result) + return result.build() @unwrap_spec(size=int) def direct_readlines(self, size=0): 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 @@ -428,6 +428,18 @@ pass assert f.subclass_closed + def test_readline_unbuffered_should_read_one_line_only(self): + import posix + + with self.file(self.temppath, 'w') as f: + f.write('foo\nbar\n') + + with self.file(self.temppath, 'r', 0) as f: + s = f.readline() + assert s == 'foo\n' + s = posix.read(f.fileno(), 10) + assert s == 'bar\n' + def test_flush_at_exit(): from pypy import conftest from pypy.tool.option import make_config, make_objspace diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -644,8 +644,7 @@ # j = (m+) % SHIFT = (m+) - (i * SHIFT) # (computed without doing "i * SHIFT", which might overflow) j = size_b % 5 - if j != 0: - j = 5 - j + j = _jmapping[j] if not we_are_translated(): assert j == (size_b*SHIFT+4)//5*5 - size_b*SHIFT # @@ -866,6 +865,12 @@ ONENEGATIVERBIGINT = rbigint([ONEDIGIT], -1, 1) NULLRBIGINT = rbigint() +_jmapping = [(5 * SHIFT) % 5, + (4 * SHIFT) % 5, + (3 * SHIFT) % 5, + (2 * SHIFT) % 5, + (1 * SHIFT) % 5] + #_________________________________________________________________ # Helper Functions diff --git a/pypy/rlib/rsre/rsre_re.py b/pypy/rlib/rsre/rsre_re.py --- a/pypy/rlib/rsre/rsre_re.py +++ b/pypy/rlib/rsre/rsre_re.py @@ -75,7 +75,7 @@ else: item = match.groups("") matchlist.append(item) - return matchlist + return matchlist def finditer(self, string, pos=0, endpos=sys.maxint): return iter(self.scanner(string, pos, endpos).search, None) diff --git a/pypy/rlib/streamio.py b/pypy/rlib/streamio.py --- a/pypy/rlib/streamio.py +++ b/pypy/rlib/streamio.py @@ -41,6 +41,7 @@ from pypy.rlib.objectmodel import specialize, we_are_translated from pypy.rlib.rarithmetic import r_longlong, intmask from pypy.rlib import rposix +from pypy.rlib.rstring import StringBuilder from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC O_BINARY = getattr(os, "O_BINARY", 0) @@ -141,8 +142,7 @@ def construct_stream_tower(stream, buffering, universal, reading, writing, binary): if buffering == 0: # no buffering - if reading: # force some minimal buffering for readline() - stream = ReadlineInputStream(stream) + pass elif buffering == 1: # line-buffering if writing: stream = LineBufferingOutputStream(stream) @@ -303,6 +303,26 @@ raise # else try again + def readline(self): + # mostly inefficient, but not as laughably bad as with the default + # readline() from Stream + result = StringBuilder() + while True: + try: + c = os.read(self.fd, 1) + except OSError, e: + if e.errno != errno.EINTR: + raise + else: + continue # try again + if not c: + break + c = c[0] + result.append(c) + if c == '\n': + break + return result.build() + def write(self, data): while data: try: @@ -700,113 +720,6 @@ flush_buffers=False) -class ReadlineInputStream(Stream): - - """Minimal buffering input stream. - - Only does buffering for readline(). The other kinds of reads, and - all writes, are not buffered at all. - """ - - bufsize = 2**13 # 8 K - - def __init__(self, base, bufsize=-1): - self.base = base - self.do_read = base.read # function to fill buffer some more - self.do_seek = base.seek # seek to a byte offset - if bufsize == -1: # Get default from the class - bufsize = self.bufsize - self.bufsize = bufsize # buffer size (hint only) - self.buf = None # raw data (may contain "\n") - self.bufstart = 0 - - def flush_buffers(self): - if self.buf is not None: - try: - self.do_seek(self.bufstart-len(self.buf), 1) - except (MyNotImplementedError, OSError): - pass - else: - self.buf = None - self.bufstart = 0 - - def readline(self): - if self.buf is not None: - i = self.buf.find('\n', self.bufstart) - else: - self.buf = '' - i = -1 - # - if i < 0: - self.buf = self.buf[self.bufstart:] - self.bufstart = 0 - while True: - bufsize = max(self.bufsize, len(self.buf) >> 2) - data = self.do_read(bufsize) - if not data: - result = self.buf # end-of-file reached - self.buf = None - return result - startsearch = len(self.buf) # there is no '\n' in buf so far - self.buf += data - i = self.buf.find('\n', startsearch) - if i >= 0: - break - # - i += 1 - result = self.buf[self.bufstart:i] - self.bufstart = i - return result - - def peek(self): - if self.buf is None: - return '' - if self.bufstart > 0: - self.buf = self.buf[self.bufstart:] - self.bufstart = 0 - return self.buf - - def tell(self): - pos = self.base.tell() - if self.buf is not None: - pos -= (len(self.buf) - self.bufstart) - return pos - - def readall(self): - result = self.base.readall() - if self.buf is not None: - result = self.buf[self.bufstart:] + result - self.buf = None - self.bufstart = 0 - return result - - def read(self, n): - if self.buf is None: - return self.do_read(n) - else: - m = n - (len(self.buf) - self.bufstart) - start = self.bufstart - if m > 0: - result = self.buf[start:] + self.do_read(m) - self.buf = None - self.bufstart = 0 - return result - elif n >= 0: - self.bufstart = start + n - return self.buf[start : self.bufstart] - else: - return '' - - seek = PassThrough("seek", flush_buffers=True) - write = PassThrough("write", flush_buffers=True) - truncate = PassThrough("truncate", flush_buffers=True) - flush = PassThrough("flush", flush_buffers=True) - flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) - try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", - flush_buffers=False) - - class BufferingOutputStream(Stream): """Standard buffering output stream. diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -396,6 +396,14 @@ v = two.pow(t, rbigint.fromint(n)) assert v.toint() == pow(2, t.tolong(), n) + def test_pow_lll_bug2(self): + x = rbigint.fromlong(2) + y = rbigint.fromlong(5100894665148900058249470019412564146962964987365857466751243988156579407594163282788332839328303748028644825680244165072186950517295679131100799612871613064597) + z = rbigint.fromlong(538564) + expected = rbigint.fromlong(163464) + got = x.pow(y, z) + assert got.eq(expected) + def test_pow_lln(self): x = 10L y = 2L diff --git a/pypy/rlib/test/test_streamio.py b/pypy/rlib/test/test_streamio.py --- a/pypy/rlib/test/test_streamio.py +++ b/pypy/rlib/test/test_streamio.py @@ -1026,7 +1026,7 @@ base.tell = f if not seek: base.seek = f - return streamio.ReadlineInputStream(base, bufsize) + return base def test_readline(self): for file in [self.makeStream(), self.makeStream(bufsize=2)]: diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py --- a/pypy/rpython/lltypesystem/lltype.py +++ b/pypy/rpython/lltypesystem/lltype.py @@ -1,9 +1,7 @@ -import py from pypy.rlib.rarithmetic import (r_int, r_uint, intmask, r_singlefloat, r_ulonglong, r_longlong, r_longfloat, r_longlonglong, base_int, normalizedinttype, longlongmask, longlonglongmask) from pypy.rlib.objectmodel import Symbolic -from pypy.tool.uid import Hashable from pypy.tool.identity_dict import identity_dict from pypy.tool import leakfinder from types import NoneType diff --git a/pypy/rpython/lltypesystem/test/test_llarena.py b/pypy/rpython/lltypesystem/test/test_llarena.py --- a/pypy/rpython/lltypesystem/test/test_llarena.py +++ b/pypy/rpython/lltypesystem/test/test_llarena.py @@ -1,16 +1,15 @@ import py + from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.lltypesystem.llarena import (arena_malloc, arena_reset, + arena_reserve, arena_free, round_up_for_allocation, ArenaError, + arena_new_view, arena_shrink_obj, arena_protect, has_protect) from pypy.rpython.lltypesystem.llmemory import cast_adr_to_ptr -from pypy.rpython.lltypesystem.llarena import arena_malloc, arena_reset -from pypy.rpython.lltypesystem.llarena import arena_reserve, arena_free -from pypy.rpython.lltypesystem.llarena import round_up_for_allocation -from pypy.rpython.lltypesystem.llarena import ArenaError, arena_new_view -from pypy.rpython.lltypesystem.llarena import arena_shrink_obj -from pypy.rpython.lltypesystem.llarena import arena_protect, has_protect from pypy.translator.c.test import test_genc, test_standalone + def test_arena(): - S = lltype.Struct('S', ('x',lltype.Signed)) + S = lltype.Struct('S', ('x', lltype.Signed)) SPTR = lltype.Ptr(S) ssize = llmemory.raw_malloc_usage(llmemory.sizeof(S)) myarenasize = 2*ssize+1 @@ -303,8 +302,6 @@ class TestStandalone(test_standalone.StandaloneTests): def test_compiled_arena_protect(self): - import os - from pypy.translator.c.test.test_genc import compile S = lltype.Struct('S', ('x', lltype.Signed)) # def fn(argv): diff --git a/pypy/rpython/normalizecalls.py b/pypy/rpython/normalizecalls.py --- a/pypy/rpython/normalizecalls.py +++ b/pypy/rpython/normalizecalls.py @@ -1,16 +1,11 @@ -import py -import types, sys -import inspect -from pypy.objspace.flow.model import Variable, Constant, Block, Link -from pypy.objspace.flow.model import checkgraph, FunctionGraph, SpaceOperation -from pypy.annotation import model as annmodel -from pypy.annotation import description -from pypy.tool.sourcetools import has_varargs, valid_identifier -from pypy.tool.sourcetools import func_with_new_name +from pypy.annotation import model as annmodel, description +from pypy.interpreter.argument import Signature +from pypy.objspace.flow.model import (Variable, Constant, Block, Link, + checkgraph, FunctionGraph, SpaceOperation) +from pypy.rlib.objectmodel import ComputedIntSymbolic from pypy.rpython.error import TyperError from pypy.rpython.rmodel import getgcflavor -from pypy.rlib.objectmodel import instantiate, ComputedIntSymbolic -from pypy.interpreter.argument import Signature +from pypy.tool.sourcetools import valid_identifier def normalize_call_familes(annotator): @@ -42,7 +37,7 @@ assert not callfamily.normalized, "change in call family normalisation" if nshapes != 1: raise_call_table_too_complex_error(callfamily, annotator) - while True: + while True: progress = False for shape, table in callfamily.calltables.items(): for row in table: @@ -96,7 +91,7 @@ break else: return False # nothing to do, all signatures already match - + shape_cnt, shape_keys, shape_star, shape_stst = shape assert not shape_star, "XXX not implemented" assert not shape_stst, "XXX not implemented" @@ -155,7 +150,7 @@ newdefaults = newdefaults[i:] break graph.defaults = tuple(newdefaults) - graph.signature = Signature([argnames[j] for j in argorder], + graph.signature = Signature([argnames[j] for j in argorder], None, None) # finished checkgraph(graph) @@ -278,14 +273,14 @@ # build the 'instantiate() -> instance of C' functions for the vtables needs_generic_instantiate = annotator.bookkeeper.needs_generic_instantiate - + for classdef in needs_generic_instantiate: assert getgcflavor(classdef) == 'gc' # only gc-case create_instantiate_function(annotator, classdef) def create_instantiate_function(annotator, classdef): # build the graph of a function that looks like - # + # # def my_instantiate(): # return instantiate(cls) # @@ -294,7 +289,7 @@ v = Variable() block = Block([]) block.operations.append(SpaceOperation('instantiate1', [], v)) - name = valid_identifier('instantiate_'+classdef.name) + name = valid_identifier('instantiate_' + classdef.name) graph = FunctionGraph(name, block) block.closeblock(Link([v], graph.returnblock)) annotator.setbinding(v, annmodel.SomeInstance(classdef)) @@ -325,6 +320,7 @@ # see pypy.jit.metainterp.pyjitpl.opimpl_int_between def __sub__(self, other): return self.compute_fn() - other + def __rsub__(self, other): return other - self.compute_fn() diff --git a/pypy/rpython/test/test_exception.py b/pypy/rpython/test/test_exception.py --- a/pypy/rpython/test/test_exception.py +++ b/pypy/rpython/test/test_exception.py @@ -1,10 +1,11 @@ import py + from pypy.translator.translator import TranslationContext -from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rpython.llinterp import LLException from pypy.rpython.error import MissingRTypeOperation + class MyException(Exception): pass diff --git a/pypy/rpython/test/test_llann.py b/pypy/rpython/test/test_llann.py --- a/pypy/rpython/test/test_llann.py +++ b/pypy/rpython/test/test_llann.py @@ -1,20 +1,18 @@ import py + +from pypy.annotation import model as annmodel +from pypy.conftest import option +from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.rpython.annlowlevel import (annotate_lowlevel_helper, + MixLevelHelperAnnotator, PseudoHighLevelCallable, llhelper, + cast_instance_to_base_ptr, cast_base_ptr_to_instance, base_ptr_lltype) +from pypy.rpython.llinterp import LLInterpreter from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.ootypesystem import ootype -from pypy.rpython.lltypesystem.rclass import OBJECTPTR from pypy.rpython.rclass import fishllattr +from pypy.rpython.test.test_llinterp import interpret from pypy.translator.translator import TranslationContext -from pypy.annotation import model as annmodel -from pypy.rpython.annlowlevel import annotate_lowlevel_helper -from pypy.rpython.annlowlevel import MixLevelHelperAnnotator -from pypy.rpython.annlowlevel import PseudoHighLevelCallable -from pypy.rpython.annlowlevel import llhelper, cast_instance_to_base_ptr -from pypy.rpython.annlowlevel import cast_base_ptr_to_instance -from pypy.rpython.annlowlevel import base_ptr_lltype -from pypy.rpython.llinterp import LLInterpreter -from pypy.rpython.test.test_llinterp import interpret -from pypy.objspace.flow.objspace import FlowObjSpace -from pypy.conftest import option + # helpers @@ -24,15 +22,17 @@ if op.opname in ops: yield op + def derived(op, orig): if op.args[0].value.__name__.startswith(orig): return op.args[0].value else: return None + class TestLowLevelAnnotateTestCase: - def setup_class(cls): - cls.space = FlowObjSpace() + def setup_class(cls): + cls.space = FlowObjSpace() from pypy.annotation.annrpython import RPythonAnnotator @@ -53,7 +53,7 @@ def test_simple2(self): S = Struct("s", ('v', Signed)) - S2 = GcStruct("s2", ('a',S), ('b',S)) + S2 = GcStruct("s2", ('a', S), ('b', S)) def llf(): s = malloc(S2) return s.a.v+s.b.v @@ -93,8 +93,8 @@ a[0] = 3 return a[0] s = self.annotate(llf, []) - assert s.knowntype == int - + assert s.knowntype == int + def test_cast_simple_widening(self): S2 = Struct("s2", ('a', Signed)) S1 = Struct("s1", ('sub1', S2), ('sub2', S2)) @@ -141,7 +141,7 @@ return p12, p13, p21, p23, p31, p32 s = self.annotate(llf, []) assert [x.ll_ptrtype for x in s.items] == [PS1, PS1, PS2, PS2, PS3, PS3] - + def test_array_length(self): A = GcArray(('v', Signed)) @@ -158,7 +158,7 @@ return p(0) s = self.annotate(llf, [annmodel.SomePtr(PF)]) assert s.knowntype == int - + def test_ll_calling_ll(self): A = GcArray(Float) @@ -194,13 +194,13 @@ if (func, T) in seen: continue seen[func, T] = True - + desc = a.bookkeeper.getdesc(func) g = desc.specialize([a.binding(x) for x in call.args[1:]]) args = g.getargs() rv = g.getreturnvar() - if func is ll_get: + if func is ll_get: vT, vp, vi = args assert a.binding(vT) == a.bookkeeper.immutablevalue(T) assert a.binding(vi).knowntype == int @@ -218,7 +218,7 @@ assert len(seen) == 4 return a, vTs # reused by a test in test_rtyper - + def test_ll_calling_ll2(self): A = GcArray(Float) B = GcArray(Signed) @@ -252,7 +252,7 @@ return s.const else: return s.ll_ptrtype - + vTs = [] for call in annotated_calls(a): @@ -359,7 +359,7 @@ s = self.annotate(llf, [annmodel.SomePtr(Ptr(S))]) assert isinstance(s, annmodel.SomePtr) assert s.ll_ptrtype == Ptr(RuntimeTypeInfo) - + def test_cast_primitive(self): def llf(u): return cast_primitive(Signed, u) @@ -454,7 +454,7 @@ F = Ptr(FuncType([Ptr(S), Signed], Signed)) G = Ptr(FuncType([Ptr(S)], Signed)) - + def h(x, y, z): s = malloc(S) s.x = x @@ -479,7 +479,7 @@ F = ootype.StaticMethod([S, Signed], Signed) G = ootype.StaticMethod([S], Signed) - + def h(x, y, z): s = ootype.new(S) s.x = x diff --git a/pypy/rpython/test/test_rbuilder.py b/pypy/rpython/test/test_rbuilder.py --- a/pypy/rpython/test/test_rbuilder.py +++ b/pypy/rpython/test/test_rbuilder.py @@ -1,10 +1,11 @@ from __future__ import with_statement + import py from pypy.rlib.rstring import StringBuilder, UnicodeBuilder from pypy.rpython.annlowlevel import llstr, hlstr from pypy.rpython.lltypesystem import rffi -from pypy.rpython.lltypesystem.rbuilder import * +from pypy.rpython.lltypesystem.rbuilder import StringBuilderRepr from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin @@ -23,6 +24,7 @@ StringBuilderRepr.ll_append(sb, llstr("abc")) assert StringBuilderRepr.ll_build(sb) == sb.buf + class BaseTestStringBuilder(BaseRtypingTest): def test_simple(self): def func(): diff --git a/pypy/rpython/test/test_rbuiltin.py b/pypy/rpython/test/test_rbuiltin.py --- a/pypy/rpython/test/test_rbuiltin.py +++ b/pypy/rpython/test/test_rbuiltin.py @@ -1,21 +1,22 @@ -from pypy.translator.translator import graphof -from pypy.rpython.test import test_llinterp -from pypy.rlib.objectmodel import instantiate, we_are_translated -from pypy.rlib.objectmodel import running_on_llinterp -from pypy.rlib.debug import llinterpcall -from pypy.rpython.lltypesystem import lltype -from pypy.tool import udir -from pypy.rlib.rarithmetic import intmask, longlongmask, r_int64, is_valid_int -from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong -from pypy.annotation.builtin import * -from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rpython.lltypesystem import rffi -from pypy.rpython import extfunc +import math +import os + import py +from pypy.rlib.debug import llinterpcall +from pypy.rlib.objectmodel import instantiate, running_on_llinterp, compute_unique_id, current_object_addr_as_int +from pypy.rlib.rarithmetic import (intmask, longlongmask, r_int64, is_valid_int, + r_int, r_uint, r_longlong, r_ulonglong) +from pypy.rlib.rstring import StringBuilder, UnicodeBuilder +from pypy.rpython.annlowlevel import hlstr, LowLevelAnnotatorPolicy +from pypy.rpython.lltypesystem import lltype, rffi +from pypy.rpython.test import test_llinterp +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin +from pypy.tool import udir +from pypy.translator.translator import graphof + def enum_direct_calls(translator, func): - blocks = [] graph = graphof(translator, func) for block in graph.iterblocks(): for op in block.operations: @@ -90,28 +91,28 @@ assert type(res) is r_int64 and res == 5 def test_rbuiltin_list(self): - def f(): - l=list((1,2,3)) + def f(): + l = list((1,2,3)) return l == [1,2,3] def g(): - l=list(('he','llo')) - return l == ['he','llo'] + l = list(('he', 'llo')) + return l == ['he', 'llo'] def r(): l = ['he','llo'] - l1=list(l) + l1 = list(l) return l == l1 and l is not l1 - result = self.interpret(f,[]) + result = self.interpret(f, []) assert result - result = self.interpret(g,[]) + result = self.interpret(g, []) assert result - result = self.interpret(r,[]) - assert result + result = self.interpret(r, []) + assert result def test_int_min(self): def fn(i, j): - return min(i,j) + return min(i ,j) ev_fun = self.interpret(fn, [0, 0]) assert self.interpret(fn, (1, 2)) == 1 assert self.interpret(fn, (1, -1)) == -1 @@ -145,28 +146,24 @@ assert self.interpret(fn, (1.1, -1)) == 1.1 def test_builtin_math_floor(self): - import math def fn(f): return math.floor(f) - import random for i in range(5): - rv = 1000 * float(i-10) #random.random() + rv = 1000 * float(i-10) res = self.interpret(fn, [rv]) - assert fn(rv) == res + assert fn(rv) == res def test_builtin_math_fmod(self): - import math def fn(f,y): return math.fmod(f,y) for i in range(10): for j in range(10): - rv = 1000 * float(i-10) + rv = 1000 * float(i-10) ry = 100 * float(i-10) +0.1 assert self.float_eq(fn(rv,ry), self.interpret(fn, (rv, ry))) def test_builtin_math_frexp(self): - import math def fn(f): return math.frexp(f) for x in (.5, 1, 1.5, 10/3.0): @@ -177,14 +174,12 @@ self.float_eq(res.item1, exponent)) def test_builtin_math_ldexp(self): - import math def fn(a, b): return math.ldexp(a, b) assert self.interpret(fn, [1, 2]) == 4 self.interpret_raises(OverflowError, fn, [1, 100000]) def test_builtin_math_modf(self): - import math def fn(f): return math.modf(f) res = self.interpret(fn, [10/3.0]) @@ -192,15 +187,13 @@ assert self.float_eq(res.item0, intpart) and self.float_eq(res.item1, fracpart) def test_os_getcwd(self): - import os def fn(): return os.getcwd() - res = self.interpret(fn, []) + res = self.interpret(fn, []) assert self.ll_to_string(res) == fn() - + def test_os_write(self): tmpdir = str(udir.udir.join("os_write_test")) - import os def wr_open(fname): fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777) os.write(fd, "hello world") @@ -213,11 +206,10 @@ assert hello == "hello world" fd = os.open(tmpdir, os.O_WRONLY|os.O_CREAT, 777) os.close(fd) - raises(OSError, os.write, fd, "hello world") + raises(OSError, os.write, fd, "hello world") def test_os_write_single_char(self): tmpdir = str(udir.udir.join("os_write_test_char")) - import os def wr_open(fname): fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777) os.write(fd, "x") @@ -230,7 +222,6 @@ assert hello == "x" def test_os_read(self): - import os tmpfile = str(udir.udir.join("os_read_test")) f = file(tmpfile, 'w') f.write('hello world') @@ -243,7 +234,6 @@ def test_os_lseek(self): self._skip_llinterpreter("os.lseek", skipOO=False) - import os tmpfile = str(udir.udir.join("os_lseek_test")) f = file(tmpfile, 'w') f.write('0123456789') @@ -269,7 +259,6 @@ assert res1 == res2 def test_os_dup(self): - import os def fn(fd): return os.dup(fd) res = self.interpret(fn, [0]) @@ -286,7 +275,6 @@ def test_os_open(self): tmpdir = str(udir.udir.join("os_open_test")) - import os def wr_open(fname): return os.open(fname, os.O_WRONLY|os.O_CREAT, 0777) def f(): @@ -302,9 +290,7 @@ def test_os_path_exists(self): self._skip_llinterpreter("os.stat()") - from pypy.rpython.annlowlevel import hlstr - - import os + def f(fn): fn = hlstr(fn) return os.path.exists(fn) @@ -315,9 +301,7 @@ def test_os_isdir(self): self._skip_llinterpreter("os.stat()") - from pypy.rpython.annlowlevel import hlstr - - import os + def f(fn): fn = hlstr(fn) return os.path.isdir(fn) @@ -332,14 +316,14 @@ def g(obj): return bool(obj) - def fn(neg): + def fn(neg): c = C.f return g(c) assert self.interpret(fn, [True]) - def fn(neg): + def fn(neg): c = None return g(c) - assert not self.interpret(fn, [True]) + assert not self.interpret(fn, [True]) def test_const_isinstance(self): class B(object): @@ -417,7 +401,6 @@ def test_os_path_join(self): self._skip_llinterpreter("os path oofakeimpl", skipLL=False) - import os.path def fn(a, b): return os.path.join(a, b) res = self.ll_to_string(self.interpret(fn, ['a', 'b'])) @@ -454,8 +437,6 @@ assert res == 321 def test_id(self): - from pypy.rlib.objectmodel import compute_unique_id - from pypy.rlib.objectmodel import current_object_addr_as_int class A: pass def fn(): @@ -477,8 +458,6 @@ assert x3 == intmask(x2) def test_id_on_builtins(self): - from pypy.rlib.objectmodel import compute_unique_id - from pypy.rlib.rstring import StringBuilder, UnicodeBuilder def fn(): return (compute_unique_id("foo"), compute_unique_id(u"bar"), @@ -491,7 +470,6 @@ assert isinstance(id, (int, r_longlong)) def test_uniqueness_of_id_on_strings(self): - from pypy.rlib.objectmodel import compute_unique_id def fn(s1, s2): return (compute_unique_id(s1), compute_unique_id(s2)) @@ -502,7 +480,6 @@ assert i1 != i2 def test_cast_primitive(self): - from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy def llf(u): return lltype.cast_primitive(lltype.Signed, u) res = self.interpret(llf, [r_uint(-1)], policy=LowLevelAnnotatorPolicy()) diff --git a/pypy/rpython/test/test_rclass.py b/pypy/rpython/test/test_rclass.py --- a/pypy/rpython/test/test_rclass.py +++ b/pypy/rpython/test/test_rclass.py @@ -1,14 +1,18 @@ +import sys + import py -import sys + +from pypy.objspace.flow.model import summary +from pypy.rlib.rarithmetic import r_longlong +from pypy.rpython.lltypesystem.lltype import (typeOf, Signed, getRuntimeTypeInfo, + identityhash) +from pypy.rpython.ootypesystem import ootype +from pypy.rpython.error import TyperError +from pypy.rpython.rclass import (IR_IMMUTABLE, IR_IMMUTABLE_ARRAY, + IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY) +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.translator.translator import TranslationContext, graphof -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.ootypesystem import ootype -from pypy.rlib.rarithmetic import r_longlong -from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rpython.rclass import IR_IMMUTABLE, IR_IMMUTABLE_ARRAY -from pypy.rpython.rclass import IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY -from pypy.rpython.error import TyperError -from pypy.objspace.flow.model import summary + class EmptyBase(object): pass diff --git a/pypy/rpython/test/test_rlist.py b/pypy/rpython/test/test_rlist.py --- a/pypy/rpython/test/test_rlist.py +++ b/pypy/rpython/test/test_rlist.py @@ -1,31 +1,32 @@ import sys import re + import py -from pypy.translator.translator import TranslationContext + +from pypy.rlib.debug import ll_assert from pypy.rpython.error import TyperError -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.ootypesystem import ootype -from pypy.rpython.rlist import * +from pypy.rpython.llinterp import LLException +from pypy.rpython.lltypesystem import rlist as ll_rlist from pypy.rpython.lltypesystem.rlist import ListRepr, FixedSizeListRepr, ll_newlist, ll_fixed_newlist -from pypy.rpython.lltypesystem import rlist as ll_rlist -from pypy.rpython.llinterp import LLException from pypy.rpython.ootypesystem import rlist as oo_rlist from pypy.rpython.rint import signed_repr -from pypy.objspace.flow.model import Constant, Variable +from pypy.rpython.rlist import * from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rlib.debug import ll_assert +from pypy.translator.translator import TranslationContext + # undo the specialization parameter for n1 in 'get set del'.split(): - for n2 in '','_nonneg': + for n2 in '', '_nonneg': name = 'll_%sitem%s' % (n1, n2) - globals()['_'+name] = globals()[name] + globals()['_' + name] = globals()[name] exec """if 1: def %s(*args): return _%s(dum_checkidx, *args) """ % (name, name) del n1, n2, name + class BaseTestListImpl: def check_list(self, l1, expected): @@ -88,8 +89,6 @@ class TestListImpl(BaseTestListImpl): - - def sample_list(self): # [42, 43, 44, 45] rlist = ListRepr(None, signed_repr) rlist.setup() @@ -134,8 +133,8 @@ del expected[start:stop] self.check_list(l, expected) + class TestFixedSizeListImpl(BaseTestListImpl): - def sample_list(self): # [42, 43, 44, 45] rlist = FixedSizeListRepr(None, signed_repr) rlist.setup() @@ -207,7 +206,7 @@ l.append(90) return len(l), l[0], l[-1] res = self.interpret(dummyfn, []) - assert res.item0 == 5 + assert res.item0 == 5 assert res.item1 == 50 assert res.item2 == 90 @@ -271,7 +270,6 @@ res = self.interpret(dummyfn, []) assert res == 25 - def test_recursive(self): def dummyfn(N): l = [] @@ -294,14 +292,14 @@ def test_add(self): def dummyfn(): l = [5] - l += [6,7] + l += [6, 7] return l + [8] res = self.interpret(dummyfn, []) assert self.ll_to_list(res) == [5, 6, 7, 8] def dummyfn(): l = [5] - l += [6,7] + l += [6, 7] l2 = l + [8] l2.append(9) return l2 @@ -369,7 +367,7 @@ return len(l) res = self.interpret(dummyfn, []) assert res == 0 - + def test_setslice(self): def dummyfn(): l = [10, 9, 8, 7] @@ -417,9 +415,11 @@ for resize2 in [False, True]: def dummyfn(): l1 = [42] - if resize1: l1.append(43) + if resize1: + l1.append(43) l2 = list(l1) - if resize2: l2.append(44) + if resize2: + l2.append(44) l2[0] = 0 return l1[0] res = self.interpret(dummyfn, ()) @@ -443,9 +443,9 @@ def test_list_index_simple(self): def dummyfn(i): - l = [5,6,7,8] + l = [5, 6, 7, 8] return l.index(i) - + res = self.interpret(dummyfn, (6,)) assert res == 1 self.interpret_raises(ValueError, dummyfn, [42]) @@ -460,7 +460,7 @@ l.pop(-1) l.pop() return l[-1] - res = self.interpret(dummyfn, ())#, view=True) + res = self.interpret(dummyfn, ()) assert res == 42 def test_insert_bug(self): @@ -492,7 +492,7 @@ res = self.interpret(f, [1]) assert self.class_name(res) == 'A' #''.join(res.super.typeptr.name) == 'A\00' - + def test_reverse(self): def dummyfn(): l = [5, 3, 2] @@ -881,7 +881,7 @@ i += 1 return str(l) res = self.ll_to_string(self.interpret(fn, [])) - res = res.replace('pypy.rpython.test.test_rlist.', '') + res = res.replace('pypy.rpython.test.test_rlist.', '') res = re.sub(' at 0x[a-z0-9]+', '', res) assert res == '[, , , , ]' @@ -990,12 +990,12 @@ del l[1] l.append(i) listlen = len(l) - l.extend(l) + l.extend(l) del l[listlen:] - l += [5,6] + l += [5,6] l[1] = i return l[j] - for i in range(6): + for i in range(6): for j in range(6): res = self.interpret(list_basic_ops, [i, j]) assert res == list_basic_ops(i, j) @@ -1138,7 +1138,7 @@ res = self.interpret(f, [0]) assert res == 1 res = self.interpret(f, [1]) - assert res == -1 + assert res == -1 def f(x): l = [1] @@ -1161,7 +1161,7 @@ res = self.interpret(f, [0]) assert res == 1 - + def test_getitem_exc_2(self): def f(x): l = [1] @@ -1189,7 +1189,7 @@ res = self.interpret(f, [0]) assert res == 1 res = self.interpret(f, [1]) - assert res == -1 + assert res == -1 def f(x): l = [1] @@ -1449,7 +1449,7 @@ r_A_list = rtyper.getrepr(s_A_list) assert isinstance(r_A_list, self.rlist.FixedSizeListRepr) r_B_list = rtyper.getrepr(s_B_list) - assert isinstance(r_B_list, self.rlist.FixedSizeListRepr) + assert isinstance(r_B_list, self.rlist.FixedSizeListRepr) assert r_A_list.lowleveltype == r_B_list.lowleveltype diff --git a/pypy/rpython/test/test_rpbc.py b/pypy/rpython/test/test_rpbc.py --- a/pypy/rpython/test/test_rpbc.py +++ b/pypy/rpython/test/test_rpbc.py @@ -1,9 +1,9 @@ import py -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.rtyper import RPythonTyper -from pypy.rpython.ootypesystem import ootype + +from pypy.annotation import policy, specialize +from pypy.rpython.lltypesystem.lltype import typeOf from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.annotation import policy, specialize + class MyBase: def m(self, x): diff --git a/pypy/rpython/test/test_rptr.py b/pypy/rpython/test/test_rptr.py --- a/pypy/rpython/test/test_rptr.py +++ b/pypy/rpython/test/test_rptr.py @@ -1,11 +1,13 @@ -import py, sys +import sys + +import py + +from pypy.annotation import model as annmodel from pypy.annotation.annrpython import RPythonAnnotator +from pypy.rlib.rarithmetic import is_valid_int from pypy.rpython.annlowlevel import annotate_lowlevel_helper, LowLevelAnnotatorPolicy -from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.lltypesystem import llmemory +from pypy.rpython.lltypesystem import llmemory, lltype from pypy.rpython.rtyper import RPythonTyper -from pypy.annotation import model as annmodel -from pypy.rlib.rarithmetic import is_valid_int # ____________________________________________________________ @@ -22,29 +24,29 @@ return s, t def test_cast_pointer(): - S = GcStruct('s', ('x', Signed)) - S1 = GcStruct('s1', ('sub', S)) - S2 = GcStruct('s2', ('sub', S1)) - PS = Ptr(S) - PS2 = Ptr(S2) + S = lltype.GcStruct('s', ('x', lltype.Signed)) + S1 = lltype.GcStruct('s1', ('sub', S)) + S2 = lltype.GcStruct('s2', ('sub', S1)) + PS = lltype.Ptr(S) + PS2 = lltype.Ptr(S2) def lldown(p): - return cast_pointer(PS, p) + return lltype.cast_pointer(PS, p) s, t = ll_rtype(lldown, [annmodel.SomePtr(PS2)]) assert s.ll_ptrtype == PS def llup(p): - return cast_pointer(PS2, p) + return lltype.cast_pointer(PS2, p) s, t = ll_rtype(llup, [annmodel.SomePtr(PS)]) assert s.ll_ptrtype == PS2 def test_runtime_type_info(): - S = GcStruct('s', ('x', Signed), rtti=True) + S = lltype.GcStruct('s', ('x', lltype.Signed), rtti=True) def ll_example(p): - return (runtime_type_info(p), - runtime_type_info(p) == getRuntimeTypeInfo(S)) + return (lltype.runtime_type_info(p), + lltype.runtime_type_info(p) == lltype.getRuntimeTypeInfo(S)) - assert ll_example(malloc(S)) == (getRuntimeTypeInfo(S), True) - s, t = ll_rtype(ll_example, [annmodel.SomePtr(Ptr(S))]) - assert s == annmodel.SomeTuple([annmodel.SomePtr(Ptr(RuntimeTypeInfo)), + assert ll_example(lltype.malloc(S)) == (lltype.getRuntimeTypeInfo(S), True) + s, t = ll_rtype(ll_example, [annmodel.SomePtr(lltype.Ptr(S))]) + assert s == annmodel.SomeTuple([annmodel.SomePtr(lltype.Ptr(lltype.RuntimeTypeInfo)), annmodel.SomeBool()]) from pypy.rpython.test.test_llinterp import interpret, gengraph @@ -53,9 +55,9 @@ policy = LowLevelAnnotatorPolicy() def h_newstruct(): - return malloc(S) - - S = GcStruct('s', ('x', Signed), + return lltype.malloc(S) + + S = lltype.GcStruct('s', ('x', lltype.Signed), adtmeths={"h_newstruct": h_newstruct}) def f(): @@ -63,14 +65,14 @@ s = interpret(f, [], policy=policy) - assert typeOf(s) == Ptr(S) + assert lltype.typeOf(s) == lltype.Ptr(S) def h_alloc(n): - return malloc(A, n) + return lltype.malloc(A, n) def h_length(a): return len(a) - A = GcArray(Signed, + A = lltype.GcArray(lltype.Signed, adtmeths={"h_alloc": h_alloc, "h_length": h_length, 'flag': True}) @@ -80,9 +82,9 @@ a = interpret(f, [], policy=policy) - assert typeOf(a) == Ptr(A) + assert lltype.typeOf(a) == lltype.Ptr(A) assert len(a) == 10 - + def f(): a = A.h_alloc(10) @@ -97,72 +99,72 @@ assert res def test_odd_ints(): - T = GcStruct('T') - S = GcStruct('S', ('t', T)) - PT = Ptr(T) - PS = Ptr(S) + T = lltype.GcStruct('T') + S = lltype.GcStruct('S', ('t', T)) + PT = lltype.Ptr(T) + PS = lltype.Ptr(S) def fn(n): - s = cast_int_to_ptr(PS, n) - assert typeOf(s) == PS - assert cast_ptr_to_int(s) == n - t = cast_pointer(PT, s) - assert typeOf(t) == PT - assert cast_ptr_to_int(t) == n - assert s == cast_pointer(PS, t) + s = lltype.cast_int_to_ptr(PS, n) + assert lltype.typeOf(s) == PS + assert lltype.cast_ptr_to_int(s) == n + t = lltype.cast_pointer(PT, s) + assert lltype.typeOf(t) == PT + assert lltype.cast_ptr_to_int(t) == n + assert s == lltype.cast_pointer(PS, t) interpret(fn, [11521]) def test_odd_ints_opaque(): - T = GcStruct('T') - Q = GcOpaqueType('Q') - PT = Ptr(T) - PQ = Ptr(Q) + T = lltype.GcStruct('T') + Q = lltype.GcOpaqueType('Q') + PT = lltype.Ptr(T) + PQ = lltype.Ptr(Q) def fn(n): - t = cast_int_to_ptr(PT, n) - assert typeOf(t) == PT - assert cast_ptr_to_int(t) == n - o = cast_opaque_ptr(PQ, t) - assert cast_ptr_to_int(o) == n + t = lltype.cast_int_to_ptr(PT, n) + assert lltype.typeOf(t) == PT + assert lltype.cast_ptr_to_int(t) == n + o = lltype.cast_opaque_ptr(PQ, t) + assert lltype.cast_ptr_to_int(o) == n fn(13) interpret(fn, [11521]) -def test_Ptr(): - S = GcStruct('s') +def test_ptr(): + S = lltype.GcStruct('s') def ll_example(): - return malloc(Ptr(S).TO) - + return lltype.malloc(lltype.Ptr(S).TO) + p = interpret(ll_example, []) - assert typeOf(p) == Ptr(S) + assert lltype.typeOf(p) == lltype.Ptr(S) def test_cast_opaque_ptr(): - O = GcOpaqueType('O') - Q = GcOpaqueType('Q') - S = GcStruct('S', ('x', Signed)) + O = lltype.GcOpaqueType('O') + Q = lltype.GcOpaqueType('Q') + S = lltype.GcStruct('S', ('x', lltype.Signed)) def fn(): - s = malloc(S) - o = cast_opaque_ptr(Ptr(O), s) - q = cast_opaque_ptr(Ptr(Q), o) - p = cast_opaque_ptr(Ptr(S), q) + s = lltype.malloc(S) + o = lltype.cast_opaque_ptr(lltype.Ptr(O), s) + q = lltype.cast_opaque_ptr(lltype.Ptr(Q), o) + p = lltype.cast_opaque_ptr(lltype.Ptr(S), q) return p == s res = interpret(fn, []) assert res is True - O1 = OpaqueType('O') - S1 = Struct('S1', ('x', Signed)) - s1 = malloc(S1, immortal=True) + O1 = lltype.OpaqueType('O') + S1 = lltype.Struct('S1', ('x', lltype.Signed)) + s1 = lltype.malloc(S1, immortal=True) def fn1(): - o1 = cast_opaque_ptr(Ptr(O1), s1) - p1 = cast_opaque_ptr(Ptr(S1), o1) + o1 = lltype.cast_opaque_ptr(lltype.Ptr(O1), s1) + p1 = lltype.cast_opaque_ptr(lltype.Ptr(S1), o1) return p1 == s1 res = interpret(fn1, []) assert res is True def test_address(): - S = GcStruct('S') - p1 = nullptr(S) - p2 = malloc(S) - + S = lltype.GcStruct('S') + p1 = lltype.nullptr(S) + p2 = lltype.malloc(S) + def g(p): return bool(llmemory.cast_ptr_to_adr(p)) def fn(n): @@ -177,8 +179,8 @@ assert res is True def test_cast_adr_to_int(): - S = Struct('S') - p = malloc(S, immortal=True) + S = lltype.Struct('S') + p = lltype.malloc(S, immortal=True) def fn(n): a = llmemory.cast_ptr_to_adr(p) if n == 2: @@ -190,7 +192,7 @@ res = interpret(fn, [2]) assert is_valid_int(res) - assert res == cast_ptr_to_int(p) + assert res == lltype.cast_ptr_to_int(p) # res = interpret(fn, [4]) assert isinstance(res, llmemory.AddressAsInt) @@ -199,60 +201,60 @@ res = interpret(fn, [6]) assert is_valid_int(res) from pypy.rpython.lltypesystem import rffi - assert res == rffi.cast(Signed, p) + assert res == rffi.cast(lltype.Signed, p) def test_flavored_malloc(): - T = GcStruct('T', ('y', Signed)) + T = lltype.GcStruct('T', ('y', lltype.Signed)) def fn(n): - p = malloc(T, flavor='gc') + p = lltype.malloc(T, flavor='gc') p.y = n return p.y res = interpret(fn, [232]) assert res == 232 - S = Struct('S', ('x', Signed)) + S = lltype.Struct('S', ('x', lltype.Signed)) def fn(n): - p = malloc(S, flavor='raw') + p = lltype.malloc(S, flavor='raw') p.x = n result = p.x - free(p, flavor='raw') - return n + lltype.free(p, flavor='raw') + return result res = interpret(fn, [23]) assert res == 23 - S = Struct('S', ('x', Signed)) + S = lltype.Struct('S', ('x', lltype.Signed)) def fn(n): - p = malloc(S, flavor='raw', track_allocation=False) + p = lltype.malloc(S, flavor='raw', track_allocation=False) p.x = n result = p.x - return n + return result res = interpret(fn, [23]) assert res == 23 - S = Struct('S', ('x', Signed)) + S = lltype.Struct('S', ('x', lltype.Signed)) def fn(n): - p = malloc(S, flavor='raw', track_allocation=False) + p = lltype.malloc(S, flavor='raw', track_allocation=False) p.x = n result = p.x - free(p, flavor='raw', track_allocation=False) - return n + lltype.free(p, flavor='raw', track_allocation=False) + return result res = interpret(fn, [23]) assert res == 23 def test_memoryerror(): - A = Array(Signed) + A = lltype.Array(lltype.Signed) def fn(n): try: - a = malloc(A, n, flavor='raw') + a = lltype.malloc(A, n, flavor='raw') except MemoryError: return -42 else: res = len(a) - free(a, flavor='raw') + lltype.free(a, flavor='raw') return res res = interpret(fn, [123]) @@ -263,23 +265,23 @@ def test_call_ptr(): - def f(x,y,z): + def f(x, y, z): return x+y+z - FTYPE = FuncType([Signed, Signed, Signed], Signed) - fptr = functionptr(FTYPE, "f", _callable=f) + FTYPE = lltype.FuncType([lltype.Signed, lltype.Signed, lltype.Signed], lltype.Signed) + fptr = lltype.functionptr(FTYPE, "f", _callable=f) - def g(x,y,z): + def g(x, y, z): tot = 0 - tot += fptr(x,y,z) - tot += fptr(*(x,y,z)) - tot += fptr(x, *(x,z)) + tot += fptr(x, y, z) + tot += fptr(*(x, y, z)) + tot += fptr(x, *(x, z)) return tot - res = interpret(g, [1,2,4]) - assert res == g(1,2,4) + res = interpret(g, [1, 2, 4]) + assert res == g(1, 2, 4) - def wrong(x,y): - fptr(*(x,y)) + def wrong(x, y): + fptr(*(x, y)) py.test.raises(TypeError, "interpret(wrong, [1, 2])") @@ -288,8 +290,8 @@ def f(): return str(p) - S = GcStruct('S', ('x', Signed)) - p = malloc(S) + S = lltype.GcStruct('S', ('x', lltype.Signed)) + p = lltype.malloc(S) res = interpret(f, []) assert res.chars[0] == '0' @@ -297,10 +299,10 @@ def test_first_subfield_access_is_cast_pointer(): - B = GcStruct("B", ('x', Signed)) - C = GcStruct("C", ('super', B), ('y', Signed)) + B = lltype.GcStruct("B", ('x', lltype.Signed)) + C = lltype.GcStruct("C", ('super', B), ('y', lltype.Signed)) def f(): - c = malloc(C) + c = lltype.malloc(C) c.super.x = 1 c.y = 2 return c.super.x + c.y @@ -311,73 +313,73 @@ graphsum = summary(graph) assert 'getsubstruct' not in graphsum assert 'cast_pointer' in graphsum - - + + def test_interior_ptr(): - S = Struct("S", ('x', Signed)) - T = GcStruct("T", ('s', S)) + S = lltype.Struct("S", ('x', lltype.Signed)) + T = lltype.GcStruct("T", ('s', S)) def f(): - t = malloc(T) + t = lltype.malloc(T) t.s.x = 1 return t.s.x res = interpret(f, []) assert res == 1 def test_interior_ptr_with_index(): - S = Struct("S", ('x', Signed)) - T = GcArray(S) + S = lltype.Struct("S", ('x', lltype.Signed)) + T = lltype.GcArray(S) def f(): - t = malloc(T, 1) + t = lltype.malloc(T, 1) t[0].x = 1 return t[0].x res = interpret(f, []) assert res == 1 def test_interior_ptr_with_field_and_index(): - S = Struct("S", ('x', Signed)) - T = GcStruct("T", ('items', Array(S))) + S = lltype.Struct("S", ('x', lltype.Signed)) + T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(): - t = malloc(T, 1) + t = lltype.malloc(T, 1) t.items[0].x = 1 return t.items[0].x res = interpret(f, []) assert res == 1 def test_interior_ptr_with_index_and_field(): - S = Struct("S", ('x', Signed)) - T = Struct("T", ('s', S)) - U = GcArray(T) + S = lltype.Struct("S", ('x', lltype.Signed)) + T = lltype.Struct("T", ('s', S)) + U = lltype.GcArray(T) def f(): - u = malloc(U, 1) + u = lltype.malloc(U, 1) u[0].s.x = 1 return u[0].s.x res = interpret(f, []) assert res == 1 def test_interior_ptr_len(): - S = Struct("S", ('x', Signed)) - T = GcStruct("T", ('items', Array(S))) + S = lltype.Struct("S", ('x', lltype.Signed)) + T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(): - t = malloc(T, 1) + t = lltype.malloc(T, 1) return len(t.items) res = interpret(f, []) assert res == 1 def test_interior_ptr_with_setitem(): - T = GcStruct("T", ('s', Array(Signed))) + T = lltype.GcStruct("T", ('s', lltype.Array(lltype.Signed))) def f(): - t = malloc(T, 1) + t = lltype.malloc(T, 1) t.s[0] = 1 return t.s[0] res = interpret(f, []) assert res == 1 - -def test_isinstance_Ptr(): - S = GcStruct("S", ('x', Signed)) + +def test_isinstance_ptr(): + S = lltype.GcStruct("S", ('x', lltype.Signed)) def f(n): - x = isinstance(Signed, Ptr) - return x + (typeOf(x) is Ptr(S)) + len(n) + x = isinstance(lltype.Signed, lltype.Ptr) + return x + (lltype.typeOf(x) is lltype.Ptr(S)) + len(n) def lltest(): f([]) return f([1]) @@ -385,10 +387,10 @@ assert s.is_constant() == False def test_staticadtmeths(): - ll_func = staticAdtMethod(lambda x: x + 42) - S = GcStruct('S', adtmeths={'ll_func': ll_func}) + ll_func = lltype.staticAdtMethod(lambda x: x + 42) + S = lltype.GcStruct('S', adtmeths={'ll_func': ll_func}) def f(): - return malloc(S).ll_func(5) + return lltype.malloc(S).ll_func(5) s, t = ll_rtype(f, []) From noreply at buildbot.pypy.org Mon Oct 8 13:14:55 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 13:14:55 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: killed shared pypy Message-ID: <20121008111455.9BE911C0274@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57896:92d6a51dfe18 Date: 2012-10-08 13:14 +0200 http://bitbucket.org/pypy/pypy/changeset/92d6a51dfe18/ Log: killed shared pypy diff --git a/pypy/translator/c/dlltool.py b/pypy/translator/c/dlltool.py --- a/pypy/translator/c/dlltool.py +++ b/pypy/translator/c/dlltool.py @@ -1,5 +1,4 @@ -from pypy.translator.driver import TranslationDriver from pypy.translator.c.genc import CBuilder from pypy.rpython.typesystem import getfunctionptr from pypy.translator.tool.cbuild import ExternalCompilationInfo @@ -39,18 +38,3 @@ def get_entry_point(self, isolated=False): return self.so_name - -class DLLDef(object): - def __init__(self, name, functions=[], policy=None, config=None): - self.name = name - self.functions = functions # [(function, annotation), ...] - self.driver = TranslationDriver(config=config) - self.driver.setup_library(self, policy=policy) - - def compile(self): - self.driver.proceed(['compile_c']) - return self.driver.c_entryp - - def getcbuilder(self, translator, config): - return CLibraryBuilder(translator, None, config, - functions=self.functions, name=self.name) diff --git a/pypy/translator/c/test/test_dlltool.py b/pypy/translator/c/test/test_dlltool.py deleted file mode 100644 --- a/pypy/translator/c/test/test_dlltool.py +++ /dev/null @@ -1,31 +0,0 @@ - -from pypy.translator.c.dlltool import DLLDef -from ctypes import CDLL -import py - -class TestDLLTool(object): - def test_basic(self): - # XXX abusing get_entry_point to get a so name makes no sense - def f(x): - return x - - def b(x): - return x + 2 - - d = DLLDef('lib', [(f, [int]), (b, [int])]) - so = d.compile() - dll = CDLL(str(so)) - assert dll.pypy_g_f(3) == 3 - assert dll.pypy_g_b(10) == 12 - - def test_split_criteria(self): - def f(x): - return x - - def b(x): - return x + 2 - - d = DLLDef('lib', [(f, [int]), (b, [int])]) - so = d.compile() - dirpath = py.path.local(so).dirpath() - assert dirpath.join('pypy_translator_c_test_test_dlltool.c').check() diff --git a/pypy/translator/goal/sharedpypy.py b/pypy/translator/goal/sharedpypy.py deleted file mode 100644 --- a/pypy/translator/goal/sharedpypy.py +++ /dev/null @@ -1,58 +0,0 @@ - -import sys, pdb, traceback -from pypy.translator.c.dlltool import DLLDef -from pypy.config.translationoption import get_combined_translation_config -from pypy.rpython.lltypesystem.rffi import charp2str, CCHARP, VOIDP -from pypy.tool.option import make_objspace -from pypy.interpreter.error import OperationError -from pypy.config.pypyoption import pypy_optiondescription, set_pypy_opt_level -from pypy.translator.goal.ann_override import PyPyAnnotatorPolicy -from pypy.config.translationoption import set_opt_level -from pypy.config.pypyoption import enable_allworkingmodules - -OVERRIDES = { - 'translation.debug': False, -} - -def main(argv): - config = get_combined_translation_config(pypy_optiondescription, - overrides=OVERRIDES, translating=True) - config.objspace.nofaking = True - config.objspace.compiler = "ast" - config.translating = True - set_opt_level(config, '1') - set_pypy_opt_level(config, '1') - enable_allworkingmodules(config) - - space = make_objspace(config) - policy = PyPyAnnotatorPolicy(single_space=space) - - def interpret(source, context): - source = charp2str(source) - w_dict = space.newdict() - try: - ec = space.getexecutioncontext() - pycode = ec.compiler.compile(source, 'source', 'exec', 0) - pycode.exec_code(space, w_dict, w_dict) - except OperationError, e: - print "OperationError:" - print " operror-type: " + e.w_type.getname(space) - print " operror-value: " + space.str_w(space.str(e.get_w_value(space))) - return 1 - return 0 - - dll = DLLDef('pypylib', [(interpret, [CCHARP, VOIDP])], policy=policy, - config=config) - exe_name = dll.compile() - -if __name__ == '__main__': - try: - main(sys.argv) - except KeyboardInterrupt: - raise - except: - e, v, tb = sys.exc_info() - traceback.print_tb(tb) - print e, v - pdb.post_mortem(tb) - From noreply at buildbot.pypy.org Mon Oct 8 13:20:11 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 13:20:11 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (fijal, arigo) fix secondary entrypoints Message-ID: <20121008112011.BA9EE1C0274@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57897:576f96610252 Date: 2012-10-08 13:17 +0200 http://bitbucket.org/pypy/pypy/changeset/576f96610252/ Log: (fijal, arigo) fix secondary entrypoints diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py --- a/pypy/translator/driver.py +++ b/pypy/translator/driver.py @@ -467,24 +467,20 @@ if translator.annotator is not None: translator.frozen = True - if self.libdef is not None: - cbuilder = self.libdef.getcbuilder(self.translator, self.config) - self.standalone = False - standalone = False + standalone = self.standalone + + if standalone: + from pypy.translator.c.genc import CStandaloneBuilder + cbuilder = CStandaloneBuilder(self.translator, self.entry_point, + config=self.config, + secondary_entrypoints=self.secondary_entrypoints) else: - standalone = self.standalone - - if standalone: - from pypy.translator.c.genc import CStandaloneBuilder - cbuilder = CStandaloneBuilder(self.translator, self.entry_point, - config=self.config, - secondary_entrypoints=self.secondary_entrypoints) - else: - from pypy.translator.c.dlltool import CLibraryBuilder - cbuilder = CLibraryBuilder(self.translator, self.entry_point, - functions=[(self.entry_point, None)], - name='lib', - config=self.config) + from pypy.translator.c.dlltool import CLibraryBuilder + functions = [(self.entry_point, None)] + self.secondary_entrypoints + cbuilder = CLibraryBuilder(self.translator, self.entry_point, + functions=functions, + name='libtesting', + config=self.config) if not standalone: # xxx more messy cbuilder.modulename = self.extmod_name database = cbuilder.build_database() From noreply at buildbot.pypy.org Mon Oct 8 13:20:13 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 13:20:13 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: oops Message-ID: <20121008112013.050A41C0274@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57898:f0d6e8dc4ba0 Date: 2012-10-08 13:19 +0200 http://bitbucket.org/pypy/pypy/changeset/f0d6e8dc4ba0/ Log: oops diff --git a/pypy/translator/interactive.py b/pypy/translator/interactive.py --- a/pypy/translator/interactive.py +++ b/pypy/translator/interactive.py @@ -20,8 +20,9 @@ # hook into driver events self.driver_setup = False + policy = kwds.pop('policy', None) self.update_options(argtypes, kwds) - self.ensure_setup(argtypes, kwds.pop('policy', None)) + self.ensure_setup(argtypes, policy) # for t.view() to work just after construction graph = self.context.buildflowgraph(entry_point) self.context._prebuilt_graphs[entry_point] = graph From noreply at buildbot.pypy.org Mon Oct 8 13:24:10 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 13:24:10 +0200 (CEST) Subject: [pypy-commit] pypy default: This is still hopeless, but attempt to open all db-4.X for X in '56789'. Message-ID: <20121008112410.28A091C0274@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57899:35840dd84c57 Date: 2012-10-08 13:23 +0200 http://bitbucket.org/pypy/pypy/changeset/35840dd84c57/ Log: This is still hopeless, but attempt to open all db-4.X for X in '56789'. diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,11 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - libpath = ctypes.util.find_library('db-4.5') - if not libpath: + for c in '56789': + libpath = ctypes.util.find_library('db-4.%s' % c) + if libpath: + break + else: raise ImportError("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' From noreply at buildbot.pypy.org Mon Oct 8 13:34:50 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 13:34:50 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: finish fixing test_genc.py Message-ID: <20121008113450.091FB1C0B7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57900:093ba824b6ab Date: 2012-10-08 13:34 +0200 http://bitbucket.org/pypy/pypy/changeset/093ba824b6ab/ Log: finish fixing test_genc.py diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -12,16 +12,25 @@ def compile(fn, argtypes, view=False, gcpolicy="none", backendopt=True, annotatorpolicy=None): argtypes_unroll = unrolling_iterable(enumerate(argtypes)) + + for argtype in argtypes: + if argtype not in [int, float, str, bool]: + raise Exception("Unsupported argtype, %r" % (argtype,)) def entry_point(argv): args = () for i, argtype in argtypes_unroll: if argtype is int: args = args + (int(argv[i + 1]),) + if argtype is bool: + if argv[i + 1] == 'True': + args = args + (True,) + else: + assert argv[i + 1] == 'False' + args = args + (False,) elif argtype is float: args = args + (float(argv[i + 1]),) else: - assert argtype is str args = args + (argv[i + 1],) res = fn(*args) print "THE RESULT IS:", res, ";" @@ -335,7 +344,7 @@ t.compile_c() if py.test.config.option.view: t.view() - assert ' BarStruct ' in t.driver.cbuilder.c_source_filename.read() + assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'BarStruct') free(foo, flavor="raw") def test_recursive_llhelper(): @@ -399,7 +408,8 @@ t.rtype() t.context._graphof(foobar_fn).inhibit_tail_call = True t.source_c() - lines = t.driver.cbuilder.c_source_filename.readlines() + lines = t.driver.cbuilder.c_source_filename.join('..', + 'pypy_translator_c_test_test_genc.c').readlines() for i, line in enumerate(lines): if '= pypy_g_foobar_fn' in line: break From noreply at buildbot.pypy.org Mon Oct 8 13:39:30 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 13:39:30 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, fijal) make getcompiled work Message-ID: <20121008113930.D6C621C027A@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57901:76215c02c5bf Date: 2012-10-08 13:38 +0200 http://bitbucket.org/pypy/pypy/changeset/76215c02c5bf/ Log: (alex, fijal) make getcompiled work diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -1,5 +1,6 @@ +import ctypes + import py -import ctypes from pypy.rpython.lltypesystem.lltype import * from pypy.translator.translator import TranslationContext, graphof @@ -9,6 +10,7 @@ from pypy.tool.nullpath import NullPyPathLocal from pypy.rlib.unroll import unrolling_iterable + def compile(fn, argtypes, view=False, gcpolicy="none", backendopt=True, annotatorpolicy=None): argtypes_unroll = unrolling_iterable(enumerate(argtypes)) @@ -16,26 +18,26 @@ for argtype in argtypes: if argtype not in [int, float, str, bool]: raise Exception("Unsupported argtype, %r" % (argtype,)) - + def entry_point(argv): args = () for i, argtype in argtypes_unroll: if argtype is int: - args = args + (int(argv[i + 1]),) - if argtype is bool: + args += (int(argv[i + 1]),) + elif argtype is bool: if argv[i + 1] == 'True': - args = args + (True,) + args += (True,) else: assert argv[i + 1] == 'False' - args = args + (False,) + args += (False,) elif argtype is float: - args = args + (float(argv[i + 1]),) + args += (float(argv[i + 1]),) else: - args = args + (argv[i + 1],) + args += (argv[i + 1],) res = fn(*args) print "THE RESULT IS:", res, ";" return 0 - + t = Translation(entry_point, None, gc=gcpolicy, backend="c", policy=annotatorpolicy) if not backendopt: diff --git a/pypy/translator/c/test/test_typed.py b/pypy/translator/c/test/test_typed.py --- a/pypy/translator/c/test/test_typed.py +++ b/pypy/translator/c/test/test_typed.py @@ -7,11 +7,11 @@ from py.test import raises -from pypy import conftest from pypy.rlib.objectmodel import compute_hash, current_object_addr_as_int from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask, longlongmask from pypy.rpython.lltypesystem import rffi, lltype from pypy.translator.test import snippet +from pypy.translator.c.test.test_genc import compile from pypy.translator.translator import TranslationContext @@ -39,15 +39,8 @@ builder.compile() return builder.get_entry_point() - def getcompiled(self, func, argtypes=None, view=False): - from pypy.translator.transform import insert_ll_stackcheck - t = self.annotatefunc(func, argtypes) - self.process(t) - if view or conftest.option.view: - t.view() - t.checkgraphs() - insert_ll_stackcheck(t) - return self.compilefunc(t, func) + def getcompiled(self, func, argtypes=[], view=False): + return compile(func, argtypes, view=view) def process(self, t): t.buildrtyper().specialize() From noreply at buildbot.pypy.org Mon Oct 8 13:47:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 13:47:34 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: (fijal, arigo) Message-ID: <20121008114734.1FA0E1C027A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: numpypy-complex2 Changeset: r57902:3acbfe0aaf8b Date: 2012-10-08 13:47 +0200 http://bitbucket.org/pypy/pypy/changeset/3acbfe0aaf8b/ Log: (fijal, arigo) - speed up test_complex - Python 2.5 compatibility 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 @@ -1,6 +1,7 @@ +from __future__ import with_statement +import sys from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest -from math import isnan, isinf, copysign -from sys import version_info, builtin_module_names +from pypy.rlib.rfloat import isnan, isinf, copysign from pypy.rlib.rcomplex import c_pow from pypy.interpreter.error import OperationError @@ -34,7 +35,7 @@ # occur). if not a and not b and not isnumpy: # only check it if we are running on top of CPython >= 2.6 - if version_info >= (2, 6) and copysign(1., a) != copysign(1., b): + if sys.version_info >= (2, 6) and copysign(1., a) != copysign(1., b): raise AssertionError( msg + \ 'zero has wrong sign: expected %r, got %r' % (a, b)) @@ -57,26 +58,50 @@ '%r and %r are not sufficiently close, %g > %g' %\ (a, b, absolute_error, max(abs_err, rel_err*abs(a)))) +def parse_testfile(fname): + """Parse a file with test values + + Empty lines or lines starting with -- are ignored + yields id, fn, arg_real, arg_imag, exp_real, exp_imag + """ + with open(fname) as fp: + for line in fp: + # skip comment lines and blank lines + if line.startswith('--') or not line.strip(): + continue + + lhs, rhs = line.split('->') + id, fn, arg_real, arg_imag = lhs.split() + rhs_pieces = rhs.split() + exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1] + flags = rhs_pieces[2:] + + yield (id, fn, + float(arg_real), float(arg_imag), + float(exp_real), float(exp_imag), + flags + ) + class AppTestUfuncs(BaseNumpyAppTest): def setup_class(cls): import os BaseNumpyAppTest.setup_class.im_func(cls) fname128 = os.path.join(os.path.dirname(__file__), 'complex_testcases.txt') fname64 = os.path.join(os.path.dirname(__file__), 'complex64_testcases.txt') - cls.w_testcases128 = cls.space.wrap(fname128) - cls.w_testcases64 = cls.space.wrap(fname64) + cls.w_testcases128 = cls.space.wrap(list(parse_testfile(fname128))) + cls.w_testcases64 = cls.space.wrap(list(parse_testfile(fname64))) def cls_c_pow(self, *args): try: retVal = c_pow(*args) return retVal - except ValueError as e: + except ValueError, e: raise OperationError(cls.space.w_ValueError, cls.space.wrap(e.message)) cls.w_c_pow = cls.space.wrap(cls_c_pow) cls.w_runAppDirect = cls.space.wrap(option.runappdirect) cls.w_isWindows = cls.space.wrap(os.name == 'nt') def cls_rAlmostEqual(self, *args, **kwargs): - if '__pypy__' not in builtin_module_names: + if '__pypy__' not in sys.builtin_module_names: kwargs['isnumpy'] = True return rAlmostEqual(*args, **kwargs) cls.w_rAlmostEqual = cls.space.wrap(cls_rAlmostEqual) @@ -237,7 +262,6 @@ cmpl(nan, 5.), cmpl(5., nan), cmpl(nan, nan), ] b = expm1(array(a,dtype=c)) - got_err = False for i in range(len(a)): try: res = cmath.exp(a[i]) - 1. @@ -251,20 +275,14 @@ res = cmpl(nan, nan) msg = 'result of expm1(%r(%r)) got %r expected %r\n ' % \ (c,a[i], b[i], res) - try: - # cast untranslated boxed results to float, - # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) - self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) - self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - except AssertionError as e: - print e.message - got_err = True - if got_err: - raise AssertionError('Errors were printed to stdout') + # cast untranslated boxed results to float, + # does no harm when translated + t1 = float(res.real) + t2 = float(b[i].real) + self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) + t1 = float(res.imag) + t2 = float(b[i].imag) + self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_not_complex(self): from _numpypy import (radians, deg2rad, degrees, rad2deg, @@ -315,7 +333,6 @@ cmpl(ninf, ninf), cmpl(5., inf), cmpl(5., ninf), cmpl(nan, 5.), cmpl(5., nan), cmpl(nan, nan), ], dtype=c) - got_err = False for p in (3, -1, 10000, 2.3, -10000, 10+3j): b = power(a, p) for i in range(len(a)): @@ -330,18 +347,12 @@ r = (nan, nan) msg = 'result of %r(%r)**%r got %r expected %r\n ' % \ (c,a[i], p, b[i], r) - try: - t1 = float(r[0]) - t2 = float(b[i].real) - self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(r[1]) - t2 = float(b[i].imag) - self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - except AssertionError as e: - print e.message - got_err = True - if got_err: - raise AssertionError('Errors were printed to stdout') + t1 = float(r[0]) + t2 = float(b[i].real) + self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) + t1 = float(r[1]) + t2 = float(b[i].imag) + self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_conjugate(self): from _numpypy import conj, conjugate, complex128, complex64 @@ -385,7 +396,6 @@ ] for c,rel_err in ((complex128, 5e-323), (complex64, 1e-7)): b = log2(array(a,dtype=c)) - got_err = False for i in range(len(a)): try: _res = cmath.log(a[i]) @@ -396,21 +406,16 @@ res = cmpl(ninf, 0) msg = 'result of log2(%r(%r)) got %r expected %r\n ' % \ (c,a[i], b[i], res) - try: - # cast untranslated boxed results to float, - # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) - self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) - self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - except AssertionError as e: - print e.message - got_err = True + # cast untranslated boxed results to float, + # does no harm when translated + t1 = float(res.real) + t2 = float(b[i].real) + self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) + t1 = float(res.imag) + t2 = float(b[i].imag) + self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) for c,rel_err in ((complex128, 5e-323), (complex64, 1e-7)): b = log1p(array(a,dtype=c)) - got_err = False for i in range(len(a)): try: #be careful, normal addition wipes out +-0j @@ -421,20 +426,14 @@ res = cmpl(ninf, 0) msg = 'result of log1p(%r(%r)) got %r expected %r\n ' % \ (c,a[i], b[i], res) - try: - # cast untranslated boxed results to float, - # does no harm when translated - t1 = float(res.real) - t2 = float(b[i].real) - self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - t1 = float(res.imag) - t2 = float(b[i].imag) - self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) - except AssertionError as e: - print e.message - got_err = True - if got_err: - raise AssertionError('Errors were printed to stdout') + # cast untranslated boxed results to float, + # does no harm when translated + t1 = float(res.real) + t2 = float(b[i].real) + self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) + t1 = float(res.imag) + t2 = float(b[i].imag) + self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_logical_ops(self): from _numpypy import logical_and, logical_or, logical_xor, logical_not @@ -540,37 +539,15 @@ def test_math(self): if self.isWindows: skip('windows does not support c99 complex') - import _numpypy as np + import sys + import _numpypy as np rAlmostEqual = self.rAlmostEqual - def parse_testfile(fname): - """Parse a file with test values - - Empty lines or lines starting with -- are ignored - yields id, fn, arg_real, arg_imag, exp_real, exp_imag - """ - with open(fname) as fp: - for line in fp: - # skip comment lines and blank lines - if line.startswith('--') or not line.strip(): - continue - - lhs, rhs = line.split('->') - id, fn, arg_real, arg_imag = lhs.split() - rhs_pieces = rhs.split() - exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1] - flags = rhs_pieces[2:] - - yield (id, fn, - float(arg_real), float(arg_imag), - float(exp_real), float(exp_imag), - flags - ) for complex_, abs_err, testcases in (\ (np.complex128, 5e-323, self.testcases128), # (np.complex64, 5e-32, self.testcases64), ): - for id, fn, ar, ai, er, ei, flags in parse_testfile(testcases): + for id, fn, ar, ai, er, ei, flags in testcases: arg = complex_(complex(ar, ai)) expected = (er, ei) if fn.startswith('acos'): @@ -613,5 +590,5 @@ abs_err=real_abs_err, msg=error_message) rAlmostEqual(float(expected[1]), float(actual[1]), msg=error_message) - - + sys.stderr.write('.') + sys.stderr.write('\n') 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 @@ -23,7 +23,7 @@ log2e = 1. / log2 def isfinite(d): - return not math.isinf(d) and not math.isnan(d) + return not rfloat.isinf(d) and not rfloat.isnan(d) def simple_unary_op(func): specialize.argtype(1)(func) @@ -671,17 +671,17 @@ @simple_binary_op def fmax(self, v1, v2): - if math.isnan(v2): + if rfloat.isnan(v2): return v1 - elif math.isnan(v1): + elif rfloat.isnan(v1): return v2 return max(v1, v2) @simple_binary_op def fmin(self, v1, v2): - if math.isnan(v2): + if rfloat.isnan(v2): return v1 - elif math.isnan(v1): + elif rfloat.isnan(v1): return v2 return min(v1, v2) @@ -1219,9 +1219,9 @@ @complex_unary_op def reciprocal(self, v): - if math.isinf(v[1]) and math.isinf(v[0]): + if rfloat.isinf(v[1]) and rfloat.isinf(v[0]): return rfloat.NAN, rfloat.NAN - if math.isinf(v[0]): + if rfloat.isinf(v[0]): return (rfloat.copysign(0., v[0]), rfloat.copysign(0., -v[1])) a2 = v[0]*v[0] + v[1]*v[1] @@ -1248,13 +1248,13 @@ @complex_unary_op def exp(self, v): - if math.isinf(v[1]): - if math.isinf(v[0]): + if rfloat.isinf(v[1]): + if rfloat.isinf(v[0]): if v[0] < 0: return 0., 0. return rfloat.INFINITY, rfloat.NAN elif (isfinite(v[0]) or \ - (math.isinf(v[0]) and v[0] > 0)): + (rfloat.isinf(v[0]) and v[0] > 0)): return rfloat.NAN, rfloat.NAN try: return rcomplex.c_exp(*v) @@ -1276,13 +1276,13 @@ def expm1(self, v): #Duplicate exp() so in the future it will be easier # to implement seterr - if math.isinf(v[1]): - if math.isinf(v[0]): + if rfloat.isinf(v[1]): + if rfloat.isinf(v[0]): if v[0] < 0: return -1., 0. return rfloat.NAN, rfloat.NAN elif (isfinite(v[0]) or \ - (math.isinf(v[0]) and v[0] > 0)): + (rfloat.isinf(v[0]) and v[0] > 0)): return rfloat.NAN, rfloat.NAN try: res = rcomplex.c_exp(*v) @@ -1295,29 +1295,29 @@ @complex_unary_op def sin(self, v): - if math.isinf(v[0]): + if rfloat.isinf(v[0]): if v[1] == 0.: return rfloat.NAN, 0. if isfinite(v[1]): return rfloat.NAN, rfloat.NAN - elif not math.isnan(v[1]): + elif not rfloat.isnan(v[1]): return rfloat.NAN, rfloat.INFINITY return rcomplex.c_sin(*v) @complex_unary_op def cos(self, v): - if math.isinf(v[0]): + if rfloat.isinf(v[0]): if v[1] == 0.: return rfloat.NAN, 0.0 if isfinite(v[1]): return rfloat.NAN, rfloat.NAN - elif not math.isnan(v[1]): + elif not rfloat.isnan(v[1]): return rfloat.INFINITY, rfloat.NAN return rcomplex.c_cos(*v) @complex_unary_op def tan(self, v): - if math.isinf(v[0]) and isfinite(v[1]): + if rfloat.isinf(v[0]) and isfinite(v[1]): return rfloat.NAN, rfloat.NAN return rcomplex.c_tan(*v) @@ -1342,29 +1342,29 @@ @complex_unary_op def sinh(self, v): - if math.isinf(v[1]): + if rfloat.isinf(v[1]): if isfinite(v[0]): if v[0] == 0.0: return 0.0, rfloat.NAN return rfloat.NAN, rfloat.NAN - elif not math.isnan(v[0]): + elif not rfloat.isnan(v[0]): return rfloat.INFINITY, rfloat.NAN return rcomplex.c_sinh(*v) @complex_unary_op def cosh(self, v): - if math.isinf(v[1]): + if rfloat.isinf(v[1]): if isfinite(v[0]): if v[0] == 0.0: return rfloat.NAN, 0.0 return rfloat.NAN, rfloat.NAN - elif not math.isnan(v[0]): + elif not rfloat.isnan(v[0]): return rfloat.INFINITY, rfloat.NAN return rcomplex.c_cosh(*v) @complex_unary_op def tanh(self, v): - if math.isinf(v[1]) and isfinite(v[0]): + if rfloat.isinf(v[1]) and isfinite(v[0]): return rfloat.NAN, rfloat.NAN return rcomplex.c_tanh(*v) diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py --- a/pypy/rlib/rcomplex.py +++ b/pypy/rlib/rcomplex.py @@ -1,5 +1,5 @@ import math -from math import copysign, fabs, pi, e +from math import fabs, pi, e from pypy.rlib.rfloat import copysign, asinh, log1p, isinf, isnan from pypy.rlib.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN from pypy.rlib.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG From noreply at buildbot.pypy.org Mon Oct 8 13:48:03 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 13:48:03 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, fijal) make test_typed start to pass Message-ID: <20121008114803.990341C027A@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57903:0f19853384ee Date: 2012-10-08 13:47 +0200 http://bitbucket.org/pypy/pypy/changeset/0f19853384ee/ Log: (alex, fijal) make test_typed start to pass diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -2,13 +2,15 @@ import py +from pypy.rlib.entrypoint import entrypoint +from pypy.rlib.unroll import unrolling_iterable +from pypy.rpython.lltypesystem import lltype from pypy.rpython.lltypesystem.lltype import * -from pypy.translator.translator import TranslationContext, graphof +from pypy.rpython.lltypesystem.rstr import STR +from pypy.tool.nullpath import NullPyPathLocal from pypy.translator.c import genc from pypy.translator.interactive import Translation -from pypy.rlib.entrypoint import entrypoint -from pypy.tool.nullpath import NullPyPathLocal -from pypy.rlib.unroll import unrolling_iterable +from pypy.translator.translator import TranslationContext, graphof def compile(fn, argtypes, view=False, gcpolicy="none", backendopt=True, @@ -58,14 +60,18 @@ assert stdout.endswith(' ;\n') pos = stdout.rindex('THE RESULT IS: ') res = stdout[pos + len('THE RESULT IS: '):-3] - if ll_res == Signed: + if ll_res == lltype.Signed: return int(res) - elif ll_res == Char: + elif ll_res == lltype.Bool: + return bool(int(res)) + elif ll_res == lltype.Char: assert len(res) == 1 return res - elif ll_res == Float: + elif ll_res == lltype.Float: return float(res) - elif ll_res == Void: + elif ll_res == lltype.Ptr(STR): + return res + elif ll_res == lltype.Void: return None raise NotImplementedError("parsing %s" % (ll_res,)) f.__name__ = fn.__name__ diff --git a/pypy/translator/c/test/test_typed.py b/pypy/translator/c/test/test_typed.py --- a/pypy/translator/c/test/test_typed.py +++ b/pypy/translator/c/test/test_typed.py @@ -54,8 +54,11 @@ assert set_attr() == 2 def test_inheritance2(self): - inheritance2 = self.getcompiled(snippet.inheritance2) - assert inheritance2() == ((-12, -12.0), (3, 12.3)) + def wrap(): + res = snippet.inheritance2() + return res == ((-12, -12.0), (3, 12.3)) + fn = self.getcompiled(wrap) + assert fn() def test_factorial2(self): factorial2 = self.getcompiled(snippet.factorial2, [int]) @@ -78,9 +81,11 @@ assert nested_whiles(5, 3) == '!!!!!' def test_call_unpack_56(self): - call_unpack_56 = self.getcompiled(snippet.call_unpack_56, []) - result = call_unpack_56() - assert result == (2, 5, 6) + def wrap(): + res = snippet.call_unpack_56() + return res == (2, 5, 6) + fn = self.getcompiled(wrap) + assert fn() def test_class_defaultattr(self): class K: @@ -97,9 +102,9 @@ z = x, y while x: x = x - 1 - return z + return z == (6, 'a') fn = self.getcompiled(tuple_repr, [int, str]) - assert fn(6, 'a') == (6, 'a') + assert fn() def test_classattribute(self): fn = self.getcompiled(snippet.classattribute, [int]) From noreply at buildbot.pypy.org Mon Oct 8 13:55:18 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 13:55:18 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: get another test running Message-ID: <20121008115518.E70031C0BC5@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57904:1e1a6ece3305 Date: 2012-10-08 13:54 +0200 http://bitbucket.org/pypy/pypy/changeset/1e1a6ece3305/ Log: get another test running diff --git a/pypy/translator/c/test/test_backendoptimized.py b/pypy/translator/c/test/test_backendoptimized.py --- a/pypy/translator/c/test/test_backendoptimized.py +++ b/pypy/translator/c/test/test_backendoptimized.py @@ -1,8 +1,8 @@ -import py +from pypy import conftest +from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong +from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.c.test.test_typed import TestTypedTestCase as _TestTypedTestCase -from pypy.translator.backendopt.all import backend_optimizations -from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong -from pypy import conftest + class TestTypedOptimizedTestCase(_TestTypedTestCase): @@ -24,7 +24,6 @@ assert f(False) == 456 def test__del__(self): - import os class B(object): pass b = B() @@ -50,7 +49,7 @@ res = fn(5) # translated function loses its last reference earlier assert res == 6 - + def test_del_inheritance(self): class State: pass diff --git a/pypy/translator/c/test/test_typed.py b/pypy/translator/c/test/test_typed.py --- a/pypy/translator/c/test/test_typed.py +++ b/pypy/translator/c/test/test_typed.py @@ -304,10 +304,10 @@ # that can't be converted to a PyListObject def wrapper(): lst = snippet.call_five() - return len(lst), lst[0] + return (len(lst), lst[0]) == (1, 5) call_five = self.getcompiled(wrapper) result = call_five() - assert result == (1, 5) + assert result def test_get_set_del_slice(self): def get_set_del_nonneg_slice(): # no neg slices for now! From noreply at buildbot.pypy.org Mon Oct 8 14:03:20 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 14:03:20 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: make boehm tests run Message-ID: <20121008120320.4E0E31C0BC5@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57905:2e1f0a72b224 Date: 2012-10-08 14:02 +0200 http://bitbucket.org/pypy/pypy/changeset/2e1f0a72b224/ Log: make boehm tests run diff --git a/pypy/translator/c/test/test_boehm.py b/pypy/translator/c/test/test_boehm.py --- a/pypy/translator/c/test/test_boehm.py +++ b/pypy/translator/c/test/test_boehm.py @@ -2,14 +2,13 @@ import py -from pypy import conftest from pypy.rlib import rgc from pypy.rlib.objectmodel import (keepalive_until_here, compute_unique_id, compute_hash, current_object_addr_as_int) from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.lltypesystem.rstr import STR -from pypy.translator.translator import TranslationContext +from pypy.translator.c.test.test_genc import compile def setup_module(mod): @@ -35,27 +34,7 @@ self._cleanups.pop()() def getcompiled(self, func, argstypelist=[], annotatorpolicy=None): - from pypy.config.pypyoption import get_pypy_config - config = get_pypy_config(translating=True) - config.translation.gc = self.gcpolicy - config.translation.thread = self.use_threads - config.translation.simplifying = True - t = TranslationContext(config=config) - self.t = t - a = t.buildannotator(policy=annotatorpolicy) - a.build_types(func, argstypelist) - t.buildrtyper().specialize() - t.checkgraphs() - def compile(): - cbuilder = CExtModuleBuilder(t, func, config=config) - c_source_filename = cbuilder.generate_source( - defines = cbuilder.DEBUG_DEFINES) - if conftest.option.view: - t.view() - cbuilder.compile() - self._cleanups.append(cbuilder.cleanup) # schedule cleanup after test - return cbuilder.get_entry_point(isolated=True) - return compile() + return compile(func, argstypelist, gcpolicy=self.gcpolicy, thread=self.use_threads) class TestUsingBoehm(AbstractGCTestClass): diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -14,7 +14,7 @@ def compile(fn, argtypes, view=False, gcpolicy="none", backendopt=True, - annotatorpolicy=None): + annotatorpolicy=None, thread=False): argtypes_unroll = unrolling_iterable(enumerate(argtypes)) for argtype in argtypes: @@ -41,7 +41,7 @@ return 0 t = Translation(entry_point, None, gc=gcpolicy, backend="c", - policy=annotatorpolicy) + policy=annotatorpolicy, thread=thread) if not backendopt: t.disable(["backendopt_lltype"]) t.annotate() @@ -77,9 +77,10 @@ f.__name__ = fn.__name__ return f + def test_simple(): def f(x): - return x*2 + return x * 2 f1 = compile(f, [int]) From noreply at buildbot.pypy.org Mon Oct 8 14:04:11 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:04:11 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: (fijal around, arigo) Message-ID: <20121008120411.3A16D1C0BE2@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: numpypy-complex2 Changeset: r57906:3378cc2fde22 Date: 2012-10-08 14:02 +0200 http://bitbucket.org/pypy/pypy/changeset/3378cc2fde22/ Log: (fijal around, arigo) - fix c_pow() to return (nan+nanj) instead of raising an RPython ValueError in some cases - reuse the logic from pypy.rlib.rcomplex from complexobject.py diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -8,7 +8,7 @@ from pypy.rlib.rbigint import rbigint from pypy.rlib.rfloat import ( formatd, DTSF_STR_PRECISION, isinf, isnan, copysign) -from pypy.rlib import jit +from pypy.rlib import jit, rcomplex from pypy.rlib.rarithmetic import intmask import math @@ -63,6 +63,9 @@ """ representation for debugging purposes """ return "" % (w_self.realval, w_self.imagval) + def as_tuple(self): + return (self.realval, self.imagval) + def sub(self, other): return W_ComplexObject(self.realval - other.realval, self.imagval - other.imagval) @@ -73,31 +76,8 @@ return W_ComplexObject(r, i) def div(self, other): - r1, i1 = self.realval, self.imagval - r2, i2 = other.realval, other.imagval - if r2 < 0: - abs_r2 = - r2 - else: - abs_r2 = r2 - if i2 < 0: - abs_i2 = - i2 - else: - abs_i2 = i2 - if abs_r2 >= abs_i2: - if abs_r2 == 0.0: - raise ZeroDivisionError - else: - ratio = i2 / r2 - denom = r2 + i2 * ratio - rr = (r1 + i1 * ratio) / denom - ir = (i1 - r1 * ratio) / denom - else: - ratio = r2 / i2 - denom = r2 * ratio + i2 - assert i2 != 0.0 - rr = (r1 * ratio + i1) / denom - ir = (i1 * ratio - r1) / denom - return W_ComplexObject(rr,ir) + rr, ir = rcomplex.c_div(self.as_tuple(), other.as_tuple()) + return W_ComplexObject(rr, ir) def divmod(self, space, other): space.warn( @@ -111,24 +91,7 @@ return (W_ComplexObject(div, 0), w_mod) def pow(self, other): - r1, i1 = self.realval, self.imagval - r2, i2 = other.realval, other.imagval - if r2 == 0.0 and i2 == 0.0: - rr, ir = 1, 0 - elif r1 == 0.0 and i1 == 0.0: - if i2 != 0.0 or r2 < 0.0: - raise ZeroDivisionError - rr, ir = (0.0, 0.0) - else: - vabs = math.hypot(r1,i1) - len = math.pow(vabs,r2) - at = math.atan2(i1,r1) - phase = at * r2 - if i2 != 0.0: - len /= math.exp(at * i2) - phase += i2 * math.log(vabs) - rr = len * math.cos(phase) - ir = len * math.sin(phase) + rr, ir = rcomplex.c_pow(self.as_tuple(), other.as_tuple()) return W_ComplexObject(rr, ir) def pow_small_int(self, n): diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -220,6 +220,9 @@ b = 5.1+2.3j raises(ValueError, pow, a, b, 0) + b = complex(float('inf'), 0.0) ** complex(10., 3.) + assert repr(b) == "(nan+nanj)" + def test_boolcontext(self): from random import random for i in xrange(100): diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py --- a/pypy/rlib/rcomplex.py +++ b/pypy/rlib/rcomplex.py @@ -86,8 +86,12 @@ if i2 != 0.0: len /= math.exp(at * i2) phase += i2 * math.log(vabs) - rr = len * math.cos(phase) - ir = len * math.sin(phase) + try: + rr = len * math.cos(phase) + ir = len * math.sin(phase) + except ValueError: + rr = NAN + ir = NAN return (rr, ir) #unary From noreply at buildbot.pypy.org Mon Oct 8 14:12:02 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:12:02 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: (fijal, arigo) Some more tests Message-ID: <20121008121202.C84DB1C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: numpypy-complex2 Changeset: r57907:0ac31cafc59f Date: 2012-10-08 14:11 +0200 http://bitbucket.org/pypy/pypy/changeset/0ac31cafc59f/ Log: (fijal, arigo) Some more tests 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 @@ -469,10 +469,10 @@ def test_basic(self): from _numpypy import (complex128, complex64, add, - subtract as sub, multiply, divide, negative, abs, - reciprocal, real, imag) + subtract as sub, multiply, divide, negative, abs, floor_divide, + reciprocal, real, imag, sign) from _numpypy import (equal, not_equal, greater, greater_equal, less, - less_equal) + less_equal, isnan) assert real(4.0) == 4.0 assert imag(0.0) == 0.0 for complex_ in complex64, complex128: @@ -523,9 +523,22 @@ assert abs(res.real-2.2) < 0.001 assert abs(res.imag+0.4) < 0.001 + assert floor_divide(c0, c0) == complex(1, 0) + assert isnan(floor_divide(c0, complex(0, 0)).real) + assert floor_divide(c0, complex(0, 0)).imag == 0.0 + assert abs(c0) == 2.5 assert abs(c2) == 5 - + assert sign(complex(0, 0)) == 0 + assert sign(complex(-42, 0)) == -1 + assert sign(complex(42, 0)) == 1 + assert sign(complex(-42, 2)) == -1 + assert sign(complex(42, 2)) == 1 + assert sign(complex(-42, -3)) == -1 + assert sign(complex(42, -3)) == 1 + assert sign(complex(0, -42)) == -1 + assert sign(complex(0, 42)) == 1 + inf_c = complex_(complex(float('inf'), 0.)) assert repr(abs(inf_c)) == 'inf' assert repr(abs(complex(float('nan'), float('nan')))) == 'nan' From noreply at buildbot.pypy.org Mon Oct 8 14:15:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:15:34 +0200 (CEST) Subject: [pypy-commit] pypy default: (mattip) Message-ID: <20121008121534.B50021C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57908:c3a7b8e4f02c Date: 2012-10-08 14:13 +0200 http://bitbucket.org/pypy/pypy/changeset/c3a7b8e4f02c/ Log: (mattip) merge the branch numpypy-complex2, which adds numpy complex support. Yay! diff too long, truncating to 2000 out of 10493 lines diff --git a/pypy/module/cmath/interp_cmath.py b/pypy/module/cmath/interp_cmath.py --- a/pypy/module/cmath/interp_cmath.py +++ b/pypy/module/cmath/interp_cmath.py @@ -1,28 +1,10 @@ import math -from math import fabs from pypy.rlib.objectmodel import specialize -from pypy.rlib.rfloat import copysign, asinh, log1p, isinf, isnan from pypy.tool.sourcetools import func_with_new_name from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import NoneNotWrapped from pypy.module.cmath import names_and_docstrings -from pypy.module.cmath.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN -from pypy.module.cmath.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG -from pypy.module.cmath.constant import M_LN2, M_LN10 -from pypy.module.cmath.constant import CM_SQRT_LARGE_DOUBLE, CM_SQRT_DBL_MIN -from pypy.module.cmath.constant import CM_LOG_LARGE_DOUBLE -from pypy.module.cmath.special_value import isfinite, special_type, INF, NAN -from pypy.module.cmath.special_value import sqrt_special_values -from pypy.module.cmath.special_value import acos_special_values -from pypy.module.cmath.special_value import acosh_special_values -from pypy.module.cmath.special_value import asinh_special_values -from pypy.module.cmath.special_value import atanh_special_values -from pypy.module.cmath.special_value import log_special_values -from pypy.module.cmath.special_value import exp_special_values -from pypy.module.cmath.special_value import cosh_special_values -from pypy.module.cmath.special_value import sinh_special_values -from pypy.module.cmath.special_value import tanh_special_values -from pypy.module.cmath.special_value import rect_special_values +from pypy.rlib import rcomplex pi = math.pi e = math.e @@ -56,235 +38,40 @@ def c_neg(x, y): - return (-x, -y) + return rcomplex.c_neg(x,y) @unaryfn def c_sqrt(x, y): - # Method: use symmetries to reduce to the case when x = z.real and y - # = z.imag are nonnegative. Then the real part of the result is - # given by - # - # s = sqrt((x + hypot(x, y))/2) - # - # and the imaginary part is - # - # d = (y/2)/s - # - # If either x or y is very large then there's a risk of overflow in - # computation of the expression x + hypot(x, y). We can avoid this - # by rewriting the formula for s as: - # - # s = 2*sqrt(x/8 + hypot(x/8, y/8)) - # - # This costs us two extra multiplications/divisions, but avoids the - # overhead of checking for x and y large. - # - # If both x and y are subnormal then hypot(x, y) may also be - # subnormal, so will lack full precision. We solve this by rescaling - # x and y by a sufficiently large power of 2 to ensure that x and y - # are normal. - - if not isfinite(x) or not isfinite(y): - return sqrt_special_values[special_type(x)][special_type(y)] - - if x == 0. and y == 0.: - return (0., y) - - ax = fabs(x) - ay = fabs(y) - - if ax < DBL_MIN and ay < DBL_MIN and (ax > 0. or ay > 0.): - # here we catch cases where hypot(ax, ay) is subnormal - ax = math.ldexp(ax, CM_SCALE_UP) - ay1= math.ldexp(ay, CM_SCALE_UP) - s = math.ldexp(math.sqrt(ax + math.hypot(ax, ay1)), - CM_SCALE_DOWN) - else: - ax /= 8. - s = 2.*math.sqrt(ax + math.hypot(ax, ay/8.)) - - d = ay/(2.*s) - - if x >= 0.: - return (s, copysign(d, y)) - else: - return (d, copysign(s, y)) - + return rcomplex.c_sqrt(x,y) @unaryfn def c_acos(x, y): - if not isfinite(x) or not isfinite(y): - return acos_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - # avoid unnecessary overflow for large arguments - real = math.atan2(fabs(y), x) - # split into cases to make sure that the branch cut has the - # correct continuity on systems with unsigned zeros - if x < 0.: - imag = -copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., y) - else: - imag = copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., -y) - else: - s1x, s1y = c_sqrt(1.-x, -y) - s2x, s2y = c_sqrt(1.+x, y) - real = 2.*math.atan2(s1x, s2x) - imag = asinh(s2x*s1y - s2y*s1x) - return (real, imag) - + return rcomplex.c_acos(x,y) @unaryfn def c_acosh(x, y): - # XXX the following two lines seem unnecessary at least on Linux; - # the tests pass fine without them - if not isfinite(x) or not isfinite(y): - return acosh_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - # avoid unnecessary overflow for large arguments - real = math.log(math.hypot(x/2., y/2.)) + M_LN2*2. - imag = math.atan2(y, x) - else: - s1x, s1y = c_sqrt(x - 1., y) - s2x, s2y = c_sqrt(x + 1., y) - real = asinh(s1x*s2x + s1y*s2y) - imag = 2.*math.atan2(s1y, s2x) - return (real, imag) - + return rcomplex.c_acosh(x,y) @unaryfn def c_asin(x, y): - # asin(z) = -i asinh(iz) - sx, sy = c_asinh(-y, x) - return (sy, -sx) - + return rcomplex.c_asin(x,y) @unaryfn def c_asinh(x, y): - if not isfinite(x) or not isfinite(y): - return asinh_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - if y >= 0.: - real = copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., x) - else: - real = -copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., -x) - imag = math.atan2(y, fabs(x)) - else: - s1x, s1y = c_sqrt(1.+y, -x) - s2x, s2y = c_sqrt(1.-y, x) - real = asinh(s1x*s2y - s2x*s1y) - imag = math.atan2(y, s1x*s2x - s1y*s2y) - return (real, imag) - + return rcomplex.c_asinh(x,y) @unaryfn def c_atan(x, y): - # atan(z) = -i atanh(iz) - sx, sy = c_atanh(-y, x) - return (sy, -sx) - + return rcomplex.c_atan(x,y) @unaryfn def c_atanh(x, y): - if not isfinite(x) or not isfinite(y): - return atanh_special_values[special_type(x)][special_type(y)] - - # Reduce to case where x >= 0., using atanh(z) = -atanh(-z). - if x < 0.: - return c_neg(*c_atanh(*c_neg(x, y))) - - ay = fabs(y) - if x > CM_SQRT_LARGE_DOUBLE or ay > CM_SQRT_LARGE_DOUBLE: - # if abs(z) is large then we use the approximation - # atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign - # of y - h = math.hypot(x/2., y/2.) # safe from overflow - real = x/4./h/h - # the two negations in the next line cancel each other out - # except when working with unsigned zeros: they're there to - # ensure that the branch cut has the correct continuity on - # systems that don't support signed zeros - imag = -copysign(math.pi/2., -y) - elif x == 1. and ay < CM_SQRT_DBL_MIN: - # C99 standard says: atanh(1+/-0.) should be inf +/- 0i - if ay == 0.: - raise ValueError("math domain error") - #real = INF - #imag = y - else: - real = -math.log(math.sqrt(ay)/math.sqrt(math.hypot(ay, 2.))) - imag = copysign(math.atan2(2., -ay) / 2, y) - else: - real = log1p(4.*x/((1-x)*(1-x) + ay*ay))/4. - imag = -math.atan2(-2.*y, (1-x)*(1+x) - ay*ay) / 2. - return (real, imag) - + return rcomplex.c_atanh(x,y) @unaryfn def c_log(x, y): - # The usual formula for the real part is log(hypot(z.real, z.imag)). - # There are four situations where this formula is potentially - # problematic: - # - # (1) the absolute value of z is subnormal. Then hypot is subnormal, - # so has fewer than the usual number of bits of accuracy, hence may - # have large relative error. This then gives a large absolute error - # in the log. This can be solved by rescaling z by a suitable power - # of 2. - # - # (2) the absolute value of z is greater than DBL_MAX (e.g. when both - # z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX) - # Again, rescaling solves this. - # - # (3) the absolute value of z is close to 1. In this case it's - # difficult to achieve good accuracy, at least in part because a - # change of 1ulp in the real or imaginary part of z can result in a - # change of billions of ulps in the correctly rounded answer. - # - # (4) z = 0. The simplest thing to do here is to call the - # floating-point log with an argument of 0, and let its behaviour - # (returning -infinity, signaling a floating-point exception, setting - # errno, or whatever) determine that of c_log. So the usual formula - # is fine here. - - # XXX the following two lines seem unnecessary at least on Linux; - # the tests pass fine without them - if not isfinite(x) or not isfinite(y): - return log_special_values[special_type(x)][special_type(y)] - - ax = fabs(x) - ay = fabs(y) - - if ax > CM_LARGE_DOUBLE or ay > CM_LARGE_DOUBLE: - real = math.log(math.hypot(ax/2., ay/2.)) + M_LN2 - elif ax < DBL_MIN and ay < DBL_MIN: - if ax > 0. or ay > 0.: - # catch cases where hypot(ax, ay) is subnormal - real = math.log(math.hypot(math.ldexp(ax, DBL_MANT_DIG), - math.ldexp(ay, DBL_MANT_DIG))) - real -= DBL_MANT_DIG*M_LN2 - else: - # log(+/-0. +/- 0i) - raise ValueError("math domain error") - #real = -INF - #imag = atan2(y, x) - else: - h = math.hypot(ax, ay) - if 0.71 <= h and h <= 1.73: - am = max(ax, ay) - an = min(ax, ay) - real = log1p((am-1)*(am+1) + an*an) / 2. - else: - real = math.log(h) - imag = math.atan2(y, x) - return (real, imag) - + return rcomplex.c_log(x,y) _inner_wrapped_log = wrapped_log @@ -300,196 +87,38 @@ @unaryfn def c_log10(x, y): - rx, ry = c_log(x, y) - return (rx / M_LN10, ry / M_LN10) - + return rcomplex.c_log10(x,y) @unaryfn def c_exp(x, y): - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = copysign(0., math.cos(y)) - imag = copysign(0., math.sin(y)) - r = (real, imag) - else: - r = exp_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN and not -infinity - if isinf(y) and (isfinite(x) or (isinf(x) and x > 0)): - raise ValueError("math domain error") - return r - - if x > CM_LOG_LARGE_DOUBLE: - l = math.exp(x-1.) - real = l * math.cos(y) * math.e - imag = l * math.sin(y) * math.e - else: - l = math.exp(x) - real = l * math.cos(y) - imag = l * math.sin(y) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - + return rcomplex.c_exp(x,y) @unaryfn def c_cosh(x, y): - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = copysign(INF, math.cos(y)) - imag = -copysign(INF, math.sin(y)) - r = (real, imag) - else: - r = cosh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN - if isinf(y) and not isnan(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - # deal correctly with cases where cosh(x) overflows but - # cosh(z) does not. - x_minus_one = x - copysign(1., x) - real = math.cos(y) * math.cosh(x_minus_one) * math.e - imag = math.sin(y) * math.sinh(x_minus_one) * math.e - else: - real = math.cos(y) * math.cosh(x) - imag = math.sin(y) * math.sinh(x) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - + return rcomplex.c_cosh(x,y) @unaryfn def c_sinh(x, y): - # special treatment for sinh(+/-inf + iy) if y is finite and nonzero - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = -copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - r = (real, imag) - else: - r = sinh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN - if isinf(y) and not isnan(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - x_minus_one = x - copysign(1., x) - real = math.cos(y) * math.sinh(x_minus_one) * math.e - imag = math.sin(y) * math.cosh(x_minus_one) * math.e - else: - real = math.cos(y) * math.sinh(x) - imag = math.sin(y) * math.cosh(x) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - + return rcomplex.c_sinh(x,y) @unaryfn def c_tanh(x, y): - # Formula: - # - # tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) / - # (1+tan(y)^2 tanh(x)^2) - # - # To avoid excessive roundoff error, 1-tanh(x)^2 is better computed - # as 1/cosh(x)^2. When abs(x) is large, we approximate 1-tanh(x)^2 - # by 4 exp(-2*x) instead, to avoid possible overflow in the - # computation of cosh(x). - - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = 1.0 # vv XXX why is the 2. there? - imag = copysign(0., 2. * math.sin(y) * math.cos(y)) - else: - real = -1.0 - imag = copysign(0., 2. * math.sin(y) * math.cos(y)) - r = (real, imag) - else: - r = tanh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/-infinity and x is finite - if isinf(y) and isfinite(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - real = copysign(1., x) - imag = 4. * math.sin(y) * math.cos(y) * math.exp(-2.*fabs(x)) - else: - tx = math.tanh(x) - ty = math.tan(y) - cx = 1. / math.cosh(x) - txty = tx * ty - denom = 1. + txty * txty - real = tx * (1. + ty*ty) / denom - imag = ((ty / denom) * cx) * cx - return real, imag - + return rcomplex.c_tanh(x,y) @unaryfn def c_cos(x, y): - # cos(z) = cosh(iz) - return c_cosh(-y, x) + return rcomplex.c_cos(x,y) @unaryfn def c_sin(x, y): - # sin(z) = -i sinh(iz) - sx, sy = c_sinh(-y, x) - return sy, -sx + return rcomplex.c_sin(x,y) @unaryfn def c_tan(x, y): - # tan(z) = -i tanh(iz) - sx, sy = c_tanh(-y, x) - return sy, -sx - + return rcomplex.c_tan(x,y) def c_rect(r, phi): - if not isfinite(r) or not isfinite(phi): - # if r is +/-infinity and phi is finite but nonzero then - # result is (+-INF +-INF i), but we need to compute cos(phi) - # and sin(phi) to figure out the signs. - if isinf(r) and isfinite(phi) and phi != 0.: - if r > 0: - real = copysign(INF, math.cos(phi)) - imag = copysign(INF, math.sin(phi)) - else: - real = -copysign(INF, math.cos(phi)) - imag = -copysign(INF, math.sin(phi)) - z = (real, imag) - else: - z = rect_special_values[special_type(r)][special_type(phi)] - - # need to raise ValueError if r is a nonzero number and phi - # is infinite - if r != 0. and not isnan(r) and isinf(phi): - raise ValueError("math domain error") - return z - - real = r * math.cos(phi) - imag = r * math.sin(phi) - return real, imag + return rcomplex.c_rect(r,phi) def wrapped_rect(space, w_x, w_y): x = space.float_w(w_x) @@ -500,28 +129,7 @@ def c_phase(x, y): - # Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't - # follow C99 for atan2(0., 0.). - if isnan(x) or isnan(y): - return NAN - if isinf(y): - if isinf(x): - if copysign(1., x) == 1.: - # atan2(+-inf, +inf) == +-pi/4 - return copysign(0.25 * math.pi, y) - else: - # atan2(+-inf, -inf) == +-pi*3/4 - return copysign(0.75 * math.pi, y) - # atan2(+-inf, x) == +-pi/2 for finite x - return copysign(0.5 * math.pi, y) - if isinf(x) or y == 0.: - if copysign(1., x) == 1.: - # atan2(+-y, +inf) = atan2(+-0, +x) = +-0. - return copysign(0., y) - else: - # atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. - return copysign(math.pi, y) - return math.atan2(y, x) + return rcomplex.c_phase(x,y) def wrapped_phase(space, w_z): x, y = space.unpackcomplex(w_z) @@ -531,28 +139,10 @@ def c_abs(x, y): - if not isfinite(x) or not isfinite(y): - # C99 rules: if either the real or the imaginary part is an - # infinity, return infinity, even if the other part is a NaN. - if isinf(x): - return INF - if isinf(y): - return INF - - # either the real or imaginary part is a NaN, - # and neither is infinite. Result should be NaN. - return NAN - - result = math.hypot(x, y) - if not isfinite(result): - raise OverflowError("math range error") - return result - + return rcomplex.c_abs(x,y) def c_polar(x, y): - phi = c_phase(x, y) - r = c_abs(x, y) - return r, phi + return rcomplex.c_polar(x,y) def wrapped_polar(space, w_z): x, y = space.unpackcomplex(w_z) @@ -562,7 +152,7 @@ def c_isinf(x, y): - return isinf(x) or isinf(y) + return rcomplex.c_isinf(x,y) def wrapped_isinf(space, w_z): x, y = space.unpackcomplex(w_z) @@ -572,7 +162,7 @@ def c_isnan(x, y): - return isnan(x) or isnan(y) + return rcomplex.c_isnan(x,y) def wrapped_isnan(space, w_z): x, y = space.unpackcomplex(w_z) diff --git a/pypy/module/cmath/test/test_cmath.py b/pypy/module/cmath/test/test_cmath.py --- a/pypy/module/cmath/test/test_cmath.py +++ b/pypy/module/cmath/test/test_cmath.py @@ -6,7 +6,7 @@ def test_special_values(): - from pypy.module.cmath.special_value import sqrt_special_values + from pypy.rlib.special_value import sqrt_special_values assert len(sqrt_special_values) == 7 assert len(sqrt_special_values[4]) == 7 assert isinstance(sqrt_special_values[5][1], tuple) @@ -115,7 +115,6 @@ Empty lines or lines starting with -- are ignored yields id, fn, arg_real, arg_imag, exp_real, exp_imag """ - fname = os.path.join(os.path.dirname(__file__), fname) with open(fname) as fp: for line in fp: # skip comment lines and blank lines @@ -186,8 +185,10 @@ def test_specific_values(): #if not float.__getformat__("double").startswith("IEEE"): # return - - for id, fn, ar, ai, er, ei, flags in parse_testfile('cmath_testcases.txt'): + + # too fragile... + fname = os.path.join(os.path.dirname(__file__), '../../../rlib/test', 'rcomplex_testcases.txt') + for id, fn, ar, ai, er, ei, flags in parse_testfile(fname): arg = (ar, ai) expected = (er, ei) function = getattr(interp_cmath, 'c_' + fn) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -64,6 +64,10 @@ 'str_': 'interp_boxes.W_StringBox', 'unicode_': 'interp_boxes.W_UnicodeBox', 'void': 'interp_boxes.W_VoidBox', + 'complexfloating': 'interp_boxes.W_ComplexFloatingBox', + 'complex_': 'interp_boxes.W_Complex128Box', + 'complex128': 'interp_boxes.W_Complex128Box', + 'complex64': 'interp_boxes.W_Complex64Box', } # ufuncs @@ -78,6 +82,8 @@ ("arccosh", "arccosh"), ("arcsinh", "arcsinh"), ("arctanh", "arctanh"), + ("conj", "conjugate"), + ("conjugate", "conjugate"), ("copysign", "copysign"), ("cos", "cos"), ("cosh", "cosh"), @@ -141,6 +147,8 @@ ('floor_divide', 'floor_divide'), ('logaddexp', 'logaddexp'), ('logaddexp2', 'logaddexp2'), + ('real', 'real'), + ('imag', 'imag'), ]: interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl 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 @@ -56,7 +56,8 @@ w_slice = "slice" w_str = "str" w_unicode = "unicode" - + w_complex = "complex" + def __init__(self): """NOT_RPYTHON""" self.fromcache = InternalSpaceCache(self).getorbuild diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -1,11 +1,12 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import operationerrfmt, OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, GetSetProperty 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.complextype import complex_typedef from pypy.rlib.rarithmetic import LONG_BIT from pypy.tool.sourcetools import func_with_new_name from pypy.module.micronumpy.arrayimpl.voidbox import VoidBoxStorage @@ -34,6 +35,25 @@ def convert_to(self, dtype): return dtype.box(self.value) +class ComplexBox(object): + _mixin_ = True + + def __init__(self, real, imag=0.): + self.real = real + self.imag = imag + + def convert_to(self, dtype): + from pypy.module.micronumpy.types import ComplexFloating + if not isinstance(dtype.itemtype, ComplexFloating): + raise TypeError('cannot convert %r to complex' % dtype) + return dtype.box_complex(self.real, self.imag) + + def convert_real_to(self, dtype): + return dtype.box(self.real) + + def convert_imag_to(self, dtype): + return dtype.box(self.imag) + class W_GenericBox(Wrappable): _attrs_ = () @@ -57,7 +77,12 @@ return space.wrap(box.value) def descr_float(self, space): - box = self.convert_to(W_Float64Box._get_dtype(space)) + try: + box = self.convert_to(W_Float64Box._get_dtype(space)) + except TypeError: + raise OperationError(space.w_TypeError, + space.wrap("Cannot convert %s to float" % self._get_dtype(space).name)) + assert isinstance(box, W_Float64Box) return space.wrap(box.value) @@ -220,6 +245,7 @@ def descr_index(space, self): return space.index(self.item(space)) + class W_VoidBox(W_FlexibleBox): @unwrap_spec(item=str) def descr_getitem(self, space, item): @@ -266,6 +292,32 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) + +class W_ComplexFloatingBox(W_InexactBox): + _attrs_ = () + def descr_get_real(self, space): + dtype = self._COMPONENTS_BOX._get_dtype(space) + box = self.convert_real_to(dtype) + assert isinstance(box, self._COMPONENTS_BOX) + return space.wrap(box) + + def descr_get_imag(self, space): + dtype = self._COMPONENTS_BOX._get_dtype(space) + box = self.convert_imag_to(dtype) + assert isinstance(box, self._COMPONENTS_BOX) + return space.wrap(box) + + +class W_Complex64Box(ComplexBox, W_ComplexFloatingBox): + descr__new__, _get_dtype = new_dtype_getter("complex64") + _COMPONENTS_BOX = W_Float32Box + + +class W_Complex128Box(ComplexBox, W_ComplexFloatingBox): + descr__new__, _get_dtype = new_dtype_getter("complex128") + _COMPONENTS_BOX = W_Float64Box + + W_GenericBox.typedef = TypeDef("generic", __module__ = "numpypy", @@ -448,3 +500,21 @@ __new__ = interp2app(W_UnicodeBox.descr__new__unicode_box.im_func), ) +W_ComplexFloatingBox.typedef = TypeDef("complexfloating", W_InexactBox.typedef, + __module__ = "numpypy", +) + + +W_Complex128Box.typedef = TypeDef("complex128", (W_ComplexFloatingBox.typedef, complex_typedef), + __module__ = "numpypy", + __new__ = interp2app(W_Complex128Box.descr__new__.im_func), + real = GetSetProperty(W_ComplexFloatingBox.descr_get_real), + imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), +) + +W_Complex64Box.typedef = TypeDef("complex64", (W_ComplexFloatingBox.typedef), + __module__ = "numpypy", + __new__ = interp2app(W_Complex64Box.descr__new__.im_func), + real = GetSetProperty(W_ComplexFloatingBox .descr_get_real), + imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), +) 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 @@ -46,6 +46,11 @@ def box(self, value): return self.itemtype.box(value) + @specialize.argtype(1, 2) + def box_complex(self, real, imag): + return self.itemtype.box_complex(real, imag) + + def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) @@ -121,6 +126,9 @@ def is_signed(self): return self.kind == SIGNEDLTR + def is_complex_type(self): + return (self.num == 14 or self.num == 15) + def is_bool_type(self): return self.kind == BOOLLTR @@ -393,6 +401,31 @@ alternate_constructors=[space.w_float], aliases=["float"], ) + # self.w_float128dtype = W_Dtype( + # types.Float128(), + # num=13, + # kind=FLOATINGLTR, + # name="float128", + # ... + # ) + self.w_complex64dtype = W_Dtype( + types.Complex64(), + num=14, + kind=FLOATINGLTR, + name="complex64", + char="F", + w_box_type = space.gettypefor(interp_boxes.W_Complex64Box), + ) + self.w_complex128dtype = W_Dtype( + types.Complex128(), + num=15, + kind=FLOATINGLTR, + name="complex128", + char="D", + w_box_type = space.gettypefor(interp_boxes.W_Complex128Box), + alternate_constructors=[space.w_complex], + aliases=["complex"], + ) self.w_stringdtype = W_Dtype( types.StringType(1), num=18, @@ -426,8 +459,9 @@ self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype, self.w_int64dtype, self.w_uint64dtype, - self.w_float32dtype, - self.w_float64dtype, self.w_stringdtype, self.w_unicodedtype, + self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, + self.w_complex128dtype, + self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, ] self.float_dtypes_by_num_bytes = sorted( 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 @@ -383,6 +383,8 @@ descr_neg = _unaryop_impl("negative") descr_abs = _unaryop_impl("absolute") descr_invert = _unaryop_impl("invert") + descr_get_real = _unaryop_impl("real") + descr_get_imag = _unaryop_impl("imag") def descr_nonzero(self, space): if self.get_size() > 1: @@ -629,6 +631,8 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), + real = GetSetProperty(W_NDimArray.descr_get_real), + imag = GetSetProperty(W_NDimArray.descr_get_imag), __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) @@ -663,8 +667,9 @@ for w_elem in elems_w: dtype = interp_ufuncs.find_dtype_for_scalar(space, w_elem, dtype) - if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: - break + #if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: + # break + if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if ndmin > len(shape): diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -17,14 +17,15 @@ return not dtype.itemtype.bool(val) class W_Ufunc(Wrappable): - _attrs_ = ["name", "promote_to_float", "promote_bools", "identity"] - _immutable_fields_ = ["promote_to_float", "promote_bools", "name"] + _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", "allow_complex"] + _immutable_fields_ = ["promote_to_float", "promote_bools", "name", "allow_complex"] def __init__(self, name, promote_to_float, promote_bools, identity, - int_only): + int_only, allow_complex): self.name = name self.promote_to_float = promote_to_float self.promote_bools = promote_bools + self.allow_complex = allow_complex self.identity = identity self.int_only = int_only @@ -215,10 +216,10 @@ _immutable_fields_ = ["func", "name"] def __init__(self, func, name, promote_to_float=False, promote_bools=False, - identity=None, bool_result=False, int_only=False): + identity=None, bool_result=False, int_only=False, allow_complex=True): W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity, - int_only) + int_only, allow_complex) self.func = func self.bool_result = bool_result @@ -233,7 +234,8 @@ calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, - promote_bools=self.promote_bools) + promote_bools=self.promote_bools, + allow_complex=self.allow_complex) if out is not None: if not isinstance(out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( @@ -267,10 +269,10 @@ argcount = 2 def __init__(self, func, name, promote_to_float=False, promote_bools=False, - identity=None, comparison_func=False, int_only=False): + identity=None, comparison_func=False, int_only=False, allow_complex=True): W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity, - int_only) + int_only, allow_complex) self.func = func self.comparison_func = comparison_func if name == 'logical_and': @@ -289,14 +291,15 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) + calc_dtype = find_binop_result_dtype(space, + w_lhs.get_dtype(), w_rhs.get_dtype(), + int_only=self.int_only, + promote_to_float=self.promote_to_float, + promote_bools=self.promote_bools, + allow_complex=self.allow_complex, + ) if space.is_w(w_out, space.w_None) or w_out is None: out = None - calc_dtype = find_binop_result_dtype(space, - w_lhs.get_dtype(), w_rhs.get_dtype(), - int_only=self.int_only, - promote_to_float=self.promote_to_float, - promote_bools=self.promote_bools, - ) elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( 'output must be an array')) @@ -340,15 +343,25 @@ def find_binop_result_dtype(space, dt1, dt2, promote_to_float=False, - promote_bools=False, int_only=False): + promote_bools=False, int_only=False, allow_complex=True): # dt1.num should be <= dt2.num if dt1.num > dt2.num: dt1, dt2 = dt2, dt1 if int_only and (not dt1.is_int_type() or not dt2.is_int_type()): raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) + if not allow_complex and (dt1.is_complex_type() or dt2.is_complex_type()): + raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) # Some operations promote op(bool, bool) to return int8, rather than bool if promote_bools and (dt1.kind == dt2.kind == interp_dtype.BOOLLTR): return interp_dtype.get_dtype_cache(space).w_int8dtype + + # Everything promotes to complex + if dt2.num == 14 or dt2.num == 15 or dt1.num == 14 or dt2.num == 15: + if dt2.num == 15 or dt1.num == 15: + return interp_dtype.get_dtype_cache(space).w_complex128dtype + else: + return interp_dtype.get_dtype_cache(space).w_complex64dtype + if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. @@ -391,9 +404,11 @@ def find_unaryop_result_dtype(space, dt, promote_to_float=False, - promote_bools=False, promote_to_largest=False): + promote_bools=False, promote_to_largest=False, allow_complex=True): if promote_bools and (dt.kind == interp_dtype.BOOLLTR): return interp_dtype.get_dtype_cache(space).w_int8dtype + if not allow_complex and (dt.is_complex_type()): + raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) if promote_to_float: if dt.kind == interp_dtype.FLOATINGLTR: return dt @@ -419,7 +434,8 @@ bool_dtype = interp_dtype.get_dtype_cache(space).w_booldtype long_dtype = interp_dtype.get_dtype_cache(space).w_longdtype int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype - + complex_type = interp_dtype.get_dtype_cache(space).w_complex128dtype + float_type = interp_dtype.get_dtype_cache(space).w_float64dtype if isinstance(w_obj, interp_boxes.W_GenericBox): dtype = w_obj.get_dtype(space) if current_guess is None: @@ -440,6 +456,14 @@ current_guess is long_dtype or current_guess is int64_dtype): return int64_dtype return current_guess + elif space.isinstance_w(w_obj, space.w_complex): + if (current_guess is None or current_guess is bool_dtype or + current_guess is long_dtype or current_guess is int64_dtype or + current_guess is complex_type or current_guess is float_type): + return complex_type + return current_guess + if current_guess is complex_type: + return complex_type return interp_dtype.get_dtype_cache(space).w_float64dtype @@ -476,7 +500,7 @@ ("floor_divide", "floordiv", 2, {"promote_bools": True}), ("divide", "div", 2, {"promote_bools": True}), ("true_divide", "div", 2, {"promote_to_float": True}), - ("mod", "mod", 2, {"promote_bools": True}), + ("mod", "mod", 2, {"promote_bools": True, 'allow_complex': False}), ("power", "pow", 2, {"promote_bools": True}), ("left_shift", "lshift", 2, {"int_only": True}), ("right_shift", "rshift", 2, {"int_only": True}), @@ -489,8 +513,10 @@ ("greater_equal", "ge", 2, {"comparison_func": True}), ("isnan", "isnan", 1, {"bool_result": True}), ("isinf", "isinf", 1, {"bool_result": True}), - ("isneginf", "isneginf", 1, {"bool_result": True}), - ("isposinf", "isposinf", 1, {"bool_result": True}), + ("isneginf", "isneginf", 1, {"bool_result": True, + "allow_complex": False}), + ("isposinf", "isposinf", 1, {"bool_result": True, + "allow_complex": False}), ("isfinite", "isfinite", 1, {"bool_result": True}), ('logical_and', 'logical_and', 2, {'comparison_func': True, @@ -503,22 +529,32 @@ ("maximum", "max", 2), ("minimum", "min", 2), - ("copysign", "copysign", 2, {"promote_to_float": True}), + ("copysign", "copysign", 2, {"promote_to_float": True, + "allow_complex": False}), ("positive", "pos", 1), ("negative", "neg", 1), ("absolute", "abs", 1), ("sign", "sign", 1, {"promote_bools": True}), - ("signbit", "signbit", 1, {"bool_result": True}), + ("signbit", "signbit", 1, {"bool_result": True, + "allow_complex": False}), ("reciprocal", "reciprocal", 1), + ("conjugate", "conj", 1), + ("real", "real", 1), + ("imag", "imag", 1), - ("fabs", "fabs", 1, {"promote_to_float": True}), + ("fabs", "fabs", 1, {"promote_to_float": True, + "allow_complex": False}), ("fmax", "fmax", 2, {"promote_to_float": True}), ("fmin", "fmin", 2, {"promote_to_float": True}), - ("fmod", "fmod", 2, {"promote_to_float": True}), - ("floor", "floor", 1, {"promote_to_float": True}), - ("ceil", "ceil", 1, {"promote_to_float": True}), - ("trunc", "trunc", 1, {"promote_to_float": True}), + ("fmod", "fmod", 2, {"promote_to_float": True, + 'allow_complex': False}), + ("floor", "floor", 1, {"promote_to_float": True, + "allow_complex": False}), + ("ceil", "ceil", 1, {"promote_to_float": True, + "allow_complex": False}), + ("trunc", "trunc", 1, {"promote_to_float": True, + "allow_complex": False}), ("exp", "exp", 1, {"promote_to_float": True}), ("exp2", "exp2", 1, {"promote_to_float": True}), ("expm1", "expm1", 1, {"promote_to_float": True}), @@ -532,7 +568,8 @@ ("arcsin", "arcsin", 1, {"promote_to_float": True}), ("arccos", "arccos", 1, {"promote_to_float": True}), ("arctan", "arctan", 1, {"promote_to_float": True}), - ("arctan2", "arctan2", 2, {"promote_to_float": True}), + ("arctan2", "arctan2", 2, {"promote_to_float": True, + "allow_complex": False}), ("sinh", "sinh", 1, {"promote_to_float": True}), ("cosh", "cosh", 1, {"promote_to_float": True}), ("tanh", "tanh", 1, {"promote_to_float": True}), @@ -540,15 +577,19 @@ ("arccosh", "arccosh", 1, {"promote_to_float": True}), ("arctanh", "arctanh", 1, {"promote_to_float": True}), - ("radians", "radians", 1, {"promote_to_float": True}), - ("degrees", "degrees", 1, {"promote_to_float": True}), + ("radians", "radians", 1, {"promote_to_float": True, + "allow_complex": False}), + ("degrees", "degrees", 1, {"promote_to_float": True, + "allow_complex": False}), ("log", "log", 1, {"promote_to_float": True}), ("log2", "log2", 1, {"promote_to_float": True}), ("log10", "log10", 1, {"promote_to_float": True}), ("log1p", "log1p", 1, {"promote_to_float": True}), - ("logaddexp", "logaddexp", 2, {"promote_to_float": True}), - ("logaddexp2", "logaddexp2", 2, {"promote_to_float": True}), + ("logaddexp", "logaddexp", 2, {"promote_to_float": True, + "allow_complex": False}), + ("logaddexp2", "logaddexp2", 2, {"promote_to_float": True, + "allow_complex": False}), ]: self.add_ufunc(space, *ufunc_def) diff --git a/pypy/module/micronumpy/test/complex64_testcases.txt b/pypy/module/micronumpy/test/complex64_testcases.txt new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/test/complex64_testcases.txt @@ -0,0 +1,2214 @@ +-- Testcases for functions in cmath. +-- +-- Each line takes the form: +-- +-- -> +-- +-- where: +-- +-- is a short name identifying the test, +-- +-- is the function to be tested (exp, cos, asinh, ...), +-- +-- is a pair of floats separated by whitespace +-- representing real and imaginary parts of a complex number, and +-- +-- is the expected (ideal) output value, again +-- represented as a pair of floats. +-- +-- is a list of the floating-point flags required by C99 +-- +-- The possible flags are: +-- +-- divide-by-zero : raised when a finite input gives a +-- mathematically infinite result. +-- +-- overflow : raised when a finite input gives a finite result whose +-- real or imaginary part is too large to fit in the usual range +-- of an IEEE 754 double. +-- +-- invalid : raised for invalid inputs. +-- +-- ignore-real-sign : indicates that the sign of the real part of +-- the result is unspecified; if the real part of the result is +-- given as inf, then both -inf and inf should be accepted as +-- correct. +-- +-- ignore-imag-sign : indicates that the sign of the imaginary part +-- of the result is unspecified. +-- +-- Flags may appear in any order. +-- +-- Lines beginning with '--' (like this one) start a comment, and are +-- ignored. Blank lines, or lines containing only whitespace, are also +-- ignored. + +-- The majority of the values below were computed with the help of +-- version 2.3 of the MPFR library for multiple-precision +-- floating-point computations with correct rounding. All output +-- values in this file are (modulo yet-to-be-discovered bugs) +-- correctly rounded, provided that each input and output decimal +-- floating-point value below is interpreted as a representation of +-- the corresponding nearest IEEE 754 double-precision value. See the +-- MPFR homepage at http://www.mpfr.org for more information about the +-- MPFR project. + +----------------------- +-- sqrt: Square root -- +----------------------- + +-- zeros +sqrt0000 sqrt 0.0 0.0 -> 0.0 0.0 +sqrt0001 sqrt 0.0 -0.0 -> 0.0 -0.0 +sqrt0002 sqrt -0.0 0.0 -> 0.0 0.0 +sqrt0003 sqrt -0.0 -0.0 -> 0.0 -0.0 +sqrt0004 sqrt 1.0 -0.0 -> 1.0 -0.0 + +-- values along both sides of real axis +sqrt0010 sqrt -1.40129846432481707092372958329e-45 0.0 -> 0.0 3.743392130574644e-23 +sqrt0011 sqrt -1.40129846432481707092372958329e-45 -0.0 -> 0.0 -3.743392130574644e-23 +sqrt0012 sqrt -1e-35 0.0 -> 0.0 3.1622776601683795e-18 +sqrt0013 sqrt -1e-35 -0.0 -> 0.0 -3.1622776601683791e-18 +sqrt0014 sqrt -1e-20 0.0 -> 0.0 9.9999999999999996e-11 +sqrt0015 sqrt -1e-20 -0.0 -> 0.0 -9.9999999999999996e-11 +sqrt0016 sqrt -9.9999999999999998e-17 0.0 -> 0.0 1e-08 +sqrt0017 sqrt -9.9999999999999998e-17 -0.0 -> 0.0 -1e-08 +sqrt0018 sqrt -0.001 0.0 -> 0.0 0.031622776601683791 +sqrt0019 sqrt -0.001 -0.0 -> 0.0 -0.031622776601683791 +sqrt0020 sqrt -0.57899999999999996 0.0 -> 0.0 0.76092049518987193 +sqrt0021 sqrt -0.57899999999999996 -0.0 -> 0.0 -0.76092049518987193 +sqrt0022 sqrt -0.99999999999999989 0.0 -> 0.0 0.99999999999999989 +sqrt0023 sqrt -0.99999999999999989 -0.0 -> 0.0 -0.99999999999999989 +sqrt0024 sqrt -1.0000000000000002 0.0 -> 0.0 1.0 +sqrt0025 sqrt -1.0000000000000002 -0.0 -> 0.0 -1.0 +sqrt0026 sqrt -1.0009999999999999 0.0 -> 0.0 1.000499875062461 +sqrt0027 sqrt -1.0009999999999999 -0.0 -> 0.0 -1.000499875062461 +sqrt0028 sqrt -2.0 0.0 -> 0.0 1.4142135623730951 +sqrt0029 sqrt -2.0 -0.0 -> 0.0 -1.4142135623730951 +sqrt0030 sqrt -23.0 0.0 -> 0.0 4.7958315233127191 +sqrt0031 sqrt -23.0 -0.0 -> 0.0 -4.7958315233127191 +sqrt0032 sqrt -10000000000000000.0 0.0 -> 0.0 100000000.0 +sqrt0033 sqrt -10000000000000000.0 -0.0 -> 0.0 -100000000.0 +sqrt0034 sqrt -9.9999999999999998e+19 0.0 -> 0.0 9.9999999999999993e+9 +sqrt0035 sqrt -9.9999999999999998e+19 -0.0 -> 0.0 -9.9999999999999993e+9 +sqrt0036 sqrt -1.0000000000000001e+29 0.0 -> 0.0 3.1622776601683796e+14 +sqrt0037 sqrt -1.0000000000000001e+29 -0.0 -> 0.0 -3.1622776601683796e+14 +sqrt0038 sqrt 1.40129846432481707092372958329e-45 0.0 -> 3.743392130574644e-162 0.0 +sqrt0039 sqrt 9.8813129168249309e-324 -0.0 -> 3.1434555694052576e-162 -0.0 +sqrt0040 sqrt 1e-305 0.0 -> 3.1622776601683791e-153 0.0 +sqrt0041 sqrt 1e-305 -0.0 -> 3.1622776601683791e-153 -0.0 +sqrt0042 sqrt 1e-150 0.0 -> 9.9999999999999996e-76 0.0 +sqrt0043 sqrt 1e-150 -0.0 -> 9.9999999999999996e-76 -0.0 +sqrt0044 sqrt 9.9999999999999998e-17 0.0 -> 1e-08 0.0 +sqrt0045 sqrt 9.9999999999999998e-17 -0.0 -> 1e-08 -0.0 +sqrt0046 sqrt 0.001 0.0 -> 0.031622776601683791 0.0 +sqrt0047 sqrt 0.001 -0.0 -> 0.031622776601683791 -0.0 +sqrt0048 sqrt 0.57899999999999996 0.0 -> 0.76092049518987193 0.0 +sqrt0049 sqrt 0.57899999999999996 -0.0 -> 0.76092049518987193 -0.0 +sqrt0050 sqrt 0.99999999999999989 0.0 -> 0.99999999999999989 0.0 +sqrt0051 sqrt 0.99999999999999989 -0.0 -> 0.99999999999999989 -0.0 +sqrt0052 sqrt 1.0000000000000002 0.0 -> 1.0 0.0 +sqrt0053 sqrt 1.0000000000000002 -0.0 -> 1.0 -0.0 +sqrt0054 sqrt 1.0009999999999999 0.0 -> 1.000499875062461 0.0 +sqrt0055 sqrt 1.0009999999999999 -0.0 -> 1.000499875062461 -0.0 +sqrt0056 sqrt 2.0 0.0 -> 1.4142135623730951 0.0 +sqrt0057 sqrt 2.0 -0.0 -> 1.4142135623730951 -0.0 +sqrt0058 sqrt 23.0 0.0 -> 4.7958315233127191 0.0 +sqrt0059 sqrt 23.0 -0.0 -> 4.7958315233127191 -0.0 +sqrt0060 sqrt 10000000000000000.0 0.0 -> 100000000.0 0.0 +sqrt0061 sqrt 10000000000000000.0 -0.0 -> 100000000.0 -0.0 +sqrt0062 sqrt 9.9999999999999998e+149 0.0 -> 9.9999999999999993e+74 0.0 +sqrt0063 sqrt 9.9999999999999998e+149 -0.0 -> 9.9999999999999993e+74 -0.0 +sqrt0064 sqrt 1.0000000000000001e+299 0.0 -> 3.1622776601683796e+149 0.0 +sqrt0065 sqrt 1.0000000000000001e+299 -0.0 -> 3.1622776601683796e+149 -0.0 + +-- random inputs +sqrt0100 sqrt -0.34252542541549913 -223039880.15076211 -> 10560.300180587592 -10560.300196805192 +sqrt0101 sqrt -0.88790791393018909 -5.3307751730827402 -> 1.5027154613689004 -1.7737140896343291 +sqrt0102 sqrt -113916.89291310767 -0.018143374626153858 -> 2.6877817875351178e-05 -337.51576691038952 +sqrt0103 sqrt -0.63187172386197121 -0.26293913366617694 -> 0.16205707495266153 -0.81125471918761971 +sqrt0104 sqrt -0.058185169308906215 -2.3548312990430991 -> 1.0717660342420072 -1.0985752598086966 +sqrt0105 sqrt -1.0580584765935896 0.14400319259151736 -> 0.069837489270111242 1.030987755262468 +sqrt0106 sqrt -1.1667595947504932 0.11159711473953678 -> 0.051598531319315251 1.0813981705111229 +sqrt0107 sqrt -0.5123728411449906 0.026175433648339085 -> 0.018278026262418718 0.71603556293597614 +sqrt0108 sqrt -3.7453400060067228 1.0946500314809635 -> 0.27990088541692498 1.9554243814742367 +sqrt0109 sqrt -0.0027736121575097673 1.0367943000839817 -> 0.71903560338719175 0.72096172651250545 +sqrt0110 sqrt 1501.2559699453188 -1.1997325207283589 -> 38.746047664730959 -0.015481998720355024 +sqrt0111 sqrt 1.4830075326850578 -0.64100878436755349 -> 1.244712815741096 -0.25749264258434584 +sqrt0112 sqrt 0.095395618499734602 -0.48226565701639595 -> 0.54175904053472879 -0.44509239434231551 +sqrt0113 sqrt 0.50109185681863277 -0.54054037379892561 -> 0.7868179858332387 -0.34349772344520979 +sqrt0114 sqrt 0.98779807595367897 -0.00019848758437225191 -> 0.99388031770665153 -9.9854872279921968e-05 +sqrt0115 sqrt 11.845472380792259 0.0010051104581506761 -> 3.4417252072345397 0.00014601840612346451 +sqrt0116 sqrt 2.3558249686735975 0.25605157371744403 -> 1.5371278477386647 0.083288964575761404 +sqrt0117 sqrt 0.77584894123159098 1.0496420627016076 -> 1.0200744386390885 0.51449287568756552 +sqrt0118 sqrt 1.8961715669604893 0.34940793467158854 -> 1.3827991781411615 0.12634080935066902 +sqrt0119 sqrt 0.96025378316565801 0.69573224860140515 -> 1.0358710342209998 0.33581991658093457 + +-- values near 0 +sqrt0120 sqrt 7.3577938365086866e-313 8.1181408465112743e-319 -> 8.5777583531543516e-157 4.732087634251168e-163 +sqrt0121 sqrt 1.2406883874892108e-310 -5.1210133324269776e-312 -> 1.1140990057468052e-155 -2.2982756945349973e-157 +sqrt0122 sqrt -7.1145453001139502e-322 2.9561379244703735e-314 -> 1.2157585807480286e-157 1.2157586100077242e-157 +sqrt0123 sqrt -4.9963244206801218e-314 -8.4718424423690227e-319 -> 1.8950582312540437e-162 -2.2352459419578971e-157 +sqrt0124 sqrt 0.0 7.699553609385195e-318 -> 1.9620848107797476e-159 1.9620848107797476e-159 +sqrt0125 sqrt -0.0 3.3900826606499415e-309 -> 4.1170879639922327e-155 4.1170879639922327e-155 +sqrt0126 sqrt 0.0 -9.8907989772250828e-319 -> 7.032353438652342e-160 -7.032353438652342e-160 +sqrt0127 sqrt -0.0 -1.3722939367590908e-315 -> 2.6194407196566702e-158 -2.6194407196566702e-158 +sqrt0128 sqrt 7.9050503334599447e-323 0.0 -> 8.8910349979403099e-162 0.0 +sqrt0129 sqrt 1.8623241768349486e-309 -0.0 -> 4.3154654173506579e-155 -0.0 +sqrt0130 sqrt -2.665971134499887e-308 0.0 -> 0.0 1.6327801856036491e-154 +sqrt0131 sqrt -1.5477066694467245e-310 -0.0 -> 0.0 -1.2440685951533077e-155 + +-- inputs whose absolute value overflows +sqrt0140 sqrt 1.6999999999999999e+308 -1.6999999999999999e+308 -> 1.4325088230154573e+154 -5.9336458271212207e+153 +sqrt0141 sqrt -1.797e+308 -9.9999999999999999e+306 -> 3.7284476432057307e+152 -1.3410406899802901e+154 + +-- special values +sqrt1000 sqrt 0.0 0.0 -> 0.0 0.0 +sqrt1001 sqrt -0.0 0.0 -> 0.0 0.0 +sqrt1002 sqrt 0.0 inf -> inf inf +sqrt1003 sqrt 2.3 inf -> inf inf +sqrt1004 sqrt inf inf -> inf inf +sqrt1005 sqrt -0.0 inf -> inf inf +sqrt1006 sqrt -2.3 inf -> inf inf +sqrt1007 sqrt -inf inf -> inf inf +sqrt1008 sqrt nan inf -> inf inf +sqrt1009 sqrt 0.0 nan -> nan nan +sqrt1010 sqrt 2.3 nan -> nan nan +sqrt1011 sqrt -0.0 nan -> nan nan +sqrt1012 sqrt -2.3 nan -> nan nan +sqrt1013 sqrt -inf 0.0 -> 0.0 inf +sqrt1014 sqrt -inf 2.3 -> 0.0 inf +sqrt1015 sqrt inf 0.0 -> inf 0.0 +sqrt1016 sqrt inf 2.3 -> inf 0.0 +sqrt1017 sqrt -inf nan -> nan inf ignore-imag-sign +sqrt1018 sqrt inf nan -> inf nan +sqrt1019 sqrt nan 0.0 -> nan nan +sqrt1020 sqrt nan 2.3 -> nan nan +sqrt1021 sqrt nan nan -> nan nan +sqrt1022 sqrt 0.0 -0.0 -> 0.0 -0.0 +sqrt1023 sqrt -0.0 -0.0 -> 0.0 -0.0 +sqrt1024 sqrt 0.0 -inf -> inf -inf +sqrt1025 sqrt 2.3 -inf -> inf -inf +sqrt1026 sqrt inf -inf -> inf -inf +sqrt1027 sqrt -0.0 -inf -> inf -inf +sqrt1028 sqrt -2.3 -inf -> inf -inf +sqrt1029 sqrt -inf -inf -> inf -inf +sqrt1030 sqrt nan -inf -> inf -inf +sqrt1031 sqrt -inf -0.0 -> 0.0 -inf +sqrt1032 sqrt -inf -2.3 -> 0.0 -inf +sqrt1033 sqrt inf -0.0 -> inf -0.0 +sqrt1034 sqrt inf -2.3 -> inf -0.0 +sqrt1035 sqrt nan -0.0 -> nan nan +sqrt1036 sqrt nan -2.3 -> nan nan + + + +-------------------------- +-- acos: Inverse cosine -- +-------------------------- + +-- zeros +acos0000 acos 0.0 0.0 -> 1.5707963267948966 -0.0 +acos0001 acos 0.0 -0.0 -> 1.5707963267948966 0.0 +acos0002 acos -0.0 0.0 -> 1.5707963267948966 -0.0 +acos0003 acos -0.0 -0.0 -> 1.5707963267948966 0.0 + +-- branch points: +/-1 +acos0010 acos 1.0 0.0 -> 0.0 -0.0 +acos0011 acos 1.0 -0.0 -> 0.0 0.0 +acos0012 acos -1.0 0.0 -> 3.1415926535897931 -0.0 +acos0013 acos -1.0 -0.0 -> 3.1415926535897931 0.0 + +-- values along both sides of real axis +acos0020 acos -9.8813129168249309e-324 0.0 -> 1.5707963267948966 -0.0 +acos0021 acos -9.8813129168249309e-324 -0.0 -> 1.5707963267948966 0.0 +acos0022 acos -1e-305 0.0 -> 1.5707963267948966 -0.0 +acos0023 acos -1e-305 -0.0 -> 1.5707963267948966 0.0 +acos0024 acos -1e-150 0.0 -> 1.5707963267948966 -0.0 +acos0025 acos -1e-150 -0.0 -> 1.5707963267948966 0.0 +acos0026 acos -9.9999999999999998e-17 0.0 -> 1.5707963267948968 -0.0 +acos0027 acos -9.9999999999999998e-17 -0.0 -> 1.5707963267948968 0.0 +acos0028 acos -0.001 0.0 -> 1.5717963269615634 -0.0 +acos0029 acos -0.001 -0.0 -> 1.5717963269615634 0.0 +acos0030 acos -0.57899999999999996 0.0 -> 2.1882979816120667 -0.0 +acos0031 acos -0.57899999999999996 -0.0 -> 2.1882979816120667 0.0 +acos0032 acos -0.99999999999999989 0.0 -> 3.1415926386886319 -0.0 +acos0033 acos -0.99999999999999989 -0.0 -> 3.1415926386886319 0.0 +acos0034 acos -1.0000000000000002 0.0 -> 3.1415926535897931 -2.1073424255447014e-08 +acos0035 acos -1.0000000000000002 -0.0 -> 3.1415926535897931 2.1073424255447014e-08 +acos0036 acos -1.0009999999999999 0.0 -> 3.1415926535897931 -0.044717633608306849 +acos0037 acos -1.0009999999999999 -0.0 -> 3.1415926535897931 0.044717633608306849 +acos0038 acos -2.0 0.0 -> 3.1415926535897931 -1.3169578969248168 +acos0039 acos -2.0 -0.0 -> 3.1415926535897931 1.3169578969248168 +acos0040 acos -23.0 0.0 -> 3.1415926535897931 -3.8281684713331012 +acos0041 acos -23.0 -0.0 -> 3.1415926535897931 3.8281684713331012 +acos0042 acos -10000000000000000.0 0.0 -> 3.1415926535897931 -37.534508668464674 +acos0043 acos -10000000000000000.0 -0.0 -> 3.1415926535897931 37.534508668464674 +acos0044 acos -9.9999999999999998e+149 0.0 -> 3.1415926535897931 -346.08091112966679 +acos0045 acos -9.9999999999999998e+149 -0.0 -> 3.1415926535897931 346.08091112966679 +acos0046 acos -1.0000000000000001e+299 0.0 -> 3.1415926535897931 -689.16608998577965 +acos0047 acos -1.0000000000000001e+299 -0.0 -> 3.1415926535897931 689.16608998577965 +acos0048 acos 9.8813129168249309e-324 0.0 -> 1.5707963267948966 -0.0 +acos0049 acos 9.8813129168249309e-324 -0.0 -> 1.5707963267948966 0.0 +acos0050 acos 1e-305 0.0 -> 1.5707963267948966 -0.0 +acos0051 acos 1e-305 -0.0 -> 1.5707963267948966 0.0 +acos0052 acos 1e-150 0.0 -> 1.5707963267948966 -0.0 +acos0053 acos 1e-150 -0.0 -> 1.5707963267948966 0.0 +acos0054 acos 9.9999999999999998e-17 0.0 -> 1.5707963267948966 -0.0 +acos0055 acos 9.9999999999999998e-17 -0.0 -> 1.5707963267948966 0.0 +acos0056 acos 0.001 0.0 -> 1.56979632662823 -0.0 +acos0057 acos 0.001 -0.0 -> 1.56979632662823 0.0 +acos0058 acos 0.57899999999999996 0.0 -> 0.95329467197772655 -0.0 +acos0059 acos 0.57899999999999996 -0.0 -> 0.95329467197772655 0.0 +acos0060 acos 0.99999999999999989 0.0 -> 1.4901161193847656e-08 -0.0 +acos0061 acos 0.99999999999999989 -0.0 -> 1.4901161193847656e-08 0.0 +acos0062 acos 1.0000000000000002 0.0 -> 0.0 -2.1073424255447014e-08 +acos0063 acos 1.0000000000000002 -0.0 -> 0.0 2.1073424255447014e-08 +acos0064 acos 1.0009999999999999 0.0 -> 0.0 -0.044717633608306849 +acos0065 acos 1.0009999999999999 -0.0 -> 0.0 0.044717633608306849 +acos0066 acos 2.0 0.0 -> 0.0 -1.3169578969248168 +acos0067 acos 2.0 -0.0 -> 0.0 1.3169578969248168 +acos0068 acos 23.0 0.0 -> 0.0 -3.8281684713331012 +acos0069 acos 23.0 -0.0 -> 0.0 3.8281684713331012 +acos0070 acos 10000000000000000.0 0.0 -> 0.0 -37.534508668464674 +acos0071 acos 10000000000000000.0 -0.0 -> 0.0 37.534508668464674 +acos0072 acos 9.9999999999999998e+149 0.0 -> 0.0 -346.08091112966679 +acos0073 acos 9.9999999999999998e+149 -0.0 -> 0.0 346.08091112966679 +acos0074 acos 1.0000000000000001e+299 0.0 -> 0.0 -689.16608998577965 +acos0075 acos 1.0000000000000001e+299 -0.0 -> 0.0 689.16608998577965 + +-- random inputs +acos0100 acos -3.3307113324596682 -10.732007530863266 -> 1.8706085694482339 3.113986806554613 +acos0101 acos -2863.952991743291 -2681013315.2571239 -> 1.5707973950301699 22.402607843274758 +acos0102 acos -0.33072639793220088 -0.85055464658253055 -> 1.8219426895922601 0.79250166729311966 +acos0103 acos -2.5722325842097802 -12.703940809821574 -> 1.7699942413107408 3.2565170156527325 +acos0104 acos -42.495233785459583 -0.54039320751337161 -> 3.1288732573153304 4.4424815519735601 +acos0105 acos -1.1363818625856401 9641.1325498630376 -> 1.5709141948820049 -9.8669410553254284 +acos0106 acos -2.4398426824157866e-11 0.33002051890266165 -> 1.570796326818066 -0.32430578041578667 +acos0107 acos -1.3521340428186552 2.9369737912076772 -> 1.9849059192339338 -1.8822893674117942 +acos0108 acos -1.827364706477915 1.0355459232147557 -> 2.5732246307960032 -1.4090688267854969 +acos0109 acos -0.25978373706403546 10.09712669185833 -> 1.5963940386378306 -3.0081673050196063 +acos0110 acos 0.33561778471072551 -4587350.6823999118 -> 1.5707962536333251 16.031960402579539 +acos0111 acos 0.49133444610998445 -0.8071422362990015 -> 1.1908761712801788 0.78573345813187867 +acos0112 acos 0.42196734507823974 -2.4812965431745115 -> 1.414091186100692 1.651707260988172 +acos0113 acos 2.961426210100655 -219.03295695248664 -> 1.5572768319822778 6.0824659885827304 +acos0114 acos 2.886209063652641 -20.38011207220606 -> 1.4302765252297889 3.718201853147642 +acos0115 acos 0.4180568075276509 1.4833433990823484 -> 1.3393834558303042 -1.2079847758301576 +acos0116 acos 52.376111405924718 0.013930429001941001 -> 0.00026601761804024188 -4.6515066691204714 +acos0117 acos 41637948387.625969 1.563418292894041 -> 3.7547918507883548e-11 -25.145424989809381 +acos0118 acos 0.061226659122249526 0.8447234394615154 -> 1.5240280306367315 -0.76791798971140812 +acos0119 acos 2.4480466420442959e+26 0.18002339201384662 -> 7.353756620564798e-28 -61.455650015996376 + +-- values near infinity +acos0200 acos 1.6206860518683021e+308 1.0308426226285283e+308 -> 0.56650826093826223 -710.54206874241561 +acos0201 acos 1.2067735875070062e+308 -1.3429173724390276e+308 -> 0.83874369390864889 710.48017794027498 +acos0202 acos -7.4130145132549047e+307 1.1759130543927645e+308 -> 2.1332729346478536 -710.21871115698752 +acos0203 acos -8.6329426442257249e+307 -1.2316282952184133e+308 -> 2.1821511032444838 710.29752145697148 +acos0204 acos 0.0 1.4289713855849746e+308 -> 1.5707963267948966 -710.24631069738996 +acos0205 acos -0.0 1.3153524545987432e+308 -> 1.5707963267948966 -710.1634604787539 +acos0206 acos 0.0 -9.6229037669269321e+307 -> 1.5707963267948966 709.85091679573691 +acos0207 acos -0.0 -4.9783616421107088e+307 -> 1.5707963267948966 709.19187157911233 +acos0208 acos 1.3937541925739389e+308 0.0 -> 0.0 -710.22135678707264 +acos0209 acos 9.1362388967371536e+307 -0.0 -> 0.0 709.79901953124613 +acos0210 acos -1.3457361220697436e+308 0.0 -> 3.1415926535897931 -710.18629698871848 +acos0211 acos -5.4699090056144284e+307 -0.0 -> 3.1415926535897931 709.28603271085649 +acos0212 acos 1.5880716932358901e+308 5.5638401252339929 -> 3.503519487773873e-308 -710.35187633140583 +acos0213 acos 1.2497211663463164e+308 -3.0456477717911024 -> 2.4370618453197486e-308 710.11227628223412 +acos0214 acos -9.9016224006029528e+307 4.9570427340789056 -> 3.1415926535897931 -709.87946935229468 +acos0215 acos -1.5854071066874139e+308 -4.4233577741497783 -> 3.1415926535897931 710.35019704672004 +acos0216 acos 9.3674623083647628 1.5209559051877979e+308 -> 1.5707963267948966 -710.30869484491086 +acos0217 acos 8.1773832021784383 -6.6093445795000056e+307 -> 1.5707963267948966 709.4752552227792 +acos0218 acos -3.1845935000665104 1.5768856396650893e+308 -> 1.5707963267948966 -710.34480761042687 +acos0219 acos -1.0577303880953903 -6.4574626815735613e+307 -> 1.5707963267948966 709.45200719662046 + +-- values near 0 +acos0220 acos 1.8566986970714045e-320 3.1867234156760402e-321 -> 1.5707963267948966 -3.1867234156760402e-321 +acos0221 acos 7.9050503334599447e-323 -8.8931816251424378e-323 -> 1.5707963267948966 8.8931816251424378e-323 +acos0222 acos -4.4465908125712189e-323 2.4654065097222727e-311 -> 1.5707963267948966 -2.4654065097222727e-311 +acos0223 acos -6.1016916408192619e-311 -2.4703282292062327e-323 -> 1.5707963267948966 2.4703282292062327e-323 +acos0224 acos 0.0 3.4305783621842729e-311 -> 1.5707963267948966 -3.4305783621842729e-311 +acos0225 acos -0.0 1.6117409498633145e-319 -> 1.5707963267948966 -1.6117409498633145e-319 +acos0226 acos 0.0 -4.9900630229965901e-322 -> 1.5707963267948966 4.9900630229965901e-322 +acos0227 acos -0.0 -4.4889279210592818e-311 -> 1.5707963267948966 4.4889279210592818e-311 +acos0228 acos 5.3297678681477214e-312 0.0 -> 1.5707963267948966 -0.0 +acos0229 acos 6.2073425897211614e-313 -0.0 -> 1.5707963267948966 0.0 +acos0230 acos -4.9406564584124654e-324 0.0 -> 1.5707963267948966 -0.0 +acos0231 acos -1.7107517052899003e-318 -0.0 -> 1.5707963267948966 0.0 + +-- special values +acos1000 acos 0.0 0.0 -> 1.5707963267948966 -0.0 +acos1001 acos 0.0 -0.0 -> 1.5707963267948966 0.0 +acos1002 acos -0.0 0.0 -> 1.5707963267948966 -0.0 +acos1003 acos -0.0 -0.0 -> 1.5707963267948966 0.0 +acos1004 acos 0.0 nan -> 1.5707963267948966 nan +acos1005 acos -0.0 nan -> 1.5707963267948966 nan +acos1006 acos -2.3 inf -> 1.5707963267948966 -inf +acos1007 acos -0.0 inf -> 1.5707963267948966 -inf +acos1008 acos 0.0 inf -> 1.5707963267948966 -inf +acos1009 acos 2.3 inf -> 1.5707963267948966 -inf +acos1010 acos -2.3 nan -> nan nan +acos1011 acos 2.3 nan -> nan nan +acos1012 acos -inf 2.3 -> 3.1415926535897931 -inf +acos1013 acos -inf 0.0 -> 3.1415926535897931 -inf +acos1014 acos inf 2.3 -> 0.0 -inf +acos1015 acos inf 0.0 -> 0.0 -inf +acos1016 acos -inf inf -> 2.3561944901923448 -inf +acos1017 acos inf inf -> 0.78539816339744828 -inf +acos1018 acos inf nan -> nan inf ignore-imag-sign +acos1019 acos -inf nan -> nan inf ignore-imag-sign +acos1020 acos nan 0.0 -> nan nan +acos1021 acos nan 2.3 -> nan nan +acos1022 acos nan inf -> nan -inf +acos1023 acos nan nan -> nan nan +acos1024 acos -2.3 -inf -> 1.5707963267948966 inf +acos1025 acos -0.0 -inf -> 1.5707963267948966 inf +acos1026 acos 0.0 -inf -> 1.5707963267948966 inf +acos1027 acos 2.3 -inf -> 1.5707963267948966 inf +acos1028 acos -inf -2.3 -> 3.1415926535897931 inf +acos1029 acos -inf -0.0 -> 3.1415926535897931 inf +acos1030 acos inf -2.3 -> 0.0 inf +acos1031 acos inf -0.0 -> 0.0 inf +acos1032 acos -inf -inf -> 2.3561944901923448 inf +acos1033 acos inf -inf -> 0.78539816339744828 inf +acos1034 acos nan -0.0 -> nan nan +acos1035 acos nan -2.3 -> nan nan +acos1036 acos nan -inf -> nan inf + + +-------------------------------------- +-- acosh: Inverse hyperbolic cosine -- +-------------------------------------- + +-- zeros +acosh0000 acosh 0.0 0.0 -> 0.0 1.5707963267948966 +acosh0001 acosh 0.0 -0.0 -> 0.0 -1.5707963267948966 +acosh0002 acosh -0.0 0.0 -> 0.0 1.5707963267948966 +acosh0003 acosh -0.0 -0.0 -> 0.0 -1.5707963267948966 + +-- branch points: +/-1 +acosh0010 acosh 1.0 0.0 -> 0.0 0.0 +acosh0011 acosh 1.0 -0.0 -> 0.0 -0.0 +acosh0012 acosh -1.0 0.0 -> 0.0 3.1415926535897931 +acosh0013 acosh -1.0 -0.0 -> 0.0 -3.1415926535897931 + +-- values along both sides of real axis +acosh0020 acosh -9.8813129168249309e-324 0.0 -> 0.0 1.5707963267948966 +acosh0021 acosh -9.8813129168249309e-324 -0.0 -> 0.0 -1.5707963267948966 +acosh0022 acosh -1e-305 0.0 -> 0.0 1.5707963267948966 +acosh0023 acosh -1e-305 -0.0 -> 0.0 -1.5707963267948966 +acosh0024 acosh -1e-150 0.0 -> 0.0 1.5707963267948966 +acosh0025 acosh -1e-150 -0.0 -> 0.0 -1.5707963267948966 +acosh0026 acosh -9.9999999999999998e-17 0.0 -> 0.0 1.5707963267948968 +acosh0027 acosh -9.9999999999999998e-17 -0.0 -> 0.0 -1.5707963267948968 +acosh0028 acosh -0.001 0.0 -> 0.0 1.5717963269615634 +acosh0029 acosh -0.001 -0.0 -> 0.0 -1.5717963269615634 +acosh0030 acosh -0.57899999999999996 0.0 -> 0.0 2.1882979816120667 +acosh0031 acosh -0.57899999999999996 -0.0 -> 0.0 -2.1882979816120667 +acosh0032 acosh -0.99999999999999989 0.0 -> 0.0 3.1415926386886319 +acosh0033 acosh -0.99999999999999989 -0.0 -> 0.0 -3.1415926386886319 +acosh0034 acosh -1.0000000000000002 0.0 -> 2.1073424255447014e-08 3.1415926535897931 +acosh0035 acosh -1.0000000000000002 -0.0 -> 2.1073424255447014e-08 -3.1415926535897931 +acosh0036 acosh -1.0009999999999999 0.0 -> 0.044717633608306849 3.1415926535897931 +acosh0037 acosh -1.0009999999999999 -0.0 -> 0.044717633608306849 -3.1415926535897931 +acosh0038 acosh -2.0 0.0 -> 1.3169578969248168 3.1415926535897931 +acosh0039 acosh -2.0 -0.0 -> 1.3169578969248168 -3.1415926535897931 +acosh0040 acosh -23.0 0.0 -> 3.8281684713331012 3.1415926535897931 +acosh0041 acosh -23.0 -0.0 -> 3.8281684713331012 -3.1415926535897931 +acosh0042 acosh -10000000000000000.0 0.0 -> 37.534508668464674 3.1415926535897931 +acosh0043 acosh -10000000000000000.0 -0.0 -> 37.534508668464674 -3.1415926535897931 +acosh0044 acosh -9.9999999999999998e+149 0.0 -> 346.08091112966679 3.1415926535897931 +acosh0045 acosh -9.9999999999999998e+149 -0.0 -> 346.08091112966679 -3.1415926535897931 +acosh0046 acosh -1.0000000000000001e+299 0.0 -> 689.16608998577965 3.1415926535897931 +acosh0047 acosh -1.0000000000000001e+299 -0.0 -> 689.16608998577965 -3.1415926535897931 +acosh0048 acosh 9.8813129168249309e-324 0.0 -> 0.0 1.5707963267948966 +acosh0049 acosh 9.8813129168249309e-324 -0.0 -> 0.0 -1.5707963267948966 +acosh0050 acosh 1e-305 0.0 -> 0.0 1.5707963267948966 +acosh0051 acosh 1e-305 -0.0 -> 0.0 -1.5707963267948966 +acosh0052 acosh 1e-150 0.0 -> 0.0 1.5707963267948966 +acosh0053 acosh 1e-150 -0.0 -> 0.0 -1.5707963267948966 +acosh0054 acosh 9.9999999999999998e-17 0.0 -> 0.0 1.5707963267948966 +acosh0055 acosh 9.9999999999999998e-17 -0.0 -> 0.0 -1.5707963267948966 +acosh0056 acosh 0.001 0.0 -> 0.0 1.56979632662823 +acosh0057 acosh 0.001 -0.0 -> 0.0 -1.56979632662823 +acosh0058 acosh 0.57899999999999996 0.0 -> 0.0 0.95329467197772655 +acosh0059 acosh 0.57899999999999996 -0.0 -> 0.0 -0.95329467197772655 +acosh0060 acosh 0.99999999999999989 0.0 -> 0.0 1.4901161193847656e-08 +acosh0061 acosh 0.99999999999999989 -0.0 -> 0.0 -1.4901161193847656e-08 +acosh0062 acosh 1.0000000000000002 0.0 -> 2.1073424255447014e-08 0.0 +acosh0063 acosh 1.0000000000000002 -0.0 -> 2.1073424255447014e-08 -0.0 +acosh0064 acosh 1.0009999999999999 0.0 -> 0.044717633608306849 0.0 +acosh0065 acosh 1.0009999999999999 -0.0 -> 0.044717633608306849 -0.0 +acosh0066 acosh 2.0 0.0 -> 1.3169578969248168 0.0 +acosh0067 acosh 2.0 -0.0 -> 1.3169578969248168 -0.0 +acosh0068 acosh 23.0 0.0 -> 3.8281684713331012 0.0 +acosh0069 acosh 23.0 -0.0 -> 3.8281684713331012 -0.0 +acosh0070 acosh 10000000000000000.0 0.0 -> 37.534508668464674 0.0 +acosh0071 acosh 10000000000000000.0 -0.0 -> 37.534508668464674 -0.0 +acosh0072 acosh 9.9999999999999998e+149 0.0 -> 346.08091112966679 0.0 +acosh0073 acosh 9.9999999999999998e+149 -0.0 -> 346.08091112966679 -0.0 +acosh0074 acosh 1.0000000000000001e+299 0.0 -> 689.16608998577965 0.0 +acosh0075 acosh 1.0000000000000001e+299 -0.0 -> 689.16608998577965 -0.0 + +-- random inputs +acosh0100 acosh -1.4328589581250843 -1.8370347775558309 -> 1.5526962646549587 -2.190250168435786 +acosh0101 acosh -0.31075819156220957 -1.0772555786839297 -> 0.95139168286193709 -1.7812228089636479 +acosh0102 acosh -1.9044776578070453 -20.485370158932124 -> 3.7177411088932359 -1.6633888745861227 +acosh0103 acosh -0.075642506000858742 -21965976320.873051 -> 24.505907742881991 -1.5707963267983402 +acosh0104 acosh -1.6162271181056307 -3.0369343458696099 -> 1.9407057262861227 -2.0429549461750209 +acosh0105 acosh -0.3103780280298063 0.00018054880018078987 -> 0.00018992877058761416 1.886386995096728 +acosh0106 acosh -9159468751.5897655 5.8014747664273649 -> 23.631201197959193 3.1415926529564078 +acosh0107 acosh -0.037739157550933884 0.21841357493510705 -> 0.21685844960602488 1.6076735133449402 +acosh0108 acosh -8225991.0508394297 0.28318543008913644 -> 16.615956520420287 3.1415926191641019 +acosh0109 acosh -35.620070502302639 0.31303237005015 -> 4.2658980006943965 3.1328013255541873 +acosh0110 acosh 96.729939906820917 -0.029345228372365334 -> 5.2650434775863548 -0.00030338895866972843 +acosh0111 acosh 0.59656024007966491 -2.0412294654163978 -> 1.4923002024287835 -1.312568421900338 +acosh0112 acosh 109.29384112677828 -0.00015454863061533812 -> 5.3871662961545477 -1.4141245154061214e-06 +acosh0113 acosh 8.6705651969361597 -3.6723631649787465 -> 2.9336180958363545 -0.40267362031872861 +acosh0114 acosh 1.8101646445052686 -0.012345132721855478 -> 1.1997148566285769 -0.0081813912760150265 +acosh0115 acosh 52.56897195025288 0.001113916065985443 -> 4.6551827622264135 2.1193445872040307e-05 +acosh0116 acosh 0.28336786164214739 355643992457.40485 -> 27.290343226816528 1.5707963267940999 +acosh0117 acosh 0.73876621291911437 2.8828594541104322e-20 -> 4.2774820978159067e-20 0.73955845836827927 +acosh0118 acosh 0.025865471781718878 37125746064318.492 -> 31.938478989418012 1.5707963267948959 +acosh0119 acosh 2.2047353511780132 0.074712248143489271 -> 1.4286403248698021 0.037997904971626598 + +-- values near infinity +acosh0200 acosh 8.1548592876467785e+307 9.0943779335951128e+307 -> 710.08944620800605 0.83981165425478954 +acosh0201 acosh 1.4237229680972531e+308 -1.0336966617874858e+308 -> 710.4543331094759 -0.6279972876348755 +acosh0202 acosh -1.5014526899738939e+308 1.5670700378448792e+308 -> 710.66420706795464 2.3348137299106697 +acosh0203 acosh -1.0939040375213928e+308 -1.0416960351127978e+308 -> 710.30182863115886 -2.380636147787027 +acosh0204 acosh 0.0 1.476062433559588e+308 -> 710.27873384716929 1.5707963267948966 +acosh0205 acosh -0.0 6.2077210326221094e+307 -> 709.41256457484769 1.5707963267948966 +acosh0206 acosh 0.0 -1.5621899909968308e+308 -> 710.33544449990734 -1.5707963267948966 +acosh0207 acosh -0.0 -8.3556624833839122e+307 -> 709.70971018048317 -1.5707963267948966 +acosh0208 acosh 1.3067079752499342e+308 0.0 -> 710.15686680107228 0.0 +acosh0209 acosh 1.5653640340214026e+308 -0.0 -> 710.33747422926706 -0.0 +acosh0210 acosh -6.9011375992290636e+307 0.0 -> 709.51845699719922 3.1415926535897931 +acosh0211 acosh -9.9539576809926973e+307 -0.0 -> 709.88474095870185 -3.1415926535897931 +acosh0212 acosh 7.6449598518914925e+307 9.5706540768268358 -> 709.62081731754802 1.2518906916769345e-307 +acosh0213 acosh 5.4325410972602197e+307 -7.8064807816522706 -> 709.279177727925 -1.4369851312471974e-307 +acosh0214 acosh -1.1523626112360465e+308 7.0617510038869336 -> 710.03117010216909 3.1415926535897931 +acosh0215 acosh -1.1685027786862599e+308 -5.1568558357925625 -> 710.04507907571417 -3.1415926535897931 +acosh0216 acosh 3.0236370339788721 1.7503248720096417e+308 -> 710.44915723458064 1.5707963267948966 +acosh0217 acosh 6.6108007926031149 -9.1469968225806149e+307 -> 709.80019633903328 -1.5707963267948966 +acosh0218 acosh -5.1096262905623959 6.4484926785412395e+307 -> 709.45061713997973 1.5707963267948966 +acosh0219 acosh -2.8080920608735846 -1.7716118836519368e+308 -> 710.46124562363445 -1.5707963267948966 + +-- values near 0 +acosh0220 acosh 4.5560530326699304e-317 7.3048989121436657e-318 -> 7.3048989121436657e-318 1.5707963267948966 +acosh0221 acosh 4.8754274133585331e-314 -9.8469794897684199e-315 -> 9.8469794897684199e-315 -1.5707963267948966 +acosh0222 acosh -4.6748876009960097e-312 9.7900342887557606e-318 -> 9.7900342887557606e-318 1.5707963267948966 +acosh0223 acosh -4.3136871538399236e-320 -4.9406564584124654e-323 -> 4.9406564584124654e-323 -1.5707963267948966 +acosh0224 acosh 0.0 4.3431013866496774e-314 -> 4.3431013866496774e-314 1.5707963267948966 +acosh0225 acosh -0.0 6.0147334335829184e-317 -> 6.0147334335829184e-317 1.5707963267948966 +acosh0226 acosh 0.0 -1.2880291387081297e-320 -> 1.2880291387081297e-320 -1.5707963267948966 +acosh0227 acosh -0.0 -1.4401563976534621e-317 -> 1.4401563976534621e-317 -1.5707963267948966 +acosh0228 acosh 1.3689680570863091e-313 0.0 -> 0.0 1.5707963267948966 +acosh0229 acosh 1.5304346893494371e-312 -0.0 -> 0.0 -1.5707963267948966 +acosh0230 acosh -3.7450175954766488e-320 0.0 -> 0.0 1.5707963267948966 +acosh0231 acosh -8.4250563080885801e-311 -0.0 -> 0.0 -1.5707963267948966 + +-- special values +acosh1000 acosh 0.0 0.0 -> 0.0 1.5707963267948966 +acosh1001 acosh -0.0 0.0 -> 0.0 1.5707963267948966 +acosh1002 acosh 0.0 inf -> inf 1.5707963267948966 +acosh1003 acosh 2.3 inf -> inf 1.5707963267948966 +acosh1004 acosh -0.0 inf -> inf 1.5707963267948966 +acosh1005 acosh -2.3 inf -> inf 1.5707963267948966 +acosh1006 acosh 0.0 nan -> nan nan +acosh1007 acosh 2.3 nan -> nan nan +acosh1008 acosh -0.0 nan -> nan nan +acosh1009 acosh -2.3 nan -> nan nan +acosh1010 acosh -inf 0.0 -> inf 3.1415926535897931 +acosh1011 acosh -inf 2.3 -> inf 3.1415926535897931 +acosh1012 acosh inf 0.0 -> inf 0.0 +acosh1013 acosh inf 2.3 -> inf 0.0 +acosh1014 acosh -inf inf -> inf 2.3561944901923448 +acosh1015 acosh inf inf -> inf 0.78539816339744828 +acosh1016 acosh inf nan -> inf nan +acosh1017 acosh -inf nan -> inf nan +acosh1018 acosh nan 0.0 -> nan nan +acosh1019 acosh nan 2.3 -> nan nan +acosh1020 acosh nan inf -> inf nan +acosh1021 acosh nan nan -> nan nan +acosh1022 acosh 0.0 -0.0 -> 0.0 -1.5707963267948966 +acosh1023 acosh -0.0 -0.0 -> 0.0 -1.5707963267948966 +acosh1024 acosh 0.0 -inf -> inf -1.5707963267948966 +acosh1025 acosh 2.3 -inf -> inf -1.5707963267948966 +acosh1026 acosh -0.0 -inf -> inf -1.5707963267948966 +acosh1027 acosh -2.3 -inf -> inf -1.5707963267948966 +acosh1028 acosh -inf -0.0 -> inf -3.1415926535897931 +acosh1029 acosh -inf -2.3 -> inf -3.1415926535897931 +acosh1030 acosh inf -0.0 -> inf -0.0 +acosh1031 acosh inf -2.3 -> inf -0.0 +acosh1032 acosh -inf -inf -> inf -2.3561944901923448 +acosh1033 acosh inf -inf -> inf -0.78539816339744828 +acosh1034 acosh nan -0.0 -> nan nan +acosh1035 acosh nan -2.3 -> nan nan +acosh1036 acosh nan -inf -> inf nan + + +------------------------ +-- asin: Inverse sine -- +------------------------ + +-- zeros +asin0000 asin 0.0 0.0 -> 0.0 0.0 +asin0001 asin 0.0 -0.0 -> 0.0 -0.0 +asin0002 asin -0.0 0.0 -> -0.0 0.0 +asin0003 asin -0.0 -0.0 -> -0.0 -0.0 + +-- branch points: +/-1 +asin0010 asin 1.0 0.0 -> 1.5707963267948966 0.0 +asin0011 asin 1.0 -0.0 -> 1.5707963267948966 -0.0 +asin0012 asin -1.0 0.0 -> -1.5707963267948966 0.0 +asin0013 asin -1.0 -0.0 -> -1.5707963267948966 -0.0 + +-- values along both sides of real axis +asin0020 asin -9.8813129168249309e-324 0.0 -> -9.8813129168249309e-324 0.0 +asin0021 asin -9.8813129168249309e-324 -0.0 -> -9.8813129168249309e-324 -0.0 +asin0022 asin -1e-305 0.0 -> -1e-305 0.0 +asin0023 asin -1e-305 -0.0 -> -1e-305 -0.0 +asin0024 asin -1e-150 0.0 -> -1e-150 0.0 +asin0025 asin -1e-150 -0.0 -> -1e-150 -0.0 +asin0026 asin -9.9999999999999998e-17 0.0 -> -9.9999999999999998e-17 0.0 +asin0027 asin -9.9999999999999998e-17 -0.0 -> -9.9999999999999998e-17 -0.0 +asin0028 asin -0.001 0.0 -> -0.0010000001666667416 0.0 +asin0029 asin -0.001 -0.0 -> -0.0010000001666667416 -0.0 +asin0030 asin -0.57899999999999996 0.0 -> -0.61750165481717001 0.0 +asin0031 asin -0.57899999999999996 -0.0 -> -0.61750165481717001 -0.0 +asin0032 asin -0.99999999999999989 0.0 -> -1.5707963118937354 0.0 +asin0033 asin -0.99999999999999989 -0.0 -> -1.5707963118937354 -0.0 +asin0034 asin -1.0000000000000002 0.0 -> -1.5707963267948966 2.1073424255447014e-08 +asin0035 asin -1.0000000000000002 -0.0 -> -1.5707963267948966 -2.1073424255447014e-08 +asin0036 asin -1.0009999999999999 0.0 -> -1.5707963267948966 0.044717633608306849 +asin0037 asin -1.0009999999999999 -0.0 -> -1.5707963267948966 -0.044717633608306849 +asin0038 asin -2.0 0.0 -> -1.5707963267948966 1.3169578969248168 +asin0039 asin -2.0 -0.0 -> -1.5707963267948966 -1.3169578969248168 +asin0040 asin -23.0 0.0 -> -1.5707963267948966 3.8281684713331012 +asin0041 asin -23.0 -0.0 -> -1.5707963267948966 -3.8281684713331012 +asin0042 asin -10000000000000000.0 0.0 -> -1.5707963267948966 37.534508668464674 +asin0043 asin -10000000000000000.0 -0.0 -> -1.5707963267948966 -37.534508668464674 +asin0044 asin -9.9999999999999998e+149 0.0 -> -1.5707963267948966 346.08091112966679 +asin0045 asin -9.9999999999999998e+149 -0.0 -> -1.5707963267948966 -346.08091112966679 +asin0046 asin -1.0000000000000001e+299 0.0 -> -1.5707963267948966 689.16608998577965 +asin0047 asin -1.0000000000000001e+299 -0.0 -> -1.5707963267948966 -689.16608998577965 +asin0048 asin 9.8813129168249309e-324 0.0 -> 9.8813129168249309e-324 0.0 +asin0049 asin 9.8813129168249309e-324 -0.0 -> 9.8813129168249309e-324 -0.0 +asin0050 asin 1e-305 0.0 -> 1e-305 0.0 +asin0051 asin 1e-305 -0.0 -> 1e-305 -0.0 +asin0052 asin 1e-150 0.0 -> 1e-150 0.0 +asin0053 asin 1e-150 -0.0 -> 1e-150 -0.0 +asin0054 asin 9.9999999999999998e-17 0.0 -> 9.9999999999999998e-17 0.0 +asin0055 asin 9.9999999999999998e-17 -0.0 -> 9.9999999999999998e-17 -0.0 +asin0056 asin 0.001 0.0 -> 0.0010000001666667416 0.0 +asin0057 asin 0.001 -0.0 -> 0.0010000001666667416 -0.0 +asin0058 asin 0.57899999999999996 0.0 -> 0.61750165481717001 0.0 +asin0059 asin 0.57899999999999996 -0.0 -> 0.61750165481717001 -0.0 +asin0060 asin 0.99999999999999989 0.0 -> 1.5707963118937354 0.0 +asin0061 asin 0.99999999999999989 -0.0 -> 1.5707963118937354 -0.0 +asin0062 asin 1.0000000000000002 0.0 -> 1.5707963267948966 2.1073424255447014e-08 +asin0063 asin 1.0000000000000002 -0.0 -> 1.5707963267948966 -2.1073424255447014e-08 +asin0064 asin 1.0009999999999999 0.0 -> 1.5707963267948966 0.044717633608306849 +asin0065 asin 1.0009999999999999 -0.0 -> 1.5707963267948966 -0.044717633608306849 +asin0066 asin 2.0 0.0 -> 1.5707963267948966 1.3169578969248168 +asin0067 asin 2.0 -0.0 -> 1.5707963267948966 -1.3169578969248168 +asin0068 asin 23.0 0.0 -> 1.5707963267948966 3.8281684713331012 +asin0069 asin 23.0 -0.0 -> 1.5707963267948966 -3.8281684713331012 +asin0070 asin 10000000000000000.0 0.0 -> 1.5707963267948966 37.534508668464674 +asin0071 asin 10000000000000000.0 -0.0 -> 1.5707963267948966 -37.534508668464674 +asin0072 asin 9.9999999999999998e+149 0.0 -> 1.5707963267948966 346.08091112966679 +asin0073 asin 9.9999999999999998e+149 -0.0 -> 1.5707963267948966 -346.08091112966679 +asin0074 asin 1.0000000000000001e+299 0.0 -> 1.5707963267948966 689.16608998577965 +asin0075 asin 1.0000000000000001e+299 -0.0 -> 1.5707963267948966 -689.16608998577965 + +-- random inputs +asin0100 asin -1.5979555835086083 -0.15003009814595247 -> -1.4515369557405788 -1.0544476399790823 +asin0101 asin -0.57488225895317679 -9.6080397838952743e-13 -> -0.61246024460412851 -1.174238005400403e-12 +asin0102 asin -3.6508087930516249 -0.36027527093220152 -> -1.4685890605305874 -1.9742273007152038 +asin0103 asin -1.5238659792326819 -1.1360813516996364 -> -0.86080051691147275 -1.3223742205689195 +asin0104 asin -1592.0639045555306 -0.72362427935018236 -> -1.5703418071175179 -8.0659336918729228 +asin0105 asin -0.19835471371312019 4.2131508416697709 -> -0.045777831019935149 2.1461732751933171 +asin0106 asin -1.918471054430213 0.40603305079779234 -> -1.3301396585791556 1.30263642314981 +asin0107 asin -254495.01623373642 0.71084414434470822 -> -1.5707935336394359 13.140183712762321 +asin0108 asin -0.31315882715691157 3.9647994288429866 -> -0.076450403840916004 2.0889762138713457 +asin0109 asin -0.90017064284720816 1.2530659485907105 -> -0.53466509741943447 1.1702811557577 +asin0110 asin 2.1615181696571075 -0.14058647488229523 -> 1.4976166323896871 -1.4085811039334604 +asin0111 asin 1.2104749210707795 -0.85732484485298999 -> 0.83913071588343924 -1.0681719250525901 +asin0112 asin 1.7059733185128891 -0.84032966373156581 -> 1.0510900815816229 -1.2967979791361652 +asin0113 asin 9.9137085017290687 -1.4608383970250893 -> 1.4237704820128891 -2.995414677560686 +asin0114 asin 117.12344751041495 -5453908091.5334015 -> 2.1475141411392012e-08 -23.112745450217066 +asin0115 asin 0.081041187798029227 0.067054349860173196 -> 0.080946786856771813 0.067223991060639698 +asin0116 asin 46.635472322049949 2.3835190718056678 -> 1.5197194940010779 4.5366989600972083 +asin0117 asin 3907.0687961127105 19.144021886390181 -> 1.5658965233083235 8.9637018715924217 +asin0118 asin 1.0889312322308273 509.01577883554768 -> 0.0021392803817829316 6.9256294494524706 +asin0119 asin 0.10851518277509224 1.5612510908217476 -> 0.058491014243902621 1.2297075725621327 + +-- values near infinity +asin0200 asin 1.5230241998821499e+308 5.5707228994084525e+307 -> 1.2201446370892068 710.37283486535966 +asin0201 asin 8.1334317698672204e+307 -9.2249425197872451e+307 -> 0.72259991284020042 -710.0962453049026 +asin0202 asin -9.9138506659241768e+307 6.701544526434995e+307 -> -0.97637511742194594 710.06887486671371 +asin0203 asin -1.4141298868173842e+308 -5.401505134514191e+307 -> -1.2059319055160587 -710.30396478954628 +asin0204 asin 0.0 9.1618092977897431e+307 -> 0.0 709.80181441050593 +asin0205 asin -0.0 6.8064342551939755e+307 -> -0.0 709.50463910853489 +asin0206 asin 0.0 -6.4997516454798215e+307 -> 0.0 -709.45853469751592 +asin0207 asin -0.0 -1.6767449053345242e+308 -> -0.0 -710.4062101803022 +asin0208 asin 5.4242749957378916e+307 0.0 -> 1.5707963267948966 709.27765497888902 +asin0209 asin 9.5342145121164749e+307 -0.0 -> 1.5707963267948966 -709.84165758595907 +asin0210 asin -7.0445698006201847e+307 0.0 -> -1.5707963267948966 709.53902780872136 +asin0211 asin -1.0016025569769706e+308 -0.0 -> -1.5707963267948966 -709.89095709697881 +asin0212 asin 1.6552203778877204e+308 0.48761543336249491 -> 1.5707963267948966 710.39328998153474 +asin0213 asin 1.2485712830384869e+308 -4.3489311161278899 -> 1.5707963267948966 -710.1113557467786 +asin0214 asin -1.5117842813353125e+308 5.123452666102434 -> -1.5707963267948966 710.30264641923031 +asin0215 asin -1.3167634313008016e+308 -0.52939679793528982 -> -1.5707963267948966 -710.16453260239768 +asin0216 asin 0.80843929176985907 1.0150851827767876e+308 -> 7.9642507396113875e-309 709.90432835561637 +asin0217 asin 8.2544809829680901 -1.7423548140539474e+308 -> 4.7375430746865733e-308 -710.44459336242164 +asin0218 asin -5.2499000118824295 4.6655578977512214e+307 -> -1.1252459249113292e-307 709.1269781491103 +asin0219 asin -5.9904782760833433 -4.7315689314781163e+307 -> -1.2660659419394637e-307 -709.14102757522312 + +-- special values +asin1000 asin -0.0 0.0 -> -0.0 0.0 +asin1001 asin 0.0 0.0 -> 0.0 0.0 +asin1002 asin -0.0 -0.0 -> -0.0 -0.0 +asin1003 asin 0.0 -0.0 -> 0.0 -0.0 +asin1004 asin -inf 0.0 -> -1.5707963267948966 inf +asin1005 asin -inf 2.2999999999999998 -> -1.5707963267948966 inf +asin1006 asin nan 0.0 -> nan nan +asin1007 asin nan 2.2999999999999998 -> nan nan +asin1008 asin -0.0 inf -> -0.0 inf +asin1009 asin -2.2999999999999998 inf -> -0.0 inf +asin1010 asin -inf inf -> -0.78539816339744828 inf +asin1011 asin nan inf -> nan inf +asin1012 asin -0.0 nan -> -0.0 nan +asin1013 asin -2.2999999999999998 nan -> nan nan +asin1014 asin -inf nan -> nan inf ignore-imag-sign +asin1015 asin nan nan -> nan nan +asin1016 asin inf 0.0 -> 1.5707963267948966 inf +asin1017 asin inf 2.2999999999999998 -> 1.5707963267948966 inf +asin1018 asin 0.0 inf -> 0.0 inf +asin1019 asin 2.2999999999999998 inf -> 0.0 inf +asin1020 asin inf inf -> 0.78539816339744828 inf +asin1021 asin 0.0 nan -> 0.0 nan +asin1022 asin 2.2999999999999998 nan -> nan nan +asin1023 asin inf nan -> nan inf ignore-imag-sign +asin1024 asin inf -0.0 -> 1.5707963267948966 -inf +asin1025 asin inf -2.2999999999999998 -> 1.5707963267948966 -inf +asin1026 asin nan -0.0 -> nan nan +asin1027 asin nan -2.2999999999999998 -> nan nan +asin1028 asin 0.0 -inf -> 0.0 -inf +asin1029 asin 2.2999999999999998 -inf -> 0.0 -inf +asin1030 asin inf -inf -> 0.78539816339744828 -inf +asin1031 asin nan -inf -> nan -inf +asin1032 asin -inf -0.0 -> -1.5707963267948966 -inf +asin1033 asin -inf -2.2999999999999998 -> -1.5707963267948966 -inf +asin1034 asin -0.0 -inf -> -0.0 -inf +asin1035 asin -2.2999999999999998 -inf -> -0.0 -inf +asin1036 asin -inf -inf -> -0.78539816339744828 -inf + + +------------------------------------ +-- asinh: Inverse hyperbolic sine -- +------------------------------------ + +-- zeros +asinh0000 asinh 0.0 0.0 -> 0.0 0.0 +asinh0001 asinh 0.0 -0.0 -> 0.0 -0.0 +asinh0002 asinh -0.0 0.0 -> -0.0 0.0 +asinh0003 asinh -0.0 -0.0 -> -0.0 -0.0 + +-- branch points: +/-i +asinh0010 asinh 0.0 1.0 -> 0.0 1.5707963267948966 +asinh0011 asinh 0.0 -1.0 -> 0.0 -1.5707963267948966 +asinh0012 asinh -0.0 1.0 -> -0.0 1.5707963267948966 +asinh0013 asinh -0.0 -1.0 -> -0.0 -1.5707963267948966 + +-- values along both sides of imaginary axis +asinh0020 asinh 0.0 -9.8813129168249309e-324 -> 0.0 -9.8813129168249309e-324 +asinh0021 asinh -0.0 -9.8813129168249309e-324 -> -0.0 -9.8813129168249309e-324 +asinh0022 asinh 0.0 -1e-305 -> 0.0 -1e-305 +asinh0023 asinh -0.0 -1e-305 -> -0.0 -1e-305 +asinh0024 asinh 0.0 -1e-150 -> 0.0 -1e-150 +asinh0025 asinh -0.0 -1e-150 -> -0.0 -1e-150 +asinh0026 asinh 0.0 -9.9999999999999998e-17 -> 0.0 -9.9999999999999998e-17 +asinh0027 asinh -0.0 -9.9999999999999998e-17 -> -0.0 -9.9999999999999998e-17 +asinh0028 asinh 0.0 -0.001 -> 0.0 -0.0010000001666667416 +asinh0029 asinh -0.0 -0.001 -> -0.0 -0.0010000001666667416 +asinh0030 asinh 0.0 -0.57899999999999996 -> 0.0 -0.61750165481717001 +asinh0031 asinh -0.0 -0.57899999999999996 -> -0.0 -0.61750165481717001 +asinh0032 asinh 0.0 -0.99999999999999989 -> 0.0 -1.5707963118937354 +asinh0033 asinh -0.0 -0.99999999999999989 -> -0.0 -1.5707963118937354 +asinh0034 asinh 0.0 -1.0000000000000002 -> 2.1073424255447014e-08 -1.5707963267948966 +asinh0035 asinh -0.0 -1.0000000000000002 -> -2.1073424255447014e-08 -1.5707963267948966 +asinh0036 asinh 0.0 -1.0009999999999999 -> 0.044717633608306849 -1.5707963267948966 +asinh0037 asinh -0.0 -1.0009999999999999 -> -0.044717633608306849 -1.5707963267948966 +asinh0038 asinh 0.0 -2.0 -> 1.3169578969248168 -1.5707963267948966 +asinh0039 asinh -0.0 -2.0 -> -1.3169578969248168 -1.5707963267948966 +asinh0040 asinh 0.0 -20.0 -> 3.6882538673612966 -1.5707963267948966 +asinh0041 asinh -0.0 -20.0 -> -3.6882538673612966 -1.5707963267948966 +asinh0042 asinh 0.0 -10000000000000000.0 -> 37.534508668464674 -1.5707963267948966 +asinh0043 asinh -0.0 -10000000000000000.0 -> -37.534508668464674 -1.5707963267948966 +asinh0044 asinh 0.0 -9.9999999999999998e+149 -> 346.08091112966679 -1.5707963267948966 +asinh0045 asinh -0.0 -9.9999999999999998e+149 -> -346.08091112966679 -1.5707963267948966 +asinh0046 asinh 0.0 -1.0000000000000001e+299 -> 689.16608998577965 -1.5707963267948966 +asinh0047 asinh -0.0 -1.0000000000000001e+299 -> -689.16608998577965 -1.5707963267948966 +asinh0048 asinh 0.0 9.8813129168249309e-324 -> 0.0 9.8813129168249309e-324 +asinh0049 asinh -0.0 9.8813129168249309e-324 -> -0.0 9.8813129168249309e-324 +asinh0050 asinh 0.0 1e-305 -> 0.0 1e-305 +asinh0051 asinh -0.0 1e-305 -> -0.0 1e-305 +asinh0052 asinh 0.0 1e-150 -> 0.0 1e-150 +asinh0053 asinh -0.0 1e-150 -> -0.0 1e-150 +asinh0054 asinh 0.0 9.9999999999999998e-17 -> 0.0 9.9999999999999998e-17 +asinh0055 asinh -0.0 9.9999999999999998e-17 -> -0.0 9.9999999999999998e-17 +asinh0056 asinh 0.0 0.001 -> 0.0 0.0010000001666667416 +asinh0057 asinh -0.0 0.001 -> -0.0 0.0010000001666667416 +asinh0058 asinh 0.0 0.57899999999999996 -> 0.0 0.61750165481717001 +asinh0059 asinh -0.0 0.57899999999999996 -> -0.0 0.61750165481717001 +asinh0060 asinh 0.0 0.99999999999999989 -> 0.0 1.5707963118937354 +asinh0061 asinh -0.0 0.99999999999999989 -> -0.0 1.5707963118937354 +asinh0062 asinh 0.0 1.0000000000000002 -> 2.1073424255447014e-08 1.5707963267948966 +asinh0063 asinh -0.0 1.0000000000000002 -> -2.1073424255447014e-08 1.5707963267948966 +asinh0064 asinh 0.0 1.0009999999999999 -> 0.044717633608306849 1.5707963267948966 +asinh0065 asinh -0.0 1.0009999999999999 -> -0.044717633608306849 1.5707963267948966 +asinh0066 asinh 0.0 2.0 -> 1.3169578969248168 1.5707963267948966 +asinh0067 asinh -0.0 2.0 -> -1.3169578969248168 1.5707963267948966 +asinh0068 asinh 0.0 20.0 -> 3.6882538673612966 1.5707963267948966 +asinh0069 asinh -0.0 20.0 -> -3.6882538673612966 1.5707963267948966 +asinh0070 asinh 0.0 10000000000000000.0 -> 37.534508668464674 1.5707963267948966 +asinh0071 asinh -0.0 10000000000000000.0 -> -37.534508668464674 1.5707963267948966 +asinh0072 asinh 0.0 9.9999999999999998e+149 -> 346.08091112966679 1.5707963267948966 +asinh0073 asinh -0.0 9.9999999999999998e+149 -> -346.08091112966679 1.5707963267948966 +asinh0074 asinh 0.0 1.0000000000000001e+299 -> 689.16608998577965 1.5707963267948966 +asinh0075 asinh -0.0 1.0000000000000001e+299 -> -689.16608998577965 1.5707963267948966 + +-- random inputs +asinh0100 asinh -0.5946402853710423 -0.044506548910000145 -> -0.56459775392653022 -0.038256221441536356 +asinh0101 asinh -0.19353958046180916 -0.017489624793193454 -> -0.19237926804196651 -0.017171741895336792 +asinh0102 asinh -0.033117585138955893 -8.5256414015933757 -> -2.8327758348650969 -1.5668848791092411 +asinh0103 asinh -1.5184043184035716 -0.73491245339073275 -> -1.2715891419764005 -0.39204624408542355 +asinh0104 asinh -0.60716120271208818 -0.28900743958436542 -> -0.59119299421187232 -0.24745931678118135 +asinh0105 asinh -0.0237177865112429 2.8832601052166313 -> -1.7205820772413236 1.5620261702963094 +asinh0106 asinh -2.3906812342743979 2.6349216848574013 -> -1.9609636249445124 0.8142142660574706 +asinh0107 asinh -0.0027605019787620517 183.85588476550555 -> -5.9072920005445066 1.5707813120847871 +asinh0108 asinh -0.99083661164404713 0.028006797051617648 -> -0.8750185251283995 0.019894099615994653 +asinh0109 asinh -3.0362951937986393 0.86377266758504867 -> -1.8636030714685221 0.26475058859950168 +asinh0110 asinh 0.34438464536152769 -0.71603790174885029 -> 0.43985415690734164 -0.71015037409294324 +asinh0111 asinh 4.4925124413876256 -60604595352.871613 -> 25.520783738612078 -1.5707963267207683 +asinh0112 asinh 2.3213991428170337 -7.5459667007307258 -> 2.7560464993451643 -1.270073210856117 +asinh0113 asinh 0.21291939741682028 -1.2720428814784408 -> 0.77275088137338266 -1.3182099250896895 +asinh0114 asinh 6.6447359379455957 -0.97196191666946996 -> 2.602830695139672 -0.14368247412319965 +asinh0115 asinh 7.1326256655083746 2.1516360452706857 -> 2.7051146374367212 0.29051701669727581 +asinh0116 asinh 0.18846550905063442 3.4705348585339832 -> 1.917697875799296 1.514155593347924 +asinh0117 asinh 0.19065075303281598 0.26216814548222012 -> 0.19603050785932474 0.26013422809614117 +asinh0118 asinh 2.0242004665739719 0.70510281647495787 -> 1.4970366212896002 0.30526007200481453 +asinh0119 asinh 37.336596461576057 717.29157391678234 -> 7.269981997945294 1.5187910219576033 + +-- values near infinity +asinh0200 asinh 1.0760517500874541e+308 1.1497786241240167e+308 -> 710.34346055651815 0.81850936961793475 +asinh0201 asinh 1.1784839328845529e+308 -1.6478429586716638e+308 -> 710.59536255783678 -0.94996311735607697 +asinh0202 asinh -4.8777682248909193e+307 1.4103736217538474e+308 -> -710.28970147376992 1.2378239519096443 +asinh0203 asinh -1.2832478903233108e+308 -1.5732392613155698e+308 -> -710.59750164290745 -0.88657181439322452 +asinh0204 asinh 0.0 6.8431383856345372e+307 -> 709.51001718444604 1.5707963267948966 +asinh0205 asinh -0.0 8.601822432238051e+307 -> -709.73874482126689 1.5707963267948966 +asinh0206 asinh 0.0 -5.5698396067303782e+307 -> 709.30413698733742 -1.5707963267948966 +asinh0207 asinh -0.0 -7.1507777734621804e+307 -> -709.55399186002705 -1.5707963267948966 +asinh0208 asinh 1.6025136110019349e+308 0.0 -> 710.3609292261076 0.0 +asinh0209 asinh 1.3927819858239114e+308 -0.0 -> 710.22065899832899 -0.0 +asinh0210 asinh -6.0442994056210995e+307 0.0 -> -709.38588631057621 0.0 +asinh0211 asinh -1.2775271979042634e+308 -0.0 -> -710.13428215553972 -0.0 +asinh0212 asinh 1.0687496260268489e+308 1.0255615699476961 -> 709.95584521407841 9.5959010882679093e-309 +asinh0213 asinh 1.0050967333370962e+308 -0.87668970117333433 -> 709.89443961168183 -8.7224410556242882e-309 +asinh0214 asinh -5.7161452814862392e+307 8.2377808413450122 -> -709.33006540611166 1.4411426644501116e-307 +asinh0215 asinh -8.2009040727653315e+307 -6.407409526654976 -> -709.69101513070109 -7.8130526461510088e-308 +asinh0216 asinh 6.4239368496483982 1.6365990821551427e+308 -> 710.38197618101287 1.5707963267948966 +asinh0217 asinh 5.4729111423315882 -1.1227237438144211e+308 -> 710.00511346983546 -1.5707963267948966 +asinh0218 asinh -8.3455818297412723 1.443172020182019e+308 -> -710.25619930551818 1.5707963267948966 +asinh0219 asinh -2.6049726230372441 -1.7952291144022702e+308 -> -710.47448847685644 -1.5707963267948966 + +-- values near 0 +asinh0220 asinh 1.2940113339664088e-314 6.9169190417774516e-323 -> 1.2940113339664088e-314 6.9169190417774516e-323 +asinh0221 asinh 2.3848478863874649e-315 -3.1907655025717717e-310 -> 2.3848478863874649e-315 -3.1907655025717717e-310 +asinh0222 asinh -3.0097643679641622e-316 4.6936236354918422e-322 -> -3.0097643679641622e-316 4.6936236354918422e-322 +asinh0223 asinh -1.787997087755751e-308 -8.5619622834902341e-310 -> -1.787997087755751e-308 -8.5619622834902341e-310 +asinh0224 asinh 0.0 1.2491433448427325e-314 -> 0.0 1.2491433448427325e-314 +asinh0225 asinh -0.0 2.5024072154538062e-308 -> -0.0 2.5024072154538062e-308 +asinh0226 asinh 0.0 -2.9643938750474793e-323 -> 0.0 -2.9643938750474793e-323 +asinh0227 asinh -0.0 -2.9396905927554169e-320 -> -0.0 -2.9396905927554169e-320 +asinh0228 asinh 5.64042930029359e-317 0.0 -> 5.64042930029359e-317 0.0 +asinh0229 asinh 3.3833911866596068e-318 -0.0 -> 3.3833911866596068e-318 -0.0 +asinh0230 asinh -4.9406564584124654e-324 0.0 -> -4.9406564584124654e-324 0.0 +asinh0231 asinh -2.2211379227994845e-308 -0.0 -> -2.2211379227994845e-308 -0.0 + +-- special values +asinh1000 asinh 0.0 0.0 -> 0.0 0.0 +asinh1001 asinh 0.0 -0.0 -> 0.0 -0.0 +asinh1002 asinh -0.0 0.0 -> -0.0 0.0 +asinh1003 asinh -0.0 -0.0 -> -0.0 -0.0 +asinh1004 asinh 0.0 inf -> inf 1.5707963267948966 +asinh1005 asinh 2.3 inf -> inf 1.5707963267948966 +asinh1006 asinh 0.0 nan -> nan nan +asinh1007 asinh 2.3 nan -> nan nan +asinh1008 asinh inf 0.0 -> inf 0.0 +asinh1009 asinh inf 2.3 -> inf 0.0 +asinh1010 asinh inf inf -> inf 0.78539816339744828 +asinh1011 asinh inf nan -> inf nan +asinh1012 asinh nan 0.0 -> nan 0.0 +asinh1013 asinh nan 2.3 -> nan nan +asinh1014 asinh nan inf -> inf nan ignore-real-sign +asinh1015 asinh nan nan -> nan nan +asinh1016 asinh 0.0 -inf -> inf -1.5707963267948966 +asinh1017 asinh 2.3 -inf -> inf -1.5707963267948966 +asinh1018 asinh inf -0.0 -> inf -0.0 +asinh1019 asinh inf -2.3 -> inf -0.0 +asinh1020 asinh inf -inf -> inf -0.78539816339744828 +asinh1021 asinh nan -0.0 -> nan -0.0 +asinh1022 asinh nan -2.3 -> nan nan +asinh1023 asinh nan -inf -> inf nan ignore-real-sign +asinh1024 asinh -0.0 -inf -> -inf -1.5707963267948966 +asinh1025 asinh -2.3 -inf -> -inf -1.5707963267948966 +asinh1026 asinh -0.0 nan -> nan nan +asinh1027 asinh -2.3 nan -> nan nan +asinh1028 asinh -inf -0.0 -> -inf -0.0 +asinh1029 asinh -inf -2.3 -> -inf -0.0 +asinh1030 asinh -inf -inf -> -inf -0.78539816339744828 +asinh1031 asinh -inf nan -> -inf nan +asinh1032 asinh -0.0 inf -> -inf 1.5707963267948966 +asinh1033 asinh -2.3 inf -> -inf 1.5707963267948966 +asinh1034 asinh -inf 0.0 -> -inf 0.0 +asinh1035 asinh -inf 2.3 -> -inf 0.0 +asinh1036 asinh -inf inf -> -inf 0.78539816339744828 + + +--------------------------- +-- atan: Inverse tangent -- +--------------------------- + +-- zeros +atan0000 atan 0.0 0.0 -> 0.0 0.0 +atan0001 atan 0.0 -0.0 -> 0.0 -0.0 +atan0002 atan -0.0 0.0 -> -0.0 0.0 +atan0003 atan -0.0 -0.0 -> -0.0 -0.0 + +-- values along both sides of imaginary axis +atan0010 atan 0.0 -9.8813129168249309e-324 -> 0.0 -9.8813129168249309e-324 From noreply at buildbot.pypy.org Mon Oct 8 14:15:36 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:15:36 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-complex2: close merged branch Message-ID: <20121008121536.572BC1C0DFC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: numpypy-complex2 Changeset: r57909:97adcdea3430 Date: 2012-10-08 14:13 +0200 http://bitbucket.org/pypy/pypy/changeset/97adcdea3430/ Log: close merged branch From noreply at buildbot.pypy.org Mon Oct 8 14:15:37 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:15:37 +0200 (CEST) Subject: [pypy-commit] pypy default: Document the merged branch Message-ID: <20121008121537.D9ADD1C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57910:cdd972e51b7e Date: 2012-10-08 14:14 +0200 http://bitbucket.org/pypy/pypy/changeset/cdd972e51b7e/ Log: Document the merged branch diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -36,6 +36,10 @@ .. branch: stdlib-2.7.3 The stdlib was updated to version 2.7.3 +.. branch: numpypy-complex2 +Complex dtype support for numpy + + .. "uninteresting" branches that we should just ignore for the whatsnew: .. branch: slightly-shorter-c From noreply at buildbot.pypy.org Mon Oct 8 14:16:30 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:16:30 +0200 (CEST) Subject: [pypy-commit] pypy closed-branches: Merge closed head 322806c120f3 on branch improve-rbigint Message-ID: <20121008121630.D24111C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: closed-branches Changeset: r57911:80187aaa7ca4 Date: 2012-10-08 14:15 +0200 http://bitbucket.org/pypy/pypy/changeset/80187aaa7ca4/ Log: Merge closed head 322806c120f3 on branch improve-rbigint From noreply at buildbot.pypy.org Mon Oct 8 14:16:32 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:16:32 +0200 (CEST) Subject: [pypy-commit] pypy closed-branches: Merge closed head 492d301343aa on branch numpy-refactor Message-ID: <20121008121632.0EC301C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: closed-branches Changeset: r57912:bb448165c8ef Date: 2012-10-08 14:15 +0200 http://bitbucket.org/pypy/pypy/changeset/bb448165c8ef/ Log: Merge closed head 492d301343aa on branch numpy-refactor From noreply at buildbot.pypy.org Mon Oct 8 14:16:33 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:16:33 +0200 (CEST) Subject: [pypy-commit] pypy closed-branches: Merge closed head 1ee6c0771fad on branch ndarray-attributes Message-ID: <20121008121633.530101C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: closed-branches Changeset: r57913:9611173eae7c Date: 2012-10-08 14:15 +0200 http://bitbucket.org/pypy/pypy/changeset/9611173eae7c/ Log: Merge closed head 1ee6c0771fad on branch ndarray-attributes From noreply at buildbot.pypy.org Mon Oct 8 14:16:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:16:34 +0200 (CEST) Subject: [pypy-commit] pypy closed-branches: Merge closed head 083540dcce4d on branch numpy-fancy-indexing Message-ID: <20121008121634.823DF1C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: closed-branches Changeset: r57914:59e24466e74a Date: 2012-10-08 14:15 +0200 http://bitbucket.org/pypy/pypy/changeset/59e24466e74a/ Log: Merge closed head 083540dcce4d on branch numpy-fancy-indexing From noreply at buildbot.pypy.org Mon Oct 8 14:16:35 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:16:35 +0200 (CEST) Subject: [pypy-commit] pypy closed-branches: Merge closed head 953c4ffc8646 on branch numpy-reintroduce-jit-drivers Message-ID: <20121008121635.D15801C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: closed-branches Changeset: r57915:e69baa1cac77 Date: 2012-10-08 14:15 +0200 http://bitbucket.org/pypy/pypy/changeset/e69baa1cac77/ Log: Merge closed head 953c4ffc8646 on branch numpy-reintroduce-jit- drivers From noreply at buildbot.pypy.org Mon Oct 8 14:16:37 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:16:37 +0200 (CEST) Subject: [pypy-commit] pypy closed-branches: Merge closed head 2a5f4da3fe5a on branch numpypy-complex Message-ID: <20121008121637.0489A1C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: closed-branches Changeset: r57916:b9074d98626b Date: 2012-10-08 14:15 +0200 http://bitbucket.org/pypy/pypy/changeset/b9074d98626b/ Log: Merge closed head 2a5f4da3fe5a on branch numpypy-complex From noreply at buildbot.pypy.org Mon Oct 8 14:16:38 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:16:38 +0200 (CEST) Subject: [pypy-commit] pypy closed-branches: Merge closed head c26fb4a6e96f on branch numpy-dtype-refactor-complex Message-ID: <20121008121638.2035E1C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: closed-branches Changeset: r57917:25dc9bf7d504 Date: 2012-10-08 14:15 +0200 http://bitbucket.org/pypy/pypy/changeset/25dc9bf7d504/ Log: Merge closed head c26fb4a6e96f on branch numpy-dtype-refactor- complex From noreply at buildbot.pypy.org Mon Oct 8 14:16:39 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:16:39 +0200 (CEST) Subject: [pypy-commit] pypy closed-branches: Merge closed head 97adcdea3430 on branch numpypy-complex2 Message-ID: <20121008121639.4854E1C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: closed-branches Changeset: r57918:ff03fed7eed1 Date: 2012-10-08 14:15 +0200 http://bitbucket.org/pypy/pypy/changeset/ff03fed7eed1/ Log: Merge closed head 97adcdea3430 on branch numpypy-complex2 From noreply at buildbot.pypy.org Mon Oct 8 14:16:40 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:16:40 +0200 (CEST) Subject: [pypy-commit] pypy closed-branches: re-close this branch Message-ID: <20121008121640.67FF81C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: closed-branches Changeset: r57919:975cef8a5e55 Date: 2012-10-08 14:15 +0200 http://bitbucket.org/pypy/pypy/changeset/975cef8a5e55/ Log: re-close this branch From noreply at buildbot.pypy.org Mon Oct 8 14:20:04 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 14:20:04 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Make rlib/parsing work Message-ID: <20121008122004.552A61C0DFA@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57920:1da2d2d81a3f Date: 2012-10-08 14:19 +0200 http://bitbucket.org/pypy/pypy/changeset/1da2d2d81a3f/ Log: Make rlib/parsing work diff --git a/pypy/rlib/parsing/test/test_deterministic.py b/pypy/rlib/parsing/test/test_deterministic.py --- a/pypy/rlib/parsing/test/test_deterministic.py +++ b/pypy/rlib/parsing/test/test_deterministic.py @@ -1,5 +1,5 @@ from pypy.rlib.parsing.deterministic import * -from pypy.translator.interactive import Translation +from pypy.translator.c.test.test_genc import compile def test_DFA_simple(): @@ -35,9 +35,7 @@ a[s0, "b"] = s2 a[s1, "b"] = s2 recognize = a.make_code() - t = Translation(recognize) - t.backendopt([str], backend="c") - cfn = t.compile_c() + cfn = compile(recognize, [str]) assert cfn("aaaaaaaaaab") assert cfn("b") assert cfn("aaaacb") @@ -69,6 +67,7 @@ assert not r.recognize("") assert not r.recognize("100101101111") + def test_NFA_with_epsilon(): a = NFA() z0 = a.add_state("z0", start=True) @@ -88,6 +87,7 @@ fda = a.make_deterministic() r = fda.get_runner() + def test_NFA_to_DFA_simple(): a = NFA() z0 = a.add_state("z0", start=True) @@ -107,8 +107,8 @@ assert not r.recognize("") assert not r.recognize("100101101111") + def test_simplify(): - #py.test.skip("optimize not working yet") a = DFA() z0 = a.add_state("z0") z1 = a.add_state("z1") @@ -140,6 +140,7 @@ assert r.recognize("00") assert not r.recognize("111111011111111") + def test_something(): a = NFA() z0 = a.add_state("z0", start=True, final=True) @@ -150,8 +151,8 @@ a.add_transition(z1, z1, "a") a.add_transition(z1, z1, "b") a.add_transition(z1, z2, "a") - fda = a.make_deterministic() - + a.make_deterministic() + def test_compress_char_set(): import string assert compress_char_set("ace") == [('a', 1), ('c', 1), ('e', 1)] @@ -160,7 +161,7 @@ assert compress_char_set("zycba") == [('a',3), ('y',2)] assert compress_char_set(string.ascii_letters) == [('A', 26), ('a', 26)] assert compress_char_set(string.printable) == [(' ', 95), ('\t', 5)] - + def test_make_nice_charset_repr(): import string assert make_nice_charset_repr("ace") == 'ace' @@ -168,7 +169,7 @@ assert make_nice_charset_repr("ABCabc") == 'A-Ca-c' assert make_nice_charset_repr("zycba") == 'a-cyz' assert make_nice_charset_repr(string.ascii_letters) == 'A-Za-z' - + # this next one is ugly because it's being generated from a dict, so the order is not stable nice = make_nice_charset_repr(string.printable) chunks = ['A-Z','a-z','0-9','\\t','\\x0b','\\n','\\r','\\x0c','\\\\','\\-'] diff --git a/pypy/rlib/parsing/test/test_regex.py b/pypy/rlib/parsing/test/test_regex.py --- a/pypy/rlib/parsing/test/test_regex.py +++ b/pypy/rlib/parsing/test/test_regex.py @@ -1,19 +1,13 @@ -import py from pypy.rlib.parsing.regex import * +from pypy.translator.c.test.test_genc import compile + def compile_rex(rex): - try: - from pypy.translator.interactive import Translation - except ImportError: - py.test.skip("pypy not found") fda = rex.make_automaton().make_deterministic() fda.optimize() fn = fda.make_code() - t = Translation(fn) - t.backendopt([str], backend="c") - if py.test.config.option.view: - t.view() - return t.compile_c() + return compile(fn, [str]) + def test_simple(): r = StringExpression("hallo") @@ -25,6 +19,7 @@ assert not r.recognize("") assert r.recognize("hallo") + def test_string_add(): r1 = StringExpression("Hello") r2 = StringExpression(", World!\n") @@ -33,6 +28,7 @@ assert r.recognize("Hello, World!\n") assert not r.recognize("asfdasdfasDF") + def test_kleene(): r1 = StringExpression("ab") r2 = r1.kleene() @@ -43,6 +39,7 @@ assert r.recognize("abab") assert not r.recognize("ababababababb") + def test_or(): r1 = StringExpression("ab").kleene() | StringExpression("cd").kleene() nda = r1.make_automaton() @@ -78,11 +75,12 @@ assert not r.recognize("acbbcbcaaccacacccc") assert r.recognize("aaaa") + def test_bigger_than_101001(): O = StringExpression("0") l = StringExpression("1") d = O | l - rex = ((l + d + d + d + d + d + +d) | (l + l + d + d + d + d) | + rex = ((l + d + d + d + d + d + +d) | (l + l + d + d + d + d) | (l + O + l + l + d + d) | (l + O + l + O + l + d)) nda = rex.make_automaton() fda = nda.make_deterministic() @@ -104,7 +102,7 @@ assert fn("101010") assert fn("101100") assert fn("110000") - + def test_even_length(): a = StringExpression("a") diff --git a/pypy/rlib/parsing/test/test_regexparse.py b/pypy/rlib/parsing/test/test_regexparse.py --- a/pypy/rlib/parsing/test/test_regexparse.py +++ b/pypy/rlib/parsing/test/test_regexparse.py @@ -1,8 +1,4 @@ -import py -from pypy.rlib.parsing.regexparse import make_runner, unescape, RegexParser -from pypy.rlib.parsing import regex -import operator -from pypy.rlib.parsing.makepackrat import PackratParser as _PackratParser +from pypy.rlib.parsing.regexparse import make_runner @@ -170,7 +166,7 @@ assert r.recognize("-0.912E+0001") assert not r.recognize("-0.a912E+0001") assert r.recognize("5") - + def test_charclass(): r = make_runner(r"\d") assert r.recognize('0') diff --git a/pypy/rlib/parsing/test/test_translate.py b/pypy/rlib/parsing/test/test_translate.py --- a/pypy/rlib/parsing/test/test_translate.py +++ b/pypy/rlib/parsing/test/test_translate.py @@ -1,11 +1,10 @@ -import py -from pypy.translator.interactive import Translation from pypy.rlib.parsing.lexer import * +# Unused, but needed for some obscure reason +from pypy.rlib.parsing.makepackrat import BacktrackException, Status from pypy.rlib.parsing.regex import * from pypy.rlib.parsing.parsing import * -from pypy.rlib.parsing import deterministic -from pypy.rlib.parsing.pypackrat import BacktrackException, Status -from pypy.conftest import option +from pypy.translator.c.test.test_genc import compile + class TestTranslateLexer(object): def get_lexer(self, rexs, names, ignore=None): @@ -34,16 +33,14 @@ "INT WHITE KEYWORD").split() res = lex("if A a 12341 0 else", True).split("-%-") assert res == "KEYWORD VAR ATOM INT INT KEYWORD".split() - t = Translation(lex) - t.annotate([str, bool]) - t.rtype() - func = t.compile_c() + func = compile(lex, [str, bool]) res = lex("if A a 12341 0 else", False).split("-%-") assert res == ("KEYWORD WHITE VAR WHITE ATOM WHITE INT WHITE " "INT WHITE KEYWORD").split() res = lex("if A a 12341 0 else", True).split("-%-") assert res == "KEYWORD VAR ATOM INT INT KEYWORD".split() + def test_translate_parser(): r0 = Rule("expression", [["additive", "EOF"]]) r1 = Rule("additive", [["multitive", "+", "additive"], ["multitive"]]) @@ -59,11 +56,7 @@ def parse(choose): tree = p.parse(data, lazy=False) return tree.symbol + " " + "-%-".join([c.symbol for c in tree.children]) - t = Translation(parse) - t.annotate([bool]) - t.backendopt() - t.rtype() - func = t.compile_c() + func = compile(parse, [bool]) res1 = parse(True) res2 = func(True) assert res1 == res2 @@ -88,15 +81,12 @@ def parse(choose): tree = p.parse(data) return tree.symbol + " " + "-%-".join([c.symbol for c in tree.children]) - t = Translation(parse) - t.annotate([bool]) - t.backendopt() - t.rtype() - func = t.compile_c() + func = compile(parse, [bool]) res1 = parse(True) res2 = func(True) assert res1 == res2 + def test_translate_ast_visitor(): from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function regexs, rules, ToAST = parse_ebnf(""" @@ -114,14 +104,11 @@ tree = tree[0] return tree.symbol + " " + "-&-".join([c.symbol for c in tree.children]) res1 = f() - t = Translation(f) - t.annotate() - t.rtype() - t.backendopt() - func = t.compile_c() + func = compile(f, []) res2 = func() assert res1 == res2 + def test_translate_pypackrat(): from pypy.rlib.parsing.pypackrat import PackratParser class parser(PackratParser): @@ -149,13 +136,7 @@ return p.expr() res = parse("5-5-5") assert res == '((5 - 5) - 5)' - t = Translation(parse) - t.annotate([str]) - t.rtype() - t.backendopt() - if option.view: - t.view() - func = t.compile_c() + func = compile(parse, [str]) res = func("5-5-5") assert res == '((5 - 5) - 5)' @@ -172,13 +153,7 @@ return p.num() res = parse("1234") assert res == '1234' - t = Translation(parse) - t.annotate([str]) - t.rtype() - t.backendopt() - if option.view: - t.view() - func = t.compile_c() + func = compile(parse, [str]) res = func("12345") assert res == '12345' res = func("0") From noreply at buildbot.pypy.org Mon Oct 8 14:28:05 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 14:28:05 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Get rid of the distinction between translator.view() and graph.show(), Message-ID: <20121008122805.5E7A81C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57921:5a96403f2b7a Date: 2012-10-08 14:27 +0200 http://bitbucket.org/pypy/pypy/changeset/5a96403f2b7a/ Log: Get rid of the distinction between translator.view() and graph.show(), by supporting both names on both objects. diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py --- a/pypy/objspace/flow/model.py +++ b/pypy/objspace/flow/model.py @@ -118,6 +118,8 @@ from pypy.translator.tool.graphpage import FlowGraphPage FlowGraphPage(t, [self]).display() + view = show + class Link(object): @@ -172,6 +174,8 @@ from pypy.translator.tool.graphpage import try_show try_show(self) + view = show + class Block(object): __slots__ = """inputargs operations exitswitch @@ -247,6 +251,8 @@ from pypy.translator.tool.graphpage import try_show try_show(self) + view = show + class Variable(object): __slots__ = ["_name", "_nr", "concretetype"] diff --git a/pypy/translator/translator.py b/pypy/translator/translator.py --- a/pypy/translator/translator.py +++ b/pypy/translator/translator.py @@ -130,12 +130,15 @@ from pypy.translator.tool.graphpage import FlowGraphPage FlowGraphPage(self).display() + show = view + def viewcg(self, center_graph=None, huge=100): """Shows the whole call graph and the class hierarchy, based on the computed annotations.""" from pypy.translator.tool.graphpage import TranslatorPage TranslatorPage(self, center_graph=center_graph, huge=huge).display() + showcg = viewcg # _______________________________________________________________ From noreply at buildbot.pypy.org Mon Oct 8 14:31:11 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 14:31:11 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merged default in Message-ID: <20121008123111.E5B041C0DFA@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57922:f7ae88167498 Date: 2012-10-08 14:30 +0200 http://bitbucket.org/pypy/pypy/changeset/f7ae88167498/ Log: merged default in diff too long, truncating to 2000 out of 10524 lines diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,11 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - libpath = ctypes.util.find_library('db-4.5') - if not libpath: + for c in '56789': + libpath = ctypes.util.find_library('db-4.%s' % c) + if libpath: + break + else: raise ImportError("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' 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 @@ -36,6 +36,10 @@ .. branch: stdlib-2.7.3 The stdlib was updated to version 2.7.3 +.. branch: numpypy-complex2 +Complex dtype support for numpy + + .. "uninteresting" branches that we should just ignore for the whatsnew: .. branch: slightly-shorter-c diff --git a/pypy/module/cmath/interp_cmath.py b/pypy/module/cmath/interp_cmath.py --- a/pypy/module/cmath/interp_cmath.py +++ b/pypy/module/cmath/interp_cmath.py @@ -1,28 +1,10 @@ import math -from math import fabs from pypy.rlib.objectmodel import specialize -from pypy.rlib.rfloat import copysign, asinh, log1p, isinf, isnan from pypy.tool.sourcetools import func_with_new_name from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import NoneNotWrapped from pypy.module.cmath import names_and_docstrings -from pypy.module.cmath.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN -from pypy.module.cmath.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG -from pypy.module.cmath.constant import M_LN2, M_LN10 -from pypy.module.cmath.constant import CM_SQRT_LARGE_DOUBLE, CM_SQRT_DBL_MIN -from pypy.module.cmath.constant import CM_LOG_LARGE_DOUBLE -from pypy.module.cmath.special_value import isfinite, special_type, INF, NAN -from pypy.module.cmath.special_value import sqrt_special_values -from pypy.module.cmath.special_value import acos_special_values -from pypy.module.cmath.special_value import acosh_special_values -from pypy.module.cmath.special_value import asinh_special_values -from pypy.module.cmath.special_value import atanh_special_values -from pypy.module.cmath.special_value import log_special_values -from pypy.module.cmath.special_value import exp_special_values -from pypy.module.cmath.special_value import cosh_special_values -from pypy.module.cmath.special_value import sinh_special_values -from pypy.module.cmath.special_value import tanh_special_values -from pypy.module.cmath.special_value import rect_special_values +from pypy.rlib import rcomplex pi = math.pi e = math.e @@ -56,235 +38,40 @@ def c_neg(x, y): - return (-x, -y) + return rcomplex.c_neg(x,y) @unaryfn def c_sqrt(x, y): - # Method: use symmetries to reduce to the case when x = z.real and y - # = z.imag are nonnegative. Then the real part of the result is - # given by - # - # s = sqrt((x + hypot(x, y))/2) - # - # and the imaginary part is - # - # d = (y/2)/s - # - # If either x or y is very large then there's a risk of overflow in - # computation of the expression x + hypot(x, y). We can avoid this - # by rewriting the formula for s as: - # - # s = 2*sqrt(x/8 + hypot(x/8, y/8)) - # - # This costs us two extra multiplications/divisions, but avoids the - # overhead of checking for x and y large. - # - # If both x and y are subnormal then hypot(x, y) may also be - # subnormal, so will lack full precision. We solve this by rescaling - # x and y by a sufficiently large power of 2 to ensure that x and y - # are normal. - - if not isfinite(x) or not isfinite(y): - return sqrt_special_values[special_type(x)][special_type(y)] - - if x == 0. and y == 0.: - return (0., y) - - ax = fabs(x) - ay = fabs(y) - - if ax < DBL_MIN and ay < DBL_MIN and (ax > 0. or ay > 0.): - # here we catch cases where hypot(ax, ay) is subnormal - ax = math.ldexp(ax, CM_SCALE_UP) - ay1= math.ldexp(ay, CM_SCALE_UP) - s = math.ldexp(math.sqrt(ax + math.hypot(ax, ay1)), - CM_SCALE_DOWN) - else: - ax /= 8. - s = 2.*math.sqrt(ax + math.hypot(ax, ay/8.)) - - d = ay/(2.*s) - - if x >= 0.: - return (s, copysign(d, y)) - else: - return (d, copysign(s, y)) - + return rcomplex.c_sqrt(x,y) @unaryfn def c_acos(x, y): - if not isfinite(x) or not isfinite(y): - return acos_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - # avoid unnecessary overflow for large arguments - real = math.atan2(fabs(y), x) - # split into cases to make sure that the branch cut has the - # correct continuity on systems with unsigned zeros - if x < 0.: - imag = -copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., y) - else: - imag = copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., -y) - else: - s1x, s1y = c_sqrt(1.-x, -y) - s2x, s2y = c_sqrt(1.+x, y) - real = 2.*math.atan2(s1x, s2x) - imag = asinh(s2x*s1y - s2y*s1x) - return (real, imag) - + return rcomplex.c_acos(x,y) @unaryfn def c_acosh(x, y): - # XXX the following two lines seem unnecessary at least on Linux; - # the tests pass fine without them - if not isfinite(x) or not isfinite(y): - return acosh_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - # avoid unnecessary overflow for large arguments - real = math.log(math.hypot(x/2., y/2.)) + M_LN2*2. - imag = math.atan2(y, x) - else: - s1x, s1y = c_sqrt(x - 1., y) - s2x, s2y = c_sqrt(x + 1., y) - real = asinh(s1x*s2x + s1y*s2y) - imag = 2.*math.atan2(s1y, s2x) - return (real, imag) - + return rcomplex.c_acosh(x,y) @unaryfn def c_asin(x, y): - # asin(z) = -i asinh(iz) - sx, sy = c_asinh(-y, x) - return (sy, -sx) - + return rcomplex.c_asin(x,y) @unaryfn def c_asinh(x, y): - if not isfinite(x) or not isfinite(y): - return asinh_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - if y >= 0.: - real = copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., x) - else: - real = -copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., -x) - imag = math.atan2(y, fabs(x)) - else: - s1x, s1y = c_sqrt(1.+y, -x) - s2x, s2y = c_sqrt(1.-y, x) - real = asinh(s1x*s2y - s2x*s1y) - imag = math.atan2(y, s1x*s2x - s1y*s2y) - return (real, imag) - + return rcomplex.c_asinh(x,y) @unaryfn def c_atan(x, y): - # atan(z) = -i atanh(iz) - sx, sy = c_atanh(-y, x) - return (sy, -sx) - + return rcomplex.c_atan(x,y) @unaryfn def c_atanh(x, y): - if not isfinite(x) or not isfinite(y): - return atanh_special_values[special_type(x)][special_type(y)] - - # Reduce to case where x >= 0., using atanh(z) = -atanh(-z). - if x < 0.: - return c_neg(*c_atanh(*c_neg(x, y))) - - ay = fabs(y) - if x > CM_SQRT_LARGE_DOUBLE or ay > CM_SQRT_LARGE_DOUBLE: - # if abs(z) is large then we use the approximation - # atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign - # of y - h = math.hypot(x/2., y/2.) # safe from overflow - real = x/4./h/h - # the two negations in the next line cancel each other out - # except when working with unsigned zeros: they're there to - # ensure that the branch cut has the correct continuity on - # systems that don't support signed zeros - imag = -copysign(math.pi/2., -y) - elif x == 1. and ay < CM_SQRT_DBL_MIN: - # C99 standard says: atanh(1+/-0.) should be inf +/- 0i - if ay == 0.: - raise ValueError("math domain error") - #real = INF - #imag = y - else: - real = -math.log(math.sqrt(ay)/math.sqrt(math.hypot(ay, 2.))) - imag = copysign(math.atan2(2., -ay) / 2, y) - else: - real = log1p(4.*x/((1-x)*(1-x) + ay*ay))/4. - imag = -math.atan2(-2.*y, (1-x)*(1+x) - ay*ay) / 2. - return (real, imag) - + return rcomplex.c_atanh(x,y) @unaryfn def c_log(x, y): - # The usual formula for the real part is log(hypot(z.real, z.imag)). - # There are four situations where this formula is potentially - # problematic: - # - # (1) the absolute value of z is subnormal. Then hypot is subnormal, - # so has fewer than the usual number of bits of accuracy, hence may - # have large relative error. This then gives a large absolute error - # in the log. This can be solved by rescaling z by a suitable power - # of 2. - # - # (2) the absolute value of z is greater than DBL_MAX (e.g. when both - # z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX) - # Again, rescaling solves this. - # - # (3) the absolute value of z is close to 1. In this case it's - # difficult to achieve good accuracy, at least in part because a - # change of 1ulp in the real or imaginary part of z can result in a - # change of billions of ulps in the correctly rounded answer. - # - # (4) z = 0. The simplest thing to do here is to call the - # floating-point log with an argument of 0, and let its behaviour - # (returning -infinity, signaling a floating-point exception, setting - # errno, or whatever) determine that of c_log. So the usual formula - # is fine here. - - # XXX the following two lines seem unnecessary at least on Linux; - # the tests pass fine without them - if not isfinite(x) or not isfinite(y): - return log_special_values[special_type(x)][special_type(y)] - - ax = fabs(x) - ay = fabs(y) - - if ax > CM_LARGE_DOUBLE or ay > CM_LARGE_DOUBLE: - real = math.log(math.hypot(ax/2., ay/2.)) + M_LN2 - elif ax < DBL_MIN and ay < DBL_MIN: - if ax > 0. or ay > 0.: - # catch cases where hypot(ax, ay) is subnormal - real = math.log(math.hypot(math.ldexp(ax, DBL_MANT_DIG), - math.ldexp(ay, DBL_MANT_DIG))) - real -= DBL_MANT_DIG*M_LN2 - else: - # log(+/-0. +/- 0i) - raise ValueError("math domain error") - #real = -INF - #imag = atan2(y, x) - else: - h = math.hypot(ax, ay) - if 0.71 <= h and h <= 1.73: - am = max(ax, ay) - an = min(ax, ay) - real = log1p((am-1)*(am+1) + an*an) / 2. - else: - real = math.log(h) - imag = math.atan2(y, x) - return (real, imag) - + return rcomplex.c_log(x,y) _inner_wrapped_log = wrapped_log @@ -300,196 +87,38 @@ @unaryfn def c_log10(x, y): - rx, ry = c_log(x, y) - return (rx / M_LN10, ry / M_LN10) - + return rcomplex.c_log10(x,y) @unaryfn def c_exp(x, y): - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = copysign(0., math.cos(y)) - imag = copysign(0., math.sin(y)) - r = (real, imag) - else: - r = exp_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN and not -infinity - if isinf(y) and (isfinite(x) or (isinf(x) and x > 0)): - raise ValueError("math domain error") - return r - - if x > CM_LOG_LARGE_DOUBLE: - l = math.exp(x-1.) - real = l * math.cos(y) * math.e - imag = l * math.sin(y) * math.e - else: - l = math.exp(x) - real = l * math.cos(y) - imag = l * math.sin(y) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - + return rcomplex.c_exp(x,y) @unaryfn def c_cosh(x, y): - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = copysign(INF, math.cos(y)) - imag = -copysign(INF, math.sin(y)) - r = (real, imag) - else: - r = cosh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN - if isinf(y) and not isnan(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - # deal correctly with cases where cosh(x) overflows but - # cosh(z) does not. - x_minus_one = x - copysign(1., x) - real = math.cos(y) * math.cosh(x_minus_one) * math.e - imag = math.sin(y) * math.sinh(x_minus_one) * math.e - else: - real = math.cos(y) * math.cosh(x) - imag = math.sin(y) * math.sinh(x) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - + return rcomplex.c_cosh(x,y) @unaryfn def c_sinh(x, y): - # special treatment for sinh(+/-inf + iy) if y is finite and nonzero - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = -copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - r = (real, imag) - else: - r = sinh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN - if isinf(y) and not isnan(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - x_minus_one = x - copysign(1., x) - real = math.cos(y) * math.sinh(x_minus_one) * math.e - imag = math.sin(y) * math.cosh(x_minus_one) * math.e - else: - real = math.cos(y) * math.sinh(x) - imag = math.sin(y) * math.cosh(x) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - + return rcomplex.c_sinh(x,y) @unaryfn def c_tanh(x, y): - # Formula: - # - # tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) / - # (1+tan(y)^2 tanh(x)^2) - # - # To avoid excessive roundoff error, 1-tanh(x)^2 is better computed - # as 1/cosh(x)^2. When abs(x) is large, we approximate 1-tanh(x)^2 - # by 4 exp(-2*x) instead, to avoid possible overflow in the - # computation of cosh(x). - - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = 1.0 # vv XXX why is the 2. there? - imag = copysign(0., 2. * math.sin(y) * math.cos(y)) - else: - real = -1.0 - imag = copysign(0., 2. * math.sin(y) * math.cos(y)) - r = (real, imag) - else: - r = tanh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/-infinity and x is finite - if isinf(y) and isfinite(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - real = copysign(1., x) - imag = 4. * math.sin(y) * math.cos(y) * math.exp(-2.*fabs(x)) - else: - tx = math.tanh(x) - ty = math.tan(y) - cx = 1. / math.cosh(x) - txty = tx * ty - denom = 1. + txty * txty - real = tx * (1. + ty*ty) / denom - imag = ((ty / denom) * cx) * cx - return real, imag - + return rcomplex.c_tanh(x,y) @unaryfn def c_cos(x, y): - # cos(z) = cosh(iz) - return c_cosh(-y, x) + return rcomplex.c_cos(x,y) @unaryfn def c_sin(x, y): - # sin(z) = -i sinh(iz) - sx, sy = c_sinh(-y, x) - return sy, -sx + return rcomplex.c_sin(x,y) @unaryfn def c_tan(x, y): - # tan(z) = -i tanh(iz) - sx, sy = c_tanh(-y, x) - return sy, -sx - + return rcomplex.c_tan(x,y) def c_rect(r, phi): - if not isfinite(r) or not isfinite(phi): - # if r is +/-infinity and phi is finite but nonzero then - # result is (+-INF +-INF i), but we need to compute cos(phi) - # and sin(phi) to figure out the signs. - if isinf(r) and isfinite(phi) and phi != 0.: - if r > 0: - real = copysign(INF, math.cos(phi)) - imag = copysign(INF, math.sin(phi)) - else: - real = -copysign(INF, math.cos(phi)) - imag = -copysign(INF, math.sin(phi)) - z = (real, imag) - else: - z = rect_special_values[special_type(r)][special_type(phi)] - - # need to raise ValueError if r is a nonzero number and phi - # is infinite - if r != 0. and not isnan(r) and isinf(phi): - raise ValueError("math domain error") - return z - - real = r * math.cos(phi) - imag = r * math.sin(phi) - return real, imag + return rcomplex.c_rect(r,phi) def wrapped_rect(space, w_x, w_y): x = space.float_w(w_x) @@ -500,28 +129,7 @@ def c_phase(x, y): - # Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't - # follow C99 for atan2(0., 0.). - if isnan(x) or isnan(y): - return NAN - if isinf(y): - if isinf(x): - if copysign(1., x) == 1.: - # atan2(+-inf, +inf) == +-pi/4 - return copysign(0.25 * math.pi, y) - else: - # atan2(+-inf, -inf) == +-pi*3/4 - return copysign(0.75 * math.pi, y) - # atan2(+-inf, x) == +-pi/2 for finite x - return copysign(0.5 * math.pi, y) - if isinf(x) or y == 0.: - if copysign(1., x) == 1.: - # atan2(+-y, +inf) = atan2(+-0, +x) = +-0. - return copysign(0., y) - else: - # atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. - return copysign(math.pi, y) - return math.atan2(y, x) + return rcomplex.c_phase(x,y) def wrapped_phase(space, w_z): x, y = space.unpackcomplex(w_z) @@ -531,28 +139,10 @@ def c_abs(x, y): - if not isfinite(x) or not isfinite(y): - # C99 rules: if either the real or the imaginary part is an - # infinity, return infinity, even if the other part is a NaN. - if isinf(x): - return INF - if isinf(y): - return INF - - # either the real or imaginary part is a NaN, - # and neither is infinite. Result should be NaN. - return NAN - - result = math.hypot(x, y) - if not isfinite(result): - raise OverflowError("math range error") - return result - + return rcomplex.c_abs(x,y) def c_polar(x, y): - phi = c_phase(x, y) - r = c_abs(x, y) - return r, phi + return rcomplex.c_polar(x,y) def wrapped_polar(space, w_z): x, y = space.unpackcomplex(w_z) @@ -562,7 +152,7 @@ def c_isinf(x, y): - return isinf(x) or isinf(y) + return rcomplex.c_isinf(x,y) def wrapped_isinf(space, w_z): x, y = space.unpackcomplex(w_z) @@ -572,7 +162,7 @@ def c_isnan(x, y): - return isnan(x) or isnan(y) + return rcomplex.c_isnan(x,y) def wrapped_isnan(space, w_z): x, y = space.unpackcomplex(w_z) diff --git a/pypy/module/cmath/test/test_cmath.py b/pypy/module/cmath/test/test_cmath.py --- a/pypy/module/cmath/test/test_cmath.py +++ b/pypy/module/cmath/test/test_cmath.py @@ -6,7 +6,7 @@ def test_special_values(): - from pypy.module.cmath.special_value import sqrt_special_values + from pypy.rlib.special_value import sqrt_special_values assert len(sqrt_special_values) == 7 assert len(sqrt_special_values[4]) == 7 assert isinstance(sqrt_special_values[5][1], tuple) @@ -115,7 +115,6 @@ Empty lines or lines starting with -- are ignored yields id, fn, arg_real, arg_imag, exp_real, exp_imag """ - fname = os.path.join(os.path.dirname(__file__), fname) with open(fname) as fp: for line in fp: # skip comment lines and blank lines @@ -186,8 +185,10 @@ def test_specific_values(): #if not float.__getformat__("double").startswith("IEEE"): # return - - for id, fn, ar, ai, er, ei, flags in parse_testfile('cmath_testcases.txt'): + + # too fragile... + fname = os.path.join(os.path.dirname(__file__), '../../../rlib/test', 'rcomplex_testcases.txt') + for id, fn, ar, ai, er, ei, flags in parse_testfile(fname): arg = (ar, ai) expected = (er, ei) function = getattr(interp_cmath, 'c_' + fn) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -64,6 +64,10 @@ 'str_': 'interp_boxes.W_StringBox', 'unicode_': 'interp_boxes.W_UnicodeBox', 'void': 'interp_boxes.W_VoidBox', + 'complexfloating': 'interp_boxes.W_ComplexFloatingBox', + 'complex_': 'interp_boxes.W_Complex128Box', + 'complex128': 'interp_boxes.W_Complex128Box', + 'complex64': 'interp_boxes.W_Complex64Box', } # ufuncs @@ -78,6 +82,8 @@ ("arccosh", "arccosh"), ("arcsinh", "arcsinh"), ("arctanh", "arctanh"), + ("conj", "conjugate"), + ("conjugate", "conjugate"), ("copysign", "copysign"), ("cos", "cos"), ("cosh", "cosh"), @@ -141,6 +147,8 @@ ('floor_divide', 'floor_divide'), ('logaddexp', 'logaddexp'), ('logaddexp2', 'logaddexp2'), + ('real', 'real'), + ('imag', 'imag'), ]: interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl 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 @@ -56,7 +56,8 @@ w_slice = "slice" w_str = "str" w_unicode = "unicode" - + w_complex = "complex" + def __init__(self): """NOT_RPYTHON""" self.fromcache = InternalSpaceCache(self).getorbuild diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -1,11 +1,12 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import operationerrfmt, OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, GetSetProperty 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.complextype import complex_typedef from pypy.rlib.rarithmetic import LONG_BIT from pypy.tool.sourcetools import func_with_new_name from pypy.module.micronumpy.arrayimpl.voidbox import VoidBoxStorage @@ -34,6 +35,25 @@ def convert_to(self, dtype): return dtype.box(self.value) +class ComplexBox(object): + _mixin_ = True + + def __init__(self, real, imag=0.): + self.real = real + self.imag = imag + + def convert_to(self, dtype): + from pypy.module.micronumpy.types import ComplexFloating + if not isinstance(dtype.itemtype, ComplexFloating): + raise TypeError('cannot convert %r to complex' % dtype) + return dtype.box_complex(self.real, self.imag) + + def convert_real_to(self, dtype): + return dtype.box(self.real) + + def convert_imag_to(self, dtype): + return dtype.box(self.imag) + class W_GenericBox(Wrappable): _attrs_ = () @@ -57,7 +77,12 @@ return space.wrap(box.value) def descr_float(self, space): - box = self.convert_to(W_Float64Box._get_dtype(space)) + try: + box = self.convert_to(W_Float64Box._get_dtype(space)) + except TypeError: + raise OperationError(space.w_TypeError, + space.wrap("Cannot convert %s to float" % self._get_dtype(space).name)) + assert isinstance(box, W_Float64Box) return space.wrap(box.value) @@ -220,6 +245,7 @@ def descr_index(space, self): return space.index(self.item(space)) + class W_VoidBox(W_FlexibleBox): @unwrap_spec(item=str) def descr_getitem(self, space, item): @@ -266,6 +292,32 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) + +class W_ComplexFloatingBox(W_InexactBox): + _attrs_ = () + def descr_get_real(self, space): + dtype = self._COMPONENTS_BOX._get_dtype(space) + box = self.convert_real_to(dtype) + assert isinstance(box, self._COMPONENTS_BOX) + return space.wrap(box) + + def descr_get_imag(self, space): + dtype = self._COMPONENTS_BOX._get_dtype(space) + box = self.convert_imag_to(dtype) + assert isinstance(box, self._COMPONENTS_BOX) + return space.wrap(box) + + +class W_Complex64Box(ComplexBox, W_ComplexFloatingBox): + descr__new__, _get_dtype = new_dtype_getter("complex64") + _COMPONENTS_BOX = W_Float32Box + + +class W_Complex128Box(ComplexBox, W_ComplexFloatingBox): + descr__new__, _get_dtype = new_dtype_getter("complex128") + _COMPONENTS_BOX = W_Float64Box + + W_GenericBox.typedef = TypeDef("generic", __module__ = "numpypy", @@ -448,3 +500,21 @@ __new__ = interp2app(W_UnicodeBox.descr__new__unicode_box.im_func), ) +W_ComplexFloatingBox.typedef = TypeDef("complexfloating", W_InexactBox.typedef, + __module__ = "numpypy", +) + + +W_Complex128Box.typedef = TypeDef("complex128", (W_ComplexFloatingBox.typedef, complex_typedef), + __module__ = "numpypy", + __new__ = interp2app(W_Complex128Box.descr__new__.im_func), + real = GetSetProperty(W_ComplexFloatingBox.descr_get_real), + imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), +) + +W_Complex64Box.typedef = TypeDef("complex64", (W_ComplexFloatingBox.typedef), + __module__ = "numpypy", + __new__ = interp2app(W_Complex64Box.descr__new__.im_func), + real = GetSetProperty(W_ComplexFloatingBox .descr_get_real), + imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), +) 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 @@ -46,6 +46,11 @@ def box(self, value): return self.itemtype.box(value) + @specialize.argtype(1, 2) + def box_complex(self, real, imag): + return self.itemtype.box_complex(real, imag) + + def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) @@ -121,6 +126,9 @@ def is_signed(self): return self.kind == SIGNEDLTR + def is_complex_type(self): + return (self.num == 14 or self.num == 15) + def is_bool_type(self): return self.kind == BOOLLTR @@ -393,6 +401,31 @@ alternate_constructors=[space.w_float], aliases=["float"], ) + # self.w_float128dtype = W_Dtype( + # types.Float128(), + # num=13, + # kind=FLOATINGLTR, + # name="float128", + # ... + # ) + self.w_complex64dtype = W_Dtype( + types.Complex64(), + num=14, + kind=FLOATINGLTR, + name="complex64", + char="F", + w_box_type = space.gettypefor(interp_boxes.W_Complex64Box), + ) + self.w_complex128dtype = W_Dtype( + types.Complex128(), + num=15, + kind=FLOATINGLTR, + name="complex128", + char="D", + w_box_type = space.gettypefor(interp_boxes.W_Complex128Box), + alternate_constructors=[space.w_complex], + aliases=["complex"], + ) self.w_stringdtype = W_Dtype( types.StringType(1), num=18, @@ -426,8 +459,9 @@ self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype, self.w_int64dtype, self.w_uint64dtype, - self.w_float32dtype, - self.w_float64dtype, self.w_stringdtype, self.w_unicodedtype, + self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, + self.w_complex128dtype, + self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, ] self.float_dtypes_by_num_bytes = sorted( 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 @@ -383,6 +383,8 @@ descr_neg = _unaryop_impl("negative") descr_abs = _unaryop_impl("absolute") descr_invert = _unaryop_impl("invert") + descr_get_real = _unaryop_impl("real") + descr_get_imag = _unaryop_impl("imag") def descr_nonzero(self, space): if self.get_size() > 1: @@ -629,6 +631,8 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), + real = GetSetProperty(W_NDimArray.descr_get_real), + imag = GetSetProperty(W_NDimArray.descr_get_imag), __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) @@ -663,8 +667,9 @@ for w_elem in elems_w: dtype = interp_ufuncs.find_dtype_for_scalar(space, w_elem, dtype) - if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: - break + #if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: + # break + if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if ndmin > len(shape): diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -17,14 +17,15 @@ return not dtype.itemtype.bool(val) class W_Ufunc(Wrappable): - _attrs_ = ["name", "promote_to_float", "promote_bools", "identity"] - _immutable_fields_ = ["promote_to_float", "promote_bools", "name"] + _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", "allow_complex"] + _immutable_fields_ = ["promote_to_float", "promote_bools", "name", "allow_complex"] def __init__(self, name, promote_to_float, promote_bools, identity, - int_only): + int_only, allow_complex): self.name = name self.promote_to_float = promote_to_float self.promote_bools = promote_bools + self.allow_complex = allow_complex self.identity = identity self.int_only = int_only @@ -215,10 +216,10 @@ _immutable_fields_ = ["func", "name"] def __init__(self, func, name, promote_to_float=False, promote_bools=False, - identity=None, bool_result=False, int_only=False): + identity=None, bool_result=False, int_only=False, allow_complex=True): W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity, - int_only) + int_only, allow_complex) self.func = func self.bool_result = bool_result @@ -233,7 +234,8 @@ calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, - promote_bools=self.promote_bools) + promote_bools=self.promote_bools, + allow_complex=self.allow_complex) if out is not None: if not isinstance(out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( @@ -267,10 +269,10 @@ argcount = 2 def __init__(self, func, name, promote_to_float=False, promote_bools=False, - identity=None, comparison_func=False, int_only=False): + identity=None, comparison_func=False, int_only=False, allow_complex=True): W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity, - int_only) + int_only, allow_complex) self.func = func self.comparison_func = comparison_func if name == 'logical_and': @@ -289,14 +291,15 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) + calc_dtype = find_binop_result_dtype(space, + w_lhs.get_dtype(), w_rhs.get_dtype(), + int_only=self.int_only, + promote_to_float=self.promote_to_float, + promote_bools=self.promote_bools, + allow_complex=self.allow_complex, + ) if space.is_w(w_out, space.w_None) or w_out is None: out = None - calc_dtype = find_binop_result_dtype(space, - w_lhs.get_dtype(), w_rhs.get_dtype(), - int_only=self.int_only, - promote_to_float=self.promote_to_float, - promote_bools=self.promote_bools, - ) elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( 'output must be an array')) @@ -340,15 +343,25 @@ def find_binop_result_dtype(space, dt1, dt2, promote_to_float=False, - promote_bools=False, int_only=False): + promote_bools=False, int_only=False, allow_complex=True): # dt1.num should be <= dt2.num if dt1.num > dt2.num: dt1, dt2 = dt2, dt1 if int_only and (not dt1.is_int_type() or not dt2.is_int_type()): raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) + if not allow_complex and (dt1.is_complex_type() or dt2.is_complex_type()): + raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) # Some operations promote op(bool, bool) to return int8, rather than bool if promote_bools and (dt1.kind == dt2.kind == interp_dtype.BOOLLTR): return interp_dtype.get_dtype_cache(space).w_int8dtype + + # Everything promotes to complex + if dt2.num == 14 or dt2.num == 15 or dt1.num == 14 or dt2.num == 15: + if dt2.num == 15 or dt1.num == 15: + return interp_dtype.get_dtype_cache(space).w_complex128dtype + else: + return interp_dtype.get_dtype_cache(space).w_complex64dtype + if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. @@ -391,9 +404,11 @@ def find_unaryop_result_dtype(space, dt, promote_to_float=False, - promote_bools=False, promote_to_largest=False): + promote_bools=False, promote_to_largest=False, allow_complex=True): if promote_bools and (dt.kind == interp_dtype.BOOLLTR): return interp_dtype.get_dtype_cache(space).w_int8dtype + if not allow_complex and (dt.is_complex_type()): + raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) if promote_to_float: if dt.kind == interp_dtype.FLOATINGLTR: return dt @@ -419,7 +434,8 @@ bool_dtype = interp_dtype.get_dtype_cache(space).w_booldtype long_dtype = interp_dtype.get_dtype_cache(space).w_longdtype int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype - + complex_type = interp_dtype.get_dtype_cache(space).w_complex128dtype + float_type = interp_dtype.get_dtype_cache(space).w_float64dtype if isinstance(w_obj, interp_boxes.W_GenericBox): dtype = w_obj.get_dtype(space) if current_guess is None: @@ -440,6 +456,14 @@ current_guess is long_dtype or current_guess is int64_dtype): return int64_dtype return current_guess + elif space.isinstance_w(w_obj, space.w_complex): + if (current_guess is None or current_guess is bool_dtype or + current_guess is long_dtype or current_guess is int64_dtype or + current_guess is complex_type or current_guess is float_type): + return complex_type + return current_guess + if current_guess is complex_type: + return complex_type return interp_dtype.get_dtype_cache(space).w_float64dtype @@ -476,7 +500,7 @@ ("floor_divide", "floordiv", 2, {"promote_bools": True}), ("divide", "div", 2, {"promote_bools": True}), ("true_divide", "div", 2, {"promote_to_float": True}), - ("mod", "mod", 2, {"promote_bools": True}), + ("mod", "mod", 2, {"promote_bools": True, 'allow_complex': False}), ("power", "pow", 2, {"promote_bools": True}), ("left_shift", "lshift", 2, {"int_only": True}), ("right_shift", "rshift", 2, {"int_only": True}), @@ -489,8 +513,10 @@ ("greater_equal", "ge", 2, {"comparison_func": True}), ("isnan", "isnan", 1, {"bool_result": True}), ("isinf", "isinf", 1, {"bool_result": True}), - ("isneginf", "isneginf", 1, {"bool_result": True}), - ("isposinf", "isposinf", 1, {"bool_result": True}), + ("isneginf", "isneginf", 1, {"bool_result": True, + "allow_complex": False}), + ("isposinf", "isposinf", 1, {"bool_result": True, + "allow_complex": False}), ("isfinite", "isfinite", 1, {"bool_result": True}), ('logical_and', 'logical_and', 2, {'comparison_func': True, @@ -503,22 +529,32 @@ ("maximum", "max", 2), ("minimum", "min", 2), - ("copysign", "copysign", 2, {"promote_to_float": True}), + ("copysign", "copysign", 2, {"promote_to_float": True, + "allow_complex": False}), ("positive", "pos", 1), ("negative", "neg", 1), ("absolute", "abs", 1), ("sign", "sign", 1, {"promote_bools": True}), - ("signbit", "signbit", 1, {"bool_result": True}), + ("signbit", "signbit", 1, {"bool_result": True, + "allow_complex": False}), ("reciprocal", "reciprocal", 1), + ("conjugate", "conj", 1), + ("real", "real", 1), + ("imag", "imag", 1), - ("fabs", "fabs", 1, {"promote_to_float": True}), + ("fabs", "fabs", 1, {"promote_to_float": True, + "allow_complex": False}), ("fmax", "fmax", 2, {"promote_to_float": True}), ("fmin", "fmin", 2, {"promote_to_float": True}), - ("fmod", "fmod", 2, {"promote_to_float": True}), - ("floor", "floor", 1, {"promote_to_float": True}), - ("ceil", "ceil", 1, {"promote_to_float": True}), - ("trunc", "trunc", 1, {"promote_to_float": True}), + ("fmod", "fmod", 2, {"promote_to_float": True, + 'allow_complex': False}), + ("floor", "floor", 1, {"promote_to_float": True, + "allow_complex": False}), + ("ceil", "ceil", 1, {"promote_to_float": True, + "allow_complex": False}), + ("trunc", "trunc", 1, {"promote_to_float": True, + "allow_complex": False}), ("exp", "exp", 1, {"promote_to_float": True}), ("exp2", "exp2", 1, {"promote_to_float": True}), ("expm1", "expm1", 1, {"promote_to_float": True}), @@ -532,7 +568,8 @@ ("arcsin", "arcsin", 1, {"promote_to_float": True}), ("arccos", "arccos", 1, {"promote_to_float": True}), ("arctan", "arctan", 1, {"promote_to_float": True}), - ("arctan2", "arctan2", 2, {"promote_to_float": True}), + ("arctan2", "arctan2", 2, {"promote_to_float": True, + "allow_complex": False}), ("sinh", "sinh", 1, {"promote_to_float": True}), ("cosh", "cosh", 1, {"promote_to_float": True}), ("tanh", "tanh", 1, {"promote_to_float": True}), @@ -540,15 +577,19 @@ ("arccosh", "arccosh", 1, {"promote_to_float": True}), ("arctanh", "arctanh", 1, {"promote_to_float": True}), - ("radians", "radians", 1, {"promote_to_float": True}), - ("degrees", "degrees", 1, {"promote_to_float": True}), + ("radians", "radians", 1, {"promote_to_float": True, + "allow_complex": False}), + ("degrees", "degrees", 1, {"promote_to_float": True, + "allow_complex": False}), ("log", "log", 1, {"promote_to_float": True}), ("log2", "log2", 1, {"promote_to_float": True}), ("log10", "log10", 1, {"promote_to_float": True}), ("log1p", "log1p", 1, {"promote_to_float": True}), - ("logaddexp", "logaddexp", 2, {"promote_to_float": True}), - ("logaddexp2", "logaddexp2", 2, {"promote_to_float": True}), + ("logaddexp", "logaddexp", 2, {"promote_to_float": True, + "allow_complex": False}), + ("logaddexp2", "logaddexp2", 2, {"promote_to_float": True, + "allow_complex": False}), ]: self.add_ufunc(space, *ufunc_def) diff --git a/pypy/module/micronumpy/test/complex64_testcases.txt b/pypy/module/micronumpy/test/complex64_testcases.txt new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/test/complex64_testcases.txt @@ -0,0 +1,2214 @@ +-- Testcases for functions in cmath. +-- +-- Each line takes the form: +-- +-- -> +-- +-- where: +-- +-- is a short name identifying the test, +-- +-- is the function to be tested (exp, cos, asinh, ...), +-- +-- is a pair of floats separated by whitespace +-- representing real and imaginary parts of a complex number, and +-- +-- is the expected (ideal) output value, again +-- represented as a pair of floats. +-- +-- is a list of the floating-point flags required by C99 +-- +-- The possible flags are: +-- +-- divide-by-zero : raised when a finite input gives a +-- mathematically infinite result. +-- +-- overflow : raised when a finite input gives a finite result whose +-- real or imaginary part is too large to fit in the usual range +-- of an IEEE 754 double. +-- +-- invalid : raised for invalid inputs. +-- +-- ignore-real-sign : indicates that the sign of the real part of +-- the result is unspecified; if the real part of the result is +-- given as inf, then both -inf and inf should be accepted as +-- correct. +-- +-- ignore-imag-sign : indicates that the sign of the imaginary part +-- of the result is unspecified. +-- +-- Flags may appear in any order. +-- +-- Lines beginning with '--' (like this one) start a comment, and are +-- ignored. Blank lines, or lines containing only whitespace, are also +-- ignored. + +-- The majority of the values below were computed with the help of +-- version 2.3 of the MPFR library for multiple-precision +-- floating-point computations with correct rounding. All output +-- values in this file are (modulo yet-to-be-discovered bugs) +-- correctly rounded, provided that each input and output decimal +-- floating-point value below is interpreted as a representation of +-- the corresponding nearest IEEE 754 double-precision value. See the +-- MPFR homepage at http://www.mpfr.org for more information about the +-- MPFR project. + +----------------------- +-- sqrt: Square root -- +----------------------- + +-- zeros +sqrt0000 sqrt 0.0 0.0 -> 0.0 0.0 +sqrt0001 sqrt 0.0 -0.0 -> 0.0 -0.0 +sqrt0002 sqrt -0.0 0.0 -> 0.0 0.0 +sqrt0003 sqrt -0.0 -0.0 -> 0.0 -0.0 +sqrt0004 sqrt 1.0 -0.0 -> 1.0 -0.0 + +-- values along both sides of real axis +sqrt0010 sqrt -1.40129846432481707092372958329e-45 0.0 -> 0.0 3.743392130574644e-23 +sqrt0011 sqrt -1.40129846432481707092372958329e-45 -0.0 -> 0.0 -3.743392130574644e-23 +sqrt0012 sqrt -1e-35 0.0 -> 0.0 3.1622776601683795e-18 +sqrt0013 sqrt -1e-35 -0.0 -> 0.0 -3.1622776601683791e-18 +sqrt0014 sqrt -1e-20 0.0 -> 0.0 9.9999999999999996e-11 +sqrt0015 sqrt -1e-20 -0.0 -> 0.0 -9.9999999999999996e-11 +sqrt0016 sqrt -9.9999999999999998e-17 0.0 -> 0.0 1e-08 +sqrt0017 sqrt -9.9999999999999998e-17 -0.0 -> 0.0 -1e-08 +sqrt0018 sqrt -0.001 0.0 -> 0.0 0.031622776601683791 +sqrt0019 sqrt -0.001 -0.0 -> 0.0 -0.031622776601683791 +sqrt0020 sqrt -0.57899999999999996 0.0 -> 0.0 0.76092049518987193 +sqrt0021 sqrt -0.57899999999999996 -0.0 -> 0.0 -0.76092049518987193 +sqrt0022 sqrt -0.99999999999999989 0.0 -> 0.0 0.99999999999999989 +sqrt0023 sqrt -0.99999999999999989 -0.0 -> 0.0 -0.99999999999999989 +sqrt0024 sqrt -1.0000000000000002 0.0 -> 0.0 1.0 +sqrt0025 sqrt -1.0000000000000002 -0.0 -> 0.0 -1.0 +sqrt0026 sqrt -1.0009999999999999 0.0 -> 0.0 1.000499875062461 +sqrt0027 sqrt -1.0009999999999999 -0.0 -> 0.0 -1.000499875062461 +sqrt0028 sqrt -2.0 0.0 -> 0.0 1.4142135623730951 +sqrt0029 sqrt -2.0 -0.0 -> 0.0 -1.4142135623730951 +sqrt0030 sqrt -23.0 0.0 -> 0.0 4.7958315233127191 +sqrt0031 sqrt -23.0 -0.0 -> 0.0 -4.7958315233127191 +sqrt0032 sqrt -10000000000000000.0 0.0 -> 0.0 100000000.0 +sqrt0033 sqrt -10000000000000000.0 -0.0 -> 0.0 -100000000.0 +sqrt0034 sqrt -9.9999999999999998e+19 0.0 -> 0.0 9.9999999999999993e+9 +sqrt0035 sqrt -9.9999999999999998e+19 -0.0 -> 0.0 -9.9999999999999993e+9 +sqrt0036 sqrt -1.0000000000000001e+29 0.0 -> 0.0 3.1622776601683796e+14 +sqrt0037 sqrt -1.0000000000000001e+29 -0.0 -> 0.0 -3.1622776601683796e+14 +sqrt0038 sqrt 1.40129846432481707092372958329e-45 0.0 -> 3.743392130574644e-162 0.0 +sqrt0039 sqrt 9.8813129168249309e-324 -0.0 -> 3.1434555694052576e-162 -0.0 +sqrt0040 sqrt 1e-305 0.0 -> 3.1622776601683791e-153 0.0 +sqrt0041 sqrt 1e-305 -0.0 -> 3.1622776601683791e-153 -0.0 +sqrt0042 sqrt 1e-150 0.0 -> 9.9999999999999996e-76 0.0 +sqrt0043 sqrt 1e-150 -0.0 -> 9.9999999999999996e-76 -0.0 +sqrt0044 sqrt 9.9999999999999998e-17 0.0 -> 1e-08 0.0 +sqrt0045 sqrt 9.9999999999999998e-17 -0.0 -> 1e-08 -0.0 +sqrt0046 sqrt 0.001 0.0 -> 0.031622776601683791 0.0 +sqrt0047 sqrt 0.001 -0.0 -> 0.031622776601683791 -0.0 +sqrt0048 sqrt 0.57899999999999996 0.0 -> 0.76092049518987193 0.0 +sqrt0049 sqrt 0.57899999999999996 -0.0 -> 0.76092049518987193 -0.0 +sqrt0050 sqrt 0.99999999999999989 0.0 -> 0.99999999999999989 0.0 +sqrt0051 sqrt 0.99999999999999989 -0.0 -> 0.99999999999999989 -0.0 +sqrt0052 sqrt 1.0000000000000002 0.0 -> 1.0 0.0 +sqrt0053 sqrt 1.0000000000000002 -0.0 -> 1.0 -0.0 +sqrt0054 sqrt 1.0009999999999999 0.0 -> 1.000499875062461 0.0 +sqrt0055 sqrt 1.0009999999999999 -0.0 -> 1.000499875062461 -0.0 +sqrt0056 sqrt 2.0 0.0 -> 1.4142135623730951 0.0 +sqrt0057 sqrt 2.0 -0.0 -> 1.4142135623730951 -0.0 +sqrt0058 sqrt 23.0 0.0 -> 4.7958315233127191 0.0 +sqrt0059 sqrt 23.0 -0.0 -> 4.7958315233127191 -0.0 +sqrt0060 sqrt 10000000000000000.0 0.0 -> 100000000.0 0.0 +sqrt0061 sqrt 10000000000000000.0 -0.0 -> 100000000.0 -0.0 +sqrt0062 sqrt 9.9999999999999998e+149 0.0 -> 9.9999999999999993e+74 0.0 +sqrt0063 sqrt 9.9999999999999998e+149 -0.0 -> 9.9999999999999993e+74 -0.0 +sqrt0064 sqrt 1.0000000000000001e+299 0.0 -> 3.1622776601683796e+149 0.0 +sqrt0065 sqrt 1.0000000000000001e+299 -0.0 -> 3.1622776601683796e+149 -0.0 + +-- random inputs +sqrt0100 sqrt -0.34252542541549913 -223039880.15076211 -> 10560.300180587592 -10560.300196805192 +sqrt0101 sqrt -0.88790791393018909 -5.3307751730827402 -> 1.5027154613689004 -1.7737140896343291 +sqrt0102 sqrt -113916.89291310767 -0.018143374626153858 -> 2.6877817875351178e-05 -337.51576691038952 +sqrt0103 sqrt -0.63187172386197121 -0.26293913366617694 -> 0.16205707495266153 -0.81125471918761971 +sqrt0104 sqrt -0.058185169308906215 -2.3548312990430991 -> 1.0717660342420072 -1.0985752598086966 +sqrt0105 sqrt -1.0580584765935896 0.14400319259151736 -> 0.069837489270111242 1.030987755262468 +sqrt0106 sqrt -1.1667595947504932 0.11159711473953678 -> 0.051598531319315251 1.0813981705111229 +sqrt0107 sqrt -0.5123728411449906 0.026175433648339085 -> 0.018278026262418718 0.71603556293597614 +sqrt0108 sqrt -3.7453400060067228 1.0946500314809635 -> 0.27990088541692498 1.9554243814742367 +sqrt0109 sqrt -0.0027736121575097673 1.0367943000839817 -> 0.71903560338719175 0.72096172651250545 +sqrt0110 sqrt 1501.2559699453188 -1.1997325207283589 -> 38.746047664730959 -0.015481998720355024 +sqrt0111 sqrt 1.4830075326850578 -0.64100878436755349 -> 1.244712815741096 -0.25749264258434584 +sqrt0112 sqrt 0.095395618499734602 -0.48226565701639595 -> 0.54175904053472879 -0.44509239434231551 +sqrt0113 sqrt 0.50109185681863277 -0.54054037379892561 -> 0.7868179858332387 -0.34349772344520979 +sqrt0114 sqrt 0.98779807595367897 -0.00019848758437225191 -> 0.99388031770665153 -9.9854872279921968e-05 +sqrt0115 sqrt 11.845472380792259 0.0010051104581506761 -> 3.4417252072345397 0.00014601840612346451 +sqrt0116 sqrt 2.3558249686735975 0.25605157371744403 -> 1.5371278477386647 0.083288964575761404 +sqrt0117 sqrt 0.77584894123159098 1.0496420627016076 -> 1.0200744386390885 0.51449287568756552 +sqrt0118 sqrt 1.8961715669604893 0.34940793467158854 -> 1.3827991781411615 0.12634080935066902 +sqrt0119 sqrt 0.96025378316565801 0.69573224860140515 -> 1.0358710342209998 0.33581991658093457 + +-- values near 0 +sqrt0120 sqrt 7.3577938365086866e-313 8.1181408465112743e-319 -> 8.5777583531543516e-157 4.732087634251168e-163 +sqrt0121 sqrt 1.2406883874892108e-310 -5.1210133324269776e-312 -> 1.1140990057468052e-155 -2.2982756945349973e-157 +sqrt0122 sqrt -7.1145453001139502e-322 2.9561379244703735e-314 -> 1.2157585807480286e-157 1.2157586100077242e-157 +sqrt0123 sqrt -4.9963244206801218e-314 -8.4718424423690227e-319 -> 1.8950582312540437e-162 -2.2352459419578971e-157 +sqrt0124 sqrt 0.0 7.699553609385195e-318 -> 1.9620848107797476e-159 1.9620848107797476e-159 +sqrt0125 sqrt -0.0 3.3900826606499415e-309 -> 4.1170879639922327e-155 4.1170879639922327e-155 +sqrt0126 sqrt 0.0 -9.8907989772250828e-319 -> 7.032353438652342e-160 -7.032353438652342e-160 +sqrt0127 sqrt -0.0 -1.3722939367590908e-315 -> 2.6194407196566702e-158 -2.6194407196566702e-158 +sqrt0128 sqrt 7.9050503334599447e-323 0.0 -> 8.8910349979403099e-162 0.0 +sqrt0129 sqrt 1.8623241768349486e-309 -0.0 -> 4.3154654173506579e-155 -0.0 +sqrt0130 sqrt -2.665971134499887e-308 0.0 -> 0.0 1.6327801856036491e-154 +sqrt0131 sqrt -1.5477066694467245e-310 -0.0 -> 0.0 -1.2440685951533077e-155 + +-- inputs whose absolute value overflows +sqrt0140 sqrt 1.6999999999999999e+308 -1.6999999999999999e+308 -> 1.4325088230154573e+154 -5.9336458271212207e+153 +sqrt0141 sqrt -1.797e+308 -9.9999999999999999e+306 -> 3.7284476432057307e+152 -1.3410406899802901e+154 + +-- special values +sqrt1000 sqrt 0.0 0.0 -> 0.0 0.0 +sqrt1001 sqrt -0.0 0.0 -> 0.0 0.0 +sqrt1002 sqrt 0.0 inf -> inf inf +sqrt1003 sqrt 2.3 inf -> inf inf +sqrt1004 sqrt inf inf -> inf inf +sqrt1005 sqrt -0.0 inf -> inf inf +sqrt1006 sqrt -2.3 inf -> inf inf +sqrt1007 sqrt -inf inf -> inf inf +sqrt1008 sqrt nan inf -> inf inf +sqrt1009 sqrt 0.0 nan -> nan nan +sqrt1010 sqrt 2.3 nan -> nan nan +sqrt1011 sqrt -0.0 nan -> nan nan +sqrt1012 sqrt -2.3 nan -> nan nan +sqrt1013 sqrt -inf 0.0 -> 0.0 inf +sqrt1014 sqrt -inf 2.3 -> 0.0 inf +sqrt1015 sqrt inf 0.0 -> inf 0.0 +sqrt1016 sqrt inf 2.3 -> inf 0.0 +sqrt1017 sqrt -inf nan -> nan inf ignore-imag-sign +sqrt1018 sqrt inf nan -> inf nan +sqrt1019 sqrt nan 0.0 -> nan nan +sqrt1020 sqrt nan 2.3 -> nan nan +sqrt1021 sqrt nan nan -> nan nan +sqrt1022 sqrt 0.0 -0.0 -> 0.0 -0.0 +sqrt1023 sqrt -0.0 -0.0 -> 0.0 -0.0 +sqrt1024 sqrt 0.0 -inf -> inf -inf +sqrt1025 sqrt 2.3 -inf -> inf -inf +sqrt1026 sqrt inf -inf -> inf -inf +sqrt1027 sqrt -0.0 -inf -> inf -inf +sqrt1028 sqrt -2.3 -inf -> inf -inf +sqrt1029 sqrt -inf -inf -> inf -inf +sqrt1030 sqrt nan -inf -> inf -inf +sqrt1031 sqrt -inf -0.0 -> 0.0 -inf +sqrt1032 sqrt -inf -2.3 -> 0.0 -inf +sqrt1033 sqrt inf -0.0 -> inf -0.0 +sqrt1034 sqrt inf -2.3 -> inf -0.0 +sqrt1035 sqrt nan -0.0 -> nan nan +sqrt1036 sqrt nan -2.3 -> nan nan + + + +-------------------------- +-- acos: Inverse cosine -- +-------------------------- + +-- zeros +acos0000 acos 0.0 0.0 -> 1.5707963267948966 -0.0 +acos0001 acos 0.0 -0.0 -> 1.5707963267948966 0.0 +acos0002 acos -0.0 0.0 -> 1.5707963267948966 -0.0 +acos0003 acos -0.0 -0.0 -> 1.5707963267948966 0.0 + +-- branch points: +/-1 +acos0010 acos 1.0 0.0 -> 0.0 -0.0 +acos0011 acos 1.0 -0.0 -> 0.0 0.0 +acos0012 acos -1.0 0.0 -> 3.1415926535897931 -0.0 +acos0013 acos -1.0 -0.0 -> 3.1415926535897931 0.0 + +-- values along both sides of real axis +acos0020 acos -9.8813129168249309e-324 0.0 -> 1.5707963267948966 -0.0 +acos0021 acos -9.8813129168249309e-324 -0.0 -> 1.5707963267948966 0.0 +acos0022 acos -1e-305 0.0 -> 1.5707963267948966 -0.0 +acos0023 acos -1e-305 -0.0 -> 1.5707963267948966 0.0 +acos0024 acos -1e-150 0.0 -> 1.5707963267948966 -0.0 +acos0025 acos -1e-150 -0.0 -> 1.5707963267948966 0.0 +acos0026 acos -9.9999999999999998e-17 0.0 -> 1.5707963267948968 -0.0 +acos0027 acos -9.9999999999999998e-17 -0.0 -> 1.5707963267948968 0.0 +acos0028 acos -0.001 0.0 -> 1.5717963269615634 -0.0 +acos0029 acos -0.001 -0.0 -> 1.5717963269615634 0.0 +acos0030 acos -0.57899999999999996 0.0 -> 2.1882979816120667 -0.0 +acos0031 acos -0.57899999999999996 -0.0 -> 2.1882979816120667 0.0 +acos0032 acos -0.99999999999999989 0.0 -> 3.1415926386886319 -0.0 +acos0033 acos -0.99999999999999989 -0.0 -> 3.1415926386886319 0.0 +acos0034 acos -1.0000000000000002 0.0 -> 3.1415926535897931 -2.1073424255447014e-08 +acos0035 acos -1.0000000000000002 -0.0 -> 3.1415926535897931 2.1073424255447014e-08 +acos0036 acos -1.0009999999999999 0.0 -> 3.1415926535897931 -0.044717633608306849 +acos0037 acos -1.0009999999999999 -0.0 -> 3.1415926535897931 0.044717633608306849 +acos0038 acos -2.0 0.0 -> 3.1415926535897931 -1.3169578969248168 +acos0039 acos -2.0 -0.0 -> 3.1415926535897931 1.3169578969248168 +acos0040 acos -23.0 0.0 -> 3.1415926535897931 -3.8281684713331012 +acos0041 acos -23.0 -0.0 -> 3.1415926535897931 3.8281684713331012 +acos0042 acos -10000000000000000.0 0.0 -> 3.1415926535897931 -37.534508668464674 +acos0043 acos -10000000000000000.0 -0.0 -> 3.1415926535897931 37.534508668464674 +acos0044 acos -9.9999999999999998e+149 0.0 -> 3.1415926535897931 -346.08091112966679 +acos0045 acos -9.9999999999999998e+149 -0.0 -> 3.1415926535897931 346.08091112966679 +acos0046 acos -1.0000000000000001e+299 0.0 -> 3.1415926535897931 -689.16608998577965 +acos0047 acos -1.0000000000000001e+299 -0.0 -> 3.1415926535897931 689.16608998577965 +acos0048 acos 9.8813129168249309e-324 0.0 -> 1.5707963267948966 -0.0 +acos0049 acos 9.8813129168249309e-324 -0.0 -> 1.5707963267948966 0.0 +acos0050 acos 1e-305 0.0 -> 1.5707963267948966 -0.0 +acos0051 acos 1e-305 -0.0 -> 1.5707963267948966 0.0 +acos0052 acos 1e-150 0.0 -> 1.5707963267948966 -0.0 +acos0053 acos 1e-150 -0.0 -> 1.5707963267948966 0.0 +acos0054 acos 9.9999999999999998e-17 0.0 -> 1.5707963267948966 -0.0 +acos0055 acos 9.9999999999999998e-17 -0.0 -> 1.5707963267948966 0.0 +acos0056 acos 0.001 0.0 -> 1.56979632662823 -0.0 +acos0057 acos 0.001 -0.0 -> 1.56979632662823 0.0 +acos0058 acos 0.57899999999999996 0.0 -> 0.95329467197772655 -0.0 +acos0059 acos 0.57899999999999996 -0.0 -> 0.95329467197772655 0.0 +acos0060 acos 0.99999999999999989 0.0 -> 1.4901161193847656e-08 -0.0 +acos0061 acos 0.99999999999999989 -0.0 -> 1.4901161193847656e-08 0.0 +acos0062 acos 1.0000000000000002 0.0 -> 0.0 -2.1073424255447014e-08 +acos0063 acos 1.0000000000000002 -0.0 -> 0.0 2.1073424255447014e-08 +acos0064 acos 1.0009999999999999 0.0 -> 0.0 -0.044717633608306849 +acos0065 acos 1.0009999999999999 -0.0 -> 0.0 0.044717633608306849 +acos0066 acos 2.0 0.0 -> 0.0 -1.3169578969248168 +acos0067 acos 2.0 -0.0 -> 0.0 1.3169578969248168 +acos0068 acos 23.0 0.0 -> 0.0 -3.8281684713331012 +acos0069 acos 23.0 -0.0 -> 0.0 3.8281684713331012 +acos0070 acos 10000000000000000.0 0.0 -> 0.0 -37.534508668464674 +acos0071 acos 10000000000000000.0 -0.0 -> 0.0 37.534508668464674 +acos0072 acos 9.9999999999999998e+149 0.0 -> 0.0 -346.08091112966679 +acos0073 acos 9.9999999999999998e+149 -0.0 -> 0.0 346.08091112966679 +acos0074 acos 1.0000000000000001e+299 0.0 -> 0.0 -689.16608998577965 +acos0075 acos 1.0000000000000001e+299 -0.0 -> 0.0 689.16608998577965 + +-- random inputs +acos0100 acos -3.3307113324596682 -10.732007530863266 -> 1.8706085694482339 3.113986806554613 +acos0101 acos -2863.952991743291 -2681013315.2571239 -> 1.5707973950301699 22.402607843274758 +acos0102 acos -0.33072639793220088 -0.85055464658253055 -> 1.8219426895922601 0.79250166729311966 +acos0103 acos -2.5722325842097802 -12.703940809821574 -> 1.7699942413107408 3.2565170156527325 +acos0104 acos -42.495233785459583 -0.54039320751337161 -> 3.1288732573153304 4.4424815519735601 +acos0105 acos -1.1363818625856401 9641.1325498630376 -> 1.5709141948820049 -9.8669410553254284 +acos0106 acos -2.4398426824157866e-11 0.33002051890266165 -> 1.570796326818066 -0.32430578041578667 +acos0107 acos -1.3521340428186552 2.9369737912076772 -> 1.9849059192339338 -1.8822893674117942 +acos0108 acos -1.827364706477915 1.0355459232147557 -> 2.5732246307960032 -1.4090688267854969 +acos0109 acos -0.25978373706403546 10.09712669185833 -> 1.5963940386378306 -3.0081673050196063 +acos0110 acos 0.33561778471072551 -4587350.6823999118 -> 1.5707962536333251 16.031960402579539 +acos0111 acos 0.49133444610998445 -0.8071422362990015 -> 1.1908761712801788 0.78573345813187867 +acos0112 acos 0.42196734507823974 -2.4812965431745115 -> 1.414091186100692 1.651707260988172 +acos0113 acos 2.961426210100655 -219.03295695248664 -> 1.5572768319822778 6.0824659885827304 +acos0114 acos 2.886209063652641 -20.38011207220606 -> 1.4302765252297889 3.718201853147642 +acos0115 acos 0.4180568075276509 1.4833433990823484 -> 1.3393834558303042 -1.2079847758301576 +acos0116 acos 52.376111405924718 0.013930429001941001 -> 0.00026601761804024188 -4.6515066691204714 +acos0117 acos 41637948387.625969 1.563418292894041 -> 3.7547918507883548e-11 -25.145424989809381 +acos0118 acos 0.061226659122249526 0.8447234394615154 -> 1.5240280306367315 -0.76791798971140812 +acos0119 acos 2.4480466420442959e+26 0.18002339201384662 -> 7.353756620564798e-28 -61.455650015996376 + +-- values near infinity +acos0200 acos 1.6206860518683021e+308 1.0308426226285283e+308 -> 0.56650826093826223 -710.54206874241561 +acos0201 acos 1.2067735875070062e+308 -1.3429173724390276e+308 -> 0.83874369390864889 710.48017794027498 +acos0202 acos -7.4130145132549047e+307 1.1759130543927645e+308 -> 2.1332729346478536 -710.21871115698752 +acos0203 acos -8.6329426442257249e+307 -1.2316282952184133e+308 -> 2.1821511032444838 710.29752145697148 +acos0204 acos 0.0 1.4289713855849746e+308 -> 1.5707963267948966 -710.24631069738996 +acos0205 acos -0.0 1.3153524545987432e+308 -> 1.5707963267948966 -710.1634604787539 +acos0206 acos 0.0 -9.6229037669269321e+307 -> 1.5707963267948966 709.85091679573691 +acos0207 acos -0.0 -4.9783616421107088e+307 -> 1.5707963267948966 709.19187157911233 +acos0208 acos 1.3937541925739389e+308 0.0 -> 0.0 -710.22135678707264 +acos0209 acos 9.1362388967371536e+307 -0.0 -> 0.0 709.79901953124613 +acos0210 acos -1.3457361220697436e+308 0.0 -> 3.1415926535897931 -710.18629698871848 +acos0211 acos -5.4699090056144284e+307 -0.0 -> 3.1415926535897931 709.28603271085649 +acos0212 acos 1.5880716932358901e+308 5.5638401252339929 -> 3.503519487773873e-308 -710.35187633140583 +acos0213 acos 1.2497211663463164e+308 -3.0456477717911024 -> 2.4370618453197486e-308 710.11227628223412 +acos0214 acos -9.9016224006029528e+307 4.9570427340789056 -> 3.1415926535897931 -709.87946935229468 +acos0215 acos -1.5854071066874139e+308 -4.4233577741497783 -> 3.1415926535897931 710.35019704672004 +acos0216 acos 9.3674623083647628 1.5209559051877979e+308 -> 1.5707963267948966 -710.30869484491086 +acos0217 acos 8.1773832021784383 -6.6093445795000056e+307 -> 1.5707963267948966 709.4752552227792 +acos0218 acos -3.1845935000665104 1.5768856396650893e+308 -> 1.5707963267948966 -710.34480761042687 +acos0219 acos -1.0577303880953903 -6.4574626815735613e+307 -> 1.5707963267948966 709.45200719662046 + +-- values near 0 +acos0220 acos 1.8566986970714045e-320 3.1867234156760402e-321 -> 1.5707963267948966 -3.1867234156760402e-321 +acos0221 acos 7.9050503334599447e-323 -8.8931816251424378e-323 -> 1.5707963267948966 8.8931816251424378e-323 +acos0222 acos -4.4465908125712189e-323 2.4654065097222727e-311 -> 1.5707963267948966 -2.4654065097222727e-311 +acos0223 acos -6.1016916408192619e-311 -2.4703282292062327e-323 -> 1.5707963267948966 2.4703282292062327e-323 +acos0224 acos 0.0 3.4305783621842729e-311 -> 1.5707963267948966 -3.4305783621842729e-311 +acos0225 acos -0.0 1.6117409498633145e-319 -> 1.5707963267948966 -1.6117409498633145e-319 +acos0226 acos 0.0 -4.9900630229965901e-322 -> 1.5707963267948966 4.9900630229965901e-322 +acos0227 acos -0.0 -4.4889279210592818e-311 -> 1.5707963267948966 4.4889279210592818e-311 +acos0228 acos 5.3297678681477214e-312 0.0 -> 1.5707963267948966 -0.0 +acos0229 acos 6.2073425897211614e-313 -0.0 -> 1.5707963267948966 0.0 +acos0230 acos -4.9406564584124654e-324 0.0 -> 1.5707963267948966 -0.0 +acos0231 acos -1.7107517052899003e-318 -0.0 -> 1.5707963267948966 0.0 + +-- special values +acos1000 acos 0.0 0.0 -> 1.5707963267948966 -0.0 +acos1001 acos 0.0 -0.0 -> 1.5707963267948966 0.0 +acos1002 acos -0.0 0.0 -> 1.5707963267948966 -0.0 +acos1003 acos -0.0 -0.0 -> 1.5707963267948966 0.0 +acos1004 acos 0.0 nan -> 1.5707963267948966 nan +acos1005 acos -0.0 nan -> 1.5707963267948966 nan +acos1006 acos -2.3 inf -> 1.5707963267948966 -inf +acos1007 acos -0.0 inf -> 1.5707963267948966 -inf +acos1008 acos 0.0 inf -> 1.5707963267948966 -inf +acos1009 acos 2.3 inf -> 1.5707963267948966 -inf +acos1010 acos -2.3 nan -> nan nan +acos1011 acos 2.3 nan -> nan nan +acos1012 acos -inf 2.3 -> 3.1415926535897931 -inf +acos1013 acos -inf 0.0 -> 3.1415926535897931 -inf +acos1014 acos inf 2.3 -> 0.0 -inf +acos1015 acos inf 0.0 -> 0.0 -inf +acos1016 acos -inf inf -> 2.3561944901923448 -inf +acos1017 acos inf inf -> 0.78539816339744828 -inf +acos1018 acos inf nan -> nan inf ignore-imag-sign +acos1019 acos -inf nan -> nan inf ignore-imag-sign +acos1020 acos nan 0.0 -> nan nan +acos1021 acos nan 2.3 -> nan nan +acos1022 acos nan inf -> nan -inf +acos1023 acos nan nan -> nan nan +acos1024 acos -2.3 -inf -> 1.5707963267948966 inf +acos1025 acos -0.0 -inf -> 1.5707963267948966 inf +acos1026 acos 0.0 -inf -> 1.5707963267948966 inf +acos1027 acos 2.3 -inf -> 1.5707963267948966 inf +acos1028 acos -inf -2.3 -> 3.1415926535897931 inf +acos1029 acos -inf -0.0 -> 3.1415926535897931 inf +acos1030 acos inf -2.3 -> 0.0 inf +acos1031 acos inf -0.0 -> 0.0 inf +acos1032 acos -inf -inf -> 2.3561944901923448 inf +acos1033 acos inf -inf -> 0.78539816339744828 inf +acos1034 acos nan -0.0 -> nan nan +acos1035 acos nan -2.3 -> nan nan +acos1036 acos nan -inf -> nan inf + + +-------------------------------------- +-- acosh: Inverse hyperbolic cosine -- +-------------------------------------- + +-- zeros +acosh0000 acosh 0.0 0.0 -> 0.0 1.5707963267948966 +acosh0001 acosh 0.0 -0.0 -> 0.0 -1.5707963267948966 +acosh0002 acosh -0.0 0.0 -> 0.0 1.5707963267948966 +acosh0003 acosh -0.0 -0.0 -> 0.0 -1.5707963267948966 + +-- branch points: +/-1 +acosh0010 acosh 1.0 0.0 -> 0.0 0.0 +acosh0011 acosh 1.0 -0.0 -> 0.0 -0.0 +acosh0012 acosh -1.0 0.0 -> 0.0 3.1415926535897931 +acosh0013 acosh -1.0 -0.0 -> 0.0 -3.1415926535897931 + +-- values along both sides of real axis +acosh0020 acosh -9.8813129168249309e-324 0.0 -> 0.0 1.5707963267948966 +acosh0021 acosh -9.8813129168249309e-324 -0.0 -> 0.0 -1.5707963267948966 +acosh0022 acosh -1e-305 0.0 -> 0.0 1.5707963267948966 +acosh0023 acosh -1e-305 -0.0 -> 0.0 -1.5707963267948966 +acosh0024 acosh -1e-150 0.0 -> 0.0 1.5707963267948966 +acosh0025 acosh -1e-150 -0.0 -> 0.0 -1.5707963267948966 +acosh0026 acosh -9.9999999999999998e-17 0.0 -> 0.0 1.5707963267948968 +acosh0027 acosh -9.9999999999999998e-17 -0.0 -> 0.0 -1.5707963267948968 +acosh0028 acosh -0.001 0.0 -> 0.0 1.5717963269615634 +acosh0029 acosh -0.001 -0.0 -> 0.0 -1.5717963269615634 +acosh0030 acosh -0.57899999999999996 0.0 -> 0.0 2.1882979816120667 +acosh0031 acosh -0.57899999999999996 -0.0 -> 0.0 -2.1882979816120667 +acosh0032 acosh -0.99999999999999989 0.0 -> 0.0 3.1415926386886319 +acosh0033 acosh -0.99999999999999989 -0.0 -> 0.0 -3.1415926386886319 +acosh0034 acosh -1.0000000000000002 0.0 -> 2.1073424255447014e-08 3.1415926535897931 +acosh0035 acosh -1.0000000000000002 -0.0 -> 2.1073424255447014e-08 -3.1415926535897931 +acosh0036 acosh -1.0009999999999999 0.0 -> 0.044717633608306849 3.1415926535897931 +acosh0037 acosh -1.0009999999999999 -0.0 -> 0.044717633608306849 -3.1415926535897931 +acosh0038 acosh -2.0 0.0 -> 1.3169578969248168 3.1415926535897931 +acosh0039 acosh -2.0 -0.0 -> 1.3169578969248168 -3.1415926535897931 +acosh0040 acosh -23.0 0.0 -> 3.8281684713331012 3.1415926535897931 +acosh0041 acosh -23.0 -0.0 -> 3.8281684713331012 -3.1415926535897931 +acosh0042 acosh -10000000000000000.0 0.0 -> 37.534508668464674 3.1415926535897931 +acosh0043 acosh -10000000000000000.0 -0.0 -> 37.534508668464674 -3.1415926535897931 +acosh0044 acosh -9.9999999999999998e+149 0.0 -> 346.08091112966679 3.1415926535897931 +acosh0045 acosh -9.9999999999999998e+149 -0.0 -> 346.08091112966679 -3.1415926535897931 +acosh0046 acosh -1.0000000000000001e+299 0.0 -> 689.16608998577965 3.1415926535897931 +acosh0047 acosh -1.0000000000000001e+299 -0.0 -> 689.16608998577965 -3.1415926535897931 +acosh0048 acosh 9.8813129168249309e-324 0.0 -> 0.0 1.5707963267948966 +acosh0049 acosh 9.8813129168249309e-324 -0.0 -> 0.0 -1.5707963267948966 +acosh0050 acosh 1e-305 0.0 -> 0.0 1.5707963267948966 +acosh0051 acosh 1e-305 -0.0 -> 0.0 -1.5707963267948966 +acosh0052 acosh 1e-150 0.0 -> 0.0 1.5707963267948966 +acosh0053 acosh 1e-150 -0.0 -> 0.0 -1.5707963267948966 +acosh0054 acosh 9.9999999999999998e-17 0.0 -> 0.0 1.5707963267948966 +acosh0055 acosh 9.9999999999999998e-17 -0.0 -> 0.0 -1.5707963267948966 +acosh0056 acosh 0.001 0.0 -> 0.0 1.56979632662823 +acosh0057 acosh 0.001 -0.0 -> 0.0 -1.56979632662823 +acosh0058 acosh 0.57899999999999996 0.0 -> 0.0 0.95329467197772655 +acosh0059 acosh 0.57899999999999996 -0.0 -> 0.0 -0.95329467197772655 +acosh0060 acosh 0.99999999999999989 0.0 -> 0.0 1.4901161193847656e-08 +acosh0061 acosh 0.99999999999999989 -0.0 -> 0.0 -1.4901161193847656e-08 +acosh0062 acosh 1.0000000000000002 0.0 -> 2.1073424255447014e-08 0.0 +acosh0063 acosh 1.0000000000000002 -0.0 -> 2.1073424255447014e-08 -0.0 +acosh0064 acosh 1.0009999999999999 0.0 -> 0.044717633608306849 0.0 +acosh0065 acosh 1.0009999999999999 -0.0 -> 0.044717633608306849 -0.0 +acosh0066 acosh 2.0 0.0 -> 1.3169578969248168 0.0 +acosh0067 acosh 2.0 -0.0 -> 1.3169578969248168 -0.0 +acosh0068 acosh 23.0 0.0 -> 3.8281684713331012 0.0 +acosh0069 acosh 23.0 -0.0 -> 3.8281684713331012 -0.0 +acosh0070 acosh 10000000000000000.0 0.0 -> 37.534508668464674 0.0 +acosh0071 acosh 10000000000000000.0 -0.0 -> 37.534508668464674 -0.0 +acosh0072 acosh 9.9999999999999998e+149 0.0 -> 346.08091112966679 0.0 +acosh0073 acosh 9.9999999999999998e+149 -0.0 -> 346.08091112966679 -0.0 +acosh0074 acosh 1.0000000000000001e+299 0.0 -> 689.16608998577965 0.0 +acosh0075 acosh 1.0000000000000001e+299 -0.0 -> 689.16608998577965 -0.0 + +-- random inputs +acosh0100 acosh -1.4328589581250843 -1.8370347775558309 -> 1.5526962646549587 -2.190250168435786 +acosh0101 acosh -0.31075819156220957 -1.0772555786839297 -> 0.95139168286193709 -1.7812228089636479 +acosh0102 acosh -1.9044776578070453 -20.485370158932124 -> 3.7177411088932359 -1.6633888745861227 +acosh0103 acosh -0.075642506000858742 -21965976320.873051 -> 24.505907742881991 -1.5707963267983402 +acosh0104 acosh -1.6162271181056307 -3.0369343458696099 -> 1.9407057262861227 -2.0429549461750209 +acosh0105 acosh -0.3103780280298063 0.00018054880018078987 -> 0.00018992877058761416 1.886386995096728 +acosh0106 acosh -9159468751.5897655 5.8014747664273649 -> 23.631201197959193 3.1415926529564078 +acosh0107 acosh -0.037739157550933884 0.21841357493510705 -> 0.21685844960602488 1.6076735133449402 +acosh0108 acosh -8225991.0508394297 0.28318543008913644 -> 16.615956520420287 3.1415926191641019 +acosh0109 acosh -35.620070502302639 0.31303237005015 -> 4.2658980006943965 3.1328013255541873 +acosh0110 acosh 96.729939906820917 -0.029345228372365334 -> 5.2650434775863548 -0.00030338895866972843 +acosh0111 acosh 0.59656024007966491 -2.0412294654163978 -> 1.4923002024287835 -1.312568421900338 +acosh0112 acosh 109.29384112677828 -0.00015454863061533812 -> 5.3871662961545477 -1.4141245154061214e-06 +acosh0113 acosh 8.6705651969361597 -3.6723631649787465 -> 2.9336180958363545 -0.40267362031872861 +acosh0114 acosh 1.8101646445052686 -0.012345132721855478 -> 1.1997148566285769 -0.0081813912760150265 +acosh0115 acosh 52.56897195025288 0.001113916065985443 -> 4.6551827622264135 2.1193445872040307e-05 +acosh0116 acosh 0.28336786164214739 355643992457.40485 -> 27.290343226816528 1.5707963267940999 +acosh0117 acosh 0.73876621291911437 2.8828594541104322e-20 -> 4.2774820978159067e-20 0.73955845836827927 +acosh0118 acosh 0.025865471781718878 37125746064318.492 -> 31.938478989418012 1.5707963267948959 +acosh0119 acosh 2.2047353511780132 0.074712248143489271 -> 1.4286403248698021 0.037997904971626598 + +-- values near infinity +acosh0200 acosh 8.1548592876467785e+307 9.0943779335951128e+307 -> 710.08944620800605 0.83981165425478954 +acosh0201 acosh 1.4237229680972531e+308 -1.0336966617874858e+308 -> 710.4543331094759 -0.6279972876348755 +acosh0202 acosh -1.5014526899738939e+308 1.5670700378448792e+308 -> 710.66420706795464 2.3348137299106697 +acosh0203 acosh -1.0939040375213928e+308 -1.0416960351127978e+308 -> 710.30182863115886 -2.380636147787027 +acosh0204 acosh 0.0 1.476062433559588e+308 -> 710.27873384716929 1.5707963267948966 +acosh0205 acosh -0.0 6.2077210326221094e+307 -> 709.41256457484769 1.5707963267948966 +acosh0206 acosh 0.0 -1.5621899909968308e+308 -> 710.33544449990734 -1.5707963267948966 +acosh0207 acosh -0.0 -8.3556624833839122e+307 -> 709.70971018048317 -1.5707963267948966 +acosh0208 acosh 1.3067079752499342e+308 0.0 -> 710.15686680107228 0.0 +acosh0209 acosh 1.5653640340214026e+308 -0.0 -> 710.33747422926706 -0.0 +acosh0210 acosh -6.9011375992290636e+307 0.0 -> 709.51845699719922 3.1415926535897931 +acosh0211 acosh -9.9539576809926973e+307 -0.0 -> 709.88474095870185 -3.1415926535897931 +acosh0212 acosh 7.6449598518914925e+307 9.5706540768268358 -> 709.62081731754802 1.2518906916769345e-307 +acosh0213 acosh 5.4325410972602197e+307 -7.8064807816522706 -> 709.279177727925 -1.4369851312471974e-307 +acosh0214 acosh -1.1523626112360465e+308 7.0617510038869336 -> 710.03117010216909 3.1415926535897931 +acosh0215 acosh -1.1685027786862599e+308 -5.1568558357925625 -> 710.04507907571417 -3.1415926535897931 +acosh0216 acosh 3.0236370339788721 1.7503248720096417e+308 -> 710.44915723458064 1.5707963267948966 +acosh0217 acosh 6.6108007926031149 -9.1469968225806149e+307 -> 709.80019633903328 -1.5707963267948966 +acosh0218 acosh -5.1096262905623959 6.4484926785412395e+307 -> 709.45061713997973 1.5707963267948966 +acosh0219 acosh -2.8080920608735846 -1.7716118836519368e+308 -> 710.46124562363445 -1.5707963267948966 + +-- values near 0 +acosh0220 acosh 4.5560530326699304e-317 7.3048989121436657e-318 -> 7.3048989121436657e-318 1.5707963267948966 +acosh0221 acosh 4.8754274133585331e-314 -9.8469794897684199e-315 -> 9.8469794897684199e-315 -1.5707963267948966 +acosh0222 acosh -4.6748876009960097e-312 9.7900342887557606e-318 -> 9.7900342887557606e-318 1.5707963267948966 +acosh0223 acosh -4.3136871538399236e-320 -4.9406564584124654e-323 -> 4.9406564584124654e-323 -1.5707963267948966 +acosh0224 acosh 0.0 4.3431013866496774e-314 -> 4.3431013866496774e-314 1.5707963267948966 +acosh0225 acosh -0.0 6.0147334335829184e-317 -> 6.0147334335829184e-317 1.5707963267948966 +acosh0226 acosh 0.0 -1.2880291387081297e-320 -> 1.2880291387081297e-320 -1.5707963267948966 +acosh0227 acosh -0.0 -1.4401563976534621e-317 -> 1.4401563976534621e-317 -1.5707963267948966 +acosh0228 acosh 1.3689680570863091e-313 0.0 -> 0.0 1.5707963267948966 +acosh0229 acosh 1.5304346893494371e-312 -0.0 -> 0.0 -1.5707963267948966 +acosh0230 acosh -3.7450175954766488e-320 0.0 -> 0.0 1.5707963267948966 +acosh0231 acosh -8.4250563080885801e-311 -0.0 -> 0.0 -1.5707963267948966 + +-- special values +acosh1000 acosh 0.0 0.0 -> 0.0 1.5707963267948966 +acosh1001 acosh -0.0 0.0 -> 0.0 1.5707963267948966 +acosh1002 acosh 0.0 inf -> inf 1.5707963267948966 +acosh1003 acosh 2.3 inf -> inf 1.5707963267948966 +acosh1004 acosh -0.0 inf -> inf 1.5707963267948966 +acosh1005 acosh -2.3 inf -> inf 1.5707963267948966 +acosh1006 acosh 0.0 nan -> nan nan +acosh1007 acosh 2.3 nan -> nan nan +acosh1008 acosh -0.0 nan -> nan nan +acosh1009 acosh -2.3 nan -> nan nan +acosh1010 acosh -inf 0.0 -> inf 3.1415926535897931 +acosh1011 acosh -inf 2.3 -> inf 3.1415926535897931 +acosh1012 acosh inf 0.0 -> inf 0.0 +acosh1013 acosh inf 2.3 -> inf 0.0 +acosh1014 acosh -inf inf -> inf 2.3561944901923448 +acosh1015 acosh inf inf -> inf 0.78539816339744828 +acosh1016 acosh inf nan -> inf nan +acosh1017 acosh -inf nan -> inf nan +acosh1018 acosh nan 0.0 -> nan nan +acosh1019 acosh nan 2.3 -> nan nan +acosh1020 acosh nan inf -> inf nan +acosh1021 acosh nan nan -> nan nan +acosh1022 acosh 0.0 -0.0 -> 0.0 -1.5707963267948966 +acosh1023 acosh -0.0 -0.0 -> 0.0 -1.5707963267948966 +acosh1024 acosh 0.0 -inf -> inf -1.5707963267948966 +acosh1025 acosh 2.3 -inf -> inf -1.5707963267948966 +acosh1026 acosh -0.0 -inf -> inf -1.5707963267948966 +acosh1027 acosh -2.3 -inf -> inf -1.5707963267948966 +acosh1028 acosh -inf -0.0 -> inf -3.1415926535897931 +acosh1029 acosh -inf -2.3 -> inf -3.1415926535897931 +acosh1030 acosh inf -0.0 -> inf -0.0 +acosh1031 acosh inf -2.3 -> inf -0.0 +acosh1032 acosh -inf -inf -> inf -2.3561944901923448 +acosh1033 acosh inf -inf -> inf -0.78539816339744828 +acosh1034 acosh nan -0.0 -> nan nan +acosh1035 acosh nan -2.3 -> nan nan +acosh1036 acosh nan -inf -> inf nan + + +------------------------ +-- asin: Inverse sine -- +------------------------ + +-- zeros +asin0000 asin 0.0 0.0 -> 0.0 0.0 +asin0001 asin 0.0 -0.0 -> 0.0 -0.0 +asin0002 asin -0.0 0.0 -> -0.0 0.0 +asin0003 asin -0.0 -0.0 -> -0.0 -0.0 + +-- branch points: +/-1 +asin0010 asin 1.0 0.0 -> 1.5707963267948966 0.0 +asin0011 asin 1.0 -0.0 -> 1.5707963267948966 -0.0 +asin0012 asin -1.0 0.0 -> -1.5707963267948966 0.0 +asin0013 asin -1.0 -0.0 -> -1.5707963267948966 -0.0 + +-- values along both sides of real axis +asin0020 asin -9.8813129168249309e-324 0.0 -> -9.8813129168249309e-324 0.0 +asin0021 asin -9.8813129168249309e-324 -0.0 -> -9.8813129168249309e-324 -0.0 +asin0022 asin -1e-305 0.0 -> -1e-305 0.0 +asin0023 asin -1e-305 -0.0 -> -1e-305 -0.0 +asin0024 asin -1e-150 0.0 -> -1e-150 0.0 +asin0025 asin -1e-150 -0.0 -> -1e-150 -0.0 +asin0026 asin -9.9999999999999998e-17 0.0 -> -9.9999999999999998e-17 0.0 +asin0027 asin -9.9999999999999998e-17 -0.0 -> -9.9999999999999998e-17 -0.0 +asin0028 asin -0.001 0.0 -> -0.0010000001666667416 0.0 +asin0029 asin -0.001 -0.0 -> -0.0010000001666667416 -0.0 +asin0030 asin -0.57899999999999996 0.0 -> -0.61750165481717001 0.0 +asin0031 asin -0.57899999999999996 -0.0 -> -0.61750165481717001 -0.0 +asin0032 asin -0.99999999999999989 0.0 -> -1.5707963118937354 0.0 +asin0033 asin -0.99999999999999989 -0.0 -> -1.5707963118937354 -0.0 +asin0034 asin -1.0000000000000002 0.0 -> -1.5707963267948966 2.1073424255447014e-08 +asin0035 asin -1.0000000000000002 -0.0 -> -1.5707963267948966 -2.1073424255447014e-08 +asin0036 asin -1.0009999999999999 0.0 -> -1.5707963267948966 0.044717633608306849 +asin0037 asin -1.0009999999999999 -0.0 -> -1.5707963267948966 -0.044717633608306849 +asin0038 asin -2.0 0.0 -> -1.5707963267948966 1.3169578969248168 +asin0039 asin -2.0 -0.0 -> -1.5707963267948966 -1.3169578969248168 +asin0040 asin -23.0 0.0 -> -1.5707963267948966 3.8281684713331012 +asin0041 asin -23.0 -0.0 -> -1.5707963267948966 -3.8281684713331012 +asin0042 asin -10000000000000000.0 0.0 -> -1.5707963267948966 37.534508668464674 +asin0043 asin -10000000000000000.0 -0.0 -> -1.5707963267948966 -37.534508668464674 +asin0044 asin -9.9999999999999998e+149 0.0 -> -1.5707963267948966 346.08091112966679 +asin0045 asin -9.9999999999999998e+149 -0.0 -> -1.5707963267948966 -346.08091112966679 +asin0046 asin -1.0000000000000001e+299 0.0 -> -1.5707963267948966 689.16608998577965 +asin0047 asin -1.0000000000000001e+299 -0.0 -> -1.5707963267948966 -689.16608998577965 +asin0048 asin 9.8813129168249309e-324 0.0 -> 9.8813129168249309e-324 0.0 +asin0049 asin 9.8813129168249309e-324 -0.0 -> 9.8813129168249309e-324 -0.0 +asin0050 asin 1e-305 0.0 -> 1e-305 0.0 +asin0051 asin 1e-305 -0.0 -> 1e-305 -0.0 +asin0052 asin 1e-150 0.0 -> 1e-150 0.0 +asin0053 asin 1e-150 -0.0 -> 1e-150 -0.0 +asin0054 asin 9.9999999999999998e-17 0.0 -> 9.9999999999999998e-17 0.0 +asin0055 asin 9.9999999999999998e-17 -0.0 -> 9.9999999999999998e-17 -0.0 +asin0056 asin 0.001 0.0 -> 0.0010000001666667416 0.0 +asin0057 asin 0.001 -0.0 -> 0.0010000001666667416 -0.0 +asin0058 asin 0.57899999999999996 0.0 -> 0.61750165481717001 0.0 +asin0059 asin 0.57899999999999996 -0.0 -> 0.61750165481717001 -0.0 +asin0060 asin 0.99999999999999989 0.0 -> 1.5707963118937354 0.0 +asin0061 asin 0.99999999999999989 -0.0 -> 1.5707963118937354 -0.0 +asin0062 asin 1.0000000000000002 0.0 -> 1.5707963267948966 2.1073424255447014e-08 +asin0063 asin 1.0000000000000002 -0.0 -> 1.5707963267948966 -2.1073424255447014e-08 +asin0064 asin 1.0009999999999999 0.0 -> 1.5707963267948966 0.044717633608306849 +asin0065 asin 1.0009999999999999 -0.0 -> 1.5707963267948966 -0.044717633608306849 +asin0066 asin 2.0 0.0 -> 1.5707963267948966 1.3169578969248168 +asin0067 asin 2.0 -0.0 -> 1.5707963267948966 -1.3169578969248168 +asin0068 asin 23.0 0.0 -> 1.5707963267948966 3.8281684713331012 +asin0069 asin 23.0 -0.0 -> 1.5707963267948966 -3.8281684713331012 +asin0070 asin 10000000000000000.0 0.0 -> 1.5707963267948966 37.534508668464674 +asin0071 asin 10000000000000000.0 -0.0 -> 1.5707963267948966 -37.534508668464674 +asin0072 asin 9.9999999999999998e+149 0.0 -> 1.5707963267948966 346.08091112966679 +asin0073 asin 9.9999999999999998e+149 -0.0 -> 1.5707963267948966 -346.08091112966679 +asin0074 asin 1.0000000000000001e+299 0.0 -> 1.5707963267948966 689.16608998577965 +asin0075 asin 1.0000000000000001e+299 -0.0 -> 1.5707963267948966 -689.16608998577965 + +-- random inputs +asin0100 asin -1.5979555835086083 -0.15003009814595247 -> -1.4515369557405788 -1.0544476399790823 +asin0101 asin -0.57488225895317679 -9.6080397838952743e-13 -> -0.61246024460412851 -1.174238005400403e-12 +asin0102 asin -3.6508087930516249 -0.36027527093220152 -> -1.4685890605305874 -1.9742273007152038 +asin0103 asin -1.5238659792326819 -1.1360813516996364 -> -0.86080051691147275 -1.3223742205689195 +asin0104 asin -1592.0639045555306 -0.72362427935018236 -> -1.5703418071175179 -8.0659336918729228 +asin0105 asin -0.19835471371312019 4.2131508416697709 -> -0.045777831019935149 2.1461732751933171 +asin0106 asin -1.918471054430213 0.40603305079779234 -> -1.3301396585791556 1.30263642314981 +asin0107 asin -254495.01623373642 0.71084414434470822 -> -1.5707935336394359 13.140183712762321 +asin0108 asin -0.31315882715691157 3.9647994288429866 -> -0.076450403840916004 2.0889762138713457 +asin0109 asin -0.90017064284720816 1.2530659485907105 -> -0.53466509741943447 1.1702811557577 +asin0110 asin 2.1615181696571075 -0.14058647488229523 -> 1.4976166323896871 -1.4085811039334604 +asin0111 asin 1.2104749210707795 -0.85732484485298999 -> 0.83913071588343924 -1.0681719250525901 +asin0112 asin 1.7059733185128891 -0.84032966373156581 -> 1.0510900815816229 -1.2967979791361652 +asin0113 asin 9.9137085017290687 -1.4608383970250893 -> 1.4237704820128891 -2.995414677560686 +asin0114 asin 117.12344751041495 -5453908091.5334015 -> 2.1475141411392012e-08 -23.112745450217066 +asin0115 asin 0.081041187798029227 0.067054349860173196 -> 0.080946786856771813 0.067223991060639698 +asin0116 asin 46.635472322049949 2.3835190718056678 -> 1.5197194940010779 4.5366989600972083 +asin0117 asin 3907.0687961127105 19.144021886390181 -> 1.5658965233083235 8.9637018715924217 +asin0118 asin 1.0889312322308273 509.01577883554768 -> 0.0021392803817829316 6.9256294494524706 +asin0119 asin 0.10851518277509224 1.5612510908217476 -> 0.058491014243902621 1.2297075725621327 + +-- values near infinity +asin0200 asin 1.5230241998821499e+308 5.5707228994084525e+307 -> 1.2201446370892068 710.37283486535966 +asin0201 asin 8.1334317698672204e+307 -9.2249425197872451e+307 -> 0.72259991284020042 -710.0962453049026 +asin0202 asin -9.9138506659241768e+307 6.701544526434995e+307 -> -0.97637511742194594 710.06887486671371 +asin0203 asin -1.4141298868173842e+308 -5.401505134514191e+307 -> -1.2059319055160587 -710.30396478954628 +asin0204 asin 0.0 9.1618092977897431e+307 -> 0.0 709.80181441050593 +asin0205 asin -0.0 6.8064342551939755e+307 -> -0.0 709.50463910853489 +asin0206 asin 0.0 -6.4997516454798215e+307 -> 0.0 -709.45853469751592 +asin0207 asin -0.0 -1.6767449053345242e+308 -> -0.0 -710.4062101803022 +asin0208 asin 5.4242749957378916e+307 0.0 -> 1.5707963267948966 709.27765497888902 +asin0209 asin 9.5342145121164749e+307 -0.0 -> 1.5707963267948966 -709.84165758595907 +asin0210 asin -7.0445698006201847e+307 0.0 -> -1.5707963267948966 709.53902780872136 +asin0211 asin -1.0016025569769706e+308 -0.0 -> -1.5707963267948966 -709.89095709697881 +asin0212 asin 1.6552203778877204e+308 0.48761543336249491 -> 1.5707963267948966 710.39328998153474 +asin0213 asin 1.2485712830384869e+308 -4.3489311161278899 -> 1.5707963267948966 -710.1113557467786 +asin0214 asin -1.5117842813353125e+308 5.123452666102434 -> -1.5707963267948966 710.30264641923031 +asin0215 asin -1.3167634313008016e+308 -0.52939679793528982 -> -1.5707963267948966 -710.16453260239768 +asin0216 asin 0.80843929176985907 1.0150851827767876e+308 -> 7.9642507396113875e-309 709.90432835561637 +asin0217 asin 8.2544809829680901 -1.7423548140539474e+308 -> 4.7375430746865733e-308 -710.44459336242164 +asin0218 asin -5.2499000118824295 4.6655578977512214e+307 -> -1.1252459249113292e-307 709.1269781491103 +asin0219 asin -5.9904782760833433 -4.7315689314781163e+307 -> -1.2660659419394637e-307 -709.14102757522312 + +-- special values +asin1000 asin -0.0 0.0 -> -0.0 0.0 +asin1001 asin 0.0 0.0 -> 0.0 0.0 +asin1002 asin -0.0 -0.0 -> -0.0 -0.0 +asin1003 asin 0.0 -0.0 -> 0.0 -0.0 +asin1004 asin -inf 0.0 -> -1.5707963267948966 inf +asin1005 asin -inf 2.2999999999999998 -> -1.5707963267948966 inf +asin1006 asin nan 0.0 -> nan nan +asin1007 asin nan 2.2999999999999998 -> nan nan +asin1008 asin -0.0 inf -> -0.0 inf +asin1009 asin -2.2999999999999998 inf -> -0.0 inf +asin1010 asin -inf inf -> -0.78539816339744828 inf +asin1011 asin nan inf -> nan inf +asin1012 asin -0.0 nan -> -0.0 nan +asin1013 asin -2.2999999999999998 nan -> nan nan +asin1014 asin -inf nan -> nan inf ignore-imag-sign +asin1015 asin nan nan -> nan nan +asin1016 asin inf 0.0 -> 1.5707963267948966 inf +asin1017 asin inf 2.2999999999999998 -> 1.5707963267948966 inf +asin1018 asin 0.0 inf -> 0.0 inf +asin1019 asin 2.2999999999999998 inf -> 0.0 inf +asin1020 asin inf inf -> 0.78539816339744828 inf +asin1021 asin 0.0 nan -> 0.0 nan +asin1022 asin 2.2999999999999998 nan -> nan nan +asin1023 asin inf nan -> nan inf ignore-imag-sign +asin1024 asin inf -0.0 -> 1.5707963267948966 -inf +asin1025 asin inf -2.2999999999999998 -> 1.5707963267948966 -inf +asin1026 asin nan -0.0 -> nan nan +asin1027 asin nan -2.2999999999999998 -> nan nan +asin1028 asin 0.0 -inf -> 0.0 -inf +asin1029 asin 2.2999999999999998 -inf -> 0.0 -inf +asin1030 asin inf -inf -> 0.78539816339744828 -inf +asin1031 asin nan -inf -> nan -inf +asin1032 asin -inf -0.0 -> -1.5707963267948966 -inf +asin1033 asin -inf -2.2999999999999998 -> -1.5707963267948966 -inf +asin1034 asin -0.0 -inf -> -0.0 -inf +asin1035 asin -2.2999999999999998 -inf -> -0.0 -inf +asin1036 asin -inf -inf -> -0.78539816339744828 -inf + + +------------------------------------ +-- asinh: Inverse hyperbolic sine -- +------------------------------------ + +-- zeros +asinh0000 asinh 0.0 0.0 -> 0.0 0.0 +asinh0001 asinh 0.0 -0.0 -> 0.0 -0.0 +asinh0002 asinh -0.0 0.0 -> -0.0 0.0 +asinh0003 asinh -0.0 -0.0 -> -0.0 -0.0 + +-- branch points: +/-i +asinh0010 asinh 0.0 1.0 -> 0.0 1.5707963267948966 +asinh0011 asinh 0.0 -1.0 -> 0.0 -1.5707963267948966 +asinh0012 asinh -0.0 1.0 -> -0.0 1.5707963267948966 +asinh0013 asinh -0.0 -1.0 -> -0.0 -1.5707963267948966 + +-- values along both sides of imaginary axis +asinh0020 asinh 0.0 -9.8813129168249309e-324 -> 0.0 -9.8813129168249309e-324 +asinh0021 asinh -0.0 -9.8813129168249309e-324 -> -0.0 -9.8813129168249309e-324 +asinh0022 asinh 0.0 -1e-305 -> 0.0 -1e-305 +asinh0023 asinh -0.0 -1e-305 -> -0.0 -1e-305 +asinh0024 asinh 0.0 -1e-150 -> 0.0 -1e-150 +asinh0025 asinh -0.0 -1e-150 -> -0.0 -1e-150 +asinh0026 asinh 0.0 -9.9999999999999998e-17 -> 0.0 -9.9999999999999998e-17 +asinh0027 asinh -0.0 -9.9999999999999998e-17 -> -0.0 -9.9999999999999998e-17 +asinh0028 asinh 0.0 -0.001 -> 0.0 -0.0010000001666667416 +asinh0029 asinh -0.0 -0.001 -> -0.0 -0.0010000001666667416 +asinh0030 asinh 0.0 -0.57899999999999996 -> 0.0 -0.61750165481717001 +asinh0031 asinh -0.0 -0.57899999999999996 -> -0.0 -0.61750165481717001 +asinh0032 asinh 0.0 -0.99999999999999989 -> 0.0 -1.5707963118937354 +asinh0033 asinh -0.0 -0.99999999999999989 -> -0.0 -1.5707963118937354 +asinh0034 asinh 0.0 -1.0000000000000002 -> 2.1073424255447014e-08 -1.5707963267948966 +asinh0035 asinh -0.0 -1.0000000000000002 -> -2.1073424255447014e-08 -1.5707963267948966 +asinh0036 asinh 0.0 -1.0009999999999999 -> 0.044717633608306849 -1.5707963267948966 +asinh0037 asinh -0.0 -1.0009999999999999 -> -0.044717633608306849 -1.5707963267948966 +asinh0038 asinh 0.0 -2.0 -> 1.3169578969248168 -1.5707963267948966 +asinh0039 asinh -0.0 -2.0 -> -1.3169578969248168 -1.5707963267948966 +asinh0040 asinh 0.0 -20.0 -> 3.6882538673612966 -1.5707963267948966 +asinh0041 asinh -0.0 -20.0 -> -3.6882538673612966 -1.5707963267948966 +asinh0042 asinh 0.0 -10000000000000000.0 -> 37.534508668464674 -1.5707963267948966 +asinh0043 asinh -0.0 -10000000000000000.0 -> -37.534508668464674 -1.5707963267948966 +asinh0044 asinh 0.0 -9.9999999999999998e+149 -> 346.08091112966679 -1.5707963267948966 +asinh0045 asinh -0.0 -9.9999999999999998e+149 -> -346.08091112966679 -1.5707963267948966 +asinh0046 asinh 0.0 -1.0000000000000001e+299 -> 689.16608998577965 -1.5707963267948966 +asinh0047 asinh -0.0 -1.0000000000000001e+299 -> -689.16608998577965 -1.5707963267948966 +asinh0048 asinh 0.0 9.8813129168249309e-324 -> 0.0 9.8813129168249309e-324 +asinh0049 asinh -0.0 9.8813129168249309e-324 -> -0.0 9.8813129168249309e-324 +asinh0050 asinh 0.0 1e-305 -> 0.0 1e-305 +asinh0051 asinh -0.0 1e-305 -> -0.0 1e-305 +asinh0052 asinh 0.0 1e-150 -> 0.0 1e-150 +asinh0053 asinh -0.0 1e-150 -> -0.0 1e-150 +asinh0054 asinh 0.0 9.9999999999999998e-17 -> 0.0 9.9999999999999998e-17 +asinh0055 asinh -0.0 9.9999999999999998e-17 -> -0.0 9.9999999999999998e-17 +asinh0056 asinh 0.0 0.001 -> 0.0 0.0010000001666667416 +asinh0057 asinh -0.0 0.001 -> -0.0 0.0010000001666667416 +asinh0058 asinh 0.0 0.57899999999999996 -> 0.0 0.61750165481717001 +asinh0059 asinh -0.0 0.57899999999999996 -> -0.0 0.61750165481717001 +asinh0060 asinh 0.0 0.99999999999999989 -> 0.0 1.5707963118937354 +asinh0061 asinh -0.0 0.99999999999999989 -> -0.0 1.5707963118937354 +asinh0062 asinh 0.0 1.0000000000000002 -> 2.1073424255447014e-08 1.5707963267948966 +asinh0063 asinh -0.0 1.0000000000000002 -> -2.1073424255447014e-08 1.5707963267948966 +asinh0064 asinh 0.0 1.0009999999999999 -> 0.044717633608306849 1.5707963267948966 +asinh0065 asinh -0.0 1.0009999999999999 -> -0.044717633608306849 1.5707963267948966 +asinh0066 asinh 0.0 2.0 -> 1.3169578969248168 1.5707963267948966 +asinh0067 asinh -0.0 2.0 -> -1.3169578969248168 1.5707963267948966 +asinh0068 asinh 0.0 20.0 -> 3.6882538673612966 1.5707963267948966 +asinh0069 asinh -0.0 20.0 -> -3.6882538673612966 1.5707963267948966 +asinh0070 asinh 0.0 10000000000000000.0 -> 37.534508668464674 1.5707963267948966 +asinh0071 asinh -0.0 10000000000000000.0 -> -37.534508668464674 1.5707963267948966 +asinh0072 asinh 0.0 9.9999999999999998e+149 -> 346.08091112966679 1.5707963267948966 +asinh0073 asinh -0.0 9.9999999999999998e+149 -> -346.08091112966679 1.5707963267948966 +asinh0074 asinh 0.0 1.0000000000000001e+299 -> 689.16608998577965 1.5707963267948966 +asinh0075 asinh -0.0 1.0000000000000001e+299 -> -689.16608998577965 1.5707963267948966 + +-- random inputs +asinh0100 asinh -0.5946402853710423 -0.044506548910000145 -> -0.56459775392653022 -0.038256221441536356 +asinh0101 asinh -0.19353958046180916 -0.017489624793193454 -> -0.19237926804196651 -0.017171741895336792 +asinh0102 asinh -0.033117585138955893 -8.5256414015933757 -> -2.8327758348650969 -1.5668848791092411 +asinh0103 asinh -1.5184043184035716 -0.73491245339073275 -> -1.2715891419764005 -0.39204624408542355 +asinh0104 asinh -0.60716120271208818 -0.28900743958436542 -> -0.59119299421187232 -0.24745931678118135 +asinh0105 asinh -0.0237177865112429 2.8832601052166313 -> -1.7205820772413236 1.5620261702963094 +asinh0106 asinh -2.3906812342743979 2.6349216848574013 -> -1.9609636249445124 0.8142142660574706 +asinh0107 asinh -0.0027605019787620517 183.85588476550555 -> -5.9072920005445066 1.5707813120847871 +asinh0108 asinh -0.99083661164404713 0.028006797051617648 -> -0.8750185251283995 0.019894099615994653 +asinh0109 asinh -3.0362951937986393 0.86377266758504867 -> -1.8636030714685221 0.26475058859950168 +asinh0110 asinh 0.34438464536152769 -0.71603790174885029 -> 0.43985415690734164 -0.71015037409294324 +asinh0111 asinh 4.4925124413876256 -60604595352.871613 -> 25.520783738612078 -1.5707963267207683 +asinh0112 asinh 2.3213991428170337 -7.5459667007307258 -> 2.7560464993451643 -1.270073210856117 +asinh0113 asinh 0.21291939741682028 -1.2720428814784408 -> 0.77275088137338266 -1.3182099250896895 +asinh0114 asinh 6.6447359379455957 -0.97196191666946996 -> 2.602830695139672 -0.14368247412319965 +asinh0115 asinh 7.1326256655083746 2.1516360452706857 -> 2.7051146374367212 0.29051701669727581 +asinh0116 asinh 0.18846550905063442 3.4705348585339832 -> 1.917697875799296 1.514155593347924 +asinh0117 asinh 0.19065075303281598 0.26216814548222012 -> 0.19603050785932474 0.26013422809614117 +asinh0118 asinh 2.0242004665739719 0.70510281647495787 -> 1.4970366212896002 0.30526007200481453 +asinh0119 asinh 37.336596461576057 717.29157391678234 -> 7.269981997945294 1.5187910219576033 + +-- values near infinity +asinh0200 asinh 1.0760517500874541e+308 1.1497786241240167e+308 -> 710.34346055651815 0.81850936961793475 +asinh0201 asinh 1.1784839328845529e+308 -1.6478429586716638e+308 -> 710.59536255783678 -0.94996311735607697 +asinh0202 asinh -4.8777682248909193e+307 1.4103736217538474e+308 -> -710.28970147376992 1.2378239519096443 +asinh0203 asinh -1.2832478903233108e+308 -1.5732392613155698e+308 -> -710.59750164290745 -0.88657181439322452 +asinh0204 asinh 0.0 6.8431383856345372e+307 -> 709.51001718444604 1.5707963267948966 +asinh0205 asinh -0.0 8.601822432238051e+307 -> -709.73874482126689 1.5707963267948966 +asinh0206 asinh 0.0 -5.5698396067303782e+307 -> 709.30413698733742 -1.5707963267948966 +asinh0207 asinh -0.0 -7.1507777734621804e+307 -> -709.55399186002705 -1.5707963267948966 +asinh0208 asinh 1.6025136110019349e+308 0.0 -> 710.3609292261076 0.0 +asinh0209 asinh 1.3927819858239114e+308 -0.0 -> 710.22065899832899 -0.0 +asinh0210 asinh -6.0442994056210995e+307 0.0 -> -709.38588631057621 0.0 +asinh0211 asinh -1.2775271979042634e+308 -0.0 -> -710.13428215553972 -0.0 +asinh0212 asinh 1.0687496260268489e+308 1.0255615699476961 -> 709.95584521407841 9.5959010882679093e-309 +asinh0213 asinh 1.0050967333370962e+308 -0.87668970117333433 -> 709.89443961168183 -8.7224410556242882e-309 +asinh0214 asinh -5.7161452814862392e+307 8.2377808413450122 -> -709.33006540611166 1.4411426644501116e-307 +asinh0215 asinh -8.2009040727653315e+307 -6.407409526654976 -> -709.69101513070109 -7.8130526461510088e-308 +asinh0216 asinh 6.4239368496483982 1.6365990821551427e+308 -> 710.38197618101287 1.5707963267948966 +asinh0217 asinh 5.4729111423315882 -1.1227237438144211e+308 -> 710.00511346983546 -1.5707963267948966 +asinh0218 asinh -8.3455818297412723 1.443172020182019e+308 -> -710.25619930551818 1.5707963267948966 +asinh0219 asinh -2.6049726230372441 -1.7952291144022702e+308 -> -710.47448847685644 -1.5707963267948966 + +-- values near 0 +asinh0220 asinh 1.2940113339664088e-314 6.9169190417774516e-323 -> 1.2940113339664088e-314 6.9169190417774516e-323 +asinh0221 asinh 2.3848478863874649e-315 -3.1907655025717717e-310 -> 2.3848478863874649e-315 -3.1907655025717717e-310 +asinh0222 asinh -3.0097643679641622e-316 4.6936236354918422e-322 -> -3.0097643679641622e-316 4.6936236354918422e-322 +asinh0223 asinh -1.787997087755751e-308 -8.5619622834902341e-310 -> -1.787997087755751e-308 -8.5619622834902341e-310 +asinh0224 asinh 0.0 1.2491433448427325e-314 -> 0.0 1.2491433448427325e-314 +asinh0225 asinh -0.0 2.5024072154538062e-308 -> -0.0 2.5024072154538062e-308 +asinh0226 asinh 0.0 -2.9643938750474793e-323 -> 0.0 -2.9643938750474793e-323 +asinh0227 asinh -0.0 -2.9396905927554169e-320 -> -0.0 -2.9396905927554169e-320 +asinh0228 asinh 5.64042930029359e-317 0.0 -> 5.64042930029359e-317 0.0 +asinh0229 asinh 3.3833911866596068e-318 -0.0 -> 3.3833911866596068e-318 -0.0 +asinh0230 asinh -4.9406564584124654e-324 0.0 -> -4.9406564584124654e-324 0.0 +asinh0231 asinh -2.2211379227994845e-308 -0.0 -> -2.2211379227994845e-308 -0.0 + +-- special values +asinh1000 asinh 0.0 0.0 -> 0.0 0.0 +asinh1001 asinh 0.0 -0.0 -> 0.0 -0.0 +asinh1002 asinh -0.0 0.0 -> -0.0 0.0 +asinh1003 asinh -0.0 -0.0 -> -0.0 -0.0 +asinh1004 asinh 0.0 inf -> inf 1.5707963267948966 +asinh1005 asinh 2.3 inf -> inf 1.5707963267948966 +asinh1006 asinh 0.0 nan -> nan nan +asinh1007 asinh 2.3 nan -> nan nan +asinh1008 asinh inf 0.0 -> inf 0.0 +asinh1009 asinh inf 2.3 -> inf 0.0 +asinh1010 asinh inf inf -> inf 0.78539816339744828 +asinh1011 asinh inf nan -> inf nan +asinh1012 asinh nan 0.0 -> nan 0.0 +asinh1013 asinh nan 2.3 -> nan nan +asinh1014 asinh nan inf -> inf nan ignore-real-sign +asinh1015 asinh nan nan -> nan nan +asinh1016 asinh 0.0 -inf -> inf -1.5707963267948966 +asinh1017 asinh 2.3 -inf -> inf -1.5707963267948966 +asinh1018 asinh inf -0.0 -> inf -0.0 +asinh1019 asinh inf -2.3 -> inf -0.0 From noreply at buildbot.pypy.org Mon Oct 8 14:35:59 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 14:35:59 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: improve error message Message-ID: <20121008123559.668771C0DFC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57923:6a47bf127494 Date: 2012-10-08 14:35 +0200 http://bitbucket.org/pypy/pypy/changeset/6a47bf127494/ Log: improve error message diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -132,9 +132,6 @@ def float(obj): return SomeFloat() - def long(obj): - return SomeObject() # XXX - def delattr(obj, s_attr): if obj.__class__ != SomeObject or obj.knowntype != object: getbookkeeper().warning( @@ -153,18 +150,17 @@ def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - s_method = obj.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)) - else: - getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' % - (obj, s_attr)) - return SomeObject() + 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)) + attr = s_attr.const + s_method = obj.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)) getattr.can_only_throw = [] def bind_callables_under(obj, classdef, name): From noreply at buildbot.pypy.org Mon Oct 8 14:52:00 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 14:52:00 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: make this test almost pass Message-ID: <20121008125200.5BFD51C0F54@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57924:6bb684c9827f Date: 2012-10-08 14:50 +0200 http://bitbucket.org/pypy/pypy/changeset/6bb684c9827f/ Log: make this test almost pass diff --git a/pypy/rlib/test/test_rrandom.py b/pypy/rlib/test/test_rrandom.py --- a/pypy/rlib/test/test_rrandom.py +++ b/pypy/rlib/test/test_rrandom.py @@ -1,6 +1,8 @@ +import _random + +from pypy.rlib.rarithmetic import intmask from pypy.rlib.rrandom import Random, N, r_uint -from pypy.rlib.rarithmetic import intmask -import _random +from pypy.translator.c.test.test_genc import compile # the numbers were created by using CPython's _randommodule.c @@ -43,13 +45,14 @@ cpyrandom.jumpahead(100) assert tuple(rnd.state) + (rnd.index, ) == cpyrandom.getstate() + def test_translate(): - from pypy.translator.interactive import Translation def f(x, y): + x = r_uint(x) + y = r_uint(y) rnd = Random(x) rnd.init_by_array([x, y]) rnd.jumpahead(intmask(y)) - return rnd.genrand32(), rnd.random() - t = Translation(f) - fc = t.compile_c([r_uint, r_uint]) - assert fc(r_uint(1), r_uint(2)) == f(r_uint(1), r_uint(2)) + return float(rnd.genrand32()) + rnd.random() + fc = compile(f, [int, int]) + assert fc(1, 2) == f(1, 2) From noreply at buildbot.pypy.org Mon Oct 8 14:52:01 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 14:52:01 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merged upstream Message-ID: <20121008125201.8C03D1C0F54@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57925:a294d5b63ccf Date: 2012-10-08 14:51 +0200 http://bitbucket.org/pypy/pypy/changeset/a294d5b63ccf/ Log: merged upstream diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -132,9 +132,6 @@ def float(obj): return SomeFloat() - def long(obj): - return SomeObject() # XXX - def delattr(obj, s_attr): if obj.__class__ != SomeObject or obj.knowntype != object: getbookkeeper().warning( @@ -153,18 +150,17 @@ def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - s_method = obj.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)) - else: - getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' % - (obj, s_attr)) - return SomeObject() + 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)) + attr = s_attr.const + s_method = obj.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)) getattr.can_only_throw = [] def bind_callables_under(obj, classdef, name): From noreply at buildbot.pypy.org Mon Oct 8 15:04:46 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 15:04:46 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Add 3 tests, 2 of which failing. Message-ID: <20121008130446.E18421C0F5A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57926:afa70036b7ef Date: 2012-10-08 14:53 +0200 http://bitbucket.org/pypy/pypy/changeset/afa70036b7ef/ Log: Add 3 tests, 2 of which failing. diff --git a/pypy/rpython/test/test_rlist.py b/pypy/rpython/test/test_rlist.py --- a/pypy/rpython/test/test_rlist.py +++ b/pypy/rpython/test/test_rlist.py @@ -622,6 +622,16 @@ res = self.interpret(fn, [i,j,case]) assert res is fn(i, j, case) + def test_list_compare_char_str(self): + def fn(i, j): + l1 = [str(i)] + l2 = [chr(j)] + return l1 == l2 + res = self.interpret(fn, [65, 65]) + assert res is False + res = self.interpret(fn, [1, 49]) + assert res is True + def test_list_compareinst(self): def fn(i, j, neg=False): diff --git a/pypy/rpython/test/test_rstr.py b/pypy/rpython/test/test_rstr.py --- a/pypy/rpython/test/test_rstr.py +++ b/pypy/rpython/test/test_rstr.py @@ -150,6 +150,16 @@ const('a')]) assert res is False + def test_char_string_compare(self): + const = self.const + lst = [const('a'), const('abc')] + res = self.interpret(lambda i1, c2: (lst[i1],) == (c2,), + [1, const('b')]) + assert res is False + res = self.interpret(lambda i1, c2: (c2,) == (lst[i1],), + [1, const('b')]) + assert res is False + def test_char_mul(self): const = self.const def fn(c, mul): diff --git a/pypy/rpython/test/test_rtuple.py b/pypy/rpython/test/test_rtuple.py --- a/pypy/rpython/test/test_rtuple.py +++ b/pypy/rpython/test/test_rtuple.py @@ -301,6 +301,16 @@ res = self.interpret(f, [53]) assert res is True + def test_compare_list_char_str(self): + def fn(i, j): + t1 = ([str(i)],) + t2 = ([chr(j)],) + return t1 == t2 + res = self.interpret(fn, [65, 65]) + assert res is False + res = self.interpret(fn, [1, 49]) + assert res is True + TUPLES = [ ((1,2), (2,3), -1), ((1,2), (1,3), -1), From noreply at buildbot.pypy.org Mon Oct 8 15:04:48 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 15:04:48 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (fijal, arigo) Message-ID: <20121008130448.146CC1C0F5A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57927:d867247c7bc9 Date: 2012-10-08 14:57 +0200 http://bitbucket.org/pypy/pypy/changeset/d867247c7bc9/ Log: (fijal, arigo) Fix one of the failures: tuple equality now correctly computes the union of the two tuples. diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -550,7 +550,9 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - return SomeObject() + raise Exception("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) @@ -558,6 +560,20 @@ def add((tup1, tup2)): return SomeTuple(items = tup1.items + tup2.items) + def eq(tup1tup2): + tup1tup2.union() + return s_Bool + ne = eq + + def lt((tup1, tup2)): + raise Exception("unsupported: (...) < (...)") + def le((tup1, tup2)): + raise Exception("unsupported: (...) <= (...)") + def gt((tup1, tup2)): + raise Exception("unsupported: (...) > (...)") + def ge((tup1, tup2)): + raise Exception("unsupported: (...) >= (...)") + class __extend__(pairtype(SomeDict, SomeDict)): From noreply at buildbot.pypy.org Mon Oct 8 15:04:49 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 15:04:49 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (fijal, arigo) Message-ID: <20121008130449.40E901C0F5A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57928:956082ef4b0a Date: 2012-10-08 15:04 +0200 http://bitbucket.org/pypy/pypy/changeset/956082ef4b0a/ Log: (fijal, arigo) - Fix the remaining test comparing two tuples with a different annotatation - Kill <= and friends on tuples diff --git a/pypy/rpython/rtuple.py b/pypy/rpython/rtuple.py --- a/pypy/rpython/rtuple.py +++ b/pypy/rpython/rtuple.py @@ -21,7 +21,6 @@ _gen_eq_function_cache = {} -_gen_cmp_function_cache = {} _gen_hash_function_cache = {} _gen_str_function_cache = {} @@ -46,49 +45,6 @@ _gen_eq_function_cache[key] = ll_eq return ll_eq -import os -def gen_cmp_function(items_r, op_funcs, eq_funcs, strict): - """generates <= and >= comparison ll_op for tuples - cmp_funcs is a tuple of (strict_comp, equality) functions - works for != with strict==True - """ - cmp_funcs = zip(op_funcs,eq_funcs) - autounrolling_funclist = unrolling_iterable(enumerate(cmp_funcs)) - key = tuple(cmp_funcs), strict - try: - return _gen_cmp_function_cache[key] - except KeyError: - def ll_cmp(t1, t2): - cmp_res = True - for i, (cmpfn, eqfn) in autounrolling_funclist: - attrname = 'item%d' % i - item1 = getattr(t1, attrname) - item2 = getattr(t2, attrname) - cmp_res = cmpfn(item1, item2) - if cmp_res: - # a strict compare is true we shortcut - return True - eq_res = eqfn(item1, item2) - if not eq_res: - # not strict and not equal we fail - return False - # Everything's equal here - if strict: - return False - else: - return True - _gen_cmp_function_cache[key] = ll_cmp - return ll_cmp - -def gen_gt_function(items_r, strict): - gt_funcs = [r_item.get_ll_gt_function() or operator.gt for r_item in items_r] - eq_funcs = [r_item.get_ll_eq_function() or operator.eq for r_item in items_r] - return gen_cmp_function( items_r, gt_funcs, eq_funcs, strict ) - -def gen_lt_function(items_r, strict): - lt_funcs = [r_item.get_ll_lt_function() or operator.lt for r_item in items_r] - eq_funcs = [r_item.get_ll_eq_function() or operator.eq for r_item in items_r] - return gen_cmp_function( items_r, lt_funcs, eq_funcs, strict ) def gen_hash_function(items_r): # based on CPython @@ -206,18 +162,6 @@ def get_ll_eq_function(self): return gen_eq_function(self.items_r) - def get_ll_ge_function(self): - return gen_gt_function(self.items_r, False) - - def get_ll_gt_function(self): - return gen_gt_function(self.items_r, True) - - def get_ll_le_function(self): - return gen_lt_function(self.items_r, False) - - def get_ll_lt_function(self): - return gen_lt_function(self.items_r, True) - def get_ll_hash_function(self): return gen_hash_function(self.items_r) @@ -292,30 +236,12 @@ rtype_inplace_add = rtype_add def rtype_eq((r_tup1, r_tup2), hop): - v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup2) - ll_eq = r_tup1.get_ll_eq_function() + s_tup = annmodel.unionof(*hop.args_s) + r_tup = hop.rtyper.getrepr(s_tup) + v_tuple1, v_tuple2 = hop.inputargs(r_tup, r_tup) + ll_eq = r_tup.get_ll_eq_function() return hop.gendirectcall(ll_eq, v_tuple1, v_tuple2) - def rtype_ge((r_tup1, r_tup2), hop): - v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup2) - ll_ge = r_tup1.get_ll_ge_function() - return hop.gendirectcall(ll_ge, v_tuple1, v_tuple2) - - def rtype_gt((r_tup1, r_tup2), hop): - v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup2) - ll_gt = r_tup1.get_ll_gt_function() - return hop.gendirectcall(ll_gt, v_tuple1, v_tuple2) - - def rtype_le((r_tup1, r_tup2), hop): - v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup2) - ll_le = r_tup1.get_ll_le_function() - return hop.gendirectcall(ll_le, v_tuple1, v_tuple2) - - def rtype_lt((r_tup1, r_tup2), hop): - v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup2) - ll_lt = r_tup1.get_ll_lt_function() - return hop.gendirectcall(ll_lt, v_tuple1, v_tuple2) - def rtype_ne(tup1tup2, hop): v_res = tup1tup2.rtype_eq(hop) return hop.genop('bool_not', [v_res], resulttype=Bool) diff --git a/pypy/rpython/test/test_rtuple.py b/pypy/rpython/test/test_rtuple.py --- a/pypy/rpython/test/test_rtuple.py +++ b/pypy/rpython/test/test_rtuple.py @@ -311,51 +311,6 @@ res = self.interpret(fn, [1, 49]) assert res is True - TUPLES = [ - ((1,2), (2,3), -1), - ((1,2), (1,3), -1), - ((1,2), (1,1), 1), - ((1,2), (1,2), 0), - ((1.,2.),(2.,3.), -1), - ((1.,2.),(1.,3.), -1), - ((1.,2.),(1.,1.), 1), - ((1.,2.),(1.,2.), 0), - ((1,2.),(2,3.), -1), - ((1,2.),(1,3.), -1), - ((1,2.),(1,1.), 1), - ((1,2.),(1,2.), 0), -## ((1,"def"),(1,"abc"), -1), -## ((1.,"abc"),(1.,"abc"), 0), - ] - - def test_tuple_comparison(self): - def f_lt( a, b, c, d ): - return (a,b) < (c,d) - def f_le( a, b, c, d ): - return (a,b) <= (c,d) - def f_gt( a, b, c, d ): - return (a,b) > (c,d) - def f_ge( a, b, c, d ): - return (a,b) >= (c,d) - def test_lt( a,b,c,d,resu ): - res = self.interpret(f_lt,[a,b,c,d]) - assert res == (resu == -1), "Error (%s,%s)<(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) - def test_le( a,b,c,d,resu ): - res = self.interpret(f_le,[a,b,c,d]) - assert res == (resu <= 0), "Error (%s,%s)<=(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) - def test_gt( a,b,c,d,resu ): - res = self.interpret(f_gt,[a,b,c,d]) - assert res == ( resu == 1 ), "Error (%s,%s)>(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) - def test_ge( a,b,c,d,resu ): - res = self.interpret(f_ge,[a,b,c,d]) - assert res == ( resu >= 0 ), "Error (%s,%s)>=(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) - - for (a,b),(c,d),resu in self.TUPLES: - yield test_lt, a,b,c,d, resu - yield test_gt, a,b,c,d, resu - yield test_le, a,b,c,d, resu - yield test_ge, a,b,c,d, resu - def test_tuple_hash_2(self): from pypy.rlib.objectmodel import compute_hash def f(n): From noreply at buildbot.pypy.org Mon Oct 8 15:04:50 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 15:04:50 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge heads Message-ID: <20121008130450.60FBD1C0F5A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57929:b0e233a6139e Date: 2012-10-08 15:04 +0200 http://bitbucket.org/pypy/pypy/changeset/b0e233a6139e/ Log: merge heads diff --git a/pypy/rlib/test/test_rrandom.py b/pypy/rlib/test/test_rrandom.py --- a/pypy/rlib/test/test_rrandom.py +++ b/pypy/rlib/test/test_rrandom.py @@ -1,6 +1,8 @@ +import _random + +from pypy.rlib.rarithmetic import intmask from pypy.rlib.rrandom import Random, N, r_uint -from pypy.rlib.rarithmetic import intmask -import _random +from pypy.translator.c.test.test_genc import compile # the numbers were created by using CPython's _randommodule.c @@ -43,13 +45,14 @@ cpyrandom.jumpahead(100) assert tuple(rnd.state) + (rnd.index, ) == cpyrandom.getstate() + def test_translate(): - from pypy.translator.interactive import Translation def f(x, y): + x = r_uint(x) + y = r_uint(y) rnd = Random(x) rnd.init_by_array([x, y]) rnd.jumpahead(intmask(y)) - return rnd.genrand32(), rnd.random() - t = Translation(f) - fc = t.compile_c([r_uint, r_uint]) - assert fc(r_uint(1), r_uint(2)) == f(r_uint(1), r_uint(2)) + return float(rnd.genrand32()) + rnd.random() + fc = compile(f, [int, int]) + assert fc(1, 2) == f(1, 2) From noreply at buildbot.pypy.org Mon Oct 8 15:25:17 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 15:25:17 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: dead import cleanup Message-ID: <20121008132517.E58DC1C0F71@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57930:da183cf8bd49 Date: 2012-10-08 15:24 +0200 http://bitbucket.org/pypy/pypy/changeset/da183cf8bd49/ Log: dead import cleanup diff --git a/pypy/rpython/lltypesystem/rbuiltin.py b/pypy/rpython/lltypesystem/rbuiltin.py --- a/pypy/rpython/lltypesystem/rbuiltin.py +++ b/pypy/rpython/lltypesystem/rbuiltin.py @@ -1,11 +1,9 @@ -from pypy.tool.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython.lltypesystem import lltype -from pypy.rpython.lltypesystem import rclass +from pypy.rlib import objectmodel +from pypy.rpython.lltypesystem import lltype, rclass from pypy.rpython.lltypesystem.rdict import rtype_r_dict -from pypy.rlib import objectmodel -from pypy.rpython.rmodel import TyperError, Constant -from pypy.rpython.rbool import bool_repr +from pypy.rpython.rmodel import TyperError + def rtype_builtin_isinstance(hop): hop.exception_cannot_occur() @@ -87,6 +85,6 @@ BUILTIN_TYPER[weakref.ref] = rtype_weakref_create BUILTIN_TYPER[llmemory.weakref_create] = rtype_weakref_create -BUILTIN_TYPER[llmemory.weakref_deref ] = rtype_weakref_deref +BUILTIN_TYPER[llmemory.weakref_deref] = rtype_weakref_deref BUILTIN_TYPER[llmemory.cast_ptr_to_weakrefptr] = rtype_cast_ptr_to_weakrefptr BUILTIN_TYPER[llmemory.cast_weakrefptr_to_ptr] = rtype_cast_weakrefptr_to_ptr diff --git a/pypy/rpython/rbuiltin.py b/pypy/rpython/rbuiltin.py --- a/pypy/rpython/rbuiltin.py +++ b/pypy/rpython/rbuiltin.py @@ -1,17 +1,12 @@ -from pypy.tool.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant -from pypy.rpython.lltypesystem import lltype, rclass, llmemory -from pypy.rpython import rint, raddress from pypy.rlib import rarithmetic, objectmodel +from pypy.rpython import raddress, rptr, extregistry from pypy.rpython.error import TyperError -from pypy.rpython.rmodel import Repr, IntegerRepr, inputconst -from pypy.rpython.rrange import rtype_builtin_range, rtype_builtin_xrange -from pypy.rpython.rrange import rtype_builtin_enumerate -from pypy.rpython import rstr -from pypy.rpython import rptr -from pypy.tool import sourcetools -from pypy.rpython import extregistry +from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.rmodel import Repr +from pypy.tool.pairtype import pairtype + class __extend__(annmodel.SomeBuiltin): def rtyper_makerepr(self, rtyper): @@ -80,7 +75,7 @@ kwds_i = {} for i, key in enumerate(keywords): index = arguments.keywords_w[i] - kwds_i['i_'+key] = index + kwds_i['i_' + key] = index return hop, kwds_i @@ -303,7 +298,7 @@ r_func, nimplicitarg = r_callable.get_r_implfunc() s_callable = r_callable.get_s_callable() - nbargs = len(hop.args_s) - 1 + nimplicitarg + nbargs = len(hop.args_s) - 1 + nimplicitarg s_sigs = r_func.get_s_signatures((nbargs, (), False, False)) if len(s_sigs) != 1: raise TyperError("cannot hlinvoke callable %r with not uniform" @@ -332,7 +327,7 @@ # collect all functions -import __builtin__, exceptions +import __builtin__ BUILTIN_TYPER = {} for name, value in globals().items(): if name.startswith('rtype_builtin_'): @@ -384,7 +379,7 @@ hop.has_implicit_exception(MemoryError) # record that we know about it hop.exception_is_here() - return hop.genop(opname, vlist, resulttype = hop.r_result.lowleveltype) + return hop.genop(opname, vlist, resulttype=hop.r_result.lowleveltype) def rtype_free(hop, i_flavor, i_track_allocation=None): vlist = [hop.inputarg(hop.args_r[0], arg=0)] @@ -504,7 +499,7 @@ elif ORIG == llmemory.Address: return llops.genop('cast_adr_to_ptr', [v_value], resulttype = TGT) elif isinstance(ORIG, lltype.Primitive): - v_value = gen_cast(llops, lltype.Signed, v_value) + v_value = gen_cast(llops, lltype.Signed, v_value) return llops.genop('cast_int_to_ptr', [v_value], resulttype=TGT) elif TGT == llmemory.Address and isinstance(ORIG, lltype.Ptr): return llops.genop('cast_ptr_to_adr', [v_value], resulttype = TGT) @@ -632,7 +627,7 @@ flags = {'flavor': flavor} cflags = hop.inputconst(lltype.Void, flags) return hop.genop('free', [vinst, cflags]) - + BUILTIN_TYPER[objectmodel.free_non_gc_object] = rtype_free_non_gc_object # keepalive_until_here @@ -682,4 +677,3 @@ BUILTIN_TYPER[llmemory.cast_adr_to_ptr] = rtype_cast_adr_to_ptr BUILTIN_TYPER[llmemory.cast_adr_to_int] = rtype_cast_adr_to_int BUILTIN_TYPER[llmemory.cast_int_to_adr] = rtype_cast_int_to_adr - From noreply at buildbot.pypy.org Mon Oct 8 15:30:14 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 15:30:14 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: make pure python r_{u, }longlong initialization work with strings Message-ID: <20121008133014.DC5CC1C0F71@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57931:b430e7ffd5f9 Date: 2012-10-08 15:29 +0200 http://bitbucket.org/pypy/pypy/changeset/b430e7ffd5f9/ Log: make pure python r_{u,}longlong initialization work with strings diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py --- a/pypy/rlib/rarithmetic.py +++ b/pypy/rlib/rarithmetic.py @@ -403,22 +403,26 @@ res = pow(x, y, m) return self._widen(other, res) + class signed_int(base_int): SIGNED = True + def __new__(klass, val=0): - if type(val) is float: + if isinstance(val, (float, str)): val = long(val) - if val > klass.MASK>>1 or val < -(klass.MASK>>1)-1: - raise OverflowError("%s does not fit in signed %d-bit integer"%(val, klass.BITS)) + if val > klass.MASK >> 1 or val < -(klass.MASK >> 1) - 1: + raise OverflowError("%s does not fit in signed %d-bit integer" % (val, klass.BITS)) if val < 0: val = ~ ((~val) & klass.MASK) return super(signed_int, klass).__new__(klass, val) typemap = {} + class unsigned_int(base_int): SIGNED = False + def __new__(klass, val=0): - if isinstance(val, (float, long)): + if isinstance(val, (float, long, str)): val = long(val) return super(unsigned_int, klass).__new__(klass, val & klass.MASK) typemap = {} From noreply at buildbot.pypy.org Mon Oct 8 15:30:55 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 8 Oct 2012 15:30:55 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: trailing whitespace removal Message-ID: <20121008133055.26FCE1C0F71@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r57932:2564e1af5588 Date: 2012-10-08 15:30 +0200 http://bitbucket.org/pypy/pypy/changeset/2564e1af5588/ Log: trailing whitespace removal diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py --- a/pypy/rlib/rarithmetic.py +++ b/pypy/rlib/rarithmetic.py @@ -63,7 +63,7 @@ # whatever size a long has, make it big enough for a pointer. return _get_bitsize(_long_typecode) -# exported for now for testing array values. +# exported for now for testing array values. # might go into its own module. def get_long_pattern(x): """get the bit pattern for a long, adjusted to pointer size""" @@ -72,7 +72,7 @@ # used in tests for ctypes and for genc and friends # to handle the win64 special case: is_emulated_long = _long_typecode != 'l' - + LONG_BIT = _get_long_bit() LONG_MASK = (2**LONG_BIT)-1 LONG_TEST = 2**(LONG_BIT-1) @@ -289,7 +289,7 @@ y = long(other) return self._widen(other, x + y) __radd__ = __add__ - + def __sub__(self, other): x = long(self) y = long(other) @@ -299,7 +299,7 @@ y = long(self) x = long(other) return self._widen(other, x - y) - + def __mul__(self, other): x = long(self) if not isinstance(other, (int, long)): @@ -454,7 +454,7 @@ def compute_annotation(self): from pypy.annotation import model as annmodel return annmodel.SomeInteger(knowntype=int_type) - + class ForTypeEntry(extregistry.ExtRegistryEntry): _about_ = int_type @@ -466,7 +466,7 @@ v_result, = hop.inputargs(hop.r_result.lowleveltype) hop.exception_cannot_occur() return v_result - + return int_type class BaseIntValueEntry(extregistry.ExtRegistryEntry): @@ -475,7 +475,7 @@ def compute_annotation(self): from pypy.annotation import model as annmodel return annmodel.SomeInteger(knowntype=r_ulonglong) - + class BaseIntTypeEntry(extregistry.ExtRegistryEntry): _about_ = base_int @@ -595,7 +595,7 @@ """ Convert little->big endian and the opposite """ from pypy.rpython.lltypesystem import lltype, rffi - + T = lltype.typeOf(arg) # XXX we cannot do arithmetics on small ints if isinstance(arg, base_int): From noreply at buildbot.pypy.org Mon Oct 8 15:59:10 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 15:59:10 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (alex, arigo, fijal) fix some tests Message-ID: <20121008135910.C7A361C0B7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57933:09ee47cbb851 Date: 2012-10-08 15:57 +0200 http://bitbucket.org/pypy/pypy/changeset/09ee47cbb851/ Log: (alex, arigo, fijal) fix some tests diff --git a/pypy/rpython/rint.py b/pypy/rpython/rint.py --- a/pypy/rpython/rint.py +++ b/pypy/rpython/rint.py @@ -396,7 +396,7 @@ # version picked by specialisation based on which # type system rtyping is using, from .ll_str module def ll_str(self, i): - pass + raise NotImplementedError ll_str._annspecialcase_ = "specialize:ts('ll_str.ll_int_str')" def rtype_hex(self, hop): diff --git a/pypy/translator/c/test/test_backendoptimized.py b/pypy/translator/c/test/test_backendoptimized.py --- a/pypy/translator/c/test/test_backendoptimized.py +++ b/pypy/translator/c/test/test_backendoptimized.py @@ -2,16 +2,11 @@ from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.c.test.test_typed import TestTypedTestCase as _TestTypedTestCase +from pypy.translator.c.test.test_genc import compile class TestTypedOptimizedTestCase(_TestTypedTestCase): - - def process(self, t): - _TestTypedTestCase.process(self, t) - self.t = t - backend_optimizations(t, merge_if_blocks=False) - if conftest.option.view: - t.view() + getcompiled = staticmethod(compile) def test_remove_same_as(self): def f(n): diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -4,6 +4,7 @@ from pypy.rlib.entrypoint import entrypoint from pypy.rlib.unroll import unrolling_iterable +from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, intmask from pypy.rpython.lltypesystem import lltype from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.lltypesystem.rstr import STR @@ -12,30 +13,49 @@ from pypy.translator.interactive import Translation from pypy.translator.translator import TranslationContext, graphof +def llrepr(v): + if isinstance(v, r_ulonglong): + return "%d:%d" % (intmask(v >> 32), intmask(v & 0xffffffff)) + elif isinstance(v, r_longlong): + return "%d:%d" % (intmask(v >> 32), intmask(v & 0xffffffff)) + return str(v) + +def parse_longlong(a): + p0, p1 = a.split(":") + return (r_longlong(int(p0)) << 32) + (r_longlong(int(p1)) & 0xffffffff) + +def parse_ulonglong(a): + p0, p1 = a.split(":") + return (r_ulonglong(int(p0)) << 32) + (r_ulonglong(int(p1)) & 0xffffffff) def compile(fn, argtypes, view=False, gcpolicy="none", backendopt=True, annotatorpolicy=None, thread=False): argtypes_unroll = unrolling_iterable(enumerate(argtypes)) for argtype in argtypes: - if argtype not in [int, float, str, bool]: + if argtype not in [int, float, str, bool, r_ulonglong, r_longlong]: raise Exception("Unsupported argtype, %r" % (argtype,)) def entry_point(argv): args = () for i, argtype in argtypes_unroll: + a = argv[i + 1] if argtype is int: - args += (int(argv[i + 1]),) + args += (int(a),) + elif argtype is r_longlong: + args += (parse_longlong(a),) + elif argtype is r_ulonglong: + args += (parse_ulonglong(a),) elif argtype is bool: - if argv[i + 1] == 'True': + if a == 'True': args += (True,) else: - assert argv[i + 1] == 'False' + assert a == 'False' args += (False,) elif argtype is float: - args += (float(argv[i + 1]),) + args += (float(a),) else: - args += (argv[i + 1],) + args += (a,) res = fn(*args) print "THE RESULT IS:", res, ";" return 0 @@ -56,11 +76,12 @@ assert len(args) == len(argtypes) for arg, argtype in zip(args, argtypes): assert isinstance(arg, argtype) - stdout = t.driver.cbuilder.cmdexec(" ".join([str(arg) for arg in args])) + stdout = t.driver.cbuilder.cmdexec(" ".join([llrepr(arg) for arg in args])) assert stdout.endswith(' ;\n') pos = stdout.rindex('THE RESULT IS: ') res = stdout[pos + len('THE RESULT IS: '):-3] - if ll_res == lltype.Signed: + if ll_res in [lltype.Signed, lltype.Unsigned, lltype.SignedLongLong, + lltype.UnsignedLongLong]: return int(res) elif ll_res == lltype.Bool: return bool(int(res)) diff --git a/pypy/translator/c/test/test_typed.py b/pypy/translator/c/test/test_typed.py --- a/pypy/translator/c/test/test_typed.py +++ b/pypy/translator/c/test/test_typed.py @@ -12,42 +12,11 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.translator.test import snippet from pypy.translator.c.test.test_genc import compile -from pypy.translator.translator import TranslationContext -class CompilationTestCase: - - def annotatefunc(self, func, argtypes=None): - from pypy.config.pypyoption import get_pypy_config - config = get_pypy_config(translating=True) - config.translation.gc = "ref" - config.translation.simplifying = True - t = TranslationContext(config=config) - if argtypes is None: - argtypes = [] - a = t.buildannotator() - a.build_types(func, argtypes) - a.simplify() - return t - - def compilefunc(self, t, func): - from pypy.translator.c import genc - self.builder = builder = genc.CExtModuleBuilder(t, func, config=t.config) - if hasattr(self, 'include_also_eci'): - builder.merge_eci(self.include_also_eci) - builder.generate_source() - builder.compile() - return builder.get_entry_point() - - def getcompiled(self, func, argtypes=[], view=False): - return compile(func, argtypes, view=view) - - def process(self, t): - t.buildrtyper().specialize() - #raisingop2direct_call(t) - - -class TestTypedTestCase(CompilationTestCase): +class TestTypedTestCase(object): + def getcompiled(self, func, argtypes): + return compile(func, argtypes, backendopt=False) def test_set_attr(self): set_attr = self.getcompiled(snippet.set_attr) @@ -104,7 +73,8 @@ x = x - 1 return z == (6, 'a') fn = self.getcompiled(tuple_repr, [int, str]) - assert fn() + assert fn(6, "a") + assert not fn(6, "xyz") def test_classattribute(self): fn = self.getcompiled(snippet.classattribute, [int]) @@ -162,7 +132,7 @@ g2.next = g1 g3.next = g2 return g3.next.next.value - fn = self.getcompiled(do_things) + fn = self.getcompiled(do_things, []) assert fn() == 1 def test_float_ops(self): @@ -173,15 +143,21 @@ assert fn(4.5) == 90.125 def test_memoryerror(self): + def g(i): + return [0] * i + def f(i): - lst = [0] * i - lst[-1] = 5 - return lst[0] + try: + lst = g(i) + lst[-1] = 5 + return lst[0] + except MemoryError: + return -1 fn = self.getcompiled(f, [int]) assert fn(1) == 5 assert fn(2) == 0 - py.test.raises(MemoryError, fn, sys.maxint // 2 + 1) - py.test.raises(MemoryError, fn, sys.maxint) + assert fn(sys.maxint // 2 + 1) == -1 + assert fn(sys.maxint) == -1 def test_chr(self): def f(x): @@ -235,27 +211,27 @@ def f(i): return 4 * i fn = self.getcompiled(f, [r_ulonglong], view=False) - assert fn(2147483647) == 4 * 2147483647 + assert fn(r_ulonglong(2147483647)) == 4 * 2147483647 def g(i): return 4 * i gn = self.getcompiled(g, [r_longlong], view=False) - assert gn(2147483647) == 4 * 2147483647 + assert gn(r_longlong(2147483647)) == 4 * 2147483647 def g(i): return i << 12 gn = self.getcompiled(g, [r_longlong]) - assert gn(2147483647) == 2147483647 << 12 + assert gn(r_longlong(2147483647)) == 2147483647 << 12 def g(i): return i >> 12 gn = self.getcompiled(g, [r_longlong]) - assert gn(-2147483647) == (-2147483647) >> 12 + assert gn(r_longlong(-2147483647)) == (-2147483647) >> 12 def g(i): return i >> 12 gn = self.getcompiled(g, [r_ulonglong]) - assert gn(2 ** 64 - 12345678) == (2 ** 64 - 12345678) >> 12 + assert gn(r_ulonglong(2 ** 64 - 12345678)) == (2 ** 64 - 12345678) >> 12 def test_specializing_int_functions(self): def f(i): @@ -275,7 +251,7 @@ def f(i): return int(i) fn = self.getcompiled(f, [r_longlong]) - assert fn(0) == 0 + assert fn(r_longlong(0)) == 0 def test_upcast_int(self): def f(v): @@ -305,7 +281,7 @@ def wrapper(): lst = snippet.call_five() return (len(lst), lst[0]) == (1, 5) - call_five = self.getcompiled(wrapper) + call_five = self.getcompiled(wrapper, []) result = call_five() assert result @@ -327,28 +303,28 @@ list_3_c = l[:2] list_9 = l[5:] list_11_h = l[3:5] - return (len(l), l[0], l[1], l[2], l[3], l[4], l[5], + return str((len(l), l[0], l[1], l[2], l[3], l[4], l[5], len(list_3_c), list_3_c[0], list_3_c[1], len(list_9), list_9[0], - len(list_11_h), list_11_h[0], list_11_h[1]) - fn = self.getcompiled(get_set_del_nonneg_slice) + len(list_11_h), list_11_h[0], list_11_h[1])) + fn = self.getcompiled(get_set_del_nonneg_slice, []) result = fn() - assert result == (6, 3, ord('c'), 8, 11, ord('h'), 9, - 2, 3, ord('c'), - 1, 9, - 2, 11, ord('h')) + assert result == str((6, 3, ord('c'), 8, 11, ord('h'), 9, + 2, 3, ord('c'), + 1, 9, + 2, 11, ord('h'))) def test_is(self): def testfn(): l1 = [] return l1 is l1 - fn = self.getcompiled(testfn) + fn = self.getcompiled(testfn, []) result = fn() assert result is True def testfn(): l1 = [] return l1 is None - fn = self.getcompiled(testfn) + fn = self.getcompiled(testfn, []) result = fn() assert result is False @@ -538,7 +514,7 @@ m = r.meth def fn(): return m() - res = self.getcompiled(fn)() + res = self.getcompiled(fn, [])() assert res == 0 def test_constant_return_disagreement(self): @@ -548,7 +524,7 @@ r = R() def fn(): return r.meth() - res = self.getcompiled(fn)() + res = self.getcompiled(fn, [])() assert res == 0 def test_stringformatting(self): @@ -604,7 +580,7 @@ compute_hash(d), compute_hash(("Hi", None, (7.5, 2, d)))) - f = self.getcompiled(fn) + f = self.getcompiled(fn, []) res = f() # xxx the next line is too precise, checking the exact implementation @@ -635,7 +611,7 @@ r = range(10, 37, 4) r.reverse() return r[0] - f = self.getcompiled(fn) + f = self.getcompiled(fn, []) assert f() == fn() def test_range_idx(self): @@ -701,7 +677,7 @@ for ii in range(1): a1.append_to_list(X()) return a1.check_list_is_true() - fn = self.getcompiled(f) + fn = self.getcompiled(f, []) assert fn() == 1 def test_recursion_detection(self): @@ -748,7 +724,7 @@ except Exception: return 42 return x - fn = self.getcompiled(f) + fn = self.getcompiled(f, []) res = fn() assert res == 42 @@ -760,7 +736,7 @@ except TypeError: return 42 return x - fn = self.getcompiled(f) + fn = self.getcompiled(f, []) res = fn() assert res == 42 @@ -772,7 +748,7 @@ except TypeError: return 42 return 0 - fn = self.getcompiled(f) + fn = self.getcompiled(f, []) res = fn() assert res == 42 From noreply at buildbot.pypy.org Mon Oct 8 15:59:11 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 15:59:11 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121008135911.E8F7C1C0B7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57934:c1fe98cd5a58 Date: 2012-10-08 15:58 +0200 http://bitbucket.org/pypy/pypy/changeset/c1fe98cd5a58/ Log: merge diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py --- a/pypy/rlib/rarithmetic.py +++ b/pypy/rlib/rarithmetic.py @@ -63,7 +63,7 @@ # whatever size a long has, make it big enough for a pointer. return _get_bitsize(_long_typecode) -# exported for now for testing array values. +# exported for now for testing array values. # might go into its own module. def get_long_pattern(x): """get the bit pattern for a long, adjusted to pointer size""" @@ -72,7 +72,7 @@ # used in tests for ctypes and for genc and friends # to handle the win64 special case: is_emulated_long = _long_typecode != 'l' - + LONG_BIT = _get_long_bit() LONG_MASK = (2**LONG_BIT)-1 LONG_TEST = 2**(LONG_BIT-1) @@ -289,7 +289,7 @@ y = long(other) return self._widen(other, x + y) __radd__ = __add__ - + def __sub__(self, other): x = long(self) y = long(other) @@ -299,7 +299,7 @@ y = long(self) x = long(other) return self._widen(other, x - y) - + def __mul__(self, other): x = long(self) if not isinstance(other, (int, long)): @@ -403,22 +403,26 @@ res = pow(x, y, m) return self._widen(other, res) + class signed_int(base_int): SIGNED = True + def __new__(klass, val=0): - if type(val) is float: + if isinstance(val, (float, str)): val = long(val) - if val > klass.MASK>>1 or val < -(klass.MASK>>1)-1: - raise OverflowError("%s does not fit in signed %d-bit integer"%(val, klass.BITS)) + if val > klass.MASK >> 1 or val < -(klass.MASK >> 1) - 1: + raise OverflowError("%s does not fit in signed %d-bit integer" % (val, klass.BITS)) if val < 0: val = ~ ((~val) & klass.MASK) return super(signed_int, klass).__new__(klass, val) typemap = {} + class unsigned_int(base_int): SIGNED = False + def __new__(klass, val=0): - if isinstance(val, (float, long)): + if isinstance(val, (float, long, str)): val = long(val) return super(unsigned_int, klass).__new__(klass, val & klass.MASK) typemap = {} @@ -450,7 +454,7 @@ def compute_annotation(self): from pypy.annotation import model as annmodel return annmodel.SomeInteger(knowntype=int_type) - + class ForTypeEntry(extregistry.ExtRegistryEntry): _about_ = int_type @@ -462,7 +466,7 @@ v_result, = hop.inputargs(hop.r_result.lowleveltype) hop.exception_cannot_occur() return v_result - + return int_type class BaseIntValueEntry(extregistry.ExtRegistryEntry): @@ -471,7 +475,7 @@ def compute_annotation(self): from pypy.annotation import model as annmodel return annmodel.SomeInteger(knowntype=r_ulonglong) - + class BaseIntTypeEntry(extregistry.ExtRegistryEntry): _about_ = base_int @@ -591,7 +595,7 @@ """ Convert little->big endian and the opposite """ from pypy.rpython.lltypesystem import lltype, rffi - + T = lltype.typeOf(arg) # XXX we cannot do arithmetics on small ints if isinstance(arg, base_int): diff --git a/pypy/rpython/lltypesystem/rbuiltin.py b/pypy/rpython/lltypesystem/rbuiltin.py --- a/pypy/rpython/lltypesystem/rbuiltin.py +++ b/pypy/rpython/lltypesystem/rbuiltin.py @@ -1,11 +1,9 @@ -from pypy.tool.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython.lltypesystem import lltype -from pypy.rpython.lltypesystem import rclass +from pypy.rlib import objectmodel +from pypy.rpython.lltypesystem import lltype, rclass from pypy.rpython.lltypesystem.rdict import rtype_r_dict -from pypy.rlib import objectmodel -from pypy.rpython.rmodel import TyperError, Constant -from pypy.rpython.rbool import bool_repr +from pypy.rpython.rmodel import TyperError + def rtype_builtin_isinstance(hop): hop.exception_cannot_occur() @@ -87,6 +85,6 @@ BUILTIN_TYPER[weakref.ref] = rtype_weakref_create BUILTIN_TYPER[llmemory.weakref_create] = rtype_weakref_create -BUILTIN_TYPER[llmemory.weakref_deref ] = rtype_weakref_deref +BUILTIN_TYPER[llmemory.weakref_deref] = rtype_weakref_deref BUILTIN_TYPER[llmemory.cast_ptr_to_weakrefptr] = rtype_cast_ptr_to_weakrefptr BUILTIN_TYPER[llmemory.cast_weakrefptr_to_ptr] = rtype_cast_weakrefptr_to_ptr diff --git a/pypy/rpython/rbuiltin.py b/pypy/rpython/rbuiltin.py --- a/pypy/rpython/rbuiltin.py +++ b/pypy/rpython/rbuiltin.py @@ -1,17 +1,12 @@ -from pypy.tool.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant -from pypy.rpython.lltypesystem import lltype, rclass, llmemory -from pypy.rpython import rint, raddress from pypy.rlib import rarithmetic, objectmodel +from pypy.rpython import raddress, rptr, extregistry from pypy.rpython.error import TyperError -from pypy.rpython.rmodel import Repr, IntegerRepr, inputconst -from pypy.rpython.rrange import rtype_builtin_range, rtype_builtin_xrange -from pypy.rpython.rrange import rtype_builtin_enumerate -from pypy.rpython import rstr -from pypy.rpython import rptr -from pypy.tool import sourcetools -from pypy.rpython import extregistry +from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.rmodel import Repr +from pypy.tool.pairtype import pairtype + class __extend__(annmodel.SomeBuiltin): def rtyper_makerepr(self, rtyper): @@ -80,7 +75,7 @@ kwds_i = {} for i, key in enumerate(keywords): index = arguments.keywords_w[i] - kwds_i['i_'+key] = index + kwds_i['i_' + key] = index return hop, kwds_i @@ -303,7 +298,7 @@ r_func, nimplicitarg = r_callable.get_r_implfunc() s_callable = r_callable.get_s_callable() - nbargs = len(hop.args_s) - 1 + nimplicitarg + nbargs = len(hop.args_s) - 1 + nimplicitarg s_sigs = r_func.get_s_signatures((nbargs, (), False, False)) if len(s_sigs) != 1: raise TyperError("cannot hlinvoke callable %r with not uniform" @@ -332,7 +327,7 @@ # collect all functions -import __builtin__, exceptions +import __builtin__ BUILTIN_TYPER = {} for name, value in globals().items(): if name.startswith('rtype_builtin_'): @@ -384,7 +379,7 @@ hop.has_implicit_exception(MemoryError) # record that we know about it hop.exception_is_here() - return hop.genop(opname, vlist, resulttype = hop.r_result.lowleveltype) + return hop.genop(opname, vlist, resulttype=hop.r_result.lowleveltype) def rtype_free(hop, i_flavor, i_track_allocation=None): vlist = [hop.inputarg(hop.args_r[0], arg=0)] @@ -504,7 +499,7 @@ elif ORIG == llmemory.Address: return llops.genop('cast_adr_to_ptr', [v_value], resulttype = TGT) elif isinstance(ORIG, lltype.Primitive): - v_value = gen_cast(llops, lltype.Signed, v_value) + v_value = gen_cast(llops, lltype.Signed, v_value) return llops.genop('cast_int_to_ptr', [v_value], resulttype=TGT) elif TGT == llmemory.Address and isinstance(ORIG, lltype.Ptr): return llops.genop('cast_ptr_to_adr', [v_value], resulttype = TGT) @@ -632,7 +627,7 @@ flags = {'flavor': flavor} cflags = hop.inputconst(lltype.Void, flags) return hop.genop('free', [vinst, cflags]) - + BUILTIN_TYPER[objectmodel.free_non_gc_object] = rtype_free_non_gc_object # keepalive_until_here @@ -682,4 +677,3 @@ BUILTIN_TYPER[llmemory.cast_adr_to_ptr] = rtype_cast_adr_to_ptr BUILTIN_TYPER[llmemory.cast_adr_to_int] = rtype_cast_adr_to_int BUILTIN_TYPER[llmemory.cast_int_to_adr] = rtype_cast_int_to_adr - From noreply at buildbot.pypy.org Mon Oct 8 16:05:30 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 16:05:30 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Unkill these three imports, and clarify them. Message-ID: <20121008140530.D97E91C0DFA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57935:d54591c6082a Date: 2012-10-08 16:05 +0200 http://bitbucket.org/pypy/pypy/changeset/d54591c6082a/ Log: Unkill these three imports, and clarify them. diff --git a/pypy/rpython/rbuiltin.py b/pypy/rpython/rbuiltin.py --- a/pypy/rpython/rbuiltin.py +++ b/pypy/rpython/rbuiltin.py @@ -1,7 +1,7 @@ from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant from pypy.rlib import rarithmetic, objectmodel -from pypy.rpython import raddress, rptr, extregistry +from pypy.rpython import raddress, rptr, extregistry, rrange from pypy.rpython.error import TyperError from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.rmodel import Repr @@ -325,6 +325,10 @@ return hop.dispatch() +rtype_builtin_range = rrange.rtype_builtin_range +rtype_builtin_xrange = rrange.rtype_builtin_xrange +rtype_builtin_enumerate = rrange.rtype_builtin_enumerate + # collect all functions import __builtin__ From noreply at buildbot.pypy.org Mon Oct 8 16:24:27 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 16:24:27 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Hack more to make it work on 32-bit. Message-ID: <20121008142427.988AA1C0F4E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57936:f04538f65c69 Date: 2012-10-08 16:24 +0200 http://bitbucket.org/pypy/pypy/changeset/f04538f65c69/ Log: Hack more to make it work on 32-bit. diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -13,20 +13,25 @@ from pypy.translator.interactive import Translation from pypy.translator.translator import TranslationContext, graphof +signed_ffffffff = r_longlong(0xffffffff) +unsigned_ffffffff = r_ulonglong(0xffffffff) + def llrepr(v): if isinstance(v, r_ulonglong): - return "%d:%d" % (intmask(v >> 32), intmask(v & 0xffffffff)) + return "%d:%d" % (intmask(v >> 32), intmask(v & unsigned_ffffffff)) elif isinstance(v, r_longlong): - return "%d:%d" % (intmask(v >> 32), intmask(v & 0xffffffff)) + return "%d:%d" % (intmask(v >> 32), intmask(v & signed_ffffffff)) return str(v) def parse_longlong(a): p0, p1 = a.split(":") - return (r_longlong(int(p0)) << 32) + (r_longlong(int(p1)) & 0xffffffff) + return (r_longlong(int(p0)) << 32) + (r_longlong(int(p1)) & + signed_ffffffff) def parse_ulonglong(a): p0, p1 = a.split(":") - return (r_ulonglong(int(p0)) << 32) + (r_ulonglong(int(p1)) & 0xffffffff) + return (r_ulonglong(int(p0)) << 32) + (r_ulonglong(int(p1)) & + unsigned_ffffffff) def compile(fn, argtypes, view=False, gcpolicy="none", backendopt=True, annotatorpolicy=None, thread=False): @@ -77,6 +82,7 @@ for arg, argtype in zip(args, argtypes): assert isinstance(arg, argtype) stdout = t.driver.cbuilder.cmdexec(" ".join([llrepr(arg) for arg in args])) + print stdout assert stdout.endswith(' ;\n') pos = stdout.rindex('THE RESULT IS: ') res = stdout[pos + len('THE RESULT IS: '):-3] From noreply at buildbot.pypy.org Mon Oct 8 16:27:38 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 16:27:38 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix some more tests Message-ID: <20121008142738.D98481C0F4E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57937:8506cd9a86fd Date: 2012-10-08 16:27 +0200 http://bitbucket.org/pypy/pypy/changeset/8506cd9a86fd/ Log: fix some more tests diff --git a/pypy/translator/c/test/test_backendoptimized.py b/pypy/translator/c/test/test_backendoptimized.py --- a/pypy/translator/c/test/test_backendoptimized.py +++ b/pypy/translator/c/test/test_backendoptimized.py @@ -15,8 +15,8 @@ else: return 456 fn = self.getcompiled(f, [bool]) - assert f(True) == 123 - assert f(False) == 456 + assert fn(True) == 123 + assert fn(False) == 456 def test__del__(self): class B(object): diff --git a/pypy/translator/c/test/test_typed.py b/pypy/translator/c/test/test_typed.py --- a/pypy/translator/c/test/test_typed.py +++ b/pypy/translator/c/test/test_typed.py @@ -5,8 +5,7 @@ import py -from py.test import raises - +from pypy.rlib.rstackovf import StackOverflow from pypy.rlib.objectmodel import compute_hash, current_object_addr_as_int from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask, longlongmask from pypy.rpython.lltypesystem import rffi, lltype @@ -18,15 +17,25 @@ def getcompiled(self, func, argtypes): return compile(func, argtypes, backendopt=False) + def get_wrapper(self, func): + def wrapper(*args): + try: + return func(*args) + except OverflowError: + return -1 + except ZeroDivisionError: + return -2 + return wrapper + def test_set_attr(self): - set_attr = self.getcompiled(snippet.set_attr) + set_attr = self.getcompiled(snippet.set_attr, []) assert set_attr() == 2 def test_inheritance2(self): def wrap(): res = snippet.inheritance2() return res == ((-12, -12.0), (3, 12.3)) - fn = self.getcompiled(wrap) + fn = self.getcompiled(wrap, []) assert fn() def test_factorial2(self): @@ -42,7 +51,8 @@ assert simple_method(55) == 55 def test_sieve_of_eratosthenes(self): - sieve_of_eratosthenes = self.getcompiled(snippet.sieve_of_eratosthenes) + sieve_of_eratosthenes = self.getcompiled(snippet.sieve_of_eratosthenes, + []) assert sieve_of_eratosthenes() == 1028 def test_nested_whiles(self): @@ -53,7 +63,7 @@ def wrap(): res = snippet.call_unpack_56() return res == (2, 5, 6) - fn = self.getcompiled(wrap) + fn = self.getcompiled(wrap, []) assert fn() def test_class_defaultattr(self): @@ -63,7 +73,7 @@ k = K() k.n += " world" return k.n - fn = self.getcompiled(class_defaultattr) + fn = self.getcompiled(class_defaultattr, []) assert fn() == "hello world" def test_tuple_repr(self): @@ -210,12 +220,12 @@ def test_long_long(self): def f(i): return 4 * i - fn = self.getcompiled(f, [r_ulonglong], view=False) + fn = self.getcompiled(f, [r_ulonglong]) assert fn(r_ulonglong(2147483647)) == 4 * 2147483647 def g(i): return 4 * i - gn = self.getcompiled(g, [r_longlong], view=False) + gn = self.getcompiled(g, [r_longlong]) assert gn(r_longlong(2147483647)) == 4 * 2147483647 def g(i): @@ -460,39 +470,45 @@ assert res == f(i, ord(l[j])) def test_int_overflow(self): - fn = self.getcompiled(snippet.add_func, [int]) - raises(OverflowError, fn, sys.maxint) + fn = self.getcompiled(self.get_wrapper(snippet.add_func), [int]) + assert fn(sys.maxint) == -1 def test_int_floordiv_ovf_zer(self): - fn = self.getcompiled(snippet.div_func, [int]) - raises(OverflowError, fn, -1) - raises(ZeroDivisionError, fn, 0) + fn = self.getcompiled(self.get_wrapper(snippet.div_func), [int]) + assert fn(-1) == -1 + assert fn(0) == -2 def test_int_mul_ovf(self): - fn = self.getcompiled(snippet.mul_func, [int, int]) + fn = self.getcompiled(self.get_wrapper(snippet.mul_func), [int, int]) for y in range(-5, 5): for x in range(-5, 5): assert fn(x, y) == snippet.mul_func(x, y) n = sys.maxint / 4 assert fn(n, 3) == snippet.mul_func(n, 3) assert fn(n, 4) == snippet.mul_func(n, 4) - raises(OverflowError, fn, n, 5) + assert fn(n, 5) == -1 def test_int_mod_ovf_zer(self): - fn = self.getcompiled(snippet.mod_func, [int]) - raises(OverflowError, fn, -1) - raises(ZeroDivisionError, fn, 0) + fn = self.getcompiled(self.get_wrapper(snippet.mod_func), [int]) + assert fn(-1) == -1 + assert fn(0) == -2 def test_int_lshift_ovf(self): - fn = self.getcompiled(snippet.lshift_func, [int]) - raises(OverflowError, fn, 1) + fn = self.getcompiled(self.get_wrapper(snippet.lshift_func), [int]) + assert fn(1) == -1 def test_int_unary_ovf(self): - fn = self.getcompiled(snippet.unary_func, [int]) + def w(a, b): + if not b: + return snippet.unary_func(a)[0] + else: + return snippet.unary_func(a)[1] + fn = self.getcompiled(self.get_wrapper(w), [int, int]) for i in range(-3, 3): - assert fn(i) == (-(i), abs(i - 1)) - raises(OverflowError, fn, -sys.maxint - 1) - raises(OverflowError, fn, -sys.maxint) + assert fn(i, 0) == -(i) + assert fn(i, 1) == abs(i - 1) + assert fn(-sys.maxint - 1, 0) == -1 + assert fn(-sys.maxint, 0) == -1 # floats def test_float_operations(self): @@ -574,17 +590,19 @@ # def fn(): d2 = D() - return (compute_hash(d2), - current_object_addr_as_int(d2), - compute_hash(c), - compute_hash(d), - compute_hash(("Hi", None, (7.5, 2, d)))) + return str((compute_hash(d2), + current_object_addr_as_int(d2), + compute_hash(c), + compute_hash(d), + compute_hash(("Hi", None, (7.5, 2, d))))) f = self.getcompiled(fn, []) res = f() # xxx the next line is too precise, checking the exact implementation - assert res[0] == res[1] + res = [int(a) for a in res[1:-1].split(",")] + if res[0] != res[1]: + assert res[0] == -res[1] - 1 assert res[2] != compute_hash(c) # likely assert res[3] == compute_hash(d) assert res[4] == compute_hash(("Hi", None, (7.5, 2, d))) @@ -619,22 +637,20 @@ r = range(10, 37, 4) try: return r[idx] - except: - raise + except IndexError: + return -1 f = self.getcompiled(fn, [int]) assert f(0) == fn(0) assert f(-1) == fn(-1) - raises(IndexError, f, 42) + assert f(42) == -1 def test_range_step(self): def fn(step): r = range(10, 37, step) - # we always raise on step = 0 return r[-2] f = self.getcompiled(fn, [int]) assert f(1) == fn(1) assert f(3) == fn(3) - raises(ValueError, f, 0) def test_range_iter(self): def fn(start, stop, step): @@ -682,15 +698,18 @@ def test_recursion_detection(self): def f(n): - if n == 0: - return 1 - else: - return n * f(n - 1) + try: + if n == 0: + return 1 + else: + return n * f(n - 1) + except StackOverflow: + return -42 fn = self.getcompiled(f, [int]) assert fn(7) == 5040 assert fn(7) == 5040 # detection must work several times, too assert fn(7) == 5040 - py.test.raises(RuntimeError, fn, -1) + assert fn(-1) == -42 def test_infinite_recursion(self): def f(x): From noreply at buildbot.pypy.org Mon Oct 8 16:30:55 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 8 Oct 2012 16:30:55 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: some more fixes Message-ID: <20121008143055.4EF9C1C0F4E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57938:58683381a492 Date: 2012-10-08 16:30 +0200 http://bitbucket.org/pypy/pypy/changeset/58683381a492/ Log: some more fixes diff --git a/pypy/translator/c/test/test_typed.py b/pypy/translator/c/test/test_typed.py --- a/pypy/translator/c/test/test_typed.py +++ b/pypy/translator/c/test/test_typed.py @@ -697,15 +697,18 @@ assert fn() == 1 def test_recursion_detection(self): - def f(n): + def g(n): try: - if n == 0: - return 1 - else: - return n * f(n - 1) + return f(n) except StackOverflow: return -42 - fn = self.getcompiled(f, [int]) + + def f(n): + if n == 0: + return 1 + else: + return n * f(n - 1) + fn = self.getcompiled(g, [int]) assert fn(7) == 5040 assert fn(7) == 5040 # detection must work several times, too assert fn(7) == 5040 @@ -801,12 +804,6 @@ self.getcompiled(func_swap, []) - def test_returns_unicode(self): - def func(i): - return u'hello' + unichr(i) - f = self.getcompiled(func, [int]) - assert f(0x1234) == u'hello\u1234' - def test_ovfcheck_float_to_int(self): from pypy.rlib.rarithmetic import ovfcheck_float_to_int From noreply at buildbot.pypy.org Mon Oct 8 16:36:43 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 16:36:43 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix the last issue in test_typed Message-ID: <20121008143643.108DA1C0F4E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57939:b419aa41c9b1 Date: 2012-10-08 16:36 +0200 http://bitbucket.org/pypy/pypy/changeset/b419aa41c9b1/ Log: Fix the last issue in test_typed diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -21,6 +21,8 @@ return "%d:%d" % (intmask(v >> 32), intmask(v & unsigned_ffffffff)) elif isinstance(v, r_longlong): return "%d:%d" % (intmask(v >> 32), intmask(v & signed_ffffffff)) + elif isinstance(v, float): + return repr(v) # extra precision than str(v) return str(v) def parse_longlong(a): From noreply at buildbot.pypy.org Mon Oct 8 17:03:18 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 17:03:18 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: The llinterp cannot convert random exception classes from random Message-ID: <20121008150318.8202F1C027A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57940:b1db1d0acb6c Date: 2012-10-08 17:02 +0200 http://bitbucket.org/pypy/pypy/changeset/b1db1d0acb6c/ Log: The llinterp cannot convert random exception classes from random pure Python runs. When we get one, convert it to UnknownException. diff --git a/pypy/jit/metainterp/test/test_virtualref.py b/pypy/jit/metainterp/test/test_virtualref.py --- a/pypy/jit/metainterp/test/test_virtualref.py +++ b/pypy/jit/metainterp/test/test_virtualref.py @@ -1,6 +1,6 @@ import py from pypy.rpython.lltypesystem import lltype, llmemory, lloperation -from pypy.rpython.llinterp import LLException +from pypy.rpython.exceptiondata import UnknownException from pypy.rlib.jit import JitDriver, dont_look_inside, vref_None from pypy.rlib.jit import virtual_ref, virtual_ref_finish, InvalidVirtualRef from pypy.rlib.jit import non_virtual_ref @@ -564,7 +564,7 @@ return res # py.test.raises(InvalidVirtualRef, "fn(10)") - py.test.raises(LLException, "self.meta_interp(fn, [10])") + py.test.raises(UnknownException, "self.meta_interp(fn, [10])") def test_call_virtualref_already_forced(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'res']) diff --git a/pypy/rpython/exceptiondata.py b/pypy/rpython/exceptiondata.py --- a/pypy/rpython/exceptiondata.py +++ b/pypy/rpython/exceptiondata.py @@ -23,6 +23,9 @@ rstackovf._StackOverflow: True, } +class UnknownException(Exception): + pass + class AbstractExceptionData: """Public information for the code generators to help with exceptions.""" @@ -67,6 +70,8 @@ return example def get_standard_ll_exc_instance_by_class(self, exceptionclass): + if exceptionclass not in self.standardexceptions: + raise UnknownException(exceptionclass) clsdef = self.rtyper.annotator.bookkeeper.getuniqueclassdef( exceptionclass) return self.get_standard_ll_exc_instance(self.rtyper, clsdef) diff --git a/pypy/rpython/test/test_llinterp.py b/pypy/rpython/test/test_llinterp.py --- a/pypy/rpython/test/test_llinterp.py +++ b/pypy/rpython/test/test_llinterp.py @@ -4,7 +4,8 @@ from pypy.rpython.lltypesystem.lltype import typeOf, Void, malloc, free from pypy.rpython.llinterp import LLInterpreter, LLException from pypy.rpython.rmodel import inputconst -from pypy.rpython.annlowlevel import hlstr +from pypy.rpython.annlowlevel import hlstr, llhelper +from pypy.rpython.exceptiondata import UnknownException from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.lltypesystem import lltype from pypy.annotation import model as annmodel @@ -645,3 +646,15 @@ res = interpret(f, []) assert not res + +def test_userdefined_exception(): + class FooError(Exception): + pass + def g(): + raise FooError + g_func = llhelper(lltype.Ptr(lltype.FuncType([], lltype.Void)), g) + def f(): + g_func() + + e = py.test.raises(UnknownException, interpret, f, []) + assert e.value.args[0] is FooError From noreply at buildbot.pypy.org Mon Oct 8 17:18:33 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 17:18:33 +0200 (CEST) Subject: [pypy-commit] cffi default: Add a section about debugging with env vars (thanks sarvi) Message-ID: <20121008151833.0A94F1C027A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r986:dbe339f3cec4 Date: 2012-10-08 17:18 +0200 http://bitbucket.org/cffi/cffi/changeset/dbe339f3cec4/ Log: Add a section about debugging with env vars (thanks sarvi) diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1089,6 +1089,44 @@ structs/unions inside structs/unions. +Debugging dlopen'ed C libraries +------------------------------- + +A few C libraries are actually hard to use correctly in a ``dlopen()`` +setting. This is because most C libraries are intented for, and tested +with, a situation where they are *linked* with another program, using +either static linking or dynamic linking --- but from a program written +in C, at start-up, using the linker's capabilities instead of +``dlopen()``. + +This can occasionally create issues. You would have the same issues in +another setting than CFFI, like with ``ctypes`` or even plain C code that +calls ``dlopen()``. This section contains a few generally useful +environment variables (on Linux) that can help when debugging these +issues. + +**export LD_TRACE_LOADED_OBJECTS=all** + + provides a lot of information, sometimes too much depending on the + setting. Output verbose debugging information about the dynamic + linker. If set to ``all`` prints all debugging information it has, if + set to ``help`` prints a help message about which categories can be + specified in this environment variable + +**export LD_VERBOSE=1** + + (glibc since 2.1) If set to a nonempty string, output symbol + versioning information about the program if querying information + about the program (i.e., either ``LD_TRACE_LOADED_OBJECTS`` has been set, + or ``--list`` or ``--verify`` options have been given to the dynamic + linker). + +**export LD_WARN=1** + + (ELF only)(glibc since 2.1.3) If set to a nonempty string, warn + about unresolved symbols. + + Reference: conversions ---------------------- From noreply at buildbot.pypy.org Mon Oct 8 17:23:02 2012 From: noreply at buildbot.pypy.org (jerith) Date: Mon, 8 Oct 2012 17:23:02 +0200 (CEST) Subject: [pypy-commit] cffi less-partial-curses-demo: Implement enough extra bits to make pypy REPL and Twisted trial happy. Message-ID: <20121008152302.54C7F1C027A@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: less-partial-curses-demo Changeset: r987:9793a0cbb33d Date: 2012-10-08 16:58 +0200 http://bitbucket.org/cffi/cffi/changeset/9793a0cbb33d/ Log: Implement enough extra bits to make pypy REPL and Twisted trial happy. diff --git a/demo/_curses.py b/demo/_curses.py --- a/demo/_curses.py +++ b/demo/_curses.py @@ -22,6 +22,11 @@ int setupterm(char *term, int fildes, int *errret); +int tigetflag(char *); +int tigetnum(char *); +char *tigetstr(char *); +char *tparm (char *, ...); + int cbreak(void); int nocbreak(void); int echo(void); @@ -205,8 +210,17 @@ initscr = Window +_setupterm_called = False -def setupterm(term=ffi.NULL, fd=-1): + +def _ensure_setupterm_called(): + if not _setupterm_called: + raise error("must call (at least) setupterm() first") + + +def setupterm(term=None, fd=-1): + if term is None: + term = ffi.NULL if fd < 0: import sys fd = sys.stdout.fileno() @@ -219,6 +233,33 @@ else: s = "setupterm: unknown error %d" % err[0] raise error(s) + global _setupterm_called + _setupterm_called = True + + +def tigetflag(capname): + _ensure_setupterm_called() + return lib.tigetflag(capname) + + +def tigetnum(capname): + _ensure_setupterm_called() + return lib.tigetnum(capname) + + +def tigetstr(capname): + _ensure_setupterm_called() + out = lib.tigetstr(capname) + if out == ffi.NULL: + return None + return ffi.string(out) + + +def tparm(name, *args): + _ensure_setupterm_called() + cargs = [ffi.cast("long", arg) for arg in args] + return ffi.string(lib.tparm(name, *cargs)) + def color_pair(n): return n << 8 From noreply at buildbot.pypy.org Mon Oct 8 17:23:03 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 17:23:03 +0200 (CEST) Subject: [pypy-commit] cffi default: Merged in jerith/cffi/less-partial-curses-demo (pull request #4) Message-ID: <20121008152303.949021C027A@cobra.cs.uni-duesseldorf.de> Author: arigo Branch: Changeset: r988:47ea85efaf40 Date: 2012-10-08 17:22 +0200 http://bitbucket.org/cffi/cffi/changeset/47ea85efaf40/ Log: Merged in jerith/cffi/less-partial-curses-demo (pull request #4) diff --git a/demo/_curses.py b/demo/_curses.py --- a/demo/_curses.py +++ b/demo/_curses.py @@ -22,6 +22,11 @@ int setupterm(char *term, int fildes, int *errret); +int tigetflag(char *); +int tigetnum(char *); +char *tigetstr(char *); +char *tparm (char *, ...); + int cbreak(void); int nocbreak(void); int echo(void); @@ -205,8 +210,17 @@ initscr = Window +_setupterm_called = False -def setupterm(term=ffi.NULL, fd=-1): + +def _ensure_setupterm_called(): + if not _setupterm_called: + raise error("must call (at least) setupterm() first") + + +def setupterm(term=None, fd=-1): + if term is None: + term = ffi.NULL if fd < 0: import sys fd = sys.stdout.fileno() @@ -219,6 +233,33 @@ else: s = "setupterm: unknown error %d" % err[0] raise error(s) + global _setupterm_called + _setupterm_called = True + + +def tigetflag(capname): + _ensure_setupterm_called() + return lib.tigetflag(capname) + + +def tigetnum(capname): + _ensure_setupterm_called() + return lib.tigetnum(capname) + + +def tigetstr(capname): + _ensure_setupterm_called() + out = lib.tigetstr(capname) + if out == ffi.NULL: + return None + return ffi.string(out) + + +def tparm(name, *args): + _ensure_setupterm_called() + cargs = [ffi.cast("long", arg) for arg in args] + return ffi.string(lib.tparm(name, *cargs)) + def color_pair(n): return n << 8 From noreply at buildbot.pypy.org Mon Oct 8 17:55:38 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 17:55:38 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: What to do for the upcoming 2.0 release. Message-ID: <20121008155538.8920C1C0B7A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r4841:6cfe6c176d33 Date: 2012-10-08 17:53 +0200 http://bitbucket.org/pypy/extradoc/changeset/6cfe6c176d33/ Log: What to do for the upcoming 2.0 release. diff --git a/planning/2.0/todo.txt b/planning/2.0/todo.txt new file mode 100644 --- /dev/null +++ b/planning/2.0/todo.txt @@ -0,0 +1,10 @@ +Things to do +============ + +* Fix ctypes performnace for 2.0 beta +* result-in-resop (maybe) +* NumPy speed for 2.0 final +* cffi on pypy on windows +* raw malloc virtuals +* bug tracker gardening +* all green buildbots From noreply at buildbot.pypy.org Mon Oct 8 17:55:39 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 17:55:39 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Kill an old file. Message-ID: <20121008155539.B149C1C0B7A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r4842:1fb34bcc5dba Date: 2012-10-08 17:53 +0200 http://bitbucket.org/pypy/extradoc/changeset/1fb34bcc5dba/ Log: Kill an old file. diff --git a/planning/todo.txt b/planning/todo.txt deleted file mode 100644 --- a/planning/todo.txt +++ /dev/null @@ -1,13 +0,0 @@ -PyPy todo areas -================== - -This is a todo list that lists various areas of PyPy that should be cleaned up -(for whatever reason: less mess, less code duplication, etc). - -translation toolchain ---------------------- - - - clean up the tangle of including headers in the C backend - - make approach for loading modules more sane, mixedmodule capture - too many platform dependencies especially for pypy-cli - From noreply at buildbot.pypy.org Mon Oct 8 17:55:41 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 8 Oct 2012 17:55:41 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: merge heads Message-ID: <20121008155541.1FE631C0B7A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r4843:0730c6ebec3f Date: 2012-10-08 17:55 +0200 http://bitbucket.org/pypy/extradoc/changeset/0730c6ebec3f/ Log: merge heads diff --git a/talk/ep2012/jit/abstract.rst b/talk/pycon-uk-2012/abstract.rst copy from talk/ep2012/jit/abstract.rst copy to talk/pycon-uk-2012/abstract.rst diff --git a/talk/ep2012/jit/talk/Makefile b/talk/pycon-uk-2012/talk/Makefile copy from talk/ep2012/jit/talk/Makefile copy to talk/pycon-uk-2012/talk/Makefile diff --git a/talk/pycon-uk-2012/talk/author.latex b/talk/pycon-uk-2012/talk/author.latex new file mode 100644 --- /dev/null +++ b/talk/pycon-uk-2012/talk/author.latex @@ -0,0 +1,8 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[PyPy JIT under the hood]{PyPy JIT under the hood} +\author[antocuni] +{Antonio Cuni} + +\institute{PyCon UK 2012} +\date{September 28, 2012} diff --git a/talk/ep2012/jit/talk/beamerdefs.txt b/talk/pycon-uk-2012/talk/beamerdefs.txt copy from talk/ep2012/jit/talk/beamerdefs.txt copy to talk/pycon-uk-2012/talk/beamerdefs.txt diff --git a/talk/ep2012/jit/talk/diagrams/architecture.svg b/talk/pycon-uk-2012/talk/diagrams/architecture.svg copy from talk/ep2012/jit/talk/diagrams/architecture.svg copy to talk/pycon-uk-2012/talk/diagrams/architecture.svg diff --git a/talk/ep2012/jit/talk/diagrams/pypytrace.svg b/talk/pycon-uk-2012/talk/diagrams/pypytrace.svg copy from talk/ep2012/jit/talk/diagrams/pypytrace.svg copy to talk/pycon-uk-2012/talk/diagrams/pypytrace.svg diff --git a/talk/ep2012/jit/talk/diagrams/trace.svg b/talk/pycon-uk-2012/talk/diagrams/trace.svg copy from talk/ep2012/jit/talk/diagrams/trace.svg copy to talk/pycon-uk-2012/talk/diagrams/trace.svg diff --git a/talk/ep2012/jit/talk/diagrams/tracetree.svg b/talk/pycon-uk-2012/talk/diagrams/tracetree.svg copy from talk/ep2012/jit/talk/diagrams/tracetree.svg copy to talk/pycon-uk-2012/talk/diagrams/tracetree.svg diff --git a/talk/ep2012/jit/talk/diagrams/tracing-phases.svg b/talk/pycon-uk-2012/talk/diagrams/tracing-phases.svg copy from talk/ep2012/jit/talk/diagrams/tracing-phases.svg copy to talk/pycon-uk-2012/talk/diagrams/tracing-phases.svg diff --git a/talk/ep2012/jit/talk/stylesheet.latex b/talk/pycon-uk-2012/talk/stylesheet.latex copy from talk/ep2012/jit/talk/stylesheet.latex copy to talk/pycon-uk-2012/talk/stylesheet.latex diff --git a/talk/pycon-uk-2012/talk/talk.pdf.info b/talk/pycon-uk-2012/talk/talk.pdf.info new file mode 100644 --- /dev/null +++ b/talk/pycon-uk-2012/talk/talk.pdf.info @@ -0,0 +1,11 @@ +AvailableTransitions=[Crossfade] +TransitionDuration = 100 +EstimatedDuration = 60*60 # in seconds +MinutesOnly = True + +PageProps = { + 1: { + 'reset': FirstTimeOnly, + 'progress': False, + }, +} diff --git a/talk/pycon-uk-2012/talk/talk.rst b/talk/pycon-uk-2012/talk/talk.rst new file mode 100644 --- /dev/null +++ b/talk/pycon-uk-2012/talk/talk.rst @@ -0,0 +1,587 @@ +.. include:: beamerdefs.txt + +================================ +PyPy JIT under the hood +================================ + +About me +--------- + +- PyPy core dev + +- PyPy py3k tech leader + +- ``pdb++``, ``fancycompleter``, ... + +- Consultant, trainer + +- You can hire me :-) + +- http://antocuni.eu + + +About this talk +---------------- + +* What is PyPy? (in 30 seconds) + +* Overview of tracing JITs + +* The PyPy JIT generator + + +Part 0: What is PyPy? +---------------------- + +* RPython toolchain + + - subset of Python + + - ideal for writing VMs + + - JIT & GC for free + +* Python interpreter + + - written in RPython + +* Whatever (dynamic) language you want + + - smalltalk, prolog, javascript, ... + + +Part 1 +------ + +**Overview of tracing JITs** + +Compilers +--------- + +* When? + + - Batch or Ahead Of Time + + - Just In Time + +|pause| + +* How? + + - Static + + - Dynamic or Adaptive + +|pause| + +* What? + + - Method-based compiler + + - Tracing compiler + +|pause| + +* PyPy: JIT, Dynamic, Tracing + + +Assumptions +----------- + +* Pareto Principle (80-20 rule) + + - the 20% of the program accounts for the 80% of the runtime + + - **hot-spots** + +* Fast Path principle + + - optimize only what is necessary + + - fall back for uncommon cases + +|pause| + +* Most of runtime spent in **loops** + +* Always the same code paths (likely) + + +Tracing JIT +----------- + +* Interpret the program as usual + +* Detect **hot** loops + +* Tracing phase + + - **linear** trace + +* Compiling + +* Execute + + - guards to ensure correctness + +* Profit :-) + + +Tracing JIT phases +------------------- + +.. animage:: diagrams/tracing-phases-p*.pdf + :align: center + :scale: 100% + + +Tracing Example (1) +-------------------- + +.. we use java instead of RPython to avoid confusion with applevel Python + + +|scriptsize| +|example<| |small| java |end_small| |>| + +.. sourcecode:: java + + interface Operation { + int DoSomething(int x); + } + class IncrOrDecr implements Operation { + public int DoSomething(int x) { + if (x < 0) return x-1; + else return x+1; + } + } + class tracing { + public static void main(String argv[]) { + int N = 100; + int i = 0; + Operation op = new IncrOrDecr(); + while (i < N) { + i = op.DoSomething(i); + } + System.out.println(i); + } + } + +|end_example| +|end_scriptsize| + + +Tracing Example (2) +-------------------- + +|scriptsize| +|column1| +|example<| |small| Java bytecode |end_small| |>| + +.. sourcecode:: java + + class IncrOrDecr { + ... + public DoSomething(I)I + ILOAD 1 + IFGE LABEL_0 + ILOAD 1 + ICONST_1 + ISUB + IRETURN + LABEL_0 + ILOAD 1 + ICONST_1 + IADD + IRETURN + } + +|end_example| + +|pause| + +|column2| +|example<| |small| Java bytecode |end_small| |>| + +.. sourcecode:: java + + class tracing { + ... + public static main( + [Ljava/lang/String;)V + ... + LABEL_0 + ILOAD 2 + ILOAD 1 + IF_ICMPGE LABEL_1 + ALOAD 3 + ILOAD 2 + INVOKEINTERFACE + Operation.DoSomething (I)I + ISTORE 2 + GOTO LABEL_0 + LABEL_1 + ... + } + +|end_example| +|end_columns| +|end_scriptsize| + + +Tracing example (3) +------------------- + +.. animage:: diagrams/trace-p*.pdf + :align: center + :scale: 80% + + +Trace trees (1) +--------------- + +|scriptsize| +|example<| |small| tracetree.java |end_small| |>| + +.. sourcecode:: java + + public static void trace_trees() { + int a = 0; + int i = 0; + int N = 100; + + while(i < N) { + if (i%2 == 0) + a++; + else + a*=2; + i++; + } + } + +|end_example| +|end_scriptsize| + +Trace trees (2) +--------------- + +.. animage:: diagrams/tracetree-p*.pdf + :align: center + :scale: 34% + + +Part 2 +------ + +**The PyPy JIT generator** + +General architecture +--------------------- + +.. animage:: diagrams/architecture-p*.pdf + :align: center + :scale: 24% + + +PyPy trace example +------------------- + +.. animage:: diagrams/pypytrace-p*.pdf + :align: center + :scale: 40% + + +PyPy optimizer +--------------- + +- intbounds + +- constant folding / pure operations + +- virtuals + +- string optimizations + +- heap (multiple get/setfield, etc) + +- ffi + +- unroll + + +Intbound optimization (1) +------------------------- + +|example<| |small| intbound.py |end_small| |>| + +.. sourcecode:: python + + def fn(): + i = 0 + while i < 5000: + i += 2 + return i + +|end_example| + +Intbound optimization (2) +-------------------------- + +|scriptsize| +|column1| +|example<| |small| unoptimized |end_small| |>| + +.. sourcecode:: python + + ... + i17 = int_lt(i15, 5000) + guard_true(i17) + i19 = int_add_ovf(i15, 2) + guard_no_overflow() + ... + +|end_example| + +|pause| + +|column2| +|example<| |small| optimized |end_small| |>| + +.. sourcecode:: python + + ... + i17 = int_lt(i15, 5000) + guard_true(i17) + i19 = int_add(i15, 2) + ... + +|end_example| +|end_columns| +|end_scriptsize| + +|pause| + +* It works **often** + +* array bound checking + +* intbound info propagates all over the trace + + +Virtuals (1) +------------- + +|example<| |small| virtuals.py |end_small| |>| + +.. sourcecode:: python + + def fn(): + i = 0 + while i < 5000: + i += 2 + return i + +|end_example| + + +Virtuals (2) +------------ + +|scriptsize| +|column1| +|example<| |small| unoptimized |end_small| |>| + +.. sourcecode:: python + + ... + guard_class(p0, W_IntObject) + i1 = getfield_pure(p0, 'intval') + i2 = int_add(i1, 2) + p3 = new(W_IntObject) + setfield_gc(p3, i2, 'intval') + ... + +|end_example| + +|pause| + +|column2| +|example<| |small| optimized |end_small| |>| + +.. sourcecode:: python + + ... + i2 = int_add(i1, 2) + ... + +|end_example| +|end_columns| +|end_scriptsize| + +|pause| + +* The most important optimization (TM) + +* It works both inside the trace and across the loop + +* It works for tons of cases + + - e.g. function frames + + +Constant folding (1) +--------------------- + +|example<| |small| constfold.py |end_small| |>| + +.. sourcecode:: python + + def fn(): + i = 0 + while i < 5000: + i += 2 + return i + +|end_example| + + +Constant folding (2) +-------------------- + +|scriptsize| +|column1| +|example<| |small| unoptimized |end_small| |>| + +.. sourcecode:: python + + ... + i1 = getfield_pure(p0, 'intval') + i2 = getfield_pure(, + 'intval') + i3 = int_add(i1, i2) + ... + +|end_example| + +|pause| + +|column2| +|example<| |small| optimized |end_small| |>| + +.. sourcecode:: python + + ... + i1 = getfield_pure(p0, 'intval') + i3 = int_add(i1, 2) + ... + +|end_example| +|end_columns| +|end_scriptsize| + +|pause| + +* It "finishes the job" + +* Works well together with other optimizations (e.g. virtuals) + +* It also does "normal, boring, static" constant-folding + + +Out of line guards (1) +----------------------- + +|example<| |small| outoflineguards.py |end_small| |>| + +.. sourcecode:: python + + N = 2 + def fn(): + i = 0 + while i < 5000: + i += N + return i + +|end_example| + + +Out of line guards (2) +---------------------- + +|scriptsize| +|column1| +|example<| |small| unoptimized |end_small| |>| + +.. sourcecode:: python + + ... + quasiimmut_field(, 'val') + guard_not_invalidated() + p0 = getfield_gc(, 'val') + ... + i2 = getfield_pure(p0, 'intval') + i3 = int_add(i1, i2) + +|end_example| + +|pause| + +|column2| +|example<| |small| optimized |end_small| |>| + +.. sourcecode:: python + + ... + guard_not_invalidated() + ... + i3 = int_add(i1, 2) + ... + +|end_example| +|end_columns| +|end_scriptsize| + +|pause| + +* Python is too dynamic, but we don't care :-) + +* No overhead in assembler code + +* Used a bit "everywhere" + +* Credits to Mark Shannon + + - for the name :-) + +Guards +------- + +- guard_true + +- guard_false + +- guard_class + +- guard_no_overflow + +- **guard_value** + +Promotion +--------- + +- guard_value + +- specialize code + +- make sure not to **overspecialize** + +- example: type of objects + +- example: function code objects, ... + +Conclusion +----------- + +- PyPy is cool :-) + +- Any question? diff --git a/talk/ep2012/jit/talk/title.latex b/talk/pycon-uk-2012/talk/title.latex copy from talk/ep2012/jit/talk/title.latex copy to talk/pycon-uk-2012/talk/title.latex From noreply at buildbot.pypy.org Mon Oct 8 21:19:46 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 8 Oct 2012 21:19:46 +0200 (CEST) Subject: [pypy-commit] pypy py3k: kill fake space.w_long Message-ID: <20121008191946.03DD01C027A@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57941:9affd9aa93db Date: 2012-10-08 12:19 -0700 http://bitbucket.org/pypy/pypy/changeset/9affd9aa93db/ Log: kill fake space.w_long diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -303,7 +303,7 @@ def setup(): for name in (ObjSpace.ConstantTable + ObjSpace.ExceptionTable + - ['int', 'str', 'float', 'long', 'tuple', 'list', + ['int', 'str', 'float', 'tuple', 'list', 'dict', 'bytes', 'complex', 'slice', 'bool', 'text', 'object', 'unicode']): setattr(FakeObjSpace, 'w_' + name, w_some_obj()) From noreply at buildbot.pypy.org Mon Oct 8 21:55:53 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 8 Oct 2012 21:55:53 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fix translation Message-ID: <20121008195553.C55C41C0F69@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57942:9866289a5a77 Date: 2012-10-08 12:55 -0700 http://bitbucket.org/pypy/pypy/changeset/9866289a5a77/ Log: fix translation diff --git a/pypy/module/select/interp_kqueue.py b/pypy/module/select/interp_kqueue.py --- a/pypy/module/select/interp_kqueue.py +++ b/pypy/module/select/interp_kqueue.py @@ -242,10 +242,7 @@ @unwrap_spec(filter=int, flags='c_uint', fflags='c_uint', data=int, udata=r_uint) def descr__init__(self, space, w_ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=r_uint(0)): - if space.isinstance_w(w_ident, space.w_long): - ident = space.uint_w(w_ident) - else: - ident = r_uint(space.c_filedescriptor_w(w_ident)) + ident = r_uint(space.c_filedescriptor_w(w_ident)) self.event = lltype.malloc(kevent, flavor="raw") rffi.setintfield(self.event, "c_ident", ident) From noreply at buildbot.pypy.org Mon Oct 8 21:55:55 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 8 Oct 2012 21:55:55 +0200 (CEST) Subject: [pypy-commit] pypy py3k: py3 syntax/changes Message-ID: <20121008195555.0B1B21C0F69@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57943:82b3f1364940 Date: 2012-10-08 12:55 -0700 http://bitbucket.org/pypy/pypy/changeset/82b3f1364940/ Log: py3 syntax/changes diff --git a/pypy/module/select/test/test_kqueue.py b/pypy/module/select/test/test_kqueue.py --- a/pypy/module/select/test/test_kqueue.py +++ b/pypy/module/select/test/test_kqueue.py @@ -26,6 +26,7 @@ def test_create_event(self): import select import sys + from operator import lt, le, gt, ge fd = sys.stderr.fileno() ev = select.kevent(fd) @@ -38,12 +39,12 @@ assert ev.udata == 0 assert ev == ev assert ev != other - assert cmp(ev, other) == -1 assert ev < other assert other >= ev - raises(TypeError, cmp, ev, None) - raises(TypeError, cmp, ev, 1) - raises(TypeError, cmp, ev, "ev") + for op in lt, le, gt, ge: + raises(TypeError, op, ev, None) + raises(TypeError, op, ev, 1) + raises(TypeError, op, ev, "ev") ev = select.kevent(fd, select.KQ_FILTER_WRITE) assert ev.ident == fd @@ -100,7 +101,7 @@ client.setblocking(False) try: client.connect(("127.0.0.1", server_socket.getsockname()[1])) - except socket.error, e: + except socket.error as e: if 'bsd' in sys.platform: assert e.args[0] == errno.ENOENT else: @@ -131,10 +132,10 @@ (client.fileno(), select.KQ_FILTER_WRITE, flags), (server.fileno(), select.KQ_FILTER_WRITE, flags), ] - client.send("Hello!") - server.send("world!!!") + client.send(b"Hello!") + server.send(b"world!!!") - for i in xrange(10): + for i in range(10): events = kq1.control(None, 4, 1) if len(events) == 4: break @@ -176,14 +177,14 @@ kq = select.kqueue() a, b = socket.socketpair() - a.send('foo') + a.send(b'foo') event1 = select.kevent(a, select.KQ_FILTER_READ, select.KQ_EV_ADD | select.KQ_EV_ENABLE) event2 = select.kevent(b, select.KQ_FILTER_READ, select.KQ_EV_ADD | select.KQ_EV_ENABLE) r = kq.control([event1, event2], 1, 1) assert r assert r[0].flags & select.KQ_EV_ERROR == 0 data = b.recv(r[0].data) - assert data == 'foo' + assert data == b'foo' a.close() b.close() From noreply at buildbot.pypy.org Tue Oct 9 00:56:24 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 9 Oct 2012 00:56:24 +0200 (CEST) Subject: [pypy-commit] pypy py3k: test range's handling of __index__, __int__ is no longer supported Message-ID: <20121008225624.09B051C0F61@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57944:55199747a938 Date: 2012-10-08 15:48 -0700 http://bitbucket.org/pypy/pypy/changeset/55199747a938/ Log: test range's handling of __index__, __int__ is no longer supported diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py --- a/pypy/module/__builtin__/test/test_functional.py +++ b/pypy/module/__builtin__/test/test_functional.py @@ -121,15 +121,20 @@ # test again, to make sure that range() is not its own iterator assert iter(x).__next__() == 2 - def test_range_object_with___int__(self): + def test_range_object_with___index__(self): class A(object): - def __int__(self): + def __index__(self): return 5 assert list(range(A())) == [0, 1, 2, 3, 4] assert list(range(0, A())) == [0, 1, 2, 3, 4] assert list(range(0, 10, A())) == [0, 5] + class A2(object): + def __index__(self): + return 'quux' + raises(TypeError, range, A2()) + def test_range_float(self): raises(TypeError, "range(0.1, 2.0, 1.1)") From noreply at buildbot.pypy.org Tue Oct 9 00:56:25 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 9 Oct 2012 00:56:25 +0200 (CEST) Subject: [pypy-commit] pypy py3k: SSL_CTX_sess_* are macros Message-ID: <20121008225625.54DD21C0F61@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57945:c83d73431362 Date: 2012-10-08 15:56 -0700 http://bitbucket.org/pypy/pypy/changeset/c83d73431362/ Log: SSL_CTX_sess_* are macros diff --git a/pypy/rlib/ropenssl.py b/pypy/rlib/ropenssl.py --- a/pypy/rlib/ropenssl.py +++ b/pypy/rlib/ropenssl.py @@ -234,7 +234,7 @@ number connect connect_good connect_renegotiate accept accept_good accept_renegotiate hits misses timeouts cache_full""".split() SSL_CTX_STATS = unrolling_iterable( - (name, external('SSL_CTX_sess_' + name, [SSL_CTX], rffi.LONG)) + (name, external('SSL_CTX_sess_' + name, [SSL_CTX], rffi.LONG, macro=True)) for name in SSL_CTX_STATS_NAMES) ssl_external('SSL_new', [SSL_CTX], SSL) From noreply at buildbot.pypy.org Tue Oct 9 01:10:19 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 9 Oct 2012 01:10:19 +0200 (CEST) Subject: [pypy-commit] pypy py3k: _utf8 is no longer immutable Message-ID: <20121008231019.037431C027A@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57946:7f0ad93793c8 Date: 2012-10-08 16:10 -0700 http://bitbucket.org/pypy/pypy/changeset/7f0ad93793c8/ Log: _utf8 is no longer immutable diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -40,7 +40,7 @@ class W_UnicodeObject(W_AbstractUnicodeObject): from pypy.objspace.std.unicodetype import unicode_typedef as typedef - _immutable_fields_ = ['_value', '_utf8'] + _immutable_fields_ = ['_value'] def __init__(w_self, unistr): assert isinstance(unistr, unicode) From noreply at buildbot.pypy.org Tue Oct 9 11:20:37 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 11:20:37 +0200 (CEST) Subject: [pypy-commit] cffi default: Rename section Message-ID: <20121009092037.8CE681C01E6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r989:0b7103b87f18 Date: 2012-10-09 11:18 +0200 http://bitbucket.org/cffi/cffi/changeset/0b7103b87f18/ Log: Rename section diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -960,8 +960,8 @@ used only as a last-resort solution. -Miscellaneous -------------- +Misc methods on ffi +------------------- ``ffi.errno``: the value of ``errno`` received from the most recent C call in this thread, and passed to the following C call, is available via From noreply at buildbot.pypy.org Tue Oct 9 11:20:38 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 11:20:38 +0200 (CEST) Subject: [pypy-commit] cffi default: Keep the loaded libraries alive as long as the 'ffi' object is kept alive. Message-ID: <20121009092038.C03101C01E6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r990:a4f49af3db3c Date: 2012-10-09 11:18 +0200 http://bitbucket.org/cffi/cffi/changeset/a4f49af3db3c/ Log: Keep the loaded libraries alive as long as the 'ffi' object is kept alive. diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -50,6 +50,7 @@ self._parsed_types = types.ModuleType('parsed_types').__dict__ self._new_types = types.ModuleType('new_types').__dict__ self._function_caches = [] + self._libraries = [] self._cdefsources = [] self._pointer_type_cache = {} if hasattr(backend, 'set_ffi'): @@ -97,6 +98,7 @@ assert isinstance(name, str) or name is None lib, function_cache = _make_ffi_library(self, name, flags) self._function_caches.append(function_cache) + self._libraries.append(lib) return lib def _typeof(self, cdecl, consider_function_as_funcptr=False): @@ -281,7 +283,9 @@ from .verifier import Verifier, _caller_dir_pycache tmpdir = tmpdir or _caller_dir_pycache() self.verifier = Verifier(self, source, tmpdir, **kwargs) - return self.verifier.load_library() + lib = self.verifier.load_library() + self._libraries.append(lib) + return lib def _get_errno(self): return self._backend.get_errno() diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py --- a/cffi/vengine_cpy.py +++ b/cffi/vengine_cpy.py @@ -140,6 +140,7 @@ # pointers, and store them as attributes on the 'library' object. class FFILibrary(object): _cffi_python_module = module + _cffi_ffi = self.ffi library = FFILibrary() module._cffi_setup(lst, ffiplatform.VerificationError, library) # diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py --- a/cffi/vengine_gen.py +++ b/cffi/vengine_gen.py @@ -53,6 +53,7 @@ # build the FFILibrary class and instance class FFILibrary(object): _cffi_generic_module = module + _cffi_ffi = self.ffi library = FFILibrary() # # finally, call the loaded_gen_xxx() functions. This will set diff --git a/testing/test_ownlib.py b/testing/test_ownlib.py --- a/testing/test_ownlib.py +++ b/testing/test_ownlib.py @@ -1,5 +1,5 @@ import py, sys -import subprocess +import subprocess, weakref from cffi import FFI from cffi.backend_ctypes import CTypesBackend @@ -98,3 +98,40 @@ ownlib.my_array = list(range(7)) for i in range(7): assert ownlib.my_array[i] == i + + def test_keepalive_lib(self): + if sys.platform == 'win32': + py.test.skip("fix the auto-generation of the tiny test lib") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + int test_getting_errno(void); + """) + ownlib = ffi.dlopen(self.module) + ffi_r = weakref.ref(ffi) + ownlib_r = weakref.ref(ownlib) + func = ownlib.test_getting_errno + del ffi + import gc; gc.collect() # ownlib stays alive + assert ownlib_r() is not None + assert ffi_r() is not None # kept alive by ownlib + res = func() + assert res == -1 + + def test_keepalive_ffi(self): + if sys.platform == 'win32': + py.test.skip("fix the auto-generation of the tiny test lib") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + int test_getting_errno(void); + """) + ownlib = ffi.dlopen(self.module) + ffi_r = weakref.ref(ffi) + ownlib_r = weakref.ref(ownlib) + func = ownlib.test_getting_errno + del ownlib + import gc; gc.collect() # ffi stays alive + assert ffi_r() is not None + assert ownlib_r() is not None # kept alive by ffi + res = func() + assert res == -1 + assert ffi.errno == 123 diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1,5 +1,5 @@ import py -import sys, math +import sys, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model from testing.support import * @@ -1192,3 +1192,29 @@ g = subprocess.Popen([sys.executable, arg]) result = g.wait() assert result == 0 + +def test_keepalive_lib(): + ffi = FFI() + ffi.cdef("int foobar(void);") + lib = ffi.verify("int foobar(void) { return 42; }") + func = lib.foobar + ffi_r = weakref.ref(ffi) + lib_r = weakref.ref(lib) + del ffi + import gc; gc.collect() # lib stays alive + assert lib_r() is not None + assert ffi_r() is not None + assert func() == 42 + +def test_keepalive_ffi(): + ffi = FFI() + ffi.cdef("int foobar(void);") + lib = ffi.verify("int foobar(void) { return 42; }") + func = lib.foobar + ffi_r = weakref.ref(ffi) + lib_r = weakref.ref(lib) + del lib + import gc; gc.collect() # ffi stays alive + assert ffi_r() is not None + assert lib_r() is not None + assert func() == 42 From noreply at buildbot.pypy.org Tue Oct 9 11:20:39 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 11:20:39 +0200 (CEST) Subject: [pypy-commit] cffi default: merge heads Message-ID: <20121009092039.C638C1C01E6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r991:ec097c369113 Date: 2012-10-09 11:20 +0200 http://bitbucket.org/cffi/cffi/changeset/ec097c369113/ Log: merge heads diff --git a/demo/_curses.py b/demo/_curses.py --- a/demo/_curses.py +++ b/demo/_curses.py @@ -22,6 +22,11 @@ int setupterm(char *term, int fildes, int *errret); +int tigetflag(char *); +int tigetnum(char *); +char *tigetstr(char *); +char *tparm (char *, ...); + int cbreak(void); int nocbreak(void); int echo(void); @@ -205,8 +210,17 @@ initscr = Window +_setupterm_called = False -def setupterm(term=ffi.NULL, fd=-1): + +def _ensure_setupterm_called(): + if not _setupterm_called: + raise error("must call (at least) setupterm() first") + + +def setupterm(term=None, fd=-1): + if term is None: + term = ffi.NULL if fd < 0: import sys fd = sys.stdout.fileno() @@ -219,6 +233,33 @@ else: s = "setupterm: unknown error %d" % err[0] raise error(s) + global _setupterm_called + _setupterm_called = True + + +def tigetflag(capname): + _ensure_setupterm_called() + return lib.tigetflag(capname) + + +def tigetnum(capname): + _ensure_setupterm_called() + return lib.tigetnum(capname) + + +def tigetstr(capname): + _ensure_setupterm_called() + out = lib.tigetstr(capname) + if out == ffi.NULL: + return None + return ffi.string(out) + + +def tparm(name, *args): + _ensure_setupterm_called() + cargs = [ffi.cast("long", arg) for arg in args] + return ffi.string(lib.tparm(name, *cargs)) + def color_pair(n): return n << 8 From noreply at buildbot.pypy.org Tue Oct 9 11:37:57 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 11:37:57 +0200 (CEST) Subject: [pypy-commit] cffi default: Add dlerror() for windows. Message-ID: <20121009093757.97F921C0ACA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r992:7673342ae1c2 Date: 2012-10-09 11:37 +0200 http://bitbucket.org/cffi/cffi/changeset/7673342ae1c2/ Log: Add dlerror() for windows. diff --git a/c/misc_win32.h b/c/misc_win32.h --- a/c/misc_win32.h +++ b/c/misc_win32.h @@ -103,6 +103,16 @@ FreeLibrary((HMODULE)handle); } +static const char *dlerror(void) +{ + static char buf[32]; + DWORD dw = GetLastError(); + if (dw == 0) + return NULL; + sprintf(buf, "error 0x%x", (unsigned int)dw); + return buf; +} + /************************************************************/ /* obscure */ From noreply at buildbot.pypy.org Tue Oct 9 11:42:56 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 11:42:56 +0200 (CEST) Subject: [pypy-commit] cffi default: Improve test, for windows Message-ID: <20121009094256.B95391C0ACA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r993:d61a612737ec Date: 2012-10-09 11:42 +0200 http://bitbucket.org/cffi/cffi/changeset/d61a612737ec/ Log: Improve test, for windows diff --git a/testing/test_ffi_backend.py b/testing/test_ffi_backend.py --- a/testing/test_ffi_backend.py +++ b/testing/test_ffi_backend.py @@ -15,7 +15,7 @@ def test_not_supported_bitfield_in_result(self): ffi = FFI(backend=self.Backend()) - ffi.cdef("struct foo_s { int x:1; };") + ffi.cdef("struct foo_s { int a,b,c,d,e; int x:1; };") e = py.test.raises(NotImplementedError, ffi.callback, "struct foo_s foo(void)", lambda: 42) assert str(e.value) == (": " From noreply at buildbot.pypy.org Tue Oct 9 11:55:19 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 11:55:19 +0200 (CEST) Subject: [pypy-commit] cffi default: More Windows compat Message-ID: <20121009095519.369E41C0B7A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r994:2b9a8ee9b5b8 Date: 2012-10-09 11:55 +0200 http://bitbucket.org/cffi/cffi/changeset/2b9a8ee9b5b8/ Log: More Windows compat diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1074,7 +1074,7 @@ ffi.cdef("struct foo_s { _Bool x; };" "_Bool foo(_Bool);") lib = ffi.verify(""" - struct foo_s { _Bool x; }; + struct foo_s { char x; }; int foo(int arg) { return !arg; } @@ -1117,7 +1117,7 @@ ffi = FFI() ffi.cdef("long double square(long double f); _Bool opposite(_Bool);") lib = ffi.verify("long double square(long double f) { return f*f; }\n" - "_Bool opposite(_Bool x) { return !x; }") + "int opposite(int x) { return !x; }") f0 = lib.square(0.0) f2 = lib.square(f) f3 = lib.square(f * 2.0) From noreply at buildbot.pypy.org Tue Oct 9 12:00:21 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 12:00:21 +0200 (CEST) Subject: [pypy-commit] cffi default: Revert 2b9a8ee9b5b8. Skip the tests completely on Windows. Message-ID: <20121009100021.BDFD81C0B7A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r995:b1a6c00c5713 Date: 2012-10-09 12:00 +0200 http://bitbucket.org/cffi/cffi/changeset/b1a6c00c5713/ Log: Revert 2b9a8ee9b5b8. Skip the tests completely on Windows. diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1070,11 +1070,13 @@ """) def test_bool(): + if sys.platform == 'win32': + py.test.skip("_Bool not in MSVC") ffi = FFI() ffi.cdef("struct foo_s { _Bool x; };" "_Bool foo(_Bool);") lib = ffi.verify(""" - struct foo_s { char x; }; + struct foo_s { _Bool x; }; int foo(int arg) { return !arg; } @@ -1111,13 +1113,15 @@ py.test.raises(TypeError, ffi.cast, "_Bool", []) def test_bool_on_long_double(): + if sys.platform == 'win32': + py.test.skip("_Bool not in MSVC") f = 1E-250 if f == 0.0 or f*f != 0.0: py.test.skip("unexpected precision") ffi = FFI() ffi.cdef("long double square(long double f); _Bool opposite(_Bool);") lib = ffi.verify("long double square(long double f) { return f*f; }\n" - "int opposite(int x) { return !x; }") + "_Bool opposite(_Bool x) { return !x; }") f0 = lib.square(0.0) f2 = lib.square(f) f3 = lib.square(f * 2.0) From noreply at buildbot.pypy.org Tue Oct 9 12:52:44 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 12:52:44 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Reintroduce a way to report the malloc counters. Message-ID: <20121009105244.19A9D1C0ACA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57947:b4853aff2f42 Date: 2012-10-09 12:52 +0200 http://bitbucket.org/pypy/pypy/changeset/b4853aff2f42/ Log: Reintroduce a way to report the malloc counters. diff --git a/pypy/translator/c/src/main.h b/pypy/translator/c/src/main.h --- a/pypy/translator/c/src/main.h +++ b/pypy/translator/c/src/main.h @@ -68,6 +68,8 @@ pypy_debug_catch_fatal_exception(); } + pypy_malloc_counters_results(); + return exitcode; memory_out: diff --git a/pypy/translator/c/src/mem.h b/pypy/translator/c/src/mem.h --- a/pypy/translator/c/src/mem.h +++ b/pypy/translator/c/src/mem.h @@ -103,6 +103,7 @@ r = (restype) PyObject_Malloc(size); \ if (r != NULL) { \ memset((void*)r, 0, size); \ + COUNT_MALLOC; \ } \ } @@ -110,11 +111,14 @@ #define OP_RAW_MALLOC(size, r, restype) { \ r = (restype) PyObject_Malloc(size); \ + if (r != NULL) { \ + COUNT_MALLOC; \ + } \ } #endif -#define OP_RAW_FREE(p, r) PyObject_Free(p); +#define OP_RAW_FREE(p, r) PyObject_Free(p); COUNT_FREE; #define OP_RAW_MEMCLEAR(p, size, r) memset((void*)p, 0, size) @@ -135,6 +139,31 @@ #define OP_FREE(p) OP_RAW_FREE(p, do_not_use) +/*------------------------------------------------------------*/ +#ifndef COUNT_OP_MALLOCS +/*------------------------------------------------------------*/ + +#define COUNT_MALLOC /* nothing */ +#define COUNT_FREE /* nothing */ + +#define pypy_malloc_counters_results() /* nothing */ + +/*------------------------------------------------------------*/ +#else /*COUNT_OP_MALLOCS*/ +/*------------------------------------------------------------*/ + +static int count_mallocs=0, count_frees=0; + +#define COUNT_MALLOC count_mallocs++ +#define COUNT_FREE count_frees++ + +#define pypy_malloc_counters_results() \ + printf("MALLOC COUNTERS: %d %d\n", count_mallocs, count_frees) + +/*------------------------------------------------------------*/ +#endif /*COUNT_OP_MALLOCS*/ +/*------------------------------------------------------------*/ + /* for Boehm GC */ #ifdef USING_BOEHM_GC diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -71,6 +71,7 @@ policy=annotatorpolicy, thread=thread) if not backendopt: t.disable(["backendopt_lltype"]) + t.driver.config.translation.countmallocs = True t.annotate() t.compile_c() ll_res = graphof(t.context, fn).getreturnvar().concretetype @@ -79,15 +80,31 @@ t.view() except AttributeError: pass - def f(*args): + + def f(*args, **kwds): + if 'expected_extra_mallocs' in kwds: + expected_extra_mallocs = kwds.pop('expected_extra_mallocs') + else: + expected_extra_mallocs = 0 + assert not kwds assert len(args) == len(argtypes) for arg, argtype in zip(args, argtypes): assert isinstance(arg, argtype) stdout = t.driver.cbuilder.cmdexec(" ".join([llrepr(arg) for arg in args])) print stdout - assert stdout.endswith(' ;\n') + stdout, lastline, empty = stdout.rsplit('\n', 2) + assert empty == '' + assert lastline.startswith('MALLOC COUNTERS: ') + mallocs, frees = map(int, lastline.split()[2:]) + assert stdout.endswith(' ;') pos = stdout.rindex('THE RESULT IS: ') - res = stdout[pos + len('THE RESULT IS: '):-3] + res = stdout[pos + len('THE RESULT IS: '):-2] + # + if isinstance(expected_extra_mallocs, int): + assert mallocs - frees == expected_extra_mallocs + else: + assert mallocs - frees in expected_extra_mallocs + # if ll_res in [lltype.Signed, lltype.Unsigned, lltype.SignedLongLong, lltype.UnsignedLongLong]: return int(res) From noreply at buildbot.pypy.org Tue Oct 9 15:37:48 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 15:37:48 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fixes Message-ID: <20121009133748.3F16B1C0F7E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57948:9fb4be9f0458 Date: 2012-10-09 15:37 +0200 http://bitbucket.org/pypy/pypy/changeset/9fb4be9f0458/ Log: Fixes diff --git a/pypy/rpython/lltypesystem/test/test_rffi.py b/pypy/rpython/lltypesystem/test/test_rffi.py --- a/pypy/rpython/lltypesystem/test/test_rffi.py +++ b/pypy/rpython/lltypesystem/test/test_rffi.py @@ -113,7 +113,7 @@ return len(res) xf = self.compile(f, [], backendopt=False) - assert xf(expected_extra_mallocs=-1) == 3 + assert xf() == 3 def test_stringstar(self): c_source = """ @@ -503,7 +503,8 @@ try: for i in range(len(d)): raw_buf[i] = d[i] - return unicode_from_buffer(raw_buf, gc_buf, len(d), len(d)-1) + return (unicode_from_buffer(raw_buf, gc_buf, len(d), len(d)-1) + .encode('ascii')) finally: keep_unicodebuffer_alive_until_here(raw_buf, gc_buf) assert f() == d[:-1] From noreply at buildbot.pypy.org Tue Oct 9 16:08:02 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Tue, 9 Oct 2012 16:08:02 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: start the talk Message-ID: <20121009140802.122A81C0F7E@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4844:2ef0495805d7 Date: 2012-10-09 16:07 +0200 http://bitbucket.org/pypy/extradoc/changeset/2ef0495805d7/ Log: start the talk diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex new file mode 100644 --- /dev/null +++ b/talk/vmil2012/presentation/talk.tex @@ -0,0 +1,123 @@ +\documentclass[utf8x]{beamer} + +% This file is a solution template for: + +% - Talk at a conference/colloquium. +% - Talk length is about 20min. +% - Style is ornate. + +\mode +{ + \usetheme{Warsaw} + % or ... + + %\setbeamercovered{transparent} + % or whatever (possibly just delete it) +} + + +\usepackage[english]{babel} +\usepackage{listings} +\usepackage{ulem} +\usepackage{color} +\usepackage{alltt} + +\usepackage[utf8x]{inputenc} + + +\newcommand\redsout[1]{{\color{red}\sout{\hbox{\color{black}{#1}}}}} + +% or whatever + +% Or whatever. Note that the encoding and the font should match. If T1 +% does not look nice, try deleting the line with the fontenc. + + +\title{The Efficient Handling of Guards in the Design of RPython's Tracing JIT} + +\author[David Schneider, Carl Friedrich Bolz]{David Schneider \and \emph{Carl Friedrich Bolz}} +% - Give the names in the same order as the appear in the paper. +% - Use the \inst{?} command only if the authors have different +% affiliation. + +\institute[Heinrich-Heine-Universität Düsseldorf]{ +Heinrich-Heine-Universität Düsseldorf, STUPS Group, Germany +} + +\date{2012 VMIL, XXX} +% - Either use conference name or its abbreviation. +% - Not really informative to the audience, more for people (including +% yourself) who are reading the slides online + + +% If you have a file called "university-logo-filename.xxx", where xxx +% is a graphic format that can be processed by latex or pdflatex, +% resp., then you can add a logo as follows: + + + + +% Delete this, if you do not want the table of contents to pop up at +% the beginning of each subsection: +%\AtBeginSubsection[] +%{ +% \begin{frame} +% \frametitle{Outline} +% \tableofcontents[currentsection,currentsubsection] +% \end{frame} +%} + + +% If you wish to uncover everything in a step-wise fashion, uncomment +% the following command: + +%\beamerdefaultoverlayspecification{<+->} + + +\begin{document} + +\begin{frame} + \titlepage +\end{frame} + +% XXX todos: +% note that two fields is a simplification +% have a diagram for the example trace +% lifting can never produce new operations +% have some sort of overview or position indicator for the many graphical slides, too easy to get lost +% more details about benchmarks, diagram? + + +% Structuring a talk is a difficult task and the following structure +% may not be suitable. Here are some rules that apply for this +% solution: + +% - Exactly two or three sections (other than the summary). +% - At *most* three subsections per section. +% - Talk about 30s to 2min per frame. So there should be between about +% 15 and 30 frames, all told. + +% - A conference audience is likely to know very little of what you +% are going to talk about. So *simplify*! +% - In a 20min talk, getting the main ideas across is hard +% enough. Leave out details, even if it means being less precise than +% you think necessary. +% - If you omit details that are vital to the proof/implementation, +% just say so once. Everybody will be happy with that. + + +\begin{frame} + \frametitle{Tracing JITs Compile by Observing an Interpreter} + \begin{itemize} + \item VM contains both an interpreter and the tracing JIT compiler + \item JIT works by observing and logging what the interpreter does + \begin{itemize} + \item for interesting, commonly executed code paths + \item produces a linear list of operations (trace) + \end{itemize} + \item trace is optimized and then turned into machine code + \end{itemize} +\end{frame} + + +\end{document} From noreply at buildbot.pypy.org Tue Oct 9 16:17:09 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 16:17:09 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix test_lltyped. Message-ID: <20121009141709.BAA221C0F6D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57949:03fee088dd73 Date: 2012-10-09 16:16 +0200 http://bitbucket.org/pypy/pypy/changeset/03fee088dd73/ Log: Fix test_lltyped. diff --git a/pypy/rpython/tool/rffi_platform.py b/pypy/rpython/tool/rffi_platform.py --- a/pypy/rpython/tool/rffi_platform.py +++ b/pypy/rpython/tool/rffi_platform.py @@ -328,13 +328,14 @@ allfields = tuple(['c_' + name for name, _ in fields]) padfields = tuple(padfields) name = self.name - padding_drop = PaddingDrop(name, allfields, padfields, - config_result.CConfig._compilation_info_) + eci = config_result.CConfig._compilation_info_ + padding_drop = PaddingDrop(name, allfields, padfields, eci) hints = {'align': info['align'], 'size': info['size'], 'fieldoffsets': tuple(fieldoffsets), 'padding': padfields, - 'get_padding_drop': padding_drop} + 'get_padding_drop': padding_drop, + 'eci': eci} if name.startswith('struct '): name = name[7:] else: diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -191,6 +191,11 @@ eci = node.compilation_info() if eci: all.append(eci) + for node in self.db.getstructdeflist(): + try: + all.append(node.STRUCT._hints['eci']) + except (AttributeError, KeyError): + pass self.merge_eci(*all) def get_gcpolicyclass(self): diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -64,6 +64,9 @@ else: args += (a,) res = fn(*args) + if isinstance(res, float): + from pypy.rlib.rfloat import formatd, DTSF_ADD_DOT_0 + res = formatd(res, 'r', 0, DTSF_ADD_DOT_0) print "THE RESULT IS:", res, ";" return 0 diff --git a/pypy/translator/c/test/test_lltyped.py b/pypy/translator/c/test/test_lltyped.py --- a/pypy/translator/c/test/test_lltyped.py +++ b/pypy/translator/c/test/test_lltyped.py @@ -1,17 +1,19 @@ import py from pypy.rpython.lltypesystem.lltype import * -from pypy.translator.c.test import test_typed +from pypy.translator.c.test.test_genc import compile from pypy.tool.sourcetools import func_with_new_name -class TestLowLevelType(test_typed.CompilationTestCase): +class TestLowLevelType(object): + def getcompiled(self, func, argtypes): + return compile(func, argtypes, backendopt=False) def test_simple(self): S = GcStruct("s", ('v', Signed)) def llf(): s = malloc(S) return s.v - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() == 0 def test_simple2(self): @@ -22,7 +24,7 @@ s.a.v = 6 s.b.v = 12 return s.a.v + s.b.v - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() == 18 def test_fixedsizearray(self): @@ -49,7 +51,7 @@ assert a42[0][0] == -5 assert a42[5][6] == -6 return len(a42)*100 + len(a42[4]) - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) res = fn() assert fn() == 607 @@ -62,7 +64,7 @@ tree.root[0].a = tree.root tree.root[1].a = tree.other assert tree.root[0].a[0].a[0].a[0].a[0].a[1].a == tree.other - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_prebuilt_array(self): @@ -78,7 +80,7 @@ for i in range(5): s += chr(64+a[i]) assert s == "HELLO" - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_call_with_fixedsizearray(self): @@ -92,7 +94,7 @@ s = malloc(S) s.a = a return g(s.a) - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) res = fn() assert res == 123 @@ -218,7 +220,7 @@ s.y += 1 return p1[0] + p2[0] + p3[0] + p4[0] - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) res = fn() assert res == 8765 @@ -484,18 +486,12 @@ x = getmax(cls) res1 = OP(x, nn) result = result + (res1,) - return result - - def assert_eq(a, b): - # for better error messages when it fails - assert len(a) == len(b) - for i in range(len(a)): - assert a[i] == b[i] + return str(result) fn = self.getcompiled(f, [int]) res = fn(1) print res - assert_eq(res, ( + assert eval(res) == ( # int -sys.maxint, undefined, # add undefined, sys.maxint-1, # sub @@ -528,11 +524,11 @@ 0, 0, # mod 0, maxlonglong*2, # lshift 0, maxlonglong, # rshift - )) + ) res = fn(5) print res - assert_eq(res, ( + assert eval(res) == ( # int -sys.maxint+4, undefined, # add undefined, sys.maxint-5, # sub @@ -565,7 +561,7 @@ 0, (maxlonglong*2+1)%5, # mod 0, maxlonglong*2-30, # lshift 0, maxlonglong>>4, # rshift - )) + ) def test_direct_ptradd_barebone(self): from pypy.rpython.lltypesystem import rffi @@ -582,7 +578,7 @@ assert a2[i] == a[i + 2] free(a, flavor='raw') - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_r_singlefloat(self): @@ -617,7 +613,7 @@ a[2][5] = 888000 def llf(): return b[3][4] + a[2][5] - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() == 888999 def test_prebuilt_nolength_array(self): @@ -633,7 +629,7 @@ for i in range(5): s += chr(64+a[i]) assert s == "HELLO" - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_prebuilt_nolength_char_array(self): @@ -654,7 +650,7 @@ s += a[i] print s assert s == "85?!" + lastchar - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_prebuilt_raw_arrays(self): @@ -692,7 +688,7 @@ return i # returns the index of the failing function i += 1 return -42 - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) res = fn() assert res == -42, "failing function: %r" % (records[res],) @@ -714,7 +710,7 @@ s += a[i] return 'abcd' == s - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() def test_ll2ctypes_array_from_c(self): @@ -736,7 +732,7 @@ s += a[i] print s return s == 'abcd' - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() def test_cast_to_void_array(self): @@ -744,13 +740,13 @@ def llf(): TYPE = Ptr(rffi.CArray(Void)) y = rffi.cast(TYPE, 0) - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_llgroup(self): from pypy.rpython.lltypesystem.test import test_llgroup f = test_llgroup.build_test() - fn = self.getcompiled(f) + fn = self.getcompiled(f, []) res = fn() assert res == 42 @@ -868,6 +864,7 @@ ("l3", Signed)]) S = rffi_platform.configure(CConfig)['STRUCT'] assert 'get_padding_drop' in S._hints + assert 'eci' in S._hints s1 = malloc(S, immortal=True) s1.c_c1 = rffi.cast(S.c_c1, -12) s1.c_s1 = rffi.cast(S.c_s1, -7843) @@ -884,7 +881,6 @@ s = s2 return s.c_l3 # - self.include_also_eci = eci fn = self.getcompiled(f, [int]) res = fn(10) assert res == -98765432 @@ -901,7 +897,7 @@ render_immortal(a2) a2[0] = 3 return a1[0] + a2[0] - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() == 45 def test_rstring_to_float(self): From noreply at buildbot.pypy.org Tue Oct 9 16:31:49 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 16:31:49 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix test_backendoptimized. Message-ID: <20121009143149.8650D1C0F78@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57950:e890f20e3560 Date: 2012-10-09 16:31 +0200 http://bitbucket.org/pypy/pypy/changeset/e890f20e3560/ Log: Fix test_backendoptimized. diff --git a/pypy/translator/c/test/test_backendoptimized.py b/pypy/translator/c/test/test_backendoptimized.py --- a/pypy/translator/c/test/test_backendoptimized.py +++ b/pypy/translator/c/test/test_backendoptimized.py @@ -38,7 +38,7 @@ a = A() return b.num_deleted - fn = self.getcompiled(f, [int]) + fn = self.getcompiled(f, [int], gcpolicy='ref') res = f(5) assert res == 5 res = fn(5) @@ -70,7 +70,7 @@ return s.a_dels * 10 + s.b_dels else: return -1 - fn = self.getcompiled(f, [int]) + fn = self.getcompiled(f, [int], gcpolicy='ref') res = f(1) assert res == 42 res = fn(1) @@ -138,7 +138,7 @@ codegenerator = self.CodeGenerator() fn = codegenerator.getcompiled(f, [r_uint]) for x in (0,1,2,3,9,27,48): - assert fn(x) == f(x) + assert fn(r_uint(x)) == f(r_uint(x)) def test_longlong_switch(self): def f(x): @@ -152,7 +152,7 @@ codegenerator = self.CodeGenerator() fn = codegenerator.getcompiled(f, [r_longlong]) for x in (0,1,2,3,9,27,48, -9): - assert fn(x) == f(x) + assert fn(r_longlong(x)) == f(r_longlong(x)) def test_ulonglong_switch(self): def f(x): @@ -166,7 +166,7 @@ codegenerator = self.CodeGenerator() fn = codegenerator.getcompiled(f, [r_ulonglong]) for x in (0,1,2,3,9,27,48, r_ulonglong(-9)): - assert fn(x) == f(x) + assert fn(r_ulonglong(x)) == f(r_ulonglong(x)) def test_chr_switch(self): def f(y): diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -4,7 +4,8 @@ from pypy.rlib.entrypoint import entrypoint from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, intmask +from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint, intmask +from pypy.rlib.objectmodel import specialize from pypy.rpython.lltypesystem import lltype from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.lltypesystem.rstr import STR @@ -16,7 +17,7 @@ signed_ffffffff = r_longlong(0xffffffff) unsigned_ffffffff = r_ulonglong(0xffffffff) -def llrepr(v): +def llrepr_in(v): if isinstance(v, r_ulonglong): return "%d:%d" % (intmask(v >> 32), intmask(v & unsigned_ffffffff)) elif isinstance(v, r_longlong): @@ -25,6 +26,13 @@ return repr(v) # extra precision than str(v) return str(v) + at specialize.argtype(0) +def llrepr_out(v): + if isinstance(v, float): + from pypy.rlib.rfloat import formatd, DTSF_ADD_DOT_0 + return formatd(v, 'r', 0, DTSF_ADD_DOT_0) + return v + def parse_longlong(a): p0, p1 = a.split(":") return (r_longlong(int(p0)) << 32) + (r_longlong(int(p1)) & @@ -40,7 +48,8 @@ argtypes_unroll = unrolling_iterable(enumerate(argtypes)) for argtype in argtypes: - if argtype not in [int, float, str, bool, r_ulonglong, r_longlong]: + if argtype not in [int, float, str, bool, r_ulonglong, r_longlong, + r_uint]: raise Exception("Unsupported argtype, %r" % (argtype,)) def entry_point(argv): @@ -49,6 +58,8 @@ a = argv[i + 1] if argtype is int: args += (int(a),) + elif argtype is r_uint: + args += (r_uint(int(a)),) elif argtype is r_longlong: args += (parse_longlong(a),) elif argtype is r_ulonglong: @@ -64,10 +75,7 @@ else: args += (a,) res = fn(*args) - if isinstance(res, float): - from pypy.rlib.rfloat import formatd, DTSF_ADD_DOT_0 - res = formatd(res, 'r', 0, DTSF_ADD_DOT_0) - print "THE RESULT IS:", res, ";" + print "THE RESULT IS:", llrepr_out(res), ";" return 0 t = Translation(entry_point, None, gc=gcpolicy, backend="c", @@ -93,7 +101,7 @@ assert len(args) == len(argtypes) for arg, argtype in zip(args, argtypes): assert isinstance(arg, argtype) - stdout = t.driver.cbuilder.cmdexec(" ".join([llrepr(arg) for arg in args])) + stdout = t.driver.cbuilder.cmdexec(" ".join([llrepr_in(arg) for arg in args])) print stdout stdout, lastline, empty = stdout.rsplit('\n', 2) assert empty == '' From noreply at buildbot.pypy.org Tue Oct 9 16:45:14 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 9 Oct 2012 16:45:14 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix test_boehm Message-ID: <20121009144514.3D81C1C01E6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57951:bdd8dd9041a6 Date: 2012-10-09 16:44 +0200 http://bitbucket.org/pypy/pypy/changeset/bdd8dd9041a6/ Log: Fix test_boehm diff --git a/pypy/translator/c/test/test_boehm.py b/pypy/translator/c/test/test_boehm.py --- a/pypy/translator/c/test/test_boehm.py +++ b/pypy/translator/c/test/test_boehm.py @@ -119,17 +119,17 @@ a3, b3, c3 = run_once() a4, b4, c4 = run_once() a5, b5, c5 = run_once() - return (s.a_dels, s.b_dels, - a1, b1, c1, - a2, b2, c2, - a3, b3, c3, - a4, b4, c4, - a5, b5, c5) + return str((s.a_dels, s.b_dels, + a1, b1, c1, + a2, b2, c2, + a3, b3, c3, + a4, b4, c4, + a5, b5, c5)) fn = self.getcompiled(f, [int]) # we can't demand that boehm has collected all of the objects, # even with the gc__collect call. res = fn(50) - res1, res2 = res[:2] + res1, res2 = eval(res)[:2] # if res1 or res2 is still 0, then we haven't tested anything so fail. # it might be the test's fault though. print res1, res2 @@ -391,14 +391,15 @@ # def fn(): d2 = D() - return (compute_hash(d2), - current_object_addr_as_int(d2), - compute_hash(c), - compute_hash(d), - compute_hash(("Hi", None, (7.5, 2, d)))) + return str((compute_hash(d2), + current_object_addr_as_int(d2), + compute_hash(c), + compute_hash(d), + compute_hash(("Hi", None, (7.5, 2, d))))) f = self.getcompiled(fn) res = f() + res = eval(res) # xxx the next line is too precise, checking the exact implementation assert res[0] == ~res[1] From noreply at buildbot.pypy.org Tue Oct 9 16:45:33 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 9 Oct 2012 16:45:33 +0200 (CEST) Subject: [pypy-commit] pypy default: remove tabs Message-ID: <20121009144533.118D81C01E6@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r57952:95b2087b812f Date: 2012-10-09 16:20 +0200 http://bitbucket.org/pypy/pypy/changeset/95b2087b812f/ Log: remove tabs 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 @@ -1274,8 +1274,8 @@ @complex_unary_op def expm1(self, v): - #Duplicate exp() so in the future it will be easier - # to implement seterr + # duplicate exp() so in the future it will be easier + # to implement seterr if rfloat.isinf(v[1]): if rfloat.isinf(v[0]): if v[0] < 0: @@ -1286,8 +1286,8 @@ return rfloat.NAN, rfloat.NAN try: res = rcomplex.c_exp(*v) - res = (res[0]-1, res[1]) - return res + res = (res[0]-1, res[1]) + return res except OverflowError: if v[1] == 0: return rfloat.INFINITY, 0.0 From noreply at buildbot.pypy.org Tue Oct 9 16:45:34 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 9 Oct 2012 16:45:34 +0200 (CEST) Subject: [pypy-commit] pypy default: implement complex for compile, fix test_zjit Message-ID: <20121009144534.3E5751C01E6@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r57953:4c46bace2a1d Date: 2012-10-09 16:45 +0200 http://bitbucket.org/pypy/pypy/changeset/4c46bace2a1d/ Log: implement complex for compile, fix test_zjit 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 @@ -108,6 +108,9 @@ def newlist(self, items): return ListObject(items) + def newcomplex(self, r, i): + return ComplexObject(r, i) + def listview(self, obj): assert isinstance(obj, ListObject) return obj.items @@ -132,6 +135,11 @@ raise OperationError(self.w_TypeError, self.wrap("slice.")) raise NotImplementedError + def unpackcomplex(self, w_obj): + if isinstance(w_obj, ComplexObject): + return w_obj.r, w_obj.i + raise NotImplementedError + def index(self, w_obj): return self.wrap(self.int_w(w_obj)) @@ -227,6 +235,12 @@ def __init__(self, v): self.v = v +class ComplexObject(W_Root): + tp = FakeSpace.w_complex + def __init__(self, r, i): + self.r = r + self.i = i + class InterpreterState(object): def __init__(self, code): self.code = code @@ -344,6 +358,20 @@ def execute(self, interp): return interp.space.wrap(self.v) +class ComplexConstant(Node): + def __init__(self, r, i): + self.r = float(r) + self.i = float(i) + + def __repr__(self): + return 'ComplexConst(%s, %s)' % (self.r, self.i) + + def wrap(self, space): + return space.newcomplex(self.r, self.i) + + def execute(self, interp): + return self.wrap(interp.space) + class RangeConstant(Node): def __init__(self, v): self.v = int(v) @@ -374,8 +402,7 @@ def execute(self, interp): w_list = self.wrap(interp.space) - dtype = get_dtype_cache(interp.space).w_float64dtype - return array(interp.space, w_list, w_dtype=dtype, w_order=None) + return array(interp.space, w_list) def __repr__(self): return "[" + ", ".join([repr(item) for item in self.items]) + "]" @@ -608,6 +635,8 @@ stack.append(RangeConstant(tokens.pop().v)) end = tokens.pop() assert end.name == 'pipe' + elif token.name == 'paren_left': + stack.append(self.parse_complex_constant(tokens)) elif accept_comma and token.name == 'comma': continue else: @@ -631,6 +660,15 @@ args += self.parse_expression(tokens, accept_comma=True) return FunctionCall(name, args) + def parse_complex_constant(self, tokens): + r = tokens.pop() + assert r.name == 'number' + assert tokens.pop().name == 'comma' + i = tokens.pop() + assert i.name == 'number' + assert tokens.pop().name == 'paren_right' + return ComplexConstant(r.v, i.v) + def parse_array_const(self, tokens): elems = [] while True: @@ -639,6 +677,8 @@ elems.append(FloatConstant(token.v)) elif token.name == 'array_left': elems.append(ArrayConstant(self.parse_array_const(tokens))) + elif token.name == 'paren_left': + elems.append(self.parse_complex_constant(tokens)) else: raise BadToken() token = tokens.pop() diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py --- a/pypy/module/micronumpy/test/test_compile.py +++ b/pypy/module/micronumpy/test/test_compile.py @@ -281,3 +281,13 @@ d -> 1 ''') assert interp.results[0].value == 0 + + def test_complex(self): + interp = self.run(''' + a = (0, 1) + b = [(0, 1), (1, 0)] + b -> 0 + ''') + assert interp.results[0].real == 0 + assert interp.results[0].imag == 1 + 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 @@ -18,6 +18,7 @@ def setup_class(cls): default = """ a = [1,2,3,4] + z = (1, 2) c = a + b sum(c) -> 1::1 a -> 3:1:2 @@ -490,4 +491,3 @@ 'new_with_vtable': 1, 'int_add': 2, 'float_ne': 1}) - From noreply at buildbot.pypy.org Tue Oct 9 17:58:07 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 9 Oct 2012 17:58:07 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix test_error, a bit by improving error messages Message-ID: <20121009155807.70F1F1C0F80@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57954:01e86a93b033 Date: 2012-10-09 17:56 +0200 http://bitbucket.org/pypy/pypy/changeset/01e86a93b033/ Log: fix test_error, a bit by improving error messages diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -1,9 +1,8 @@ -import sys import types -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception +from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - format_someobject_error, AnnotatorError) + AnnotatorError, gather_error) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -38,7 +37,7 @@ self.links_followed = {} # set of links that have ever been followed self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: graph} + self.blocked_blocks = {} # set of {blocked_block: (graph, index)} # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks # --- end of debugging information --- @@ -341,7 +340,7 @@ self.flowin(graph, block) except BlockedInference, e: self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, e.opindex) except Exception, e: # hack for debug tools only if not hasattr(e, '__annotator_block'): @@ -360,7 +359,7 @@ self.pendingblocks[block] = graph assert block in self.annotated self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. @@ -368,7 +367,7 @@ for a, cell in zip(block.inputargs, inputcells): self.setbinding(a, cell) self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input @@ -397,7 +396,7 @@ for i in range(len(block.operations)): try: self.bookkeeper.enter((graph, block, i)) - self.consider_op(block.operations[i]) + self.consider_op(block, i) finally: self.bookkeeper.leave() @@ -573,7 +572,8 @@ #___ creating the annotations based on operations ______ - def consider_op(self, op): + def consider_op(self, block, opindex): + op = block.operations[opindex] argcells = [self.binding(a) for a in op.args] consider_meth = getattr(self,'consider_op_'+op.opname, None) @@ -588,16 +588,17 @@ # boom -- in the assert of setbinding() for arg in argcells: if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op) + raise BlockedInference(self, op, opindex) try: resultcell = consider_meth(*argcells) - except Exception: + except Exception, e: graph = self.bookkeeper.position_key[0] - raise_nicer_exception(op, str(graph)) + e.args = e.args + (gather_error(self, graph, block, opindex),) + raise if resultcell is None: resultcell = self.noreturnvalue(op) elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op) # the operation cannot succeed + raise BlockedInference(self, op, opindex) # the operation cannot succeed assert isinstance(resultcell, annmodel.SomeObject) assert isinstance(op.result, Variable) self.setbinding(op.result, resultcell) # bind resultcell to op.result @@ -648,13 +649,14 @@ """This exception signals the type inference engine that the situation is currently blocked, and that it should try to progress elsewhere.""" - def __init__(self, annotator, op): + def __init__(self, annotator, op, opindex): self.annotator = annotator try: self.break_at = annotator.bookkeeper.position_key except AttributeError: self.break_at = None self.op = op + self.opindex = opindex def __repr__(self): if not self.break_at: diff --git a/pypy/tool/ansi_print.py b/pypy/tool/ansi_print.py --- a/pypy/tool/ansi_print.py +++ b/pypy/tool/ansi_print.py @@ -72,23 +72,3 @@ file=self.file, newline=newline, flush=flush) ansi_log = AnsiLog() - -# ____________________________________________________________ -# Nice helper - -def raise_nicer_exception(*extraargs): - cls, e, tb = sys.exc_info() - str_e = str(e) - class ExcSubclass(cls): - def __str__(self): - lines = [str_e] - for extra in extraargs: - lines.append('\t.. %r' % (extra,)) - return '\n'.join(lines) - ExcSubclass.__name__ = cls.__name__ + "'" - ExcSubclass.__module__ = cls.__module__ - try: - e.__class__ = ExcSubclass - except TypeError: # doesn't work any more on 2.5 :-( - pass - raise ExcSubclass, e, tb diff --git a/pypy/tool/error.py b/pypy/tool/error.py --- a/pypy/tool/error.py +++ b/pypy/tool/error.py @@ -2,8 +2,8 @@ """ error handling features, just a way of displaying errors """ -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception -from pypy.objspace.flow.model import Constant, Variable +from pypy.tool.ansi_print import ansi_log +from pypy.objspace.flow.model import Variable import sys import py @@ -15,7 +15,6 @@ SHOW_DEFAULT_LINES_OF_CODE = 0 from pypy.interpreter.pytraceback import offset2lineno -import traceback def source_lines1(graph, block, operindex=None, offset=None, long=False, \ show_lines_of_code=SHOW_DEFAULT_LINES_OF_CODE): @@ -71,29 +70,16 @@ class NoSuchAttrError(Exception): pass -def gather_error(annotator, block, graph): - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +def gather_error(annotator, graph, block, operindex): msg = [""] - msg.append('-+' * 30) - from pypy.annotation import model - msg.append("Blocked block -- operation cannot succeed") - if model.DEBUG: - _, _, operindex = annotator.why_not_annotated[block][1].break_at - else: - # guess the blocked operation by the fact that its return value is - # not annotated - for operindex in range(len(block.operations)): - if block.operations[operindex].result not in annotator.bindings: - break - else: - operindex = None if operindex is not None: oper = block.operations[operindex] - msg.append(" " + str(oper)) + if oper.opname == 'simple_call': + format_simple_call(annotator, oper, msg) else: oper = None - msg.append(" (inconsistency - the block is fully annotated??)") + msg.append(" " + str(oper)) msg += source_lines(graph, block, operindex, long=True) if oper is not None: if SHOW_ANNOTATIONS: @@ -104,17 +90,17 @@ msg.append(" " + str(arg) + " = " + str(annotator.binding(arg))) except KeyError: pass - if model.DEBUG and SHOW_TRACEBACK: - msg.extend(traceback.format_exception(*annotator.why_not_annotated[block])) return "\n".join(msg) def format_blocked_annotation_error(annotator, blocked_blocks): text = [] - for block, graph in blocked_blocks.items(): - text.append(gather_error(annotator, block, graph)) + for block, (graph, index) in blocked_blocks.items(): + text.append('-+' * 30) + text.append("Blocked block -- operation cannot succeed") + text.append(gather_error(annotator, graph, block, index)) return '\n'.join(text) -def format_simple_call(annotator, oper, what, msg): +def format_simple_call(annotator, oper, msg): msg.append("Simple call of incompatible family:") try: descs = annotator.bindings[oper.args[0]].descriptions @@ -147,32 +133,6 @@ msg.append(" %s" % (r,)) msg.append("") -def format_someobject_error(annotator, position_key, what, s_value, called_from_graph, binding=""): - XXXXXXXXXXXXXXXXXXXXXX - #block = getattr(annotator, 'flowin_block', None) or block - msg = ["annotation of %r degenerated to SomeObject()" % (what,)] - if position_key is not None: - graph, block, operindex = position_key - if operindex is not None: - oper = block.operations[operindex] - if oper.opname == 'simple_call': - format_simple_call(annotator, oper, what, msg) - else: - msg.append(str(oper)) - else: - msg.append("at the start of the block with input arguments:") - for v in block.inputargs: - s_v = annotator.binding(v, "(no annotation)") - msg.append("%8s: %s" % (v, s_v)) - msg.append('') - msg += source_lines(graph, block, operindex, long=True) - - if called_from_graph is not None: - msg.append(".. called from %r" % (called_from_graph,)) - msg.append("Previous annotation:") - msg.append(" " + str(binding)) - return "\n".join(msg) - def debug(drv, use_pdb=True): # XXX unify some code with pypy.translator.goal.translate from pypy.translator.tool.pdbplus import PdbPlusShow diff --git a/pypy/tool/test/test_error.py b/pypy/tool/test/test_error.py --- a/pypy/tool/test/test_error.py +++ b/pypy/tool/test/test_error.py @@ -4,6 +4,7 @@ from pypy.translator.translator import TranslationContext from pypy.tool.error import AnnotatorError +from pypy.annotation.model import UnionError import py @@ -37,7 +38,7 @@ a = 9 return a - py.test.raises(AnnotatorError, compile_function, someobject_degeneration, [int]) + py.test.raises(UnionError, compile_function, someobject_degeneration, [int]) def test_someobject2(): def someobject_deg(n): @@ -47,12 +48,12 @@ return AAA() return a - py.test.raises(AnnotatorError, compile_function, someobject_deg, [int]) + py.test.raises(UnionError, compile_function, someobject_deg, [int]) def test_eval_someobject(): exec("def f(n):\n if n == 2:\n return 'a'\n else:\n return 3") - py.test.raises(AnnotatorError, compile_function, f, [int]) + py.test.raises(UnionError, compile_function, f, [int]) def test_someobject_from_call(): def one(x): @@ -70,6 +71,6 @@ try: compile_function(fn, [int]) - except AnnotatorError, e: - assert 'function one' in e.args[0] - assert 'function two' in e.args[0] + except UnionError, e: + assert 'function one' in e.args[2] + assert 'function two' in e.args[2] From noreply at buildbot.pypy.org Tue Oct 9 17:58:08 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 9 Oct 2012 17:58:08 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121009155808.B0C0E1C0F81@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57955:fd19fa683cfe Date: 2012-10-09 17:57 +0200 http://bitbucket.org/pypy/pypy/changeset/fd19fa683cfe/ Log: merge diff --git a/pypy/rpython/lltypesystem/test/test_rffi.py b/pypy/rpython/lltypesystem/test/test_rffi.py --- a/pypy/rpython/lltypesystem/test/test_rffi.py +++ b/pypy/rpython/lltypesystem/test/test_rffi.py @@ -113,7 +113,7 @@ return len(res) xf = self.compile(f, [], backendopt=False) - assert xf(expected_extra_mallocs=-1) == 3 + assert xf() == 3 def test_stringstar(self): c_source = """ @@ -503,7 +503,8 @@ try: for i in range(len(d)): raw_buf[i] = d[i] - return unicode_from_buffer(raw_buf, gc_buf, len(d), len(d)-1) + return (unicode_from_buffer(raw_buf, gc_buf, len(d), len(d)-1) + .encode('ascii')) finally: keep_unicodebuffer_alive_until_here(raw_buf, gc_buf) assert f() == d[:-1] diff --git a/pypy/rpython/tool/rffi_platform.py b/pypy/rpython/tool/rffi_platform.py --- a/pypy/rpython/tool/rffi_platform.py +++ b/pypy/rpython/tool/rffi_platform.py @@ -328,13 +328,14 @@ allfields = tuple(['c_' + name for name, _ in fields]) padfields = tuple(padfields) name = self.name - padding_drop = PaddingDrop(name, allfields, padfields, - config_result.CConfig._compilation_info_) + eci = config_result.CConfig._compilation_info_ + padding_drop = PaddingDrop(name, allfields, padfields, eci) hints = {'align': info['align'], 'size': info['size'], 'fieldoffsets': tuple(fieldoffsets), 'padding': padfields, - 'get_padding_drop': padding_drop} + 'get_padding_drop': padding_drop, + 'eci': eci} if name.startswith('struct '): name = name[7:] else: diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -191,6 +191,11 @@ eci = node.compilation_info() if eci: all.append(eci) + for node in self.db.getstructdeflist(): + try: + all.append(node.STRUCT._hints['eci']) + except (AttributeError, KeyError): + pass self.merge_eci(*all) def get_gcpolicyclass(self): diff --git a/pypy/translator/c/src/main.h b/pypy/translator/c/src/main.h --- a/pypy/translator/c/src/main.h +++ b/pypy/translator/c/src/main.h @@ -68,6 +68,8 @@ pypy_debug_catch_fatal_exception(); } + pypy_malloc_counters_results(); + return exitcode; memory_out: diff --git a/pypy/translator/c/src/mem.h b/pypy/translator/c/src/mem.h --- a/pypy/translator/c/src/mem.h +++ b/pypy/translator/c/src/mem.h @@ -103,6 +103,7 @@ r = (restype) PyObject_Malloc(size); \ if (r != NULL) { \ memset((void*)r, 0, size); \ + COUNT_MALLOC; \ } \ } @@ -110,11 +111,14 @@ #define OP_RAW_MALLOC(size, r, restype) { \ r = (restype) PyObject_Malloc(size); \ + if (r != NULL) { \ + COUNT_MALLOC; \ + } \ } #endif -#define OP_RAW_FREE(p, r) PyObject_Free(p); +#define OP_RAW_FREE(p, r) PyObject_Free(p); COUNT_FREE; #define OP_RAW_MEMCLEAR(p, size, r) memset((void*)p, 0, size) @@ -135,6 +139,31 @@ #define OP_FREE(p) OP_RAW_FREE(p, do_not_use) +/*------------------------------------------------------------*/ +#ifndef COUNT_OP_MALLOCS +/*------------------------------------------------------------*/ + +#define COUNT_MALLOC /* nothing */ +#define COUNT_FREE /* nothing */ + +#define pypy_malloc_counters_results() /* nothing */ + +/*------------------------------------------------------------*/ +#else /*COUNT_OP_MALLOCS*/ +/*------------------------------------------------------------*/ + +static int count_mallocs=0, count_frees=0; + +#define COUNT_MALLOC count_mallocs++ +#define COUNT_FREE count_frees++ + +#define pypy_malloc_counters_results() \ + printf("MALLOC COUNTERS: %d %d\n", count_mallocs, count_frees) + +/*------------------------------------------------------------*/ +#endif /*COUNT_OP_MALLOCS*/ +/*------------------------------------------------------------*/ + /* for Boehm GC */ #ifdef USING_BOEHM_GC diff --git a/pypy/translator/c/test/test_backendoptimized.py b/pypy/translator/c/test/test_backendoptimized.py --- a/pypy/translator/c/test/test_backendoptimized.py +++ b/pypy/translator/c/test/test_backendoptimized.py @@ -38,7 +38,7 @@ a = A() return b.num_deleted - fn = self.getcompiled(f, [int]) + fn = self.getcompiled(f, [int], gcpolicy='ref') res = f(5) assert res == 5 res = fn(5) @@ -70,7 +70,7 @@ return s.a_dels * 10 + s.b_dels else: return -1 - fn = self.getcompiled(f, [int]) + fn = self.getcompiled(f, [int], gcpolicy='ref') res = f(1) assert res == 42 res = fn(1) @@ -138,7 +138,7 @@ codegenerator = self.CodeGenerator() fn = codegenerator.getcompiled(f, [r_uint]) for x in (0,1,2,3,9,27,48): - assert fn(x) == f(x) + assert fn(r_uint(x)) == f(r_uint(x)) def test_longlong_switch(self): def f(x): @@ -152,7 +152,7 @@ codegenerator = self.CodeGenerator() fn = codegenerator.getcompiled(f, [r_longlong]) for x in (0,1,2,3,9,27,48, -9): - assert fn(x) == f(x) + assert fn(r_longlong(x)) == f(r_longlong(x)) def test_ulonglong_switch(self): def f(x): @@ -166,7 +166,7 @@ codegenerator = self.CodeGenerator() fn = codegenerator.getcompiled(f, [r_ulonglong]) for x in (0,1,2,3,9,27,48, r_ulonglong(-9)): - assert fn(x) == f(x) + assert fn(r_ulonglong(x)) == f(r_ulonglong(x)) def test_chr_switch(self): def f(y): diff --git a/pypy/translator/c/test/test_boehm.py b/pypy/translator/c/test/test_boehm.py --- a/pypy/translator/c/test/test_boehm.py +++ b/pypy/translator/c/test/test_boehm.py @@ -119,17 +119,17 @@ a3, b3, c3 = run_once() a4, b4, c4 = run_once() a5, b5, c5 = run_once() - return (s.a_dels, s.b_dels, - a1, b1, c1, - a2, b2, c2, - a3, b3, c3, - a4, b4, c4, - a5, b5, c5) + return str((s.a_dels, s.b_dels, + a1, b1, c1, + a2, b2, c2, + a3, b3, c3, + a4, b4, c4, + a5, b5, c5)) fn = self.getcompiled(f, [int]) # we can't demand that boehm has collected all of the objects, # even with the gc__collect call. res = fn(50) - res1, res2 = res[:2] + res1, res2 = eval(res)[:2] # if res1 or res2 is still 0, then we haven't tested anything so fail. # it might be the test's fault though. print res1, res2 @@ -391,14 +391,15 @@ # def fn(): d2 = D() - return (compute_hash(d2), - current_object_addr_as_int(d2), - compute_hash(c), - compute_hash(d), - compute_hash(("Hi", None, (7.5, 2, d)))) + return str((compute_hash(d2), + current_object_addr_as_int(d2), + compute_hash(c), + compute_hash(d), + compute_hash(("Hi", None, (7.5, 2, d))))) f = self.getcompiled(fn) res = f() + res = eval(res) # xxx the next line is too precise, checking the exact implementation assert res[0] == ~res[1] diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -4,7 +4,8 @@ from pypy.rlib.entrypoint import entrypoint from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, intmask +from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint, intmask +from pypy.rlib.objectmodel import specialize from pypy.rpython.lltypesystem import lltype from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.lltypesystem.rstr import STR @@ -16,7 +17,7 @@ signed_ffffffff = r_longlong(0xffffffff) unsigned_ffffffff = r_ulonglong(0xffffffff) -def llrepr(v): +def llrepr_in(v): if isinstance(v, r_ulonglong): return "%d:%d" % (intmask(v >> 32), intmask(v & unsigned_ffffffff)) elif isinstance(v, r_longlong): @@ -25,6 +26,13 @@ return repr(v) # extra precision than str(v) return str(v) + at specialize.argtype(0) +def llrepr_out(v): + if isinstance(v, float): + from pypy.rlib.rfloat import formatd, DTSF_ADD_DOT_0 + return formatd(v, 'r', 0, DTSF_ADD_DOT_0) + return v + def parse_longlong(a): p0, p1 = a.split(":") return (r_longlong(int(p0)) << 32) + (r_longlong(int(p1)) & @@ -40,7 +48,8 @@ argtypes_unroll = unrolling_iterable(enumerate(argtypes)) for argtype in argtypes: - if argtype not in [int, float, str, bool, r_ulonglong, r_longlong]: + if argtype not in [int, float, str, bool, r_ulonglong, r_longlong, + r_uint]: raise Exception("Unsupported argtype, %r" % (argtype,)) def entry_point(argv): @@ -49,6 +58,8 @@ a = argv[i + 1] if argtype is int: args += (int(a),) + elif argtype is r_uint: + args += (r_uint(int(a)),) elif argtype is r_longlong: args += (parse_longlong(a),) elif argtype is r_ulonglong: @@ -64,13 +75,14 @@ else: args += (a,) res = fn(*args) - print "THE RESULT IS:", res, ";" + print "THE RESULT IS:", llrepr_out(res), ";" return 0 t = Translation(entry_point, None, gc=gcpolicy, backend="c", policy=annotatorpolicy, thread=thread) if not backendopt: t.disable(["backendopt_lltype"]) + t.driver.config.translation.countmallocs = True t.annotate() t.compile_c() ll_res = graphof(t.context, fn).getreturnvar().concretetype @@ -79,15 +91,31 @@ t.view() except AttributeError: pass - def f(*args): + + def f(*args, **kwds): + if 'expected_extra_mallocs' in kwds: + expected_extra_mallocs = kwds.pop('expected_extra_mallocs') + else: + expected_extra_mallocs = 0 + assert not kwds assert len(args) == len(argtypes) for arg, argtype in zip(args, argtypes): assert isinstance(arg, argtype) - stdout = t.driver.cbuilder.cmdexec(" ".join([llrepr(arg) for arg in args])) + stdout = t.driver.cbuilder.cmdexec(" ".join([llrepr_in(arg) for arg in args])) print stdout - assert stdout.endswith(' ;\n') + stdout, lastline, empty = stdout.rsplit('\n', 2) + assert empty == '' + assert lastline.startswith('MALLOC COUNTERS: ') + mallocs, frees = map(int, lastline.split()[2:]) + assert stdout.endswith(' ;') pos = stdout.rindex('THE RESULT IS: ') - res = stdout[pos + len('THE RESULT IS: '):-3] + res = stdout[pos + len('THE RESULT IS: '):-2] + # + if isinstance(expected_extra_mallocs, int): + assert mallocs - frees == expected_extra_mallocs + else: + assert mallocs - frees in expected_extra_mallocs + # if ll_res in [lltype.Signed, lltype.Unsigned, lltype.SignedLongLong, lltype.UnsignedLongLong]: return int(res) diff --git a/pypy/translator/c/test/test_lltyped.py b/pypy/translator/c/test/test_lltyped.py --- a/pypy/translator/c/test/test_lltyped.py +++ b/pypy/translator/c/test/test_lltyped.py @@ -1,17 +1,19 @@ import py from pypy.rpython.lltypesystem.lltype import * -from pypy.translator.c.test import test_typed +from pypy.translator.c.test.test_genc import compile from pypy.tool.sourcetools import func_with_new_name -class TestLowLevelType(test_typed.CompilationTestCase): +class TestLowLevelType(object): + def getcompiled(self, func, argtypes): + return compile(func, argtypes, backendopt=False) def test_simple(self): S = GcStruct("s", ('v', Signed)) def llf(): s = malloc(S) return s.v - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() == 0 def test_simple2(self): @@ -22,7 +24,7 @@ s.a.v = 6 s.b.v = 12 return s.a.v + s.b.v - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() == 18 def test_fixedsizearray(self): @@ -49,7 +51,7 @@ assert a42[0][0] == -5 assert a42[5][6] == -6 return len(a42)*100 + len(a42[4]) - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) res = fn() assert fn() == 607 @@ -62,7 +64,7 @@ tree.root[0].a = tree.root tree.root[1].a = tree.other assert tree.root[0].a[0].a[0].a[0].a[0].a[1].a == tree.other - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_prebuilt_array(self): @@ -78,7 +80,7 @@ for i in range(5): s += chr(64+a[i]) assert s == "HELLO" - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_call_with_fixedsizearray(self): @@ -92,7 +94,7 @@ s = malloc(S) s.a = a return g(s.a) - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) res = fn() assert res == 123 @@ -218,7 +220,7 @@ s.y += 1 return p1[0] + p2[0] + p3[0] + p4[0] - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) res = fn() assert res == 8765 @@ -484,18 +486,12 @@ x = getmax(cls) res1 = OP(x, nn) result = result + (res1,) - return result - - def assert_eq(a, b): - # for better error messages when it fails - assert len(a) == len(b) - for i in range(len(a)): - assert a[i] == b[i] + return str(result) fn = self.getcompiled(f, [int]) res = fn(1) print res - assert_eq(res, ( + assert eval(res) == ( # int -sys.maxint, undefined, # add undefined, sys.maxint-1, # sub @@ -528,11 +524,11 @@ 0, 0, # mod 0, maxlonglong*2, # lshift 0, maxlonglong, # rshift - )) + ) res = fn(5) print res - assert_eq(res, ( + assert eval(res) == ( # int -sys.maxint+4, undefined, # add undefined, sys.maxint-5, # sub @@ -565,7 +561,7 @@ 0, (maxlonglong*2+1)%5, # mod 0, maxlonglong*2-30, # lshift 0, maxlonglong>>4, # rshift - )) + ) def test_direct_ptradd_barebone(self): from pypy.rpython.lltypesystem import rffi @@ -582,7 +578,7 @@ assert a2[i] == a[i + 2] free(a, flavor='raw') - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_r_singlefloat(self): @@ -617,7 +613,7 @@ a[2][5] = 888000 def llf(): return b[3][4] + a[2][5] - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() == 888999 def test_prebuilt_nolength_array(self): @@ -633,7 +629,7 @@ for i in range(5): s += chr(64+a[i]) assert s == "HELLO" - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_prebuilt_nolength_char_array(self): @@ -654,7 +650,7 @@ s += a[i] print s assert s == "85?!" + lastchar - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_prebuilt_raw_arrays(self): @@ -692,7 +688,7 @@ return i # returns the index of the failing function i += 1 return -42 - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) res = fn() assert res == -42, "failing function: %r" % (records[res],) @@ -714,7 +710,7 @@ s += a[i] return 'abcd' == s - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() def test_ll2ctypes_array_from_c(self): @@ -736,7 +732,7 @@ s += a[i] print s return s == 'abcd' - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() def test_cast_to_void_array(self): @@ -744,13 +740,13 @@ def llf(): TYPE = Ptr(rffi.CArray(Void)) y = rffi.cast(TYPE, 0) - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) fn() def test_llgroup(self): from pypy.rpython.lltypesystem.test import test_llgroup f = test_llgroup.build_test() - fn = self.getcompiled(f) + fn = self.getcompiled(f, []) res = fn() assert res == 42 @@ -868,6 +864,7 @@ ("l3", Signed)]) S = rffi_platform.configure(CConfig)['STRUCT'] assert 'get_padding_drop' in S._hints + assert 'eci' in S._hints s1 = malloc(S, immortal=True) s1.c_c1 = rffi.cast(S.c_c1, -12) s1.c_s1 = rffi.cast(S.c_s1, -7843) @@ -884,7 +881,6 @@ s = s2 return s.c_l3 # - self.include_also_eci = eci fn = self.getcompiled(f, [int]) res = fn(10) assert res == -98765432 @@ -901,7 +897,7 @@ render_immortal(a2) a2[0] = 3 return a1[0] + a2[0] - fn = self.getcompiled(llf) + fn = self.getcompiled(llf, []) assert fn() == 45 def test_rstring_to_float(self): From noreply at buildbot.pypy.org Tue Oct 9 22:11:53 2012 From: noreply at buildbot.pypy.org (hodgestar) Date: Tue, 9 Oct 2012 22:11:53 +0200 (CEST) Subject: [pypy-commit] pypy default: (jerith) Fix link to getting-started-dev in 'Further reading' sections of the archictecture documentation. Fixes issue 1280. Message-ID: <20121009201153.EEB1A1C002D@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: Changeset: r57956:5c65254c7298 Date: 2012-10-09 22:11 +0200 http://bitbucket.org/pypy/pypy/changeset/5c65254c7298/ Log: (jerith) Fix link to getting-started-dev in 'Further reading' sections of the archictecture documentation. Fixes issue 1280. diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -238,7 +238,7 @@ interpreter`_. .. _`documentation index`: index.html#project-documentation -.. _`getting-started`: getting-started.html +.. _`getting-started`: getting-started-dev.html .. _`PyPy's approach to virtual machine construction`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dls2006/pypy-vm-construction.pdf .. _`the translation document`: translation.html .. _`RPython toolchain`: translation.html From noreply at buildbot.pypy.org Tue Oct 9 22:15:01 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 9 Oct 2012 22:15:01 +0200 (CEST) Subject: [pypy-commit] pypy default: unused imports Message-ID: <20121009201501.123BF1C002D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r57957:36131c51ef8b Date: 2012-10-09 13:13 -0700 http://bitbucket.org/pypy/pypy/changeset/36131c51ef8b/ Log: unused imports diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -1,5 +1,4 @@ import operator -import sys from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.objspace.std import model, newformat @@ -13,7 +12,6 @@ isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd, DTSF_ADD_DOT_0, DTSF_STR_PRECISION) from pypy.rlib.rbigint import rbigint -from pypy.rlib.objectmodel import we_are_translated from pypy.rlib import rfloat from pypy.tool.sourcetools import func_with_new_name @@ -292,8 +290,6 @@ return space.wrap(_hash_float(space, w_value.floatval)) def _hash_float(space, v): - from pypy.objspace.std.longobject import hash__Long - if isnan(v): return 0 From noreply at buildbot.pypy.org Wed Oct 10 00:54:13 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 10 Oct 2012 00:54:13 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Simplify HostCode._initialize() Message-ID: <20121009225413.05EB91C01E6@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57958:6f2151c95eb7 Date: 2012-10-05 23:20 +0100 http://bitbucket.org/pypy/pypy/changeset/6f2151c95eb7/ Log: Simplify HostCode._initialize() * Use HostCode.formalargcount instead of recomputing it. * Flowspacify FSFrame.save_locals_stack(), .restore_locals_stack() and .init_cells() * Add test for the corner case of function arguments that are also cell variables diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -42,26 +42,18 @@ def _initialize(self): # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] + self._args_as_cellvars = {} if self.co_cellvars: - argcount = self.co_argcount - assert argcount >= 0 # annotator hint - if self.co_flags & CO_VARARGS: - argcount += 1 - if self.co_flags & CO_VARKEYWORDS: - argcount += 1 # Cell vars could shadow already-set arguments. # See comment in PyCode._initialize() argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] - for j in range(argcount): + for j in range(self.formalargcount): if cellname == argvars[j]: # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad self._args_as_cellvars[i] = j @classmethod diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -247,6 +247,21 @@ self.valuestackdepth = code.co_nlocals self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals) + def save_locals_stack(self): + return self.locals_stack_w[:self.valuestackdepth] + + def restore_locals_stack(self, items_w): + self.locals_stack_w[:len(items_w)] = items_w + self.init_cells() + self.dropvaluesuntil(len(items_w)) + + def init_cells(self): + if self.cells is None: + return + args_to_copy = self.pycode._args_as_cellvars + for cellnum, argnum in args_to_copy.iteritems(): + self.cells[cellnum].set(self.locals_stack_w[argnum]) + def getstate(self): # getfastscope() can return real None, for undefined locals data = self.save_locals_stack() diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1054,7 +1054,7 @@ with py.test.raises(FlowingError): self.codetest(f) - def test_cellvar(self): + def test_cellvar_store(self): def f(): x = 5 return x @@ -1063,6 +1063,18 @@ assert len(graph.startblock.exits) == 1 assert graph.startblock.exits[0].target == graph.returnblock + def test_arg_as_cellvar(self): + def f(x, y, z): + a, b, c = 1, 2, 3 + z = b + return z + lambda: (a, b, x, z) # make cell variables + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + assert not graph.startblock.operations + assert graph.startblock.exits[0].args[0].value == 2 + def test_lambda(self): def f(): g = lambda m, n: n*m From noreply at buildbot.pypy.org Wed Oct 10 02:56:23 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 10 Oct 2012 02:56:23 +0200 (CEST) Subject: [pypy-commit] pypy py3k: ensure __repr/str__ results are unicode Message-ID: <20121010005623.566ED1C0ECB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57959:0543550e6088 Date: 2012-10-09 11:24 -0700 http://bitbucket.org/pypy/pypy/changeset/0543550e6088/ Log: ensure __repr/str__ results are unicode diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -673,20 +673,12 @@ "unsupported operand type for %(targetname)s(): '%%s'", typename) w_result = space.get_and_call_function(w_impl, w_obj) + if space.isinstance_w(w_result, space.w_unicode): + return w_result - if space.is_true(space.isinstance(w_result, space.w_str)): - return w_result - try: - result = space.unicode_w(w_result) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - typename = space.type(w_result).getname(space) - msg = "%(specialname)s returned non-%(targetname)s (type '%%s')" - raise operationerrfmt(space.w_TypeError, msg, typename) - else: - # re-wrap the result as a real string - return space.wrap(result) + typename = space.type(w_result).getname(space) + msg = "%(specialname)s returned non-%(targetname)s (type '%%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) assert not hasattr(DescrOperation, %(targetname)r) DescrOperation.%(targetname)s = %(targetname)s del %(targetname)s diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py --- a/pypy/objspace/test/test_descroperation.py +++ b/pypy/objspace/test/test_descroperation.py @@ -300,6 +300,17 @@ assert x == 'àèì' assert type(x) is str + + def test_byte_results_unicode(self): + class A(object): + def __str__(self): + return b'foo' + def __repr__(self): + return b'bar' + + for operate in (str, repr): + raises(TypeError, operate, A()) + def test_missing_getattribute(self): class X(object): pass From noreply at buildbot.pypy.org Wed Oct 10 02:56:24 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 10 Oct 2012 02:56:24 +0200 (CEST) Subject: [pypy-commit] pypy py3k: simplify Message-ID: <20121010005624.8D2601C0ECB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57960:dae42652b387 Date: 2012-10-09 17:52 -0700 http://bitbucket.org/pypy/pypy/changeset/dae42652b387/ Log: simplify diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -288,15 +288,7 @@ return w_obj w_unicode_method = space.lookup(w_obj, "__str__") - if w_unicode_method is None: - return space.repr(w_obj) - - w_res = space.get_and_call_function(w_unicode_method, w_obj) - if not space.isinstance_w(w_res, space.w_unicode): - typename = space.type(w_res).getname(space) - msg = "__str__ returned non-string (type %s)" % typename - raise OperationError(space.w_TypeError, space.wrap(msg)) - return w_res + return space.repr(w_obj) if w_unicode_method is None else space.str(w_obj) def descr_new_(space, w_unicodetype, w_object=u'', w_encoding=None, w_errors=None): # NB. the default value of w_obj is really a *wrapped* empty string: From noreply at buildbot.pypy.org Wed Oct 10 02:56:25 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 10 Oct 2012 02:56:25 +0200 (CEST) Subject: [pypy-commit] pypy py3k: add mode to TextIOWrapper repr Message-ID: <20121010005625.B7F0E1C0ECB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57961:1c9014214660 Date: 2012-10-09 17:53 -0700 http://bitbucket.org/pypy/pypy/changeset/1c9014214660/ Log: add mode to TextIOWrapper repr diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -441,15 +441,18 @@ self._check_init(space) W_TextIOBase._check_closed(self, space, message) + def __w_attr_repr(self, space, name): + w_attr = space.findattr(self, space.wrap(name)) + if w_attr is None: + return space.wrap("") + return space.mod(space.wrap("%s=%%r " % name), w_attr) + def descr_repr(self, space): - w_name = space.findattr(self, space.wrap("name")) - if w_name is None: - w_name_str = space.wrap("") - else: - w_name_str = space.mod(space.wrap("name=%r "), w_name) - w_args = space.newtuple([w_name_str, self.w_encoding]) + w_args = space.newtuple([self.__w_attr_repr(space, 'name'), + self.__w_attr_repr(space, 'mode'), + self.w_encoding]) return space.mod( - space.wrap("<_io.TextIOWrapper %sencoding=%r>"), w_args + space.wrap("<_io.TextIOWrapper %s%sencoding=%r>"), w_args ) def isatty_w(self, space): diff --git a/pypy/module/_io/test/test_textio.py b/pypy/module/_io/test/test_textio.py --- a/pypy/module/_io/test/test_textio.py +++ b/pypy/module/_io/test/test_textio.py @@ -209,6 +209,10 @@ t = _io.TextIOWrapper(b, encoding="utf-8") b.name = "dummy" assert repr(t) == "<_io.TextIOWrapper name='dummy' encoding='utf-8'>" + t.mode = "r" + assert repr(t) == "<_io.TextIOWrapper name='dummy' mode='r' encoding='utf-8'>" + b.name = b"dummy" + assert repr(t) == "<_io.TextIOWrapper name=b'dummy' mode='r' encoding='utf-8'>" def test_rawio(self): # Issue #12591: TextIOWrapper must work with raw I/O objects, so From noreply at buildbot.pypy.org Wed Oct 10 02:56:27 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 10 Oct 2012 02:56:27 +0200 (CEST) Subject: [pypy-commit] pypy py3k: update ascii per runicode changes Message-ID: <20121010005627.026F01C0ECB@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57962:f3a3a83a6f7d Date: 2012-10-09 17:54 -0700 http://bitbucket.org/pypy/pypy/changeset/f3a3a83a6f7d/ Log: update ascii per runicode changes diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -5,10 +5,9 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import unwrap_spec -from pypy.rlib.runicode import UNICHR, str_decode_ascii, unicode_encode_ascii +from pypy.rlib import rfloat from pypy.rlib.rfloat import isnan, isinf, round_double -from pypy.rlib import rfloat -import __builtin__ +from pypy.rlib.runicode import UNICHR NoneNotWrapped = gateway.NoneNotWrapped def abs(space, w_val): @@ -22,12 +21,11 @@ object, but escape the non-ASCII characters in the string returned by repr() using \\x, \\u or \\U escapes. This generates a string similar to that returned by repr() in Python 2.""" - len_ = __builtin__.len + from pypy.objspace.std.unicodetype import decode_object, encode_object # repr is guaranteed to be unicode - repr = space.unicode_w(space.repr(w_obj)) - encoded = unicode_encode_ascii(repr, len_(repr), 'backslashreplace') - decoded = str_decode_ascii(encoded, len_(encoded), None, final=True)[0] - return space.wrap(decoded) + w_repr = space.repr(w_obj) + w_encoded = encode_object(space, w_repr, 'ascii', 'backslashreplace') + return decode_object(space, w_encoded, 'ascii', None) @unwrap_spec(code=int) def chr(space, code): From noreply at buildbot.pypy.org Wed Oct 10 09:27:27 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 09:27:27 +0200 (CEST) Subject: [pypy-commit] cffi default: Enum types are always 'int' so far. Detect overflows. Message-ID: <20121010072727.B9AD11C01E6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r996:edd85beeb288 Date: 2012-10-10 09:25 +0200 http://bitbucket.org/cffi/cffi/changeset/edd85beeb288/ Log: Enum types are always 'int' so far. Detect overflows. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -34,6 +34,7 @@ # define PyText_FromString PyUnicode_FromString # define PyText_FromStringAndSize PyUnicode_FromStringAndSize # define PyText_InternInPlace PyUnicode_InternInPlace +# define PyIntOrLong_Check PyLong_Check #else # define STR_OR_BYTES "str" # define PyText_Type PyString_Type @@ -45,6 +46,7 @@ # define PyText_FromString PyString_FromString # define PyText_FromStringAndSize PyString_FromStringAndSize # define PyText_InternInPlace PyString_InternInPlace +# define PyIntOrLong_Check(op) (PyInt_Check(op) || PyLong_Check(op)) #endif #if PY_MAJOR_VERSION >= 3 @@ -430,11 +432,7 @@ if (io == NULL) return -1; -#if PY_MAJOR_VERSION < 3 - if (PyInt_Check(io) || PyLong_Check(io)) { -#else - if (PyLong_Check(io)) { -#endif + if (PyIntOrLong_Check(io)) { res = _my_PyLong_AsLongLong(io); } else { @@ -487,11 +485,7 @@ if (io == NULL) return (unsigned PY_LONG_LONG)-1; -#if PY_MAJOR_VERSION < 3 - if (PyInt_Check(io) || PyLong_Check(io)) { -#else - if (PyLong_Check(io)) { -#endif + if (PyIntOrLong_Check(io)) { res = _my_PyLong_AsUnsignedLongLong(io, strict); } else { @@ -2335,11 +2329,7 @@ if (io == NULL) return -1; -#if PY_MAJOR_VERSION < 3 - if (PyInt_Check(io) || PyLong_Check(io) || PyFloat_Check(io)) { -#else - if (PyLong_Check(io) || PyFloat_Check(io)) { -#endif + if (PyIntOrLong_Check(io) || PyFloat_Check(io)) { res = _my_PyObject_AsBool(io); } else { @@ -3943,8 +3933,22 @@ if (dict1 == NULL) goto error; for (i=n; --i >= 0; ) { - if (PyDict_SetItem(dict1, PyTuple_GET_ITEM(enumerators, i), - PyTuple_GET_ITEM(enumvalues, i)) < 0) + PyObject *key = PyTuple_GET_ITEM(enumerators, i); + PyObject *value = PyTuple_GET_ITEM(enumvalues, i); + long lvalue; + if (!PyText_Check(key)) { + PyErr_SetString(PyExc_TypeError, + "enumerators must be a list of strings"); + goto error; + } + lvalue = PyLong_AsLong(value); + if ((lvalue == -1 && PyErr_Occurred()) || lvalue != (int)lvalue) { + PyErr_Format(PyExc_OverflowError, + "enum '%s' declaration for '%s' does not fit an int", + ename, PyText_AS_UTF8(key)); + goto error; + } + if (PyDict_SetItem(dict1, key, value) < 0) goto error; } diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1160,6 +1160,13 @@ e = py.test.raises(TypeError, newp, BStructPtr, [None]) assert "must be a str or int, not NoneType" in str(e.value) +def test_enum_overflow(): + for ovf in (sys.maxint+1, -sys.maxint-2, 2**31, -2**31-1): + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (5, ovf)) + assert str(e.value) == ( + "enum 'foo' declaration for 'b' does not fit an int") + def test_callback_returning_enum(): BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1084,6 +1084,11 @@ length 0, allocating a ``char[]`` of the correct size, and casting it to a struct pointer) +* Enum types are always ``int``. GCC supports enums containing + larger constants (``unsigned int``, or ``long long``) as an extension + to the C standard, but CFFI does not. Use + ``typedef my_enum;`` and then some ``#define foo ``. + .. versionadded:: 0.4 Now supported: the common GCC extension of anonymous nested structs/unions inside structs/unions. From noreply at buildbot.pypy.org Wed Oct 10 10:53:04 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 10:53:04 +0200 (CEST) Subject: [pypy-commit] buildbot default: reconfigure slaves and kill old unused target Message-ID: <20121010085304.4BCD11C0117@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r706:552456ffa2ed Date: 2012-10-10 10:52 +0200 http://bitbucket.org/pypy/buildbot/changeset/552456ffa2ed/ Log: reconfigure slaves and kill old unused target diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -231,7 +231,6 @@ JITWIN64 = "pypy-c-jit-win-x86-64" JITFREEBSD64 = 'pypy-c-jit-freebsd-7-x86-64' -JITONLYLINUX32 = "jitonly-own-linux-x86-32" JITBACKENDONLYLINUXARMEL = "jitbackendonly-own-linux-armel" JITBACKENDONLYLINUXARMELXDIST = "jitbackendonly-own-linux-armel-xdist" JITONLYLINUXPPC64 = "jitonly-own-linux-ppc-64" @@ -317,62 +316,48 @@ "locks": [TannitCPU.access('exclusive')], }, {"name": LINUX64, - "slavenames": ["tannit64"], + "slavenames": ["tannit64", "allegro64"], "builddir": LINUX64, "factory": pypyOwnTestFactory, "category": 'linux64', # this build needs 4 CPUs "locks": [TannitCPU.access('exclusive')], }, - {"name": LINUX64 + "2", - "slavenames": ["allegro64"], - "builddir": LINUX64 + "2", - "factory": pypyOwnTestFactory, - "category": 'linux64', - # no locks, this is not a tannit build - }, {"name": APPLVLLINUX32, - "slavenames": ["bigdogvm1", "tannit32"], + "slavenames": ["tannit32", "allegro32"], "builddir": APPLVLLINUX32, "factory": pypyTranslatedAppLevelTestFactory, 'category': 'linux32', "locks": [TannitCPU.access('counting')], }, {"name": APPLVLLINUX64, - "slavenames": ["tannit64"], + "slavenames": ["tannit64", "allegro64"], "builddir": APPLVLLINUX64, "factory": pypyTranslatedAppLevelTestFactory64, "category": "linux64", "locks": [TannitCPU.access('counting')], }, {"name": OJITLINUX32, - "slavenames": ["bigdogvm1", "tannit32"], + "slavenames": ["tannit32", "allegro32"], "builddir": OJITLINUX32, "factory": pypy_OjitTranslatedTestFactory, "category": 'linux32', "locks": [TannitCPU.access('counting')], }, {"name" : JITLINUX32, - "slavenames": ["bigdogvm1", "tannit32"], + "slavenames": ["tannit32", "allegro32"], 'builddir' : JITLINUX32, 'factory' : pypyJITTranslatedTestFactory, 'category' : 'linux32', "locks": [TannitCPU.access('counting')], }, {'name': JITLINUX64, - 'slavenames': ['tannit64'], + 'slavenames': ['tannit64', "allegro64"], 'builddir': JITLINUX64, 'factory': pypyJITTranslatedTestFactory64, 'category': 'linux64', "locks": [TannitCPU.access('counting')], }, - {"name": JITONLYLINUX32, - "slavenames": ["tannit32", "bigdogvm1"], - "builddir": JITONLYLINUX32, - "factory": pypyJitOnlyOwnTestFactory, - "category": 'linux32', - "locks": [TannitCPU.access('counting')], - }, {"name": JITBENCH, "slavenames": ["tannit32"], "builddir": JITBENCH, From noreply at buildbot.pypy.org Wed Oct 10 10:57:21 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 10:57:21 +0200 (CEST) Subject: [pypy-commit] buildbot default: oops, one missing Message-ID: <20121010085721.54BFB1C01CA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r707:8b5f1dc1dd1e Date: 2012-10-10 10:57 +0200 http://bitbucket.org/pypy/buildbot/changeset/8b5f1dc1dd1e/ Log: oops, one missing diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -308,7 +308,7 @@ 'builders': [ {"name": LINUX32, - "slavenames": ["bigdogvm1", "tannit32"], + "slavenames": ["tannit32", "allegro32"], "builddir": LINUX32, "factory": pypyOwnTestFactory, "category": 'linux32', From noreply at buildbot.pypy.org Wed Oct 10 11:01:17 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 11:01:17 +0200 (CEST) Subject: [pypy-commit] buildbot default: reorder and disable the lock for now Message-ID: <20121010090117.968E21C01CA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r708:f0489e4edd86 Date: 2012-10-10 11:00 +0200 http://bitbucket.org/pypy/buildbot/changeset/f0489e4edd86/ Log: reorder and disable the lock for now diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -308,55 +308,55 @@ 'builders': [ {"name": LINUX32, - "slavenames": ["tannit32", "allegro32"], + "slavenames": ["allegro32", "tannit32"], "builddir": LINUX32, "factory": pypyOwnTestFactory, "category": 'linux32', # this build needs 4 CPUs - "locks": [TannitCPU.access('exclusive')], + #"locks": [TannitCPU.access('exclusive')], }, {"name": LINUX64, - "slavenames": ["tannit64", "allegro64"], + "slavenames": ["allegro64", "tannit64"], "builddir": LINUX64, "factory": pypyOwnTestFactory, "category": 'linux64', # this build needs 4 CPUs - "locks": [TannitCPU.access('exclusive')], + #"locks": [TannitCPU.access('exclusive')], }, {"name": APPLVLLINUX32, - "slavenames": ["tannit32", "allegro32"], + "slavenames": ["allegro32", "tannit32"], "builddir": APPLVLLINUX32, "factory": pypyTranslatedAppLevelTestFactory, 'category': 'linux32', - "locks": [TannitCPU.access('counting')], + #"locks": [TannitCPU.access('counting')], }, {"name": APPLVLLINUX64, - "slavenames": ["tannit64", "allegro64"], + "slavenames": ["allegro64", "tannit64"], "builddir": APPLVLLINUX64, "factory": pypyTranslatedAppLevelTestFactory64, "category": "linux64", - "locks": [TannitCPU.access('counting')], + #"locks": [TannitCPU.access('counting')], }, {"name": OJITLINUX32, - "slavenames": ["tannit32", "allegro32"], + "slavenames": ["allegro32", "tannit32"], "builddir": OJITLINUX32, "factory": pypy_OjitTranslatedTestFactory, "category": 'linux32', - "locks": [TannitCPU.access('counting')], + #"locks": [TannitCPU.access('counting')], }, {"name" : JITLINUX32, - "slavenames": ["tannit32", "allegro32"], + "slavenames": ["allegro32", "tannit32"], 'builddir' : JITLINUX32, 'factory' : pypyJITTranslatedTestFactory, 'category' : 'linux32', - "locks": [TannitCPU.access('counting')], + #"locks": [TannitCPU.access('counting')], }, {'name': JITLINUX64, - 'slavenames': ['tannit64', "allegro64"], + 'slavenames': ["allegro64", 'tannit64'], 'builddir': JITLINUX64, 'factory': pypyJITTranslatedTestFactory64, 'category': 'linux64', - "locks": [TannitCPU.access('counting')], + #"locks": [TannitCPU.access('counting')], }, {"name": JITBENCH, "slavenames": ["tannit32"], From noreply at buildbot.pypy.org Wed Oct 10 11:09:13 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 11:09:13 +0200 (CEST) Subject: [pypy-commit] cffi default: Fixes for Python 3. Message-ID: <20121010090913.1083F1C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r997:69cddb87c25f Date: 2012-10-10 11:07 +0200 http://bitbucket.org/cffi/cffi/changeset/69cddb87c25f/ Log: Fixes for Python 3. diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1161,7 +1161,7 @@ assert "must be a str or int, not NoneType" in str(e.value) def test_enum_overflow(): - for ovf in (sys.maxint+1, -sys.maxint-2, 2**31, -2**31-1): + for ovf in (2**63, -2**63-1, 2**31, -2**31-1): e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), (5, ovf)) assert str(e.value) == ( @@ -2134,9 +2134,9 @@ py.test.raises(OverflowError, newp, BBoolP, 2) py.test.raises(OverflowError, newp, BBoolP, -1) BCharP = new_pointer_type(new_primitive_type("char")) - p = newp(BCharP, 'X') + p = newp(BCharP, b'X') q = cast(BBoolP, p) - assert q[0] == ord('X') + assert q[0] == ord(b'X') py.test.raises(TypeError, string, cast(BBool, False)) BDouble = new_primitive_type("double") assert int(cast(BBool, cast(BDouble, 0.1))) == 1 diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -71,7 +71,7 @@ csource = '\n'.join(csourcelines) try: ast = _get_parser().parse(csource) - except pycparser.c_parser.ParseError, e: + except pycparser.c_parser.ParseError as e: self.convert_pycparser_error(e, csource) return ast, macros diff --git a/cffi/model.py b/cffi/model.py --- a/cffi/model.py +++ b/cffi/model.py @@ -356,7 +356,7 @@ type(ffi._backend).__typecache = weakref.WeakValueDictionary() try: res = getattr(ffi._backend, funcname)(*args) - except NotImplementedError, e: + except NotImplementedError as e: raise NotImplementedError("%r: %s" % (srctype, e)) ffi._backend.__typecache[args] = res return res diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py --- a/cffi/vengine_cpy.py +++ b/cffi/vengine_cpy.py @@ -384,7 +384,7 @@ try: prnt(' { %s = &p->%s; (void)tmp; }' % ( ftype.get_c_name('(*tmp)', 'field %r'%fname), fname)) - except ffiplatform.VerificationError, e: + except ffiplatform.VerificationError as e: prnt(' /* %s */' % str(e)) # cannot verify it, ignore prnt('}') prnt('static PyObject *') diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py --- a/cffi/vengine_gen.py +++ b/cffi/vengine_gen.py @@ -207,7 +207,7 @@ try: prnt(' { %s = &p->%s; (void)tmp; }' % ( ftype.get_c_name('(*tmp)', 'field %r'%fname), fname)) - except ffiplatform.VerificationError, e: + except ffiplatform.VerificationError as e: prnt(' /* %s */' % str(e)) # cannot verify it, ignore prnt('}') self.export_symbols.append(layoutfuncname) diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -1266,7 +1266,8 @@ return a - b # assert cb(-100, -10) == -90 - assert cb(sys.maxint, -10) == 42 + sz = ffi.sizeof("long") + assert cb((1 << (sz*8-1)) - 1, -10) == 42 def test_unique_types(self): ffi1 = FFI(backend=self.Backend()) @@ -1400,15 +1401,18 @@ assert not isinstance(ffi.typeof("int"), ffi.CData) assert not isinstance(ffi.cast("int", 0), ffi.CType) assert not isinstance(ffi.new("int *"), ffi.CType) + + def test_CData_CType_2(self): + ffi = FFI(backend=self.Backend()) assert isinstance(ffi.typeof("int"), ffi.CType) def test_bool(self): ffi = FFI(backend=self.Backend()) assert int(ffi.cast("_Bool", 0.1)) == 1 assert int(ffi.cast("_Bool", -0.0)) == 0 - assert int(ffi.cast("_Bool", '\x02')) == 1 - assert int(ffi.cast("_Bool", '\x00')) == 0 - assert int(ffi.cast("_Bool", '\x80')) == 1 + assert int(ffi.cast("_Bool", b'\x02')) == 1 + assert int(ffi.cast("_Bool", b'\x00')) == 0 + assert int(ffi.cast("_Bool", b'\x80')) == 1 assert ffi.new("_Bool *", False)[0] == 0 assert ffi.new("_Bool *", 1)[0] == 1 py.test.raises(OverflowError, ffi.new, "_Bool *", 2) 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 @@ -35,6 +35,6 @@ assert count > 0, "timeout" assert seen == [(10, 10), (12, 15)] -print 'STARTING' +print('STARTING') _run_callback_in_thread() -print 'DONE' +print('DONE') diff --git a/testing/test_ctypes.py b/testing/test_ctypes.py --- a/testing/test_ctypes.py +++ b/testing/test_ctypes.py @@ -1,4 +1,4 @@ -import py +import py, sys from testing import backend_tests from cffi.backend_ctypes import CTypesBackend @@ -30,3 +30,8 @@ def test_nested_anonymous_union(self): py.test.skip("ctypes backend: not supported: nested anonymous union") + + def test_CData_CType_2(self): + if sys.version_info >= (3,): + py.test.skip("ctypes backend: not supported in Python 3: CType") + backend_tests.BackendTests.test_CData_CType_2(self) diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -986,12 +986,12 @@ p = ffi.new("struct foo_s *") assert ffi.sizeof(p[0]) == 3 * ffi.sizeof("int") # with alignment p.a = 1234567 - p.b = 'X' - p.c = 'Y' + p.b = b'X' + p.c = b'Y' assert p.a == 1234567 - assert p.b == 'X' - assert p.c == 'Y' - assert p.d == 'Y' + assert p.b == b'X' + assert p.c == b'Y' + assert p.d == b'Y' def test_nested_anonymous_struct_exact_error(): if sys.platform == 'win32': From noreply at buildbot.pypy.org Wed Oct 10 11:12:58 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 11:12:58 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: kill the ability to not pass arguments to translate Message-ID: <20121010091258.5291F1C002D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57963:f81dc995c1dc Date: 2012-10-09 18:23 +0200 http://bitbucket.org/pypy/pypy/changeset/f81dc995c1dc/ Log: kill the ability to not pass arguments to translate diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py --- a/pypy/config/test/test_config.py +++ b/pypy/config/test/test_config.py @@ -111,8 +111,8 @@ else: return 'foo' - t = Translation(f) - t.rtype([int]) + t = Translation(f, [int]) + t.rtype() block = t.context.graphs[0].startblock assert len(block.exits[0].target.operations) == 0 diff --git a/pypy/translator/interactive.py b/pypy/translator/interactive.py --- a/pypy/translator/interactive.py +++ b/pypy/translator/interactive.py @@ -17,11 +17,8 @@ self.entry_point = entry_point self.context = TranslationContext(config=self.config) - # hook into driver events - self.driver_setup = False - policy = kwds.pop('policy', None) - self.update_options(argtypes, kwds) + self.update_options(kwds) self.ensure_setup(argtypes, policy) # for t.view() to work just after construction graph = self.context.buildflowgraph(entry_point) @@ -35,28 +32,17 @@ def ensure_setup(self, argtypes=None, policy=None): standalone = argtypes is None - if not self.driver_setup: - if standalone: - assert argtypes is None - else: - if argtypes is None: - argtypes = [] - self.driver.setup(self.entry_point, argtypes, policy, - empty_translator=self.context) - self.ann_argtypes = argtypes - self.ann_policy = policy - self.driver_setup = True + if standalone: + assert argtypes is None else: - # check consistency - if standalone: - assert argtypes is None - assert self.ann_argtypes is None - elif argtypes is not None and argtypes != self.ann_argtypes: - raise Exception("inconsistent argtype supplied") - if policy is not None and policy != self.ann_policy: - raise Exception("inconsistent annotation polish supplied") + if argtypes is None: + argtypes = [] + self.driver.setup(self.entry_point, argtypes, policy, + empty_translator=self.context) + self.ann_argtypes = argtypes + self.ann_policy = policy - def update_options(self, argtypes, kwds): + def update_options(self, kwds): gc = kwds.pop('gc', None) if gc: self.config.translation.gc = gc @@ -64,11 +50,11 @@ def ensure_opt(self, name, value=None, fallback=None): if value is not None: - self.update_options(None, {name: value}) + self.update_options({name: value}) return value val = getattr(self.config.translation, name, None) if fallback is not None and val is None: - self.update_options(None, {name: fallback}) + self.update_options({name: fallback}) return fallback if val is not None: return val @@ -97,69 +83,69 @@ # backend independent - def annotate(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def annotate(self, **kwds): + self.update_options(kwds) return self.driver.annotate() # type system dependent - def rtype(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def rtype(self, **kwds): + self.update_options(kwds) ts = self.ensure_type_system() return getattr(self.driver, 'rtype_' + ts)() - def backendopt(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def backendopt(self, **kwds): + self.update_options(kwds) ts = self.ensure_type_system('lltype') return getattr(self.driver, 'backendopt_' + ts)() # backend depedent - def source(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def source(self, **kwds): + self.update_options(kwds) backend = self.ensure_backend() getattr(self.driver, 'source_' + backend)() - def source_c(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def source_c(self, **kwds): + self.update_options(kwds) self.ensure_backend('c') self.driver.source_c() - def source_cl(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def source_cl(self, **kwds): + self.update_options(kwds) self.ensure_backend('cl') self.driver.source_cl() - def compile(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def compile(self, **kwds): + self.update_options(kwds) backend = self.ensure_backend() getattr(self.driver, 'compile_' + backend)() return self.driver.c_entryp - def compile_c(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def compile_c(self, **kwds): + self.update_options(kwds) self.ensure_backend('c') self.driver.compile_c() return self.driver.c_entryp - def compile_cli(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def compile_cli(self, **kwds): + self.update_options(kwds) self.ensure_backend('cli') self.driver.compile_cli() return self.driver.c_entryp - def source_cli(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def source_cli(self, **kwds): + self.update_options(kwds) self.ensure_backend('cli') self.driver.source_cli() - def compile_jvm(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def compile_jvm(self, **kwds): + self.update_options(kwds) self.ensure_backend('jvm') self.driver.compile_jvm() return self.driver.c_entryp - def source_jvm(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) + def source_jvm(self, **kwds): + self.update_options(kwds) self.ensure_backend('jvm') self.driver.source_jvm() From noreply at buildbot.pypy.org Wed Oct 10 11:12:59 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 11:12:59 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix test_interactive Message-ID: <20121010091259.8A9C11C002D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57964:b55b47d177f4 Date: 2012-10-10 11:12 +0200 http://bitbucket.org/pypy/pypy/changeset/b55b47d177f4/ Log: fix test_interactive diff --git a/pypy/bin/translatorshell.py b/pypy/bin/translatorshell.py --- a/pypy/bin/translatorshell.py +++ b/pypy/bin/translatorshell.py @@ -8,10 +8,10 @@ Example: - t = Translation(func) + t = Translation(func, [int]) # pass the list of args types t.view() # control flow graph - t.annotate([int]) # pass the list of args types + t.annotate() t.view() # graph + annotations under the mouse t.rtype() # use low level operations diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -27,7 +27,7 @@ ``pypy/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: - >>> t = Translation(snippet.is_perfect_number) + >>> t = Translation(snippet.is_perfect_number, [int]) >>> t.view() After that, the graph viewer pops up, that lets you interactively inspect the @@ -40,7 +40,7 @@ We have a type annotator that can completely infer types for functions like ``is_perfect_number`` (as well as for much larger examples):: - >>> t.annotate([int]) + >>> t.annotate() >>> t.view() Move the mouse over variable names (in red) to see their inferred types. @@ -74,8 +74,8 @@ >>> def myfunc(a, b): return a+b ... - >>> t = Translation(myfunc) - >>> t.annotate([int, int]) + >>> t = Translation(myfunc, [int, int]) + >>> t.annotate() >>> f = t.compile_cli() # or compile_jvm() >>> f(4, 5) 9 diff --git a/pypy/translator/backendopt/test/test_escape.py b/pypy/translator/backendopt/test/test_escape.py --- a/pypy/translator/backendopt/test/test_escape.py +++ b/pypy/translator/backendopt/test/test_escape.py @@ -5,11 +5,9 @@ from pypy.rlib.objectmodel import instantiate from pypy import conftest -import py - def build_adi(function, types): - t = Translation(function) - t.rtype(types) + t = Translation(function, types) + t.rtype() if conftest.option.view: t.view() adi = AbstractDataFlowInterpreter(t.context) diff --git a/pypy/translator/c/test/test_symbolic.py b/pypy/translator/c/test/test_symbolic.py --- a/pypy/translator/c/test/test_symbolic.py +++ b/pypy/translator/c/test/test_symbolic.py @@ -4,8 +4,8 @@ from pypy.rlib.objectmodel import ComputedIntSymbolic def getcompiled(f, args): - t = Translation(f) - fn = t.compile_c(args) + t = Translation(f, args) + fn = t.compile_c() if conftest.option.view: t.view() return fn, t diff --git a/pypy/translator/test/test_interactive.py b/pypy/translator/test/test_interactive.py --- a/pypy/translator/test/test_interactive.py +++ b/pypy/translator/test/test_interactive.py @@ -10,20 +10,13 @@ assert t.context is t.driver.translator assert t.config is t.driver.config is t.context.config - s = t.annotate([int, int]) + s = t.annotate() assert s.knowntype == int t = Translation(f, [int, int]) s = t.annotate() assert s.knowntype == int - t = Translation(f) - s = t.annotate([int, int]) - assert s.knowntype == int - - t = Translation(f, [int, int]) - py.test.raises(Exception, "t.annotate([int, float])") - def test_simple_rtype(): @@ -31,17 +24,11 @@ return x+y t = Translation(f, [int, int]) - s = t.annotate() + t.annotate() t.rtype() assert 'rtype_lltype' in t.driver.done - t = Translation(f) - s = t.annotate([int, int]) - t.rtype() - - assert 'rtype_lltype' in t.driver.done - def test_simple_backendopt(): def f(x, y): return x,y @@ -51,17 +38,12 @@ assert 'backendopt_lltype' in t.driver.done - t = Translation(f, [int, int]) - t.backendopt() - - assert 'backendopt_lltype' in t.driver.done - def test_simple_source(): def f(x, y): return x,y - t = Translation(f, backend='c') - t.annotate([int, int]) + t = Translation(f, [int, int], backend='c') + t.annotate() t.source() assert 'source_c' in t.driver.done @@ -84,39 +66,18 @@ assert 'backendopt' not in t.driver.done def test_simple_compile_c(): + import ctypes + def f(x,y): return x+y t = Translation(f, [int, int]) t.source(backend='c') - t_f = t.compile() + t.compile() - res = t_f(2,3) - assert res == 5 - - t = Translation(f, [int, int]) - t_f = t.compile_c() - - res = t_f(2,3) - assert res == 5 - -def test_simple_compile_c_isolate(): - from pypy.tool import isolate - - def f(x,y): - return x+y - - t = Translation(f, [int, int]) - t.set_backend_extra_options(c_isolated=True) - t_f = t.compile() - - assert isinstance(t_f, isolate.IsolateInvoker) - - res = t_f(2,3) - assert res == 5 - - # cleanup - t_f.close_isolate() + dll = ctypes.CDLL(str(t.driver.c_entryp)) + f = dll.pypy_g_f + assert f(2, 3) == 5 def test_simple_rtype_with_type_system(): @@ -124,37 +85,32 @@ return x+y t = Translation(f, [int, int]) - s = t.annotate() t.rtype(type_system='lltype') assert 'rtype_lltype' in t.driver.done t = Translation(f, [int, int]) - s = t.annotate() t.rtype(type_system='ootype') assert 'rtype_ootype' in t.driver.done - t = Translation(f, type_system='ootype') - s = t.annotate([int, int]) + t = Translation(f, [int, int], type_system='ootype') t.rtype() assert 'rtype_ootype' in t.driver.done - t = Translation(f) - s = t.annotate([int, int]) + t = Translation(f, [int, int]) t.rtype(backend='cli') assert 'rtype_ootype' in t.driver.done - t = Translation(f, backend='cli', type_system='ootype') - s = t.annotate([int, int]) + t = Translation(f, [int, int], backend='cli', type_system='ootype') t.rtype() assert 'rtype_ootype' in t.driver.done - t = Translation(f, type_system='lltype') - s = t.annotate([int, int]) + t = Translation(f, [int, int], type_system='lltype') + t.annotate() py.test.raises(Exception, "t.rtype(backend='cli')") - t = Translation(f, backend='cli') - s = t.annotate([int, int]) + t = Translation(f, [int, int], backend='cli') + t.annotate() py.test.raises(Exception, "t.rtype(type_system='lltype')") From noreply at buildbot.pypy.org Wed Oct 10 11:20:58 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 11:20:58 +0200 (CEST) Subject: [pypy-commit] pypy default: Update from cffi. Message-ID: <20121010092058.8473A1C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r57965:565fa280208d Date: 2012-10-10 11:20 +0200 http://bitbucket.org/pypy/pypy/changeset/565fa280208d/ Log: Update from cffi. diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -248,7 +248,17 @@ raise OperationError(space.w_ValueError, space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] - enumvalues = [space.int_w(w) for w in enumvalues_w] + enumvalues = [] + try: + for w in enumvalues_w: + enumvalues.append(space.c_int_w(w)) + except OperationError, e: + if not e.match(space, space.w_OverflowError): + raise + i = len(enumvalues) + raise operationerrfmt(space.w_OverflowError, + "enum '%s' declaration for '%s' does not fit an int", + name, enumerators[i]) ctype = ctypeenum.W_CTypeEnum(space, name, enumerators, enumvalues) return ctype 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 @@ -1156,6 +1156,13 @@ e = py.test.raises(TypeError, newp, BStructPtr, [None]) assert "must be a str or int, not NoneType" in str(e.value) +def test_enum_overflow(): + for ovf in (2**63, -2**63-1, 2**31, -2**31-1): + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (5, ovf)) + assert str(e.value) == ( + "enum 'foo' declaration for 'b' does not fit an int") + def test_callback_returning_enum(): BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) @@ -2123,9 +2130,9 @@ py.test.raises(OverflowError, newp, BBoolP, 2) py.test.raises(OverflowError, newp, BBoolP, -1) BCharP = new_pointer_type(new_primitive_type("char")) - p = newp(BCharP, 'X') + p = newp(BCharP, b'X') q = cast(BBoolP, p) - assert q[0] == ord('X') + assert q[0] == ord(b'X') py.test.raises(TypeError, string, cast(BBool, False)) BDouble = new_primitive_type("double") assert int(cast(BBool, cast(BDouble, 0.1))) == 1 From noreply at buildbot.pypy.org Wed Oct 10 11:30:05 2012 From: noreply at buildbot.pypy.org (stefanor) Date: Wed, 10 Oct 2012 11:30:05 +0200 (CEST) Subject: [pypy-commit] pypy default: Spelling and grammatical errors spotted by lintian Message-ID: <20121010093005.CE79F1C081E@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r57966:188d16ca09be Date: 2012-10-10 11:28 +0200 http://bitbucket.org/pypy/pypy/changeset/188d16ca09be/ Log: Spelling and grammatical errors spotted by lintian diff --git a/py/_io/capture.py b/py/_io/capture.py --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -176,7 +176,7 @@ class StdCaptureFD(Capture): - """ This class allows to capture writes to FD1 and FD2 + """ This class allows capturing writes to FD1 and FD2 and may connect a NULL file to FD0 (and prevent reads from sys.stdin). If any of the 0,1,2 file descriptors is invalid it will not be captured. @@ -267,8 +267,8 @@ return l class StdCapture(Capture): - """ This class allows to capture writes to sys.stdout|stderr "in-memory" - and will raise errors on tries to read from sys.stdin. It only + """ This class allows capturing writes to sys.stdout|stderr "in-memory" + and will raise errors on read attempts from sys.stdin. It only modifies sys.stdout|stderr|stdin attributes and does not touch underlying File Descriptors (use StdCaptureFD for that). """ diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -2,9 +2,9 @@ """ Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME -Print a report for the static data informations contained in FILENAME +Print a report for the static data information contained in FILENAME -The static data informations are saved in the file staticdata.info when +The static data information is saved in the file staticdata.info when passing --dump_static_data_info to translate.py. Options: diff --git a/pypy/jit/backend/cli/methodfactory.py b/pypy/jit/backend/cli/methodfactory.py --- a/pypy/jit/backend/cli/methodfactory.py +++ b/pypy/jit/backend/cli/methodfactory.py @@ -27,7 +27,7 @@ return self.dynmeth.CreateDelegate(delegatetype, consts) -# the assemblyData singleton contains the informations about the +# the assemblyData singleton contains the information about the # assembly we are currently writing to class AssemblyData: assembly = None diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -97,7 +97,7 @@ 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 informations about it. + ``compiled_loop`` for more information about it. """ raise NotImplementedError diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -317,7 +317,7 @@ except BadVirtualState: raise InvalidLoop('The state of the optimizer at the end of ' + 'peeled loop is inconsistent with the ' + - 'VirtualState at the begining of the peeled ' + + 'VirtualState at the beginning of the peeled ' + 'loop') jumpop.initarglist(jumpargs) diff --git a/pypy/module/posix/app_posix.py b/pypy/module/posix/app_posix.py --- a/pypy/module/posix/app_posix.py +++ b/pypy/module/posix/app_posix.py @@ -198,7 +198,7 @@ def wait3(options): """ wait3(options) -> (pid, status, rusage) - Wait for completion of a child process and provides resource usage informations + Wait for completion of a child process and provides resource usage information """ from _pypy_wait import wait3 return wait3(options) @@ -206,7 +206,7 @@ def wait4(pid, options): """ wait4(pid, options) -> (pid, status, rusage) - Wait for completion of the child process "pid" and provides resource usage informations + Wait for completion of the child process "pid" and provides resource usage information """ from _pypy_wait import wait4 return wait4(pid, options) diff --git a/pypy/module/pypyjit/interp_resop.py b/pypy/module/pypyjit/interp_resop.py --- a/pypy/module/pypyjit/interp_resop.py +++ b/pypy/module/pypyjit/interp_resop.py @@ -63,7 +63,7 @@ """ set_optimize_hook(hook) Set a compiling hook that will be called each time a loop is optimized, - but before assembler compilation. This allows to add additional + but before assembler compilation. This allows adding additional optimizations on Python level. The hook will be called with the pypyjit.JitLoopInfo object. Refer to it's diff --git a/pypy/tool/bench/htmlreport.py b/pypy/tool/bench/htmlreport.py --- a/pypy/tool/bench/htmlreport.py +++ b/pypy/tool/bench/htmlreport.py @@ -226,7 +226,7 @@ ) def render_revision_header(self, sample): - """return a header for a report with informations about + """return a header for a report with information about committer, messages, revision date. """ revision_id = pyhtml.li('Revision ID: %s' % (sample.revision_id,)) diff --git a/pypy/tool/bench/result.py b/pypy/tool/bench/result.py --- a/pypy/tool/bench/result.py +++ b/pypy/tool/bench/result.py @@ -13,7 +13,7 @@ class PerfResultCollection(object): - """Holds informations about several PerfResult objects. The + """Holds information about several PerfResult objects. The objects should have the same test_id and revision_id""" def __init__(self, results=None): @@ -166,7 +166,7 @@ count = py.std.itertools.count() def annotate(self, result): """Try to put extra information for each revision on the - PerfResult objects. These informations are retrieved from a + PerfResult objects. These information are retrieved from a branch object. """ #if self.branch is None: diff --git a/pypy/tool/memusage/log2gnumeric.py b/pypy/tool/memusage/log2gnumeric.py --- a/pypy/tool/memusage/log2gnumeric.py +++ b/pypy/tool/memusage/log2gnumeric.py @@ -7,7 +7,7 @@ $ PYPYLOG=gc-collect,jit-mem:logfile pypy your-program.py -This will produce "logfile", containing informations about the memory used by +This will produce "logfile", containing information about the memory used by the GC and the number of loops created/freed by the JIT. If you want, you can also measure the amout of used memory as seen by the OS diff --git a/pypy/tool/sourcetools.py b/pypy/tool/sourcetools.py --- a/pypy/tool/sourcetools.py +++ b/pypy/tool/sourcetools.py @@ -120,7 +120,7 @@ # various helper functions # class MyStr(str): - """ custom string which allows to add attributes. """ + """ custom string which allows adding attributes. """ def newcode(fromcode, **kwargs): names = [x for x in dir(fromcode) if x[:3] == 'co_'] diff --git a/pypy/translator/goal/timing.py b/pypy/translator/goal/timing.py --- a/pypy/translator/goal/timing.py +++ b/pypy/translator/goal/timing.py @@ -1,5 +1,5 @@ -""" Module for keeping detailed informations about +""" Module for keeping detailed information about times of certain driver parts """ diff --git a/pypy/translator/microbench/pybench/platform.py b/pypy/translator/microbench/pybench/platform.py --- a/pypy/translator/microbench/pybench/platform.py +++ b/pypy/translator/microbench/pybench/platform.py @@ -811,7 +811,7 @@ split=re.compile('[\s,]').split): """ Queries the given executable (defaults to the Python interpreter - binary) for various architecture informations. + binary) for various architecture information. Returns a tuple (bits,linkage) which contain information about the bit architecture and the linkage format used for the diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py --- a/pypy/translator/platform/__init__.py +++ b/pypy/translator/platform/__init__.py @@ -215,7 +215,7 @@ largs = self._link_args_from_eci(eci, standalone) return self._link(cc_link, ofiles, largs, standalone, exe_name) - # below are some detailed informations for platforms + # below are some detailed information for platforms def include_dirs_for_libffi(self): dirs = self._include_dirs_for_libffi() diff --git a/pypy/translator/tool/staticsizereport.py b/pypy/translator/tool/staticsizereport.py --- a/pypy/translator/tool/staticsizereport.py +++ b/pypy/translator/tool/staticsizereport.py @@ -201,7 +201,7 @@ f = infofile.open('w') pickle.dump(info, f) f.close() - log.info('static data informations dumped to %s' % infofile) + log.info('static data information dumped to %s' % infofile) return infofile From noreply at buildbot.pypy.org Wed Oct 10 11:51:57 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 11:51:57 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix in test_extfunc: avoids the test runner getting killed with SIGUSR1. Message-ID: <20121010095157.DC8A11C0E82@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57967:cec6ccad68b1 Date: 2012-10-10 11:38 +0200 http://bitbucket.org/pypy/pypy/changeset/cec6ccad68b1/ Log: Fix in test_extfunc: avoids the test runner getting killed with SIGUSR1. diff --git a/pypy/translator/c/test/test_extfunc.py b/pypy/translator/c/test/test_extfunc.py --- a/pypy/translator/c/test/test_extfunc.py +++ b/pypy/translator/c/test/test_extfunc.py @@ -569,6 +569,7 @@ import signal from pypy.module.signal import interp_signal def does_stuff(): + os.setpgid(0, 0) # become its own separated process group interp_signal.pypysig_setflag(signal.SIGUSR1) os.killpg(os.getpgrp(), signal.SIGUSR1) interp_signal.pypysig_ignore(signal.SIGUSR1) From noreply at buildbot.pypy.org Wed Oct 10 11:51:59 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 11:51:59 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix test_exception. Adds a general way to expect fatal RPython errors. Message-ID: <20121010095159.289F41C0E82@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57968:b11c05a74ff1 Date: 2012-10-10 11:51 +0200 http://bitbucket.org/pypy/pypy/changeset/b11c05a74ff1/ Log: Fix test_exception. Adds a general way to expect fatal RPython errors. diff --git a/pypy/translator/c/test/test_exception.py b/pypy/translator/c/test/test_exception.py --- a/pypy/translator/c/test/test_exception.py +++ b/pypy/translator/c/test/test_exception.py @@ -62,23 +62,20 @@ return 5 else: return 2 - f1 = getcompiled(f) + f1 = getcompiled(f, []) assert f1() == 5 def test_raise_outside_testfn(): def testfn(n): if n < 0: raise ValueError("hello") + elif n > 0: + raise MyException("world") else: - raise MyException("world") + return 0 f1 = getcompiled(testfn, [int]) - assert py.test.raises(ValueError, f1, -1) - try: - f1(1) - except Exception, e: - assert str(e) == 'MyException' # which is genc's best effort - else: - py.test.fail("f1(1) did not raise anything") + f1(-1, expected_exception_name='ValueError') + f1(1, expected_exception_name='MyException') def test_memoryerror(): # in rev 30717 this test causes a segfault on some Linux, but usually @@ -113,7 +110,7 @@ assert f1(10) == 42 assert f1(sys.maxint) == 1000 for i in range(20): - assert f1((sys.maxint+1) // 2 - i) == 1000 + assert f1(int((sys.maxint+1) // 2 - i)) == 1000 assert f1(sys.maxint // 2 - 16384) == 1000 assert f1(sys.maxint // 2 + 16384) == 1000 @@ -126,11 +123,7 @@ assert res is None, repr(res) res = f1(42) assert res is None, repr(res) - e = py.test.raises(Exception, f1, -2) - assert e.type.__name__ == 'AssertionError' - # ^^^ indirection, because we really want - # the original AssertionError and not the - # one patched by the py lib + f1(-2, expected_exception_name='AssertionError') def test_reraise_exception(): diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -93,16 +93,24 @@ pass def f(*args, **kwds): - if 'expected_extra_mallocs' in kwds: - expected_extra_mallocs = kwds.pop('expected_extra_mallocs') - else: - expected_extra_mallocs = 0 + expected_extra_mallocs = kwds.pop('expected_extra_mallocs', 0) + expected_exception_name = kwds.pop('expected_exception_name', None) assert not kwds assert len(args) == len(argtypes) for arg, argtype in zip(args, argtypes): assert isinstance(arg, argtype) - stdout = t.driver.cbuilder.cmdexec(" ".join([llrepr_in(arg) for arg in args])) + + stdout = t.driver.cbuilder.cmdexec( + " ".join([llrepr_in(arg) for arg in args]), + expect_crash=(expected_exception_name is not None)) print stdout + if expected_exception_name is not None: + stdout, stderr = stdout + stderr, lastline, empty = stderr.rsplit('\n', 2) + assert empty == '' + assert lastline == ('Fatal RPython error: ' + + expected_exception_name) + return None stdout, lastline, empty = stdout.rsplit('\n', 2) assert empty == '' assert lastline.startswith('MALLOC COUNTERS: ') From noreply at buildbot.pypy.org Wed Oct 10 13:01:01 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 13:01:01 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix this test too Message-ID: <20121010110101.21FFD1C0E84@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57969:5efa41fbc8c6 Date: 2012-10-10 13:00 +0200 http://bitbucket.org/pypy/pypy/changeset/5efa41fbc8c6/ Log: Fix this test too diff --git a/pypy/translator/c/test/test_extfunc.py b/pypy/translator/c/test/test_extfunc.py --- a/pypy/translator/c/test/test_extfunc.py +++ b/pypy/translator/c/test/test_extfunc.py @@ -8,25 +8,15 @@ from pypy.translator.c.test.test_standalone import StandaloneTests posix = __import__(os.name) -# note: clock synchronizes itself! def test_time_clock(): def does_stuff(): - return time.clock() + t1 = t2 = time.clock() + while abs(t2 - t1) < 0.01: + t2 = time.clock() + return t2 - t1 f1 = compile(does_stuff, []) - t0 = time.clock() - t1 = f1() - t2 = time.clock() - t3 = f1() - t4 = time.clock() - t5 = f1() - t6 = time.clock() - # time.clock() and t1() might have a different notion of zero, so - # we can only subtract two numbers returned by the same function. - assert 0 <= t2-t0 - assert 0 <= t3-t1 <= t4-t0 - assert 0 <= t4-t2 <= t5-t1 <= t6-t0 - assert 0 <= t5-t3 <= t6-t2 - assert 0 <= t6-t4 + t = f1() + assert 0 < t < 1.5 def test_time_sleep(): def does_nothing(): From noreply at buildbot.pypy.org Wed Oct 10 13:20:13 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 13:20:13 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Needs a custom ErrorWrapper class to repr nicely instead of with escaping. Message-ID: <20121010112013.116251C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57970:5543bcb2c705 Date: 2012-10-10 13:19 +0200 http://bitbucket.org/pypy/pypy/changeset/5543bcb2c705/ Log: Needs a custom ErrorWrapper class to repr nicely instead of with escaping. diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -2,7 +2,7 @@ from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - AnnotatorError, gather_error) + AnnotatorError, gather_error, ErrorWrapper) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -593,7 +593,8 @@ resultcell = consider_meth(*argcells) except Exception, e: graph = self.bookkeeper.position_key[0] - e.args = e.args + (gather_error(self, graph, block, opindex),) + e.args = e.args + ( + ErrorWrapper(gather_error(self, graph, block, opindex)),) raise if resultcell is None: resultcell = self.noreturnvalue(op) diff --git a/pypy/tool/error.py b/pypy/tool/error.py --- a/pypy/tool/error.py +++ b/pypy/tool/error.py @@ -70,6 +70,13 @@ class NoSuchAttrError(Exception): pass +class ErrorWrapper(object): + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + return '<%s>' % (self.msg,) + def gather_error(annotator, graph, block, operindex): msg = [""] @@ -101,7 +108,7 @@ return '\n'.join(text) def format_simple_call(annotator, oper, msg): - msg.append("Simple call of incompatible family:") + msg.append("Occurred processing the following simple_call:") try: descs = annotator.bindings[oper.args[0]].descriptions except (KeyError, AttributeError), e: @@ -124,13 +131,6 @@ except (AttributeError, TypeError): r = repr(desc) msg.append(" %s returning" % (r,)) - if hasattr(desc, 'getuniquegraph'): - graph = desc.getuniquegraph() - r = annotator.binding(graph.returnblock.inputargs[0], - "(no annotation)") - else: - r = '?' - msg.append(" %s" % (r,)) msg.append("") def debug(drv, use_pdb=True): From noreply at buildbot.pypy.org Wed Oct 10 14:48:26 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 14:48:26 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (fijal, arigo) Message-ID: <20121010124826.1DA821C0117@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57971:cccfbccb0b5a Date: 2012-10-10 14:48 +0200 http://bitbucket.org/pypy/pypy/changeset/cccfbccb0b5a/ Log: (fijal, arigo) in-progress: refactoring the NoneNotWrapped away, yay diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -13,8 +13,6 @@ import py -NoneNotWrapped = object() - from pypy.interpreter import eval from pypy.interpreter.argument import Arguments, Signature from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, @@ -97,6 +95,10 @@ self.miniglobals[name] = obj return name + +def is_none(space, w_obj): + return w_obj is None or space.is_w(w_obj, space.w_None) + #________________________________________________________________ @@ -519,8 +521,6 @@ # When a BuiltinCode is stored in a Function object, # you get the functionality of CPython's built-in function type. - NOT_RPYTHON_ATTRIBUTES = ['_bltin', '_unwrap_spec'] - def __init__(self, func, unwrap_spec=None, self_type=None, descrmismatch=None): "NOT_RPYTHON" # 'implfunc' is the interpreter-level function. @@ -802,17 +802,8 @@ class interp2app(Wrappable): """Build a gateway that calls 'f' at interp-level.""" - # NOTICE interp2app defaults are stored and passed as - # wrapped values, this to avoid having scope_w be of mixed - # wrapped and unwrapped types; - # an exception is made for the NoneNotWrapped special value - # which is passed around as default as an unwrapped None, - # unwrapped None and wrapped types are compatible - # # Takes optionally an unwrap_spec, see BuiltinCode - NOT_RPYTHON_ATTRIBUTES = ['_staticdefs'] - instancecache = {} def __new__(cls, f, app_name=None, unwrap_spec=None, descrmismatch=None, @@ -854,6 +845,7 @@ def _getdefaults(self, space): "NOT_RPYTHON" + import pdb; pdb.set_trace() defs_w = [] for val in self._staticdefs: if val is NoneNotWrapped: diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -1,6 +1,5 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.pyopcode import LoopBlock from pypy.rlib import jit from pypy.rlib.objectmodel import specialize diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -8,9 +8,6 @@ import inspect class MixedModule(Module): - - NOT_RPYTHON_ATTRIBUTES = ['loaders'] - applevel_name = None expose__file__attribute = True diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -9,7 +9,7 @@ from pypy.interpreter import eval from pypy.interpreter.argument import Signature from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped, unwrap_spec +from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.astcompiler.consts import ( CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED, CO_GENERATOR, CO_CONTAINSGLOBALS) @@ -342,8 +342,7 @@ argcount, nlocals, stacksize, flags, codestring, w_constants, w_names, w_varnames, filename, name, firstlineno, - lnotab, w_freevars=NoneNotWrapped, - w_cellvars=NoneNotWrapped, + lnotab, w_freevars=None, w_cellvars=None, magic=default_magic): if argcount < 0: raise OperationError(space.w_ValueError, diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import NoneNotWrapped, interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.rlib.rstring import UnicodeBuilder from pypy.rlib.objectmodel import we_are_translated @@ -598,7 +598,8 @@ raise OperationError(space.w_TypeError, space.wrap("invalid mapping")) - at unwrap_spec(string=str, errors='str_or_None') + at unwrap_spec(string=str, errors='str_or_None', + w_mapping = (W_Root, 'space.w_None')) def charmap_decode(space, string, errors="strict", w_mapping=None): if errors is None: errors = 'strict' @@ -617,7 +618,8 @@ final, state.decode_error_handler, mapping) return space.newtuple([space.wrap(result), space.wrap(consumed)]) - at unwrap_spec(uni=unicode, errors='str_or_None') + at unwrap_spec(uni=unicode, errors='str_or_None', + w_mapping = (W_Root, 'space.w_None')) def charmap_encode(space, uni, errors="strict", w_mapping=None): if errors is None: errors = 'strict' 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 @@ -48,7 +48,7 @@ def setlocale(space, category, w_locale=None): "(integer,string=None) -> string. Activates/queries locale processing." - if space.is_w(w_locale, space.w_None) or w_locale is None: + if w_locale is None or space.is_w(w_locale, space.w_None): locale = None else: locale = space.str_w(w_locale) diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -61,8 +61,8 @@ raise converted_error(space, e) return common_wrapgethost(space, res) - at unwrap_spec(name=str) -def getservbyname(space, name, w_proto=None): + at unwrap_spec(name=str, w_proto = (W_Root, 'space.w_None')) +def getservbyname(space, name, w_proto): """getservbyname(servicename[, protocolname]) -> integer Return a port number from a service name and protocol name. @@ -79,8 +79,8 @@ raise converted_error(space, e) return space.wrap(port) - at unwrap_spec(port=int) -def getservbyport(space, port, w_proto=None): + at unwrap_spec(port=int, w_proto = (W_Root, 'space.w_None')) +def getservbyport(space, port, w_proto): """getservbyport(port[, protocolname]) -> string Return the service name from a port number and protocol name. diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -87,7 +87,7 @@ self.space = space self.w_obj = w_obj - if space.is_w(w_times, space.w_None): + if w_times is None: self.counting = False self.count = 0 else: @@ -966,7 +966,8 @@ self.new_group = True #new group raise StopIteration -def W_GroupBy___new__(space, w_subtype, w_iterable, w_key=None): + at unwrap_spec(w_key = (W_Root, 'space.w_None')) +def W_GroupBy___new__(space, w_subtype, w_iterable, w_key): r = space.allocate_instance(W_GroupBy, w_subtype) r.__init__(space, w_iterable, w_key) return space.wrap(r) @@ -1336,7 +1337,8 @@ self.stopped = True return w_result -def W_Permutations__new__(space, w_subtype, w_iterable, w_r=None): + at unwrap_spec(w_r = (W_Root, 'space.w_None')) +def W_Permutations__new__(space, w_subtype, w_iterable, w_r): pool_w = space.fixedview(w_iterable) if space.is_w(w_r, space.w_None): r = len(pool_w) diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -4,7 +4,7 @@ from pypy.module.micronumpy.iter import Chunk, Chunks from pypy.module.micronumpy.strides import shape_agreement from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, is_none def where(space, w_arr, w_x=None, w_y=None): """where(condition, [x, y]) @@ -127,7 +127,7 @@ @unwrap_spec(repeats=int) def repeat(space, w_arr, repeats, w_axis=None): arr = convert_to_array(space, w_arr) - if space.is_w(w_axis, space.w_None): + if is_none(space, w_axis): arr = arr.descr_flatten(space) orig_size = arr.get_shape()[0] shape = [arr.get_shape()[0] * repeats] 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 @@ -1,7 +1,7 @@ from pypy.interpreter.error import operationerrfmt, OperationError from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, is_none from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\ ArrayArgumentException from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes @@ -293,7 +293,7 @@ return space.newlist(l_w) def descr_ravel(self, space, w_order=None): - if w_order is None or space.is_w(w_order, space.w_None): + if is_none(space, w_order): order = 'C' else: order = space.str_w(w_order) @@ -306,15 +306,18 @@ # if w_axis is None and w_out is Nont this is an equivalent to # fancy indexing raise Exception("unsupported for now") - if not space.is_w(w_axis, space.w_None): + if not is_none(space, w_axis): raise OperationError(space.w_NotImplementedError, space.wrap("axis unsupported for take")) - if not space.is_w(w_out, space.w_None): + if not is_none(space, w_out): raise OperationError(space.w_NotImplementedError, space.wrap("out unsupported for take")) return self.getitem_int(space, convert_to_array(space, w_obj)) def descr_compress(self, space, w_obj, w_axis=None): + if not is_none(space, w_axis): + raise OperationError(space.w_NotImplementedError, + space.wrap("axis unsupported for compress")) index = convert_to_array(space, w_obj) return self.getitem_filter(space, index) @@ -341,7 +344,7 @@ return coords def descr_item(self, space, w_arg=None): - if space.is_w(w_arg, space.w_None): + if is_none(space, w_arg): if self.is_scalar(): return self.get_scalar_value().item(space) if self.get_size() == 1: diff --git a/pypy/module/select/interp_kqueue.py b/pypy/module/select/interp_kqueue.py --- a/pypy/module/select/interp_kqueue.py +++ b/pypy/module/select/interp_kqueue.py @@ -143,8 +143,8 @@ def descr_close(self, space): self.close() - @unwrap_spec(max_events=int) - def descr_control(self, space, w_changelist, max_events, w_timeout=None): + @unwrap_spec(max_events=int, w_timeout = (W_Root, 'space.w_None')) + def descr_control(self, space, w_changelist, max_events, w_timeout): self.check_closed(space) diff --git a/pypy/module/select/interp_select.py b/pypy/module/select/interp_select.py --- a/pypy/module/select/interp_select.py +++ b/pypy/module/select/interp_select.py @@ -41,7 +41,8 @@ raise OperationError(space.w_KeyError, space.wrap(fd)) # XXX should this maybe be w_fd? - def poll(self, space, w_timeout=None): + @unwrap_spec(w_timeout = (W_Root, 'space.w_None')) + def poll(self, space, w_timeout): if space.is_w(w_timeout, space.w_None): timeout = -1 else: @@ -100,7 +101,8 @@ reslist_w.append(list_w[i]) -def select(space, w_iwtd, w_owtd, w_ewtd, w_timeout=None): + at unwrap_spec(w_timeout = (W_Root, 'space.w_None')) +def select(space, w_iwtd, w_owtd, w_ewtd, w_timeout): """Wait until one or more file descriptors are ready for some kind of I/O. The first three arguments are sequences of file descriptors to be waited for: rlist -- wait until ready for reading diff --git a/pypy/objspace/std/booltype.py b/pypy/objspace/std/booltype.py --- a/pypy/objspace/std/booltype.py +++ b/pypy/objspace/std/booltype.py @@ -1,8 +1,9 @@ -from pypy.interpreter import gateway +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.inttype import int_typedef -def descr__new__(space, w_booltype, w_obj=None): + at unwrap_spec(w_obj = (W_Root, 'space.w_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 @@ -17,6 +18,6 @@ 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__ = gateway.interp2app(descr__new__), + __new__ = interp2app(descr__new__), ) bool_typedef.acceptable_as_base_class = False diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py --- a/pypy/objspace/std/complextype.py +++ b/pypy/objspace/std/complextype.py @@ -1,4 +1,4 @@ -from pypy.interpreter import gateway +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.register_all import register_all from pypy.objspace.std.strutil import string_to_float, ParseStringError @@ -115,14 +115,15 @@ return realpart, imagpart -def descr__new__(space, w_complextype, w_real=0.0, w_imag=None): + at unwrap_spec(w_real = (W_Root, 'space.wrap("0.0")')) +def descr__new__(space, w_complextype, w_real, w_imag=None): from pypy.objspace.std.complexobject import W_ComplexObject # if w_real is already a complex number and there is no second # argument, return it. Note that we cannot return w_real if # it is an instance of a *subclass* of complex, or if w_complextype # is itself a subclass of complex. - noarg2 = space.is_w(w_imag, space.w_None) + noarg2 = w_imag is None if (noarg2 and space.is_w(w_complextype, space.w_complex) and space.is_w(space.type(w_real), space.w_complex)): return w_real @@ -232,8 +233,8 @@ Create a complex number from a real part and an optional imaginary part. This is equivalent to (real + imag*1j) where imag defaults to 0.""", - __new__ = gateway.interp2app(descr__new__), - __getnewargs__ = gateway.interp2app(descr___getnewargs__), + __new__ = interp2app(descr__new__), + __getnewargs__ = interp2app(descr___getnewargs__), real = complexwprop('realval'), imag = complexwprop('imagval'), ) diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py --- a/pypy/objspace/std/formatting.py +++ b/pypy/objspace/std/formatting.py @@ -500,7 +500,7 @@ [_name[-1] for _name in dir(StringFormatter) if len(_name) == 5 and _name.startswith('fmt_')]) -def format(space, w_fmt, values_w, w_valuedict=None, do_unicode=False): +def format(space, w_fmt, values_w, w_valuedict, do_unicode): "Entry point" if not do_unicode: fmt = space.str_w(w_fmt) diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -570,3 +570,6 @@ assert '{0:F}'.format(complex(NAN, 0)) == 'NAN+0.000000j' assert '{0:f}'.format(complex(NAN, NAN)) == 'nan+nanj' assert '{0:F}'.format(complex(NAN, NAN)) == 'NAN+NANj' + + def test_complex_two_arguments(self): + raises(TypeError, complex, 5, None) diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter import gateway +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.register_all import register_all from pypy.objspace.std.basestringtype import basestring_typedef @@ -335,7 +335,10 @@ w_encoding, w_errors) -def descr_new_(space, w_unicodetype, w_string='', w_encoding=None, w_errors=None): + at unwrap_spec(w_string = (W_Root, 'space.wrap("")'), + w_encoding = (W_Root, 'space.w_None'), + w_errors = (W_Root, 'space.w_None')) +def descr_new_(space, w_unicodetype, w_string, w_encoding, w_errors): # NB. the default value of w_obj is really a *wrapped* empty string: # there is gateway magic at work from pypy.objspace.std.unicodeobject import W_UnicodeObject @@ -375,7 +378,7 @@ # ____________________________________________________________ unicode_typedef = StdTypeDef("unicode", basestring_typedef, - __new__ = gateway.interp2app(descr_new_), + __new__ = interp2app(descr_new_), __doc__ = '''unicode(string [, encoding[, errors]]) -> object Create a new Unicode object from the given encoded string. From noreply at buildbot.pypy.org Wed Oct 10 15:21:58 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 15:21:58 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: in-progress Message-ID: <20121010132158.A810C1C0E82@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57972:d3d2090571dd Date: 2012-10-10 15:21 +0200 http://bitbucket.org/pypy/pypy/changeset/d3d2090571dd/ Log: in-progress diff --git a/pypy/module/_rawffi/array.py b/pypy/module/_rawffi/array.py --- a/pypy/module/_rawffi/array.py +++ b/pypy/module/_rawffi/array.py @@ -3,7 +3,7 @@ to app-level with apropriate interface """ -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, is_none from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty from pypy.rpython.lltypesystem import lltype, rffi from pypy.interpreter.error import OperationError @@ -48,7 +48,7 @@ @unwrap_spec(length=int, autofree=bool) def descr_call(self, space, length, w_items=None, autofree=False): result = self.allocate(space, length, autofree) - if not space.is_w(w_items, space.w_None): + if is_none(space, w_items): items_w = space.unpackiterable(w_items) iterlength = len(items_w) if iterlength > length: diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -4,9 +4,10 @@ from pypy.module.micronumpy.iter import Chunk, Chunks from pypy.module.micronumpy.strides import shape_agreement from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import unwrap_spec, is_none +from pypy.interpreter.gateway import unwrap_spec, is_none, W_Root -def where(space, w_arr, w_x=None, w_y=None): + at unwrap_spec(w_x = (W_Root, 'space.w_None'), w_y = (W_Root, 'space.w_None')) +def where(space, w_arr, w_x, w_y): """where(condition, [x, y]) Return elements, either from `x` or `y`, depending on `condition`. 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 @@ -2,7 +2,7 @@ import sys from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, is_none from pypy.interpreter.typedef import (TypeDef, GetSetProperty, interp_attrproperty, interp_attrproperty_w) from pypy.module.micronumpy import types, interp_boxes @@ -19,7 +19,7 @@ UNICODELTR = 'U' def decode_w_dtype(space, w_dtype): - if w_dtype is None or space.is_w(w_dtype, space.w_None): + if is_none(space, w_dtype): return None return space.interp_w(W_Dtype, space.call_function(space.gettypefor(W_Dtype), w_dtype)) @@ -208,7 +208,7 @@ def descr__new__(space, w_subtype, w_dtype): cache = get_dtype_cache(space) - if space.is_w(w_dtype, space.w_None): + if is_none(space, w_dtype): return cache.w_float64dtype elif space.isinstance_w(w_dtype, w_subtype): return w_dtype 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 @@ -1,7 +1,8 @@ from pypy.interpreter.error import operationerrfmt, OperationError from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec, is_none +from pypy.interpreter.gateway import interp2app, unwrap_spec, is_none,\ + W_Root from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\ ArrayArgumentException from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes @@ -18,6 +19,8 @@ from pypy.rlib.rstring import StringBuilder def _find_shape(space, w_size): + if is_none(space, w_size): + return [] if space.isinstance_w(w_size, space.w_int): return [space.int_w(w_size)] shape = [] @@ -476,11 +479,13 @@ return loop.multidim_dot(space, self, other, result, dtype, other_critical_dim) - def descr_var(self, space, w_axis=None): + @unwrap_spec(w_axis = (W_Root, 'space.w_None')) + def descr_var(self, space, w_axis): return get_appbridge_cache(space).call_method(space, '_var', self, w_axis) - def descr_std(self, space, w_axis=None): + @unwrap_spec(w_axis = (W_Root, 'space.w_None')) + def descr_std(self, space, w_axis): return get_appbridge_cache(space).call_method(space, '_std', self, w_axis) @@ -488,7 +493,7 @@ def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False): def impl(self, space, w_axis=None, w_out=None, w_dtype=None): - if space.is_w(w_out, space.w_None) or not w_out: + if is_none(space, w_out): out = None elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( @@ -509,7 +514,7 @@ descr_any = _reduce_ufunc_impl('logical_or') def descr_mean(self, space, w_axis=None, w_out=None): - if space.is_w(w_axis, space.w_None): + if is_none(space, w_axis): w_denom = space.wrap(self.get_size()) else: axis = unwrap_axis_arg(space, len(self.get_shape()), w_axis) @@ -531,9 +536,9 @@ @unwrap_spec(offset=int) def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None, offset=0, w_strides=None, w_order=None): - if (offset != 0 or not space.is_w(w_strides, space.w_None) or - not space.is_w(w_order, space.w_None) or - not space.is_w(w_buffer, space.w_None)): + if (offset != 0 or is_none(space, w_strides) or + not is_none(space, w_order) or + not is_none(space, w_buffer)): raise OperationError(space.w_NotImplementedError, space.wrap("unsupported param")) dtype = space.interp_w(interp_dtype.W_Dtype, @@ -644,12 +649,12 @@ def array(space, w_object, w_dtype=None, copy=True, w_order=None, subok=False, ndmin=0): if not space.issequence_w(w_object): - if w_dtype is None or space.is_w(w_dtype, space.w_None): + if is_none(space, w_dtype): 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)) return W_NDimArray.new_scalar(space, dtype, w_object) - if w_order is None or space.is_w(w_order, space.w_None): + if is_none(space, w_order): order = 'C' else: order = space.str_w(w_order) diff --git a/pypy/module/micronumpy/interp_support.py b/pypy/module/micronumpy/interp_support.py --- a/pypy/module/micronumpy/interp_support.py +++ b/pypy/module/micronumpy/interp_support.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, is_none, W_Root from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy import interp_dtype, loop from pypy.objspace.std.strutil import strip_spaces @@ -75,7 +75,7 @@ loop.fromstring_loop(a, dtype, itemsize, s) return space.wrap(a) - at unwrap_spec(s=str, count=int, sep=str) + at unwrap_spec(s=str, count=int, sep=str, w_dtype=(W_Root, 'space.w_None')) def fromstring(space, s, w_dtype=None, count=-1, sep=''): dtype = space.interp_w(interp_dtype.W_Dtype, space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype) @@ -87,7 +87,7 @@ return _fromstring_text(space, s, count, sep, length, dtype) def unwrap_axis_arg(space, shapelen, w_axis): - if space.is_w(w_axis, space.w_None) or not w_axis: + if is_none(space, w_axis): axis = maxint else: axis = space.int_w(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 @@ -1,6 +1,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app, unwrap_spec,\ + is_none from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty from pypy.module.micronumpy import interp_boxes, interp_dtype, loop from pypy.rlib import jit @@ -73,7 +74,7 @@ return self.call(space, args_w) @unwrap_spec(skipna=bool, keepdims=bool) - def descr_reduce(self, space, w_obj, w_axis=NoneNotWrapped, w_dtype=None, + def descr_reduce(self, space, w_obj, w_axis=None, w_dtype=None, skipna=False, keepdims=False, w_out=None): """reduce(...) reduce(a, axis=0) @@ -130,7 +131,7 @@ from pypy.module.micronumpy.interp_numarray import W_NDimArray if w_axis is None: w_axis = space.wrap(0) - if space.is_w(w_out, space.w_None): + if is_none(space, w_out): out = None elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( @@ -298,7 +299,7 @@ promote_bools=self.promote_bools, allow_complex=self.allow_complex, ) - if space.is_w(w_out, space.w_None) or w_out is None: + if is_none(space, w_out): out = None elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( From noreply at buildbot.pypy.org Wed Oct 10 16:37:55 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 10 Oct 2012 16:37:55 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: a rough structure of the talk Message-ID: <20121010143755.DDB351C0FCD@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4845:2f3f32b81966 Date: 2012-10-10 16:37 +0200 http://bitbucket.org/pypy/extradoc/changeset/2f3f32b81966/ Log: a rough structure of the talk diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -44,7 +44,7 @@ Heinrich-Heine-Universität Düsseldorf, STUPS Group, Germany } -\date{2012 VMIL, XXX} +\date{2012 VMIL, 21st of October, 2012} % - Either use conference name or its abbreviation. % - Not really informative to the audience, more for people (including % yourself) who are reading the slides online @@ -80,31 +80,7 @@ \titlepage \end{frame} -% XXX todos: -% note that two fields is a simplification -% have a diagram for the example trace -% lifting can never produce new operations -% have some sort of overview or position indicator for the many graphical slides, too easy to get lost -% more details about benchmarks, diagram? - - -% Structuring a talk is a difficult task and the following structure -% may not be suitable. Here are some rules that apply for this -% solution: - -% - Exactly two or three sections (other than the summary). -% - At *most* three subsections per section. -% - Talk about 30s to 2min per frame. So there should be between about -% 15 and 30 frames, all told. - -% - A conference audience is likely to know very little of what you -% are going to talk about. So *simplify*! -% - In a 20min talk, getting the main ideas across is hard -% enough. Leave out details, even if it means being less precise than -% you think necessary. -% - If you omit details that are vital to the proof/implementation, -% just say so once. Everybody will be happy with that. - +\section{Introduction} \begin{frame} \frametitle{Tracing JITs Compile by Observing an Interpreter} @@ -119,5 +95,52 @@ \end{itemize} \end{frame} +\begin{frame} + \frametitle{Guards} +\end{frame} + +% this talk wants to go over a lot of details that are usually glossed over as +% "easy" when tracing JITs are introduced. + +\begin{frame} + \frametitle{Bridges} +\end{frame} + +\begin{frame} + \frametitle{RPython and PyPy} +\end{frame} + +\begin{frame} + \frametitle{Running Example} +\end{frame} + +\section{High-Level} + +\begin{frame} + \frametitle{Symbolic Frame Capturing} +\end{frame} + +\begin{frame} + \frametitle{Symbolic Frame Compression} +\end{frame} + +\begin{frame} + \frametitle{Interaction with Optimization} +\end{frame} + +\begin{frame} + \frametitle{Emitting Guards} +\end{frame} + +\begin{frame} + \frametitle{Patching Guards for Bridges} +\end{frame} + +\section{Evaluation} + +%as in paper +%fancy graphs +%something about execution speed +% \end{document} From noreply at buildbot.pypy.org Wed Oct 10 17:04:49 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 10 Oct 2012 17:04:49 +0200 (CEST) Subject: [pypy-commit] pypy py3k: allow unicode spaces in int literals Message-ID: <20121010150449.BF4D21C0FCD@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57973:76ac06f4ecdf Date: 2012-10-10 16:08 +0200 http://bitbucket.org/pypy/pypy/changeset/76ac06f4ecdf/ Log: allow unicode spaces in int literals diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -1,7 +1,20 @@ +# -*- encoding: utf-8 -*- import py import sys from pypy.conftest import gettestobjspace +def test_unicode_to_decimal_w(): + from pypy.objspace.std.unicodeobject import unicode_to_decimal_w + space = gettestobjspace(usemodules=('unicodedata',)) + w_s = space.wrap(u"\N{EM SPACE}-3\N{EN SPACE}") + s2 = unicode_to_decimal_w(space, w_s) + assert s2 == " -3 " + # + w_s = space.wrap(u'\U0001D7CF\U0001D7CE') # 𝟏𝟎 + s2 = unicode_to_decimal_w(space, w_s) + assert s2 == "10" + + class AppTestUnicodeStringStdOnly: def test_compares(self): assert type('a') != type(b'a') diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -99,6 +99,9 @@ for i in xrange(len(unistr)): uchr = ord(unistr[i]) if uchr > 127: + if unicodedb.isspace(uchr): + result[i] = ' ' + continue try: uchr = ord(u'0') + unicodedb.decimal(uchr) except KeyError: From noreply at buildbot.pypy.org Wed Oct 10 17:04:51 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 10 Oct 2012 17:04:51 +0200 (CEST) Subject: [pypy-commit] pypy py3k: this is a cpython impl detail Message-ID: <20121010150451.1FC6E1C0FCD@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57974:c40e27031eda Date: 2012-10-10 16:11 +0200 http://bitbucket.org/pypy/pypy/changeset/c40e27031eda/ Log: this is a cpython impl detail diff --git a/lib-python/3.2/test/test_int.py b/lib-python/3.2/test/test_int.py --- a/lib-python/3.2/test/test_int.py +++ b/lib-python/3.2/test/test_int.py @@ -1,7 +1,7 @@ import sys import unittest -from test.support import run_unittest +from test.support import run_unittest, check_impl_detail L = [ ('0', 0), @@ -298,9 +298,10 @@ try: int(TruncReturnsNonIntegral()) except TypeError as e: - self.assertEqual(str(e), - "__trunc__ returned non-Integral" - " (type NonIntegral)") + if check_impl_detail(cpython=True): + self.assertEqual(str(e), + "__trunc__ returned non-Integral" + " (type NonIntegral)") else: self.fail("Failed to raise TypeError with %s" % ((base, trunc_result_base),)) From noreply at buildbot.pypy.org Wed Oct 10 17:04:52 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 10 Oct 2012 17:04:52 +0200 (CEST) Subject: [pypy-commit] pypy py3k: bah, of course we need to call unicode_w in the unicode set strategy Message-ID: <20121010150452.530131C0FCD@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57975:ba0a57363695 Date: 2012-10-10 16:53 +0200 http://bitbucket.org/pypy/pypy/changeset/ba0a57363695/ Log: bah, of course we need to call unicode_w in the unicode set strategy diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -695,7 +695,7 @@ return True def unwrap(self, w_item): - return self.space.str_w(w_item) + return self.space.unicode_w(w_item) def wrap(self, item): return self.space.wrap(item) diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py --- a/pypy/objspace/std/test/test_setobject.py +++ b/pypy/objspace/std/test/test_setobject.py @@ -1,3 +1,4 @@ +# -*- encoding: utf-8 -*- """ The main test for the set implementation is located in the stdlibs test/test_set.py which is located in lib-python @@ -961,3 +962,17 @@ # getting a RuntimeError because iterating over the old storage # gives us 1, but 1 is not in the set any longer. raises(RuntimeError, list, it) + + def test_unicodestrategy(self): + s = 'àèìòù' + myset = {s} + s2 = myset.pop() + assert s2 == s + + def test_preserve_identity_of_strings(self): + s = 'hello' + myset = {s} + s2 = myset.pop() + assert s2 == s + assert s2 is s + From noreply at buildbot.pypy.org Wed Oct 10 17:04:53 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 10 Oct 2012 17:04:53 +0200 (CEST) Subject: [pypy-commit] pypy py3k: getsizeof is an impl detail Message-ID: <20121010150453.7F7891C0FCD@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r57976:7e1c4acc4231 Date: 2012-10-10 17:01 +0200 http://bitbucket.org/pypy/pypy/changeset/7e1c4acc4231/ Log: getsizeof is an impl detail diff --git a/lib-python/3.2/test/test_collections.py b/lib-python/3.2/test/test_collections.py --- a/lib-python/3.2/test/test_collections.py +++ b/lib-python/3.2/test/test_collections.py @@ -1163,6 +1163,7 @@ with self.assertRaises(KeyError): od.move_to_end('x') + @support.impl_detail(pypy=False) def test_sizeof(self): # Wimpy test: Just verify the reported size is larger than a regular dict d = dict(a=1) From noreply at buildbot.pypy.org Wed Oct 10 17:38:02 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 17:38:02 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: try to use more consistently space.is_none Message-ID: <20121010153802.3AF7A1C01CA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57977:56e41853186e Date: 2012-10-10 17:37 +0200 http://bitbucket.org/pypy/pypy/changeset/56e41853186e/ Log: try to use more consistently space.is_none diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -719,8 +719,16 @@ # done by a method call on w_two (and not on w_one, because of the # expected programming style where we say "if x is None" or # "if x is object"). + assert w_two is not None + assert w_one is not None return w_two.is_w(self, w_one) + def is_none(self, w_obj): + """ mostly for checking inputargs that have unwrap_spec and + can accept both w_None and None + """ + return w_obj is None or self.is_w(w_obj, self.w_None) + def id(self, w_obj): w_result = w_obj.immutable_unique_id(self) if w_result is None: diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -96,9 +96,6 @@ return name -def is_none(space, w_obj): - return w_obj is None or space.is_w(w_obj, space.w_None) - #________________________________________________________________ diff --git a/pypy/module/__pypy__/interp_identitydict.py b/pypy/module/__pypy__/interp_identitydict.py --- a/pypy/module/__pypy__/interp_identitydict.py +++ b/pypy/module/__pypy__/interp_identitydict.py @@ -34,6 +34,8 @@ raise OperationError(space.w_KeyError, w_key) def get(self, space, w_key, w_default=None): + if w_default is None: + w_default = space.w_None return self.dict.get(w_key, w_default) def keys(self, space): 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 @@ -31,7 +31,6 @@ "expected a callable object, not %s", space.type(w_callable).getname(space)) self.w_callable = w_callable - self.w_error = w_error # fresult = self.getfunctype().ctitem size = fresult.size @@ -40,7 +39,7 @@ size = SIZE_OF_FFI_ARG self.ll_error = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw', zero=True) - if not space.is_w(w_error, space.w_None): + if not space.is_none(w_error): convert_from_object_fficallback(fresult, self.ll_error, w_error) # self.unique_id = compute_unique_id(self) diff --git a/pypy/module/_cffi_backend/func.py b/pypy/module/_cffi_backend/func.py --- a/pypy/module/_cffi_backend/func.py +++ b/pypy/module/_cffi_backend/func.py @@ -1,15 +1,12 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.rpython.lltypesystem import lltype, rffi - +from pypy.interpreter.gateway import unwrap_spec, W_Root from pypy.module._cffi_backend import ctypeobj, cdataobj # ____________________________________________________________ - at unwrap_spec(ctype=ctypeobj.W_CType) -def newp(space, ctype, w_init=None): + at unwrap_spec(ctype=ctypeobj.W_CType, w_init=(W_Root, 'space.w_None')) +def newp(space, ctype, w_init): return ctype.newp(w_init) # ____________________________________________________________ diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -267,7 +267,7 @@ @unwrap_spec(errors=str) -def encode(space, w_obj, w_encoding=NoneNotWrapped, errors='strict'): +def encode(space, w_obj, w_encoding=None, errors='strict'): """encode(obj, [encoding[,errors]]) -> object Encodes obj using the codec registered for encoding. encoding defaults @@ -290,7 +290,7 @@ return space.newtuple([space.wrap(s), space.wrap(len(s))]) @unwrap_spec(errors=str) -def decode(space, w_obj, w_encoding=NoneNotWrapped, errors='strict'): +def decode(space, w_obj, w_encoding=None, errors='strict'): """decode(obj, [encoding[,errors]]) -> object Decodes obj using the codec registered for encoding. encoding defaults @@ -598,15 +598,14 @@ raise OperationError(space.w_TypeError, space.wrap("invalid mapping")) - at unwrap_spec(string=str, errors='str_or_None', - w_mapping = (W_Root, 'space.w_None')) + at unwrap_spec(string=str, errors='str_or_None') def charmap_decode(space, string, errors="strict", w_mapping=None): if errors is None: errors = 'strict' if len(string) == 0: return space.newtuple([space.wrap(u''), space.wrap(0)]) - if space.is_w(w_mapping, space.w_None): + if space.is_none(w_mapping): mapping = None else: mapping = Charmap_Decode(space, w_mapping) @@ -618,12 +617,11 @@ final, state.decode_error_handler, mapping) return space.newtuple([space.wrap(result), space.wrap(consumed)]) - at unwrap_spec(uni=unicode, errors='str_or_None', - w_mapping = (W_Root, 'space.w_None')) + at unwrap_spec(uni=unicode, errors='str_or_None') def charmap_encode(space, uni, errors="strict", w_mapping=None): if errors is None: errors = 'strict' - if space.is_w(w_mapping, space.w_None): + if space.is_none(w_mapping): mapping = None else: mapping = Charmap_Encode(space, w_mapping) diff --git a/pypy/module/_ffi/interp_struct.py b/pypy/module/_ffi/interp_struct.py --- a/pypy/module/_ffi/interp_struct.py +++ b/pypy/module/_ffi/interp_struct.py @@ -115,7 +115,7 @@ @unwrap_spec(name=str) def descr_new_structdescr(space, w_type, name, w_fields=None): descr = W__StructDescr(name) - if w_fields is not space.w_None: + if not space.is_none(w_fields): descr.define_fields(space, w_fields) return descr 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 @@ -239,7 +239,7 @@ def direct_truncate(self, w_size=None): # note: a wrapped size! stream = self.getstream() space = self.space - if w_size is None or space.is_w(w_size, space.w_None): + if space.is_none(w_size): size = stream.tell() else: size = space.r_longlong_w(w_size) diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -1,7 +1,7 @@ from __future__ import with_statement from pypy.interpreter.typedef import ( TypeDef, GetSetProperty, generic_new_descr, interp_attrproperty_w) -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.buffer import RWBuffer from pypy.rlib.rstring import StringBuilder @@ -387,7 +387,8 @@ self._check_init(space) return space.call_method(self.w_raw, "fileno") - def truncate_w(self, space, w_size=None): + @unwrap_spec(w_size = (W_Root, 'space.w_None')) + def truncate_w(self, space, w_size): self._check_init(space) with self.lock: if self.writable: diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -27,7 +27,7 @@ self.string_size = 0 self.pos = 0 - if not space.is_w(w_initial_bytes, space.w_None): + if not space.is_none(w_initial_bytes): self.write_w(space, w_initial_bytes) self.pos = 0 @@ -108,7 +108,7 @@ def truncate_w(self, space, w_size=None): self._check_closed(space) - if space.is_w(w_size, space.w_None): + if space.is_none(w_size): size = self.pos else: size = space.r_longlong_w(w_size) diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -410,7 +410,7 @@ def truncate_w(self, space, w_size=None): self._check_closed(space) self._check_writable(space) - if space.is_w(w_size, space.w_None): + if space.is_none(w_size): w_size = self.tell_w(space) try: diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -11,7 +11,7 @@ DEFAULT_BUFFER_SIZE = 8192 def convert_size(space, w_size): - if space.is_w(w_size, space.w_None): + if space.is_none(w_size): return -1 else: return space.int_w(w_size) diff --git a/pypy/module/_io/interp_stringio.py b/pypy/module/_io/interp_stringio.py --- a/pypy/module/_io/interp_stringio.py +++ b/pypy/module/_io/interp_stringio.py @@ -1,6 +1,6 @@ from pypy.interpreter.typedef import ( TypeDef, generic_new_descr, GetSetProperty) -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.module._io.interp_textio import W_TextIOBase, W_IncrementalNewlineDecoder from pypy.module._io.interp_iobase import convert_size @@ -12,7 +12,8 @@ self.buf = [] self.pos = 0 - def descr_init(self, space, w_initvalue=None, w_newline="\n"): + @unwrap_spec(w_newline = (W_Root, 'space.wrap("\\n")')) + def descr_init(self, space, w_initvalue=None, w_newline=None): # In case __init__ is called multiple times self.buf = [] self.pos = 0 @@ -47,7 +48,7 @@ space.wrap(int(self.readtranslate)) ) - if not space.is_w(w_initvalue, space.w_None): + if not space.is_none(w_initvalue): self.write_w(space, w_initvalue) self.pos = 0 @@ -225,7 +226,7 @@ def truncate_w(self, space, w_size=None): self._check_closed(space) - if space.is_w(w_size, space.w_None): + if space.is_none(w_size): size = self.pos else: size = space.int_w(w_size) 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 @@ -48,7 +48,7 @@ def setlocale(space, category, w_locale=None): "(integer,string=None) -> string. Activates/queries locale processing." - if w_locale is None or space.is_w(w_locale, space.w_None): + if space.is_none(w_locale): locale = None else: locale = space.str_w(w_locale) 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 @@ -225,7 +225,7 @@ def semlock_acquire(self, space, block, w_timeout): if not block: full_msecs = 0 - elif space.is_w(w_timeout, space.w_None): + elif space.is_none(w_timeout): full_msecs = rwin32.INFINITE else: timeout = space.float_w(w_timeout) diff --git a/pypy/module/_rawffi/array.py b/pypy/module/_rawffi/array.py --- a/pypy/module/_rawffi/array.py +++ b/pypy/module/_rawffi/array.py @@ -3,7 +3,7 @@ to app-level with apropriate interface """ -from pypy.interpreter.gateway import interp2app, unwrap_spec, is_none +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty from pypy.rpython.lltypesystem import lltype, rffi from pypy.interpreter.error import OperationError @@ -13,7 +13,7 @@ from pypy.module._rawffi.interp_rawffi import TYPEMAP from pypy.module._rawffi.interp_rawffi import size_alignment from pypy.module._rawffi.interp_rawffi import unpack_shape_with_length -from pypy.rlib.rarithmetic import intmask, r_uint +from pypy.rlib.rarithmetic import r_uint def push_elem(ll_array, pos, value): TP = lltype.typeOf(value) @@ -48,7 +48,7 @@ @unwrap_spec(length=int, autofree=bool) def descr_call(self, space, length, w_items=None, autofree=False): result = self.allocate(space, length, autofree) - if is_none(space, w_items): + if not space.is_none(w_items): items_w = space.unpackiterable(w_items) iterlength = len(items_w) if iterlength > length: 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 @@ -645,23 +645,23 @@ sock_fd = space.int_w(space.call_method(w_sock, "fileno")) w_timeout = space.call_method(w_sock, "gettimeout") - if space.is_w(w_timeout, space.w_None): + if space.is_none(w_timeout): has_timeout = False else: has_timeout = True - if space.is_w(w_key_file, space.w_None): + if space.is_none(w_key_file): key_file = None else: key_file = space.str_w(w_key_file) - if space.is_w(w_cert_file, space.w_None): + if space.is_none(w_cert_file): cert_file = None else: cert_file = space.str_w(w_cert_file) - if space.is_w(w_cacerts_file, space.w_None): + if space.is_none(w_cacerts_file): cacerts_file = None else: cacerts_file = space.str_w(w_cacerts_file) - if space.is_w(w_ciphers, space.w_None): + if space.is_none(w_ciphers): ciphers = None else: ciphers = space.str_w(w_ciphers) diff --git a/pypy/module/_warnings/interp_warnings.py b/pypy/module/_warnings/interp_warnings.py --- a/pypy/module/_warnings/interp_warnings.py +++ b/pypy/module/_warnings/interp_warnings.py @@ -311,7 +311,7 @@ def get_source_line(space, w_globals, lineno): - if space.is_w(w_globals, space.w_None): + if space.is_none(w_globals): return None # Check/get the requisite pieces needed for the loader. 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 @@ -254,7 +254,7 @@ if __args__.arguments_w: raise OperationError(space.w_TypeError, space.wrap( "__new__ expected at most 2 arguments")) - if space.is_w(w_callable, space.w_None): + if space.is_none(w_callable): return get_or_make_weakref(space, w_subtype, w_obj) else: return make_weakref_with_callback(space, w_subtype, w_obj, w_callable) @@ -326,7 +326,7 @@ """Create a proxy object that weakly references 'obj'. 'callback', if given, is called with the proxy as an argument when 'obj' is about to be finalized.""" - if space.is_w(w_callable, space.w_None): + if space.is_none(w_callable): return get_or_make_proxy(space, w_obj) else: return make_proxy_with_callback(space, w_obj, w_callable) diff --git a/pypy/module/cStringIO/interp_stringio.py b/pypy/module/cStringIO/interp_stringio.py --- a/pypy/module/cStringIO/interp_stringio.py +++ b/pypy/module/cStringIO/interp_stringio.py @@ -165,10 +165,10 @@ self.seek(i) return ''.join(bigbuffer[p:i]) - def descr_truncate(self, w_size=None): # note: a wrapped size! + def descr_truncate(self, w_size=None): self.check_closed() space = self.space - if w_size is None or space.is_w(w_size, space.w_None): + if space.is_none(w_size): size = self.tell() else: size = space.int_w(w_size) @@ -249,7 +249,7 @@ # ____________________________________________________________ def StringIO(space, w_string=None): - if space.is_w(w_string, space.w_None): + if space.is_none(w_string): return space.wrap(W_OutputType(space)) else: string = space.bufferstr_w(w_string) 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 @@ -188,7 +188,7 @@ return ret def cmethod_descr_get(space, w_function, w_obj, w_cls=None): - asking_for_bound = (space.is_w(w_cls, space.w_None) or + asking_for_bound = (space.is_none(w_cls) or not space.is_w(w_obj, space.w_None) or space.is_w(w_cls, space.type(space.w_None))) if asking_for_bound: diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -884,8 +884,10 @@ def __init__(self, space, w_iterable, w_fun): self.space = space self.w_iterable = self.space.iter(w_iterable) - self.identity_fun = self.space.is_w(w_fun, self.space.w_None) - self.w_fun = w_fun + if space.is_none(w_fun): + self.w_fun = None + else: + self.w_fun = w_fun self.index = 0 self.lookahead = False self.exhausted = False @@ -915,7 +917,7 @@ raise else: self.w_lookahead = w_obj - if self.identity_fun: + if self.w_fun is None: self.w_key = w_obj else: self.w_key = self.space.call_function(self.w_fun, w_obj) @@ -952,7 +954,7 @@ else: raise else: - if self.identity_fun: + if self.w_fun is None: w_new_key = w_obj else: w_new_key = self.space.call_function(self.w_fun, w_obj) @@ -966,8 +968,7 @@ self.new_group = True #new group raise StopIteration - at unwrap_spec(w_key = (W_Root, 'space.w_None')) -def W_GroupBy___new__(space, w_subtype, w_iterable, w_key): +def W_GroupBy___new__(space, w_subtype, w_iterable, w_key=None): r = space.allocate_instance(W_GroupBy, w_subtype) r.__init__(space, w_iterable, w_key) return space.wrap(r) @@ -1337,10 +1338,9 @@ self.stopped = True return w_result - at unwrap_spec(w_r = (W_Root, 'space.w_None')) -def W_Permutations__new__(space, w_subtype, w_iterable, w_r): +def W_Permutations__new__(space, w_subtype, w_iterable, w_r=None): pool_w = space.fixedview(w_iterable) - if space.is_w(w_r, space.w_None): + if space.is_none(w_r): r = len(pool_w) else: r = space.gateway_nonnegint_w(w_r) diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -4,10 +4,9 @@ from pypy.module.micronumpy.iter import Chunk, Chunks from pypy.module.micronumpy.strides import shape_agreement from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import unwrap_spec, is_none, W_Root +from pypy.interpreter.gateway import unwrap_spec - at unwrap_spec(w_x = (W_Root, 'space.w_None'), w_y = (W_Root, 'space.w_None')) -def where(space, w_arr, w_x, w_y): +def where(space, w_arr, w_x=None, w_y=None): """where(condition, [x, y]) Return elements, either from `x` or `y`, depending on `condition`. @@ -67,12 +66,15 @@ NOTE: support for not passing x and y is unsupported """ - if space.is_w(w_y, space.w_None): - if space.is_w(w_x, space.w_None): + if space.is_none(w_y): + if space.is_none(w_x): raise OperationError(space.w_NotImplementedError, space.wrap( "1-arg where unsupported right now")) raise OperationError(space.w_ValueError, space.wrap( "Where should be called with either 1 or 3 arguments")) + if space.is_none(w_x): + raise OperationError(space.w_ValueError, space.wrap( + "Where should be called with either 1 or 3 arguments")) arr = convert_to_array(space, w_arr) x = convert_to_array(space, w_x) y = convert_to_array(space, w_y) @@ -128,7 +130,7 @@ @unwrap_spec(repeats=int) def repeat(space, w_arr, repeats, w_axis=None): arr = convert_to_array(space, w_arr) - if is_none(space, w_axis): + if space.is_none(w_axis): arr = arr.descr_flatten(space) orig_size = arr.get_shape()[0] shape = [arr.get_shape()[0] * repeats] 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 @@ -1,8 +1,7 @@ from pypy.interpreter.error import operationerrfmt, OperationError from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec, is_none,\ - W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\ ArrayArgumentException from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes @@ -19,7 +18,7 @@ from pypy.rlib.rstring import StringBuilder def _find_shape(space, w_size): - if is_none(space, w_size): + if space.is_none(w_size): return [] if space.isinstance_w(w_size, space.w_int): return [space.int_w(w_size)] @@ -296,7 +295,7 @@ return space.newlist(l_w) def descr_ravel(self, space, w_order=None): - if is_none(space, w_order): + if space.is_none(w_order): order = 'C' else: order = space.str_w(w_order) @@ -309,16 +308,16 @@ # if w_axis is None and w_out is Nont this is an equivalent to # fancy indexing raise Exception("unsupported for now") - if not is_none(space, w_axis): + if not space.is_none(w_axis): raise OperationError(space.w_NotImplementedError, space.wrap("axis unsupported for take")) - if not is_none(space, w_out): + if not space.is_none(w_out): raise OperationError(space.w_NotImplementedError, space.wrap("out unsupported for take")) return self.getitem_int(space, convert_to_array(space, w_obj)) def descr_compress(self, space, w_obj, w_axis=None): - if not is_none(space, w_axis): + if not space.is_none(w_axis): raise OperationError(space.w_NotImplementedError, space.wrap("axis unsupported for compress")) index = convert_to_array(space, w_obj) @@ -347,7 +346,7 @@ return coords def descr_item(self, space, w_arg=None): - if is_none(space, w_arg): + if space.is_none(w_arg): if self.is_scalar(): return self.get_scalar_value().item(space) if self.get_size() == 1: @@ -493,7 +492,7 @@ def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False): def impl(self, space, w_axis=None, w_out=None, w_dtype=None): - if is_none(space, w_out): + if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( @@ -514,7 +513,7 @@ descr_any = _reduce_ufunc_impl('logical_or') def descr_mean(self, space, w_axis=None, w_out=None): - if is_none(space, w_axis): + if space.is_none(w_axis): w_denom = space.wrap(self.get_size()) else: axis = unwrap_axis_arg(space, len(self.get_shape()), w_axis) @@ -536,9 +535,8 @@ @unwrap_spec(offset=int) def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None, offset=0, w_strides=None, w_order=None): - if (offset != 0 or is_none(space, w_strides) or - not is_none(space, w_order) or - not is_none(space, w_buffer)): + if (offset != 0 or space.is_none(w_strides) or not space.is_none(w_order) or + not space.is_none(w_buffer)): raise OperationError(space.w_NotImplementedError, space.wrap("unsupported param")) dtype = space.interp_w(interp_dtype.W_Dtype, @@ -649,12 +647,12 @@ def array(space, w_object, w_dtype=None, copy=True, w_order=None, subok=False, ndmin=0): if not space.issequence_w(w_object): - if is_none(space, w_dtype): + if space.is_none(w_dtype): 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)) return W_NDimArray.new_scalar(space, dtype, w_object) - if is_none(space, w_order): + if space.is_none(w_order): order = 'C' else: order = space.str_w(w_order) diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -1,7 +1,6 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import interp2app, unwrap_spec,\ - is_none +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty from pypy.module.micronumpy import interp_boxes, interp_dtype, loop from pypy.rlib import jit @@ -131,7 +130,7 @@ from pypy.module.micronumpy.interp_numarray import W_NDimArray if w_axis is None: w_axis = space.wrap(0) - if is_none(space, w_out): + if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( @@ -299,7 +298,7 @@ promote_bools=self.promote_bools, allow_complex=self.allow_complex, ) - if is_none(space, w_out): + if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( diff --git a/pypy/module/oracle/interp_cursor.py b/pypy/module/oracle/interp_cursor.py --- a/pypy/module/oracle/interp_cursor.py +++ b/pypy/module/oracle/interp_cursor.py @@ -164,7 +164,7 @@ @unwrap_spec(name=str) def callfunc(self, space, name, w_returnType, w_parameters=None): retvar = interp_variable.newVariableByType(space, self, w_returnType, 1) - if space.is_w(w_parameters, space.w_None): + if space.is_none(w_parameters): w_parameters = None self._call(space, name, retvar, w_parameters) @@ -174,7 +174,7 @@ @unwrap_spec(name=str) def callproc(self, space, name, w_parameters=None): - if space.is_w(w_parameters, space.w_None): + if space.is_none(w_parameters): w_parameters = None self._call(space, name, None, w_parameters) @@ -763,7 +763,7 @@ return space.w_None - def fetchmany(self, space, w_numRows=NoneNotWrapped): + def fetchmany(self, space, w_numRows=None): if w_numRows is not None: numRows = space.int_w(w_numRows) else: @@ -957,7 +957,7 @@ @unwrap_spec(size=int) def var(self, space, w_type, size=0, w_arraysize=None, w_inconverter=None, w_outconverter=None): - if space.is_w(w_arraysize, space.w_None): + if space.is_none(w_arraysize): arraySize = self.bindArraySize else: arraySize = space.int_w(w_arraysize) diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -1,7 +1,6 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.gateway import NoneNotWrapped -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.error import OperationError from pypy.rlib import rgc from pypy.rpython.lltypesystem import rffi, lltype @@ -643,7 +642,7 @@ else: context = space.str_w(w_context) - if space.is_w(w_encoding, space.w_None): + if space.is_none(w_encoding): encoding = None else: encoding = space.str_w(w_encoding) @@ -774,10 +773,10 @@ ) def ParserCreate(space, w_encoding=None, w_namespace_separator=None, - w_intern=NoneNotWrapped): + w_intern=None): """ParserCreate([encoding[, namespace_separator]]) -> parser Return a new XML parser object.""" - if space.is_w(w_encoding, space.w_None): + if space.is_none(w_encoding): encoding = None elif space.is_true(space.isinstance(w_encoding, space.w_str)): encoding = space.str_w(w_encoding) @@ -788,7 +787,7 @@ space.wrap('ParserCreate() argument 1 must be string or None,' ' not %s' % (type_name,))) - if space.is_w(w_namespace_separator, space.w_None): + if space.is_none(w_namespace_separator): namespace_separator = 0 elif space.is_true(space.isinstance(w_namespace_separator, space.w_str)): separator = space.str_w(w_namespace_separator) 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 @@ -354,7 +354,7 @@ def _get_inttime(space, w_seconds): # w_seconds can be a wrapped None (it will be automatically wrapped # in the callers, so we never get a real None here). - if space.is_w(w_seconds, space.w_None): + if space.is_none(w_seconds): seconds = pytime.time() else: seconds = space.float_w(w_seconds) @@ -385,7 +385,10 @@ return space.call_function(w_struct_time, w_time_tuple) def _gettmarg(space, w_tup, allowNone=True): - if allowNone and space.is_w(w_tup, space.w_None): + if space.is_none(w_tup): + if not allowNone: + raise OperationError(space.w_TypeError, + space.wrap("tuple expected")) # default to the current local time tt = rffi.r_time_t(int(pytime.time())) t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw') diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py --- a/pypy/objspace/std/typetype.py +++ b/pypy/objspace/std/typetype.py @@ -6,8 +6,7 @@ from pypy.objspace.std.stdtypedef import StdTypeDef -def descr__new__(space, w_typetype, w_name, w_bases=gateway.NoneNotWrapped, - w_dict=gateway.NoneNotWrapped): +def descr__new__(space, w_typetype, w_name, w_bases=None, w_dict=None): "This is used to create user-defined classes only." # XXX check types diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -216,11 +216,11 @@ return space.sys.defaultencoding def _get_encoding_and_errors(space, w_encoding, w_errors): - if space.is_w(w_encoding, space.w_None): + if space.is_none(w_encoding): encoding = None else: encoding = space.str_w(w_encoding) - if space.is_w(w_errors, space.w_None): + if space.is_none(w_errors): errors = None else: errors = space.str_w(w_errors) @@ -335,10 +335,8 @@ w_encoding, w_errors) - at unwrap_spec(w_string = (W_Root, 'space.wrap("")'), - w_encoding = (W_Root, 'space.w_None'), - w_errors = (W_Root, 'space.w_None')) -def descr_new_(space, w_unicodetype, w_string, w_encoding, w_errors): + at unwrap_spec(w_string = (W_Root, 'space.wrap("")')) +def descr_new_(space, w_unicodetype, w_string, w_encoding=None, w_errors=None): # NB. the default value of w_obj is really a *wrapped* empty string: # there is gateway magic at work from pypy.objspace.std.unicodeobject import W_UnicodeObject From noreply at buildbot.pypy.org Wed Oct 10 17:42:57 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 17:42:57 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix fix fix a bit more Message-ID: <20121010154257.CABC91C01CA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57978:18f173be9b33 Date: 2012-10-10 17:42 +0200 http://bitbucket.org/pypy/pypy/changeset/18f173be9b33/ Log: Fix fix fix a bit more diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -58,10 +58,12 @@ if isinstance(el, str): getattr(self, "visit_%s" % (el,))(el, *args) elif isinstance(el, tuple): - if el[0] == 'self': + if el[0] == 'INTERNAL:self': self.visit_self(el[1], *args) else: - self.visit_function(el, *args) + assert len(el) == 2 # 2nd arg is str that evals to 'default' + assert el[0] is W_Root # for now + self.visit__W_Root(W_Root, *args) elif isinstance(el, type): for typ in self.bases_order: if issubclass(el, typ): @@ -107,9 +109,6 @@ self.func = original_sig.func self.orig_arg = iter(original_sig.argnames).next - def visit_function(self, (func, cls), app_sig): - self.dispatch(cls, app_sig) - def visit_self(self, cls, app_sig): self.visit__Wrappable(cls, app_sig) @@ -207,10 +206,6 @@ def scopenext(self): return "scope_w[%d]" % self.succ() - def visit_function(self, (func, cls)): - self.run_args.append("%s(%s)" % (self.use(func), - self.scopenext())) - def visit_self(self, typ): self.run_args.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.scopenext())) @@ -346,9 +341,6 @@ self.args.append(arg) return arg - def visit_function(self, (func, cls)): - raise FastFuncNotSupported - def visit_self(self, typ): self.unwrap.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.nextarg())) @@ -552,7 +544,7 @@ unwrap_spec = list(unwrap_spec) if descrmismatch is not None: assert issubclass(self_type, Wrappable) - unwrap_spec[0] = ('self', self_type) + unwrap_spec[0] = ('INTERNAL:self', self_type) self.descrmismatch_op = descrmismatch self.descr_reqcls = self_type else: 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 @@ -439,25 +439,6 @@ raises(gateway.OperationError, space.call_function, w_app_g3_u, w(42)) - - def test_interp2app_unwrap_spec_func(self): - space = self.space - w = space.wrap - def g_id(space, w_x): - return w_x - l =[] - def checker(w_x): - l.append(w_x) - return w_x - - app_g_id = gateway.interp2app_temp(g_id, - unwrap_spec=[gateway.ObjSpace, - (checker, gateway.W_Root)]) - w_app_g_id = space.wrap(app_g_id) - assert space.eq_w(space.call_function(w_app_g_id,w("foo")),w("foo")) - assert len(l) == 1 - assert space.eq_w(l[0], w("foo")) - def test_interp2app_classmethod(self): space = self.space w = space.wrap diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.rlib.rstring import UnicodeBuilder from pypy.rlib.objectmodel import we_are_translated diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -1,4 +1,4 @@ -from pypy.interpreter.gateway import unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import unwrap_spec from pypy.rlib import rposix, objectmodel, rurandom from pypy.rlib.objectmodel import specialize from pypy.rlib.rarithmetic import r_longlong @@ -302,7 +302,7 @@ def __init__(self, space): self.stat_float_times = True -def stat_float_times(space, w_value=NoneNotWrapped): +def stat_float_times(space, w_value=None): """stat_float_times([newval]) -> oldval Determine whether os.[lf]stat represents time stamps as float objects. diff --git a/pypy/objspace/std/frozensettype.py b/pypy/objspace/std/frozensettype.py --- a/pypy/objspace/std/frozensettype.py +++ b/pypy/objspace/std/frozensettype.py @@ -36,8 +36,7 @@ register_all(vars(), globals()) -def descr__frozenset__new__(space, w_frozensettype, - w_iterable=gateway.NoneNotWrapped): +def descr__frozenset__new__(space, w_frozensettype, w_iterable=None): from pypy.objspace.std.setobject import W_FrozensetObject if (space.is_w(w_frozensettype, space.w_frozenset) and w_iterable is not None and type(w_iterable) is W_FrozensetObject): diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py --- a/pypy/objspace/std/inttype.py +++ b/pypy/objspace/std/inttype.py @@ -1,4 +1,5 @@ -from pypy.interpreter import gateway, typedef +from pypy.interpreter import typedef +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.buffer import Buffer from pypy.objspace.std.register_all import register_all @@ -88,7 +89,8 @@ from pypy.objspace.std.longobject import newlong return newlong(space, bigint) -def descr__new__(space, w_inttype, w_x=0, w_base=gateway.NoneNotWrapped): + at unwrap_spec(w_x = (W_Root, 'space.wrap(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 @@ -198,9 +200,9 @@ 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__ = gateway.interp2app(descr__new__), - conjugate = gateway.interp2app(descr_conjugate), - bit_length = gateway.interp2app(descr_bit_length), + __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), diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py --- a/pypy/objspace/std/longtype.py +++ b/pypy/objspace/std/longtype.py @@ -1,5 +1,6 @@ from pypy.interpreter.error import OperationError -from pypy.interpreter import gateway, typedef +from pypy.interpreter import typedef +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.strutil import string_to_bigint, ParseStringError @@ -8,7 +9,8 @@ return space.long(w_int) -def descr__new__(space, w_longtype, w_x=0, w_base=gateway.NoneNotWrapped): + at unwrap_spec(w_x = (W_Root, 'space.wrap(0)')) +def descr__new__(space, w_longtype, w_x, w_base=None): from pypy.objspace.std.longobject import W_LongObject from pypy.rlib.rbigint import rbigint if space.config.objspace.std.withsmalllong: @@ -126,12 +128,12 @@ 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.''', - __new__ = gateway.interp2app(descr__new__), - conjugate = gateway.interp2app(descr_conjugate), + __new__ = interp2app(descr__new__), + conjugate = interp2app(descr_conjugate), numerator = typedef.GetSetProperty(descr_get_numerator), denominator = typedef.GetSetProperty(descr_get_denominator), real = typedef.GetSetProperty(descr_get_real), imag = typedef.GetSetProperty(descr_get_imag), - bit_length = gateway.interp2app(bit_length), + bit_length = interp2app(bit_length), ) long_typedef.registermethods(globals()) diff --git a/pypy/objspace/std/tupletype.py b/pypy/objspace/std/tupletype.py --- a/pypy/objspace/std/tupletype.py +++ b/pypy/objspace/std/tupletype.py @@ -45,7 +45,7 @@ "appears in the tuple") -def descr__new__(space, w_tupletype, w_sequence=gateway.NoneNotWrapped): +def descr__new__(space, w_tupletype, w_sequence=None): from pypy.objspace.std.tupleobject import W_TupleObject if w_sequence is None: tuple_w = [] From noreply at buildbot.pypy.org Wed Oct 10 17:51:01 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 17:51:01 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: finish module Message-ID: <20121010155101.26A8E1C01CA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57979:bb4344e09c6e Date: 2012-10-10 17:50 +0200 http://bitbucket.org/pypy/pypy/changeset/bb4344e09c6e/ Log: finish module diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -84,17 +84,17 @@ raise OperationError(space.w_TypeError, w('eval() arg 1 must be a string or code object')) - if space.is_w(w_globals, space.w_None): + if space.is_none(w_globals): caller = space.getexecutioncontext().gettopframe_nohidden() if caller is None: w_globals = space.newdict() - if space.is_w(w_locals, space.w_None): + if space.is_none(w_locals): w_locals = w_globals else: w_globals = caller.w_globals - if space.is_w(w_locals, space.w_None): + if space.is_none(w_locals): w_locals = caller.getdictscope() - elif space.is_w(w_locals, space.w_None): + elif space.is_none(w_locals): w_locals = w_globals # xxx removed: adding '__builtins__' to the w_globals dict, if there diff --git a/pypy/module/__builtin__/descriptor.py b/pypy/module/__builtin__/descriptor.py --- a/pypy/module/__builtin__/descriptor.py +++ b/pypy/module/__builtin__/descriptor.py @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.interpreter.function import StaticMethod, ClassMethod -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.typedef import (TypeDef, interp_attrproperty_w, generic_new_descr) from pypy.objspace.descroperation import object_getattribute @@ -48,7 +48,7 @@ w(self), w(name)) def descr_new_super(space, w_subtype, w_starttype, w_obj_or_type=None): - if space.is_w(w_obj_or_type, space.w_None): + if space.is_none(w_obj_or_type): w_type = None # unbound super object else: w_objtype = space.type(w_obj_or_type) @@ -96,6 +96,10 @@ def __init__(self, space): pass + @unwrap_spec(w_fget = (W_Root, 'space.w_None'), + w_fset = (W_Root, 'space.w_None'), + w_fdel = (W_Root, 'space.w_None'), + w_doc = (W_Root, 'space.w_None')) def init(self, space, w_fget=None, w_fset=None, w_fdel=None, w_doc=None): self.w_fget = w_fget self.w_fset = w_fset diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -47,7 +47,7 @@ n = 0 return n -def range_int(space, w_x, w_y=NoneNotWrapped, w_step=1): +def range_int(space, w_x, w_y=None, w_step=1): """Return a list of integers in arithmetic position from start (defaults to zero) to stop - 1 by step (defaults to 1). Use a negative step to get a list in decending order.""" @@ -207,7 +207,7 @@ self.w_iter = w_iter self.w_index = w_start - def descr___new__(space, w_subtype, w_iterable, w_start=NoneNotWrapped): + def descr___new__(space, w_subtype, w_iterable, w_start=None): self = space.allocate_instance(W_Enumerate, w_subtype) if w_start is None: w_start = space.wrap(0) @@ -321,13 +321,13 @@ def descr_new(space, w_subtype, w_start, w_stop=None, w_step=None): start = _toint(space, w_start) - if space.is_w(w_step, space.w_None): # no step argument provided + if space.is_none(w_step): # no step argument provided step = 1 promote_step = True else: step = _toint(space, w_step) promote_step = False - if space.is_w(w_stop, space.w_None): # only 1 argument provided + if space.is_none(w_stop): # only 1 argument provided start, stop = 0, start else: stop = _toint(space, w_stop) diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -311,7 +311,7 @@ space.w_TypeError, space.wrap("instance() first arg must be class")) w_result = w_class.instantiate(space) - if not space.is_w(w_dict, space.w_None): + if not space.is_none(w_dict): w_result.setdict(space, w_dict) return w_result @@ -656,7 +656,7 @@ def descr_pow(self, space, w_other, w_modulo=None): - if space.is_w(w_modulo, space.w_None): + if space.is_none(w_modulo): w_a, w_b = _coerce_helper(space, self, w_other) if w_a is None: w_a = self @@ -676,7 +676,7 @@ return space.w_NotImplemented def descr_rpow(self, space, w_other, w_modulo=None): - if space.is_w(w_modulo, space.w_None): + if space.is_none(w_modulo): w_a, w_b = _coerce_helper(space, self, w_other) if w_a is None: w_a = self diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -4,7 +4,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, W_Root from pypy.rlib.runicode import UNICHR from pypy.rlib.rfloat import isnan, isinf, round_double from pypy.rlib import rfloat @@ -59,7 +59,7 @@ space.delattr(w_object, w_name) return space.w_None -def getattr(space, w_object, w_name, w_defvalue=NoneNotWrapped): +def getattr(space, w_object, w_name, w_defvalue=None): """Get a named attribute from an object. getattr(x, 'y') is equivalent to ``x.y''.""" w_name = checkattrname(space, w_name) @@ -176,7 +176,7 @@ ''', filename=__file__).interphook("iter_sentinel") -def iter(space, w_collection_or_callable, w_sentinel=NoneNotWrapped): +def iter(space, w_collection_or_callable, w_sentinel=None): """iter(collection) -> iterator over the elements of the collection. iter(callable, sentinel) -> iterator calling callable() until it returns @@ -187,7 +187,7 @@ else: return iter_sentinel(space, w_collection_or_callable, w_sentinel) -def next(space, w_iterator, w_default=NoneNotWrapped): +def next(space, w_iterator, w_default=None): """next(iterator[, default]) Return the next item from the iterator. If default is given and the iterator is exhausted, it is returned instead of raising StopIteration.""" @@ -202,7 +202,8 @@ """Return the integer ordinal of a character.""" return space.ord(w_val) -def pow(space, w_base, w_exponent, w_modulus=None): + at unwrap_spec(w_modulus = (W_Root, 'space.w_None')) +def pow(space, w_base, w_exponent, w_modulus): """With two arguments, equivalent to ``base**exponent''. With three arguments, equivalent to ``(base**exponent) % modulus'', but much more efficient for large exponents.""" diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -2,7 +2,7 @@ from pypy.interpreter.typedef import ( TypeDef, GetSetProperty, interp_attrproperty_w, interp_attrproperty, generic_new_descr) -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import intmask, r_ulonglong, r_uint @@ -46,13 +46,12 @@ def descr_init(self, space, w_decoder, translate, w_errors=None): self.w_decoder = w_decoder self.translate = translate - if space.is_w(w_errors, space.w_None): + if space.is_none(w_errors): self.w_errors = space.wrap("strict") else: self.w_errors = w_errors self.seennl = 0 - pendingcr = False def newlines_get_w(self, space): return self.w_newlines_dict.get(self.seennl, space.w_None) @@ -365,11 +364,11 @@ raise OperationError(space.w_IOError, space.wrap( "could not determine default encoding")) - if space.is_w(w_errors, space.w_None): + if space.is_none(w_errors): w_errors = space.wrap("strict") self.w_errors = w_errors - if space.is_w(w_newline, space.w_None): + if space.is_none(w_newline): newline = None else: newline = space.unicode_w(w_newline) @@ -484,6 +483,7 @@ self._writeflush(space) space.call_method(self.w_buffer, "flush") + @unwrap_spec(w_pos = (W_Root, 'space.w_None')) def truncate_w(self, space, w_pos=None): self._check_init(space) diff --git a/pypy/module/_minimal_curses/interp_curses.py b/pypy/module/_minimal_curses/interp_curses.py --- a/pypy/module/_minimal_curses/interp_curses.py +++ b/pypy/module/_minimal_curses/interp_curses.py @@ -48,7 +48,7 @@ fd = space.int_w(space.call_function(space.getattr(w_stdout, space.wrap('fileno')))) try: - if space.is_w(w_termname, space.w_None) or w_termname is None: + if space.is_none(w_termname): _curses_setupterm_null(fd) else: _curses_setupterm(space.str_w(w_termname), fd) diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py --- a/pypy/module/imp/interp_imp.py +++ b/pypy/module/imp/interp_imp.py @@ -33,7 +33,7 @@ return space.wrap(chr(a) + chr(b) + chr(c) + chr(d)) def get_file(space, w_file, filename, filemode): - if w_file is None or space.is_w(w_file, space.w_None): + if space.is_none(w_file): try: return streamio.open_file_as_stream(filename, filemode) except StreamErrors, e: @@ -46,7 +46,7 @@ def find_module(space, w_name, w_path=None): name = space.str0_w(w_name) - if space.is_w(w_path, space.w_None): + if space.is_none(w_path): w_path = None find_info = importing.find_module( @@ -103,7 +103,7 @@ importing.load_source_module( space, w_modulename, w_mod, filename, stream.readall(), stream.try_to_find_file_descriptor()) - if space.is_w(w_file, space.w_None): + if space.is_none(w_file): stream.close() return w_mod @@ -118,7 +118,7 @@ importing.load_compiled_module( space, w_modulename, w_module, filename, magic, timestamp, stream.readall()) - if space.is_w(w_file, space.w_None): + if space.is_none(w_file): stream.close() @unwrap_spec(filename='str0') From noreply at buildbot.pypy.org Wed Oct 10 18:02:42 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 18:02:42 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: make test_newgc pass Message-ID: <20121010160242.E07EE1C01CA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57980:c2dd48042f55 Date: 2012-10-10 18:02 +0200 http://bitbucket.org/pypy/pypy/changeset/c2dd48042f55/ Log: make test_newgc pass diff --git a/pypy/translator/c/test/test_newgc.py b/pypy/translator/c/test/test_newgc.py --- a/pypy/translator/c/test/test_newgc.py +++ b/pypy/translator/c/test/test_newgc.py @@ -41,7 +41,7 @@ print res return 0 - t = Translation(main, standalone=True, gc=cls.gcpolicy, + t = Translation(main, gc=cls.gcpolicy, taggedpointers=cls.taggedpointers, gcremovetypeptr=cls.removetypeptr) t.disable(['backendopt']) From noreply at buildbot.pypy.org Wed Oct 10 18:44:26 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 18:44:26 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix fix fix in-progress Message-ID: <20121010164426.4CFD81C0117@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57981:2fee47ecd40e Date: 2012-10-10 18:44 +0200 http://bitbucket.org/pypy/pypy/changeset/2fee47ecd40e/ Log: Fix fix fix in-progress diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -101,15 +101,7 @@ def maketestobjspace(config=None): if config is None: config = make_config(option) - try: - space = make_objspace(config) - except OperationError, e: - check_keyboard_interrupt(e) - if option.verbose: - import traceback - traceback.print_exc() - py.test.fail("fatal: cannot initialize objspace: %r" % - (config.objspace.name,)) + space = make_objspace(config) space.startup() # Initialize all builtin modules space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), appsupport.build_pytest_assertion(space)) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -448,6 +448,7 @@ - positional arguments must be as many as the function parameters - keywords arguments allow to change only some parameter specs """ + assert spec or kwargs def decorator(func): if kwargs: if spec: @@ -829,18 +830,28 @@ self.__name__ = f.func_name self.name = app_name self.as_classmethod = as_classmethod - self._staticdefs = list(f.func_defaults or ()) + + if not f.func_defaults: + self._staticdefs = [] + else: + from pypy.interpreter import pycode + defaults = f.func_defaults + argnames, _, _ = pycode.cpython_code_signature(f.func_code) + self._staticdefs = zip(argnames[-len(defaults):], defaults) return self def _getdefaults(self, space): "NOT_RPYTHON" - import pdb; pdb.set_trace() defs_w = [] - for val in self._staticdefs: - if val is NoneNotWrapped: + for name, defaultval in self._staticdefs: + if name.startswith('w_'): + assert defaultval is None, ( + "%s: default value for '%s' can only be None; " + "use unwrap_spec(...=(W_Root, 'default_expr'))" % ( + self._code.identifier, name)) defs_w.append(None) else: - defs_w.append(space.wrap(val)) + defs_w.append(space.wrap(defaultval)) return defs_w # lazy binding to space 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 @@ -571,6 +571,46 @@ unwrap_spec = gateway.BuiltinCode(f)._unwrap_spec assert unwrap_spec == [ObjSpace, W_Root, int] + def test_unwrap_spec_default_applevel(self): + space = self.space + @gateway.unwrap_spec(w_x = (W_Root, 'space.wrap(42)')) + def g(space, w_x): + return w_x + w_g = space.wrap(gateway.interp2app_temp(g)) + args = argument.Arguments(space, []) + w_res = space.call_args(w_g, args) + assert space.eq_w(w_res, space.wrap(42)) + # + args = argument.Arguments(space, [space.wrap(84)]) + w_res = space.call_args(w_g, args) + assert space.eq_w(w_res, space.wrap(84)) + + def test_unwrap_spec_default_applevel_2(self): + space = self.space + @gateway.unwrap_spec(w_x = (W_Root, 'space.wrap(42)'), y=int) + def g(space, w_x, y=10): + return space.add(w_x, space.wrap(y)) + w_g = space.wrap(gateway.interp2app_temp(g)) + args = argument.Arguments(space, []) + w_res = space.call_args(w_g, args) + assert space.eq_w(w_res, space.wrap(52)) + # + args = argument.Arguments(space, [space.wrap(84)]) + w_res = space.call_args(w_g, args) + assert space.eq_w(w_res, space.wrap(94)) + # + args = argument.Arguments(space, [space.wrap(84), space.wrap(-1)]) + w_res = space.call_args(w_g, args) + assert space.eq_w(w_res, space.wrap(83)) + + def test_unwrap_spec_default_applevel_bogus(self): + space = self.space + @gateway.unwrap_spec(w_x = (W_Root, 'space.wrap(42)'), y=int) + def g(space, w_x, y): + never_called + py.test.raises(AssertionError, space.wrap, gateway.interp2app_temp(g)) + + class AppTestPyTestMark: @py.test.mark.unlikely_to_exist def test_anything(self): diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -9,7 +9,6 @@ from pypy.rlib.rfloat import isnan, isinf, round_double from pypy.rlib import rfloat import __builtin__ -NoneNotWrapped = gateway.NoneNotWrapped def abs(space, w_val): "abs(number) -> number\n\nReturn the absolute value of the argument." diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -5,7 +5,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import unwrap_spec from pypy.rlib import jit from pypy.rlib.runicode import MAXUNICODE @@ -252,7 +252,7 @@ cdll = RawCDLL(handle) return space.wrap(W_CDLL(space, "python api", cdll)) -def getsizeof(space, w_object, w_default=NoneNotWrapped): +def getsizeof(space, w_object, w_default=None): """Not implemented on PyPy.""" if w_default is None: raise OperationError(space.w_TypeError, diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py --- a/pypy/objspace/std/floattype.py +++ b/pypy/objspace/std/floattype.py @@ -2,7 +2,8 @@ import sys from pypy.rlib.unroll import unrolling_iterable from pypy.rlib import rfloat, rarithmetic -from pypy.interpreter import gateway, typedef +from pypy.interpreter import typedef +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError from pypy.objspace.std.register_all import register_all @@ -21,7 +22,8 @@ register_all(vars(), globals()) -def descr__new__(space, w_floattype, w_x=0.0): + at unwrap_spec(w_x = (W_Root, 'space.wrap(0.0)')) +def descr__new__(space, w_floattype, w_x): from pypy.objspace.std.floatobject import W_FloatObject w_value = w_x # 'x' is the keyword argument name in CPython w_special = space.lookup(w_value, "__float__") @@ -86,7 +88,7 @@ _double_format, _float_format = detect_floatformat() - at gateway.unwrap_spec(kind=str) + at unwrap_spec(kind=str) def descr___getformat__(space, w_cls, kind): if kind == "float": return space.wrap(_float_format) @@ -111,7 +113,7 @@ i = co_end - 1 - j return _hex_from_char(s[i]) - at gateway.unwrap_spec(s=str) + at unwrap_spec(s=str) def descr_fromhex(space, w_cls, s): length = len(s) i = 0 @@ -274,12 +276,10 @@ __doc__ = '''float(x) -> floating point number Convert a string or number to a floating point number, if possible.''', - __new__ = gateway.interp2app(descr__new__), - __getformat__ = gateway.interp2app(descr___getformat__, - as_classmethod=True), - fromhex = gateway.interp2app(descr_fromhex, - as_classmethod=True), - conjugate = gateway.interp2app(descr_conjugate), + __new__ = interp2app(descr__new__), + __getformat__ = interp2app(descr___getformat__, as_classmethod=True), + fromhex = interp2app(descr_fromhex, as_classmethod=True), + conjugate = interp2app(descr_conjugate), real = typedef.GetSetProperty(descr_get_real), imag = typedef.GetSetProperty(descr_get_imag), ) diff --git a/pypy/objspace/std/stdtypedef.py b/pypy/objspace/std/stdtypedef.py --- a/pypy/objspace/std/stdtypedef.py +++ b/pypy/objspace/std/stdtypedef.py @@ -186,10 +186,11 @@ app_defaults = multimethod.extras.get('defaults', ()) i = len(argnames) - len(app_defaults) wrapper_signature = wrapper_arglist[:] + unwrap_spec_kwds = {} for app_default in app_defaults: name = wrapper_signature[i] - wrapper_signature[i] = '%s=%s' % (name, name) - miniglobals[name] = app_default + unwrap_spec_kwds[name] = (gateway.W_Root, + 'space.wrap(%r)' % (app_default,)) i += 1 wrapper_signature.insert(0, wrapper_signature.pop(selfindex)) @@ -239,7 +240,10 @@ """ % (prefix, wrapper_sig, renaming, expr, multimethod.operatorsymbol, ', '.join(solid_arglist)) exec compile2(code, '', 'exec') in miniglobals - return miniglobals["%s_perform_call" % prefix] + func = miniglobals["%s_perform_call" % prefix] + if unwrap_spec_kwds: + func = gateway.unwrap_spec(**unwrap_spec_kwds)(func) + return func def wrap_trampoline_in_gateway(func, methname, multimethod): """NOT_RPYTHON""" diff --git a/pypy/objspace/std/stringtype.py b/pypy/objspace/std/stringtype.py --- a/pypy/objspace/std/stringtype.py +++ b/pypy/objspace/std/stringtype.py @@ -1,4 +1,4 @@ -from pypy.interpreter import gateway +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.basestringtype import basestring_typedef from pypy.objspace.std.register_all import register_all @@ -290,7 +290,8 @@ # ____________________________________________________________ -def descr__new__(space, w_stringtype, w_object=''): + at unwrap_spec(w_object = (W_Root, 'space.wrap("")')) +def descr__new__(space, w_stringtype, w_object): # NB. the default value of w_object is really a *wrapped* empty string: # there is gateway magic at work from pypy.objspace.std.stringobject import W_StringObject @@ -311,7 +312,7 @@ # ____________________________________________________________ str_typedef = StdTypeDef("str", basestring_typedef, - __new__ = gateway.interp2app(descr__new__), + __new__ = interp2app(descr__new__), __doc__ = '''str(object) -> string Return a nice string representation of the object. From noreply at buildbot.pypy.org Wed Oct 10 19:06:51 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 19:06:51 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (fijal, arigo) Message-ID: <20121010170651.24A091C0117@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57982:1b821342e675 Date: 2012-10-10 19:06 +0200 http://bitbucket.org/pypy/pypy/changeset/1b821342e675/ Log: (fijal, arigo) Complicated messy logic for assigning defaults diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -13,7 +13,7 @@ import py -from pypy.interpreter import eval +from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments, Signature from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, SpaceCache, DescrMismatch) @@ -501,7 +501,7 @@ return unwrap_spec -class BuiltinCode(eval.Code): +class BuiltinCode(Code): "The code object implementing a built-in (interpreter-level) hook." _immutable_ = True hidden_applevel = True @@ -515,7 +515,7 @@ "NOT_RPYTHON" # 'implfunc' is the interpreter-level function. # Note that this uses a lot of (construction-time) introspection. - eval.Code.__init__(self, func.__name__) + Code.__init__(self, func.__name__) self.docstring = func.__doc__ self.identifier = "%s-%s-%s" % (func.__module__, func.__name__, @@ -536,6 +536,7 @@ # First extract the signature from the (CPython-level) code object from pypy.interpreter import pycode argnames, varargname, kwargname = pycode.cpython_code_signature(func.func_code) + self._argnames = argnames if unwrap_spec is None: unwrap_spec = build_unwrap_spec(func, argnames, self_type) @@ -671,7 +672,7 @@ class BuiltinCodePassThroughArguments1(BuiltinCode): _immutable_ = True - fast_natural_arity = eval.Code.PASSTHROUGHARGS1 + fast_natural_arity = Code.PASSTHROUGHARGS1 def funcrun_obj(self, func, w_obj, args): space = func.space @@ -834,9 +835,8 @@ if not f.func_defaults: self._staticdefs = [] else: - from pypy.interpreter import pycode + argnames = self._code._argnames defaults = f.func_defaults - argnames, _, _ = pycode.cpython_code_signature(f.func_code) self._staticdefs = zip(argnames[-len(defaults):], defaults) return self @@ -852,6 +852,31 @@ defs_w.append(None) else: defs_w.append(space.wrap(defaultval)) + if self._code._unwrap_spec: + UNDEFINED = object() + alldefs_w = [UNDEFINED] * len(self._code.sig[0]) + if defs_w: + alldefs_w[-len(defs_w):] = defs_w + code = self._code + assert isinstance(code._unwrap_spec, (list, tuple)) + assert isinstance(code._argnames, list) + assert len(code._unwrap_spec) == len(code._argnames) + for i in range(len(code._unwrap_spec)-1, -1, -1): + spec = code._unwrap_spec[i] + argname = code._argnames[i] + if isinstance(spec, tuple) and spec[0] is W_Root: + w_default = eval(spec[1], {'space': space}) + assert argname.startswith('w_') + argname = argname[2:] + j = self._code.sig[0].index(argname) + assert alldefs_w[j] in (UNDEFINED, None) + alldefs_w[j] = w_default + first_defined = 0 + while (first_defined < len(alldefs_w) and + alldefs_w[first_defined] is UNDEFINED): + first_defined += 1 + defs_w = alldefs_w[first_defined:] + assert UNDEFINED not in defs_w return defs_w # lazy binding to space From noreply at buildbot.pypy.org Wed Oct 10 19:28:21 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 19:28:21 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: kill NoneNotWrapped Message-ID: <20121010172821.86F851C0E82@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57983:34bc0615b806 Date: 2012-10-10 19:28 +0200 http://bitbucket.org/pypy/pypy/changeset/34bc0615b806/ Log: kill NoneNotWrapped diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -9,7 +9,7 @@ `import` statements:: from pypy.interpreter.baseobjspace import Wrappable - from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -343,7 +343,7 @@ def fget_func_defaults(self, space): values_w = self.defs_w # the `None in values_w` check here is to ensure that interp-level - # functions with a default of NoneNotWrapped do not get their defaults + # functions with a default of None do not get their defaults # exposed at applevel if not values_w or None in values_w: return space.w_None diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py --- a/pypy/interpreter/test/test_function.py +++ b/pypy/interpreter/test/test_function.py @@ -760,7 +760,7 @@ def test_func_defaults(self): from pypy.interpreter import gateway - def g(w_a=gateway.NoneNotWrapped): + def g(w_a=None): pass app_g = gateway.interp2app_temp(g) space = self.space diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -5,7 +5,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped, interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.typedef import TypeDef from pypy.rlib import jit from pypy.rlib.objectmodel import specialize @@ -47,7 +47,8 @@ n = 0 return n -def range_int(space, w_x, w_y=None, w_step=1): + at unwrap_spec(w_step = (W_Root, 'space.wrap(1)')) +def range_int(space, w_x, w_y=None, w_step=None): """Return a list of integers in arithmetic position from start (defaults to zero) to stop - 1 by step (defaults to 1). Use a negative step to get a list in decending order.""" diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -388,8 +388,9 @@ def make_decoder_wrapper(name): rname = "str_decode_%s" % (name.replace("_decode", ""), ) assert hasattr(runicode, rname) - @unwrap_spec(string='bufferstr', errors='str_or_None') - def wrap_decoder(space, string, errors="strict", w_final=False): + @unwrap_spec(string='bufferstr', errors='str_or_None', + w_final=(W_Root, 'space.w_False')) + def wrap_decoder(space, string, errors="strict", w_final=None): if errors is None: errors = 'strict' final = space.is_true(w_final) @@ -447,8 +448,9 @@ allow_surrogates=True) return space.newtuple([space.wrap(result), space.wrap(len(uni))]) - at unwrap_spec(string='bufferstr', errors='str_or_None') -def utf_8_decode(space, string, errors="strict", w_final=False): + at unwrap_spec(string='bufferstr', errors='str_or_None', + w_final = (W_Root, 'space.w_False')) +def utf_8_decode(space, string, errors="strict", w_final=None): if errors is None: errors = 'strict' final = space.is_true(w_final) @@ -459,8 +461,9 @@ allow_surrogates=True) return space.newtuple([space.wrap(result), space.wrap(consumed)]) - at unwrap_spec(data=str, errors='str_or_None', byteorder=int) -def utf_16_ex_decode(space, data, errors='strict', byteorder=0, w_final=False): + at unwrap_spec(data=str, errors='str_or_None', byteorder=int, + w_final=(W_Root, 'space.w_False')) +def utf_16_ex_decode(space, data, errors='strict', byteorder=0, w_final=None): if errors is None: errors = 'strict' final = space.is_true(w_final) @@ -479,8 +482,9 @@ return space.newtuple([space.wrap(res), space.wrap(consumed), space.wrap(byteorder)]) - at unwrap_spec(data=str, errors='str_or_None', byteorder=int) -def utf_32_ex_decode(space, data, errors='strict', byteorder=0, w_final=False): + at unwrap_spec(data=str, errors='str_or_None', byteorder=int, + w_final=(W_Root, 'space.w_False')) +def utf_32_ex_decode(space, data, errors='strict', byteorder=0, w_final=None): final = space.is_true(w_final) state = space.fromcache(CodecState) if byteorder == 0: @@ -660,13 +664,13 @@ return -1 return space.int_w(w_code) - at unwrap_spec(string='bufferstr', errors='str_or_None') -def unicode_escape_decode(space, string, errors="strict", w_final=False): + at unwrap_spec(string='bufferstr', errors='str_or_None', + w_final=(W_Root, 'space.w_False')) +def unicode_escape_decode(space, string, errors="strict", w_final=None): if errors is None: errors = 'strict' final = space.is_true(w_final) state = space.fromcache(CodecState) - errorhandler=state.decode_error_handler unicode_name_handler = state.get_unicodedata_handler(space) diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py --- a/pypy/module/_collections/interp_deque.py +++ b/pypy/module/_collections/interp_deque.py @@ -3,7 +3,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.interpreter.typedef import GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError from pypy.rlib.debug import check_nonneg @@ -80,7 +80,7 @@ self.space.w_RuntimeError, self.space.wrap("deque mutated during iteration")) - def init(self, w_iterable=NoneNotWrapped, w_maxlen=None): + def init(self, w_iterable=None, w_maxlen=None): space = self.space if space.is_w(w_maxlen, space.w_None): maxlen = sys.maxint diff --git a/pypy/module/_csv/interp_csv.py b/pypy/module/_csv/interp_csv.py --- a/pypy/module/_csv/interp_csv.py +++ b/pypy/module/_csv/interp_csv.py @@ -2,7 +2,7 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.interpreter.typedef import GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) @@ -116,15 +116,15 @@ dialect.quoting = tmp_quoting return dialect -def W_Dialect___new__(space, w_subtype, w_dialect = NoneNotWrapped, - w_delimiter = NoneNotWrapped, - w_doublequote = NoneNotWrapped, - w_escapechar = NoneNotWrapped, - w_lineterminator = NoneNotWrapped, - w_quotechar = NoneNotWrapped, - w_quoting = NoneNotWrapped, - w_skipinitialspace = NoneNotWrapped, - w_strict = NoneNotWrapped, +def W_Dialect___new__(space, w_subtype, w_dialect = None, + w_delimiter = None, + w_doublequote = None, + w_escapechar = None, + w_lineterminator = None, + w_quotechar = None, + w_quoting = None, + w_skipinitialspace = None, + w_strict = None, ): dialect = _build_dialect(space, w_dialect, w_delimiter, w_doublequote, w_escapechar, w_lineterminator, w_quotechar, diff --git a/pypy/module/_csv/interp_reader.py b/pypy/module/_csv/interp_reader.py --- a/pypy/module/_csv/interp_reader.py +++ b/pypy/module/_csv/interp_reader.py @@ -1,7 +1,7 @@ from pypy.rlib.rstring import StringBuilder from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped, unwrap_spec +from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.typedef import TypeDef, interp2app from pypy.interpreter.typedef import interp_attrproperty_w, interp_attrproperty from pypy.module._csv.interp_csv import _build_dialect @@ -213,15 +213,15 @@ return w_result -def csv_reader(space, w_iterator, w_dialect=NoneNotWrapped, - w_delimiter = NoneNotWrapped, - w_doublequote = NoneNotWrapped, - w_escapechar = NoneNotWrapped, - w_lineterminator = NoneNotWrapped, - w_quotechar = NoneNotWrapped, - w_quoting = NoneNotWrapped, - w_skipinitialspace = NoneNotWrapped, - w_strict = NoneNotWrapped, +def csv_reader(space, w_iterator, w_dialect=None, + w_delimiter = None, + w_doublequote = None, + w_escapechar = None, + w_lineterminator = None, + w_quotechar = None, + w_quoting = None, + w_skipinitialspace = None, + w_strict = None, ): """ csv_reader = reader(iterable [, dialect='excel'] diff --git a/pypy/module/_csv/interp_writer.py b/pypy/module/_csv/interp_writer.py --- a/pypy/module/_csv/interp_writer.py +++ b/pypy/module/_csv/interp_writer.py @@ -1,7 +1,6 @@ from pypy.rlib.rstring import StringBuilder from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.typedef import TypeDef, interp2app from pypy.interpreter.typedef import interp_attrproperty_w from pypy.module._csv.interp_csv import _build_dialect @@ -131,15 +130,15 @@ self.writerow(w_seq) -def csv_writer(space, w_fileobj, w_dialect=NoneNotWrapped, - w_delimiter = NoneNotWrapped, - w_doublequote = NoneNotWrapped, - w_escapechar = NoneNotWrapped, - w_lineterminator = NoneNotWrapped, - w_quotechar = NoneNotWrapped, - w_quoting = NoneNotWrapped, - w_skipinitialspace = NoneNotWrapped, - w_strict = NoneNotWrapped, +def csv_writer(space, w_fileobj, w_dialect=None, + w_delimiter = None, + w_doublequote = None, + w_escapechar = None, + w_lineterminator = None, + w_quotechar = None, + w_quoting = None, + w_skipinitialspace = None, + w_strict = None, ): """ csv_writer = csv.writer(fileobj [, dialect='excel'] diff --git a/pypy/module/_lsprof/interp_lsprof.py b/pypy/module/_lsprof/interp_lsprof.py --- a/pypy/module/_lsprof/interp_lsprof.py +++ b/pypy/module/_lsprof/interp_lsprof.py @@ -3,7 +3,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.interpreter.function import Method, Function -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import (TypeDef, GetSetProperty, interp_attrproperty) from pypy.rlib import jit @@ -266,8 +266,8 @@ return timer_size_int(0) return read_timestamp() - def enable(self, space, w_subcalls=NoneNotWrapped, - w_builtins=NoneNotWrapped): + def enable(self, space, w_subcalls=None, + w_builtins=None): if self.is_enabled: return # ignored if w_subcalls is not None: @@ -378,7 +378,7 @@ factor) @unwrap_spec(time_unit=float, subcalls=bool, builtins=bool) -def descr_new_profile(space, w_type, w_callable=NoneNotWrapped, time_unit=0.0, +def descr_new_profile(space, w_type, w_callable=None, time_unit=0.0, subcalls=True, builtins=True): p = space.allocate_instance(W_Profiler, w_type) p.__init__(space, w_callable, time_unit, subcalls, builtins) diff --git a/pypy/module/_random/interp_random.py b/pypy/module/_random/interp_random.py --- a/pypy/module/_random/interp_random.py +++ b/pypy/module/_random/interp_random.py @@ -1,6 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.gateway import NoneNotWrapped, interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.baseobjspace import Wrappable from pypy.rlib.rarithmetic import r_uint, intmask from pypy.rlib import rrandom @@ -22,7 +22,7 @@ def random(self, space): return space.newfloat(self._rnd.random()) - def seed(self, space, w_n=NoneNotWrapped): + def seed(self, space, w_n=None): if w_n is None: w_n = space.newint(int(time.time())) else: diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, make_weakref_descr,\ interp_attrproperty -from pypy.interpreter.gateway import NoneNotWrapped, interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.rlib.rarithmetic import intmask from pypy.rlib import rsocket from pypy.rlib.rsocket import RSocket, AF_INET, SOCK_STREAM @@ -121,7 +121,7 @@ raise converted_error(space, e) @unwrap_spec(level=int, optname=int) - def getsockopt_w(self, space, level, optname, w_buflen=NoneNotWrapped): + def getsockopt_w(self, space, level, optname, w_buflen=None): """getsockopt(level, option[, buffersize]) -> value Get a socket option. See the Unix manual for level and option. @@ -228,7 +228,7 @@ raise converted_error(space, e) @unwrap_spec(data='bufferstr') - def sendto_w(self, space, data, w_param2, w_param3=NoneNotWrapped): + def sendto_w(self, space, data, w_param2, w_param3=None): """sendto(data[, flags], address) -> count Like send(data, flags) but allows specifying the destination address. diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -3,7 +3,7 @@ from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.typedef import make_weakref_descr -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import intmask from pypy.tool.pairtype import extendabletype @@ -387,13 +387,16 @@ return space.call_method(w_re, '_expand', space.wrap(self.srepat), space.wrap(self), w_template) - def start_w(self, w_groupnum=0): + @unwrap_spec(w_groupnum = (W_Root, 'space.wrap(0)')) + def start_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[0]) - def end_w(self, w_groupnum=0): + @unwrap_spec(w_groupnum = (W_Root, 'space.wrap(0)')) + def end_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[1]) - def span_w(self, w_groupnum=0): + @unwrap_spec(w_groupnum = (W_Root, 'space.wrap(0)')) + def span_w(self, w_groupnum): start, end = self.do_span(w_groupnum) return self.space.newtuple([self.space.wrap(start), self.space.wrap(end)]) diff --git a/pypy/module/_warnings/interp_warnings.py b/pypy/module/_warnings/interp_warnings.py --- a/pypy/module/_warnings/interp_warnings.py +++ b/pypy/module/_warnings/interp_warnings.py @@ -1,4 +1,4 @@ -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, W_Root from pypy.interpreter.error import OperationError def create_filter(space, w_category, action): @@ -343,7 +343,9 @@ w_source_line = space.getitem(w_source_list, space.wrap(lineno - 1)) return w_source_line - at unwrap_spec(lineno=int) + at unwrap_spec(lineno=int, w_module = (W_Root, 'space.w_None'), + w_registry = (W_Root, 'space.w_None'), + w_module_globals = (W_Root, 'space.w_None')) def warn_explicit(space, w_message, w_category, w_filename, lineno, w_module=None, w_registry=None, w_module_globals=None): diff --git a/pypy/module/cmath/interp_cmath.py b/pypy/module/cmath/interp_cmath.py --- a/pypy/module/cmath/interp_cmath.py +++ b/pypy/module/cmath/interp_cmath.py @@ -2,7 +2,6 @@ from pypy.rlib.objectmodel import specialize from pypy.tool.sourcetools import func_with_new_name from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped from pypy.module.cmath import names_and_docstrings from pypy.rlib import rcomplex @@ -75,7 +74,7 @@ _inner_wrapped_log = wrapped_log -def wrapped_log(space, w_z, w_base=NoneNotWrapped): +def wrapped_log(space, w_z, w_base=None): w_logz = _inner_wrapped_log(space, w_z) if w_base is not None: w_logbase = _inner_wrapped_log(space, w_base) diff --git a/pypy/module/marshal/interp_marshal.py b/pypy/module/marshal/interp_marshal.py --- a/pypy/module/marshal/interp_marshal.py +++ b/pypy/module/marshal/interp_marshal.py @@ -1,4 +1,5 @@ from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import W_Root, unwrap_spec from pypy.rlib.rarithmetic import intmask from pypy.rlib import rstackovf from pypy.module._file.interp_file import W_File @@ -6,7 +7,8 @@ Py_MARSHAL_VERSION = 2 -def dump(space, w_data, w_f, w_version=Py_MARSHAL_VERSION): + at unwrap_spec(w_version = (W_Root, 'space.wrap(%d)' % Py_MARSHAL_VERSION)) +def dump(space, w_data, w_f, w_version): """Write the 'data' object into the open file 'f'.""" # special case real files for performance file = space.interpclass_w(w_f) @@ -23,7 +25,8 @@ finally: writer.finished() -def dumps(space, w_data, w_version=Py_MARSHAL_VERSION): + at unwrap_spec(w_version = (W_Root, 'space.wrap(%d)' % Py_MARSHAL_VERSION)) +def dumps(space, w_data, w_version): """Return the string that would have been written to a file by dump(data, file).""" m = StringMarshaller(space, space.int_w(w_version)) 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 @@ -3,7 +3,6 @@ from pypy.rlib import rfloat, unroll from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped class State: def __init__(self, space): @@ -204,7 +203,7 @@ space.wrap('math domain error')) return space.wrap(result) -def log(space, w_x, w_base=NoneNotWrapped): +def log(space, w_x, w_base=None): """log(x[, base]) -> the logarithm of x to the given base. If the base not specified, returns the natural logarithm (base e) of x. """ diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -1,7 +1,7 @@ from pypy.interpreter.error import OperationError, wrap_oserror from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.rlib import rmmap, rarithmetic from pypy.rlib.rmmap import RValueError, RTypeError @@ -35,7 +35,7 @@ return self.space.wrap(self.mmap.read(num)) @unwrap_spec(tofind='bufferstr') - def find(self, tofind, w_start=NoneNotWrapped, w_end=NoneNotWrapped): + def find(self, tofind, w_start=None, w_end=None): space = self.space if w_start is None: start = self.mmap.pos @@ -48,7 +48,7 @@ return space.wrap(self.mmap.find(tofind, start, end)) @unwrap_spec(tofind='bufferstr') - def rfind(self, tofind, w_start=NoneNotWrapped, w_end=NoneNotWrapped): + def rfind(self, tofind, w_start=None, w_end=None): space = self.space if w_start is None: start = self.mmap.pos diff --git a/pypy/module/oracle/interp_connect.py b/pypy/module/oracle/interp_connect.py --- a/pypy/module/oracle/interp_connect.py +++ b/pypy/module/oracle/interp_connect.py @@ -1,13 +1,11 @@ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.typedef import (TypeDef, interp_attrproperty_w, GetSetProperty) from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import rffi, lltype -Null = NoneNotWrapped - from pypy.module.oracle import roci, interp_error from pypy.module.oracle.config import string_w, StringBuffer, MAX_STRING_CHARS from pypy.module.oracle.interp_environ import Environment @@ -35,18 +33,18 @@ threaded=bool, twophase=bool, events=bool, purity=bool) def descr_new(space, w_subtype, - w_user=NoneNotWrapped, - w_password=NoneNotWrapped, - w_dsn=NoneNotWrapped, + w_user=None, + w_password=None, + w_dsn=None, mode=roci.OCI_DEFAULT, handle=0, # XXX should be a ptr type - w_pool=Null, + w_pool=None, threaded=False, twophase=False, events=False, - w_cclass=Null, + w_cclass=None, purity=0, - w_newpassword=Null): + w_newpassword=None): self = space.allocate_instance(W_Connection, w_subtype) W_Connection.__init__(self) diff --git a/pypy/module/oracle/interp_pool.py b/pypy/module/oracle/interp_pool.py --- a/pypy/module/oracle/interp_pool.py +++ b/pypy/module/oracle/interp_pool.py @@ -1,14 +1,11 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.argument import Arguments, Signature -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import rffi, lltype -Null = NoneNotWrapped - from pypy.module.oracle import roci, config from pypy.module.oracle import interp_error, interp_environ from pypy.module.oracle.interp_error import get @@ -22,7 +19,7 @@ def descr_new(space, w_subtype, w_user, w_password, w_dsn, min, max, increment, - w_connectiontype=Null, + w_connectiontype=None, threaded=False, getmode=roci.OCI_SPOOL_ATTRVAL_NOWAIT, events=False, diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -5,7 +5,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, W_Root from pypy.rlib import jit from pypy.rlib.runicode import MAXUNICODE @@ -20,7 +20,8 @@ "trying to change the builtin-in module %r" % (name,)) space.setitem(w_modules, space.wrap(name), w_module) -def _getframe(space, w_depth=0): + at unwrap_spec(w_depth = (W_Root, 'space.wrap(0)')) +def _getframe(space, w_depth): """Return a frame object from the call stack. If optional integer depth is given, return the frame object that many calls below the top of the stack. If that is deeper than the call stack, ValueError is raised. The default 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 @@ -5,7 +5,7 @@ from pypy.module.thread import ll_thread as thread from pypy.module.thread.error import wrap_thread_error from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import unwrap_spec, NoneNotWrapped, Arguments +from pypy.interpreter.gateway import unwrap_spec, Arguments # Here are the steps performed to start a new thread: # @@ -152,7 +152,7 @@ space.call_method(w_threading, "_after_fork") -def start_new_thread(space, w_callable, w_args, w_kwargs=NoneNotWrapped): +def start_new_thread(space, w_callable, w_args, w_kwargs=None): """Start a new thread and return its identifier. The thread will call the function with positional arguments from the tuple args and keyword arguments taken from the optional dictionary kwargs. The thread exits when the diff --git a/pypy/module/unicodedata/interp_ucd.py b/pypy/module/unicodedata/interp_ucd.py --- a/pypy/module/unicodedata/interp_ucd.py +++ b/pypy/module/unicodedata/interp_ucd.py @@ -1,7 +1,7 @@ """ Implementation of the interpreter-level functions in the module unicodedata. """ -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, interp_attrproperty @@ -139,7 +139,7 @@ raise OperationError(space.w_KeyError, msg) return space.wrap(code_to_unichr(code)) - def name(self, space, w_unichr, w_default=NoneNotWrapped): + def name(self, space, w_unichr, w_default=None): code = unichr_to_code_w(space, w_unichr) try: name = self._name(code) @@ -150,7 +150,7 @@ return space.wrap(name) - def decimal(self, space, w_unichr, w_default=NoneNotWrapped): + def decimal(self, space, w_unichr, w_default=None): code = unichr_to_code_w(space, w_unichr) try: return space.wrap(self._decimal(code)) @@ -160,7 +160,7 @@ return w_default raise OperationError(space.w_ValueError, space.wrap('not a decimal')) - def digit(self, space, w_unichr, w_default=NoneNotWrapped): + def digit(self, space, w_unichr, w_default=None): code = unichr_to_code_w(space, w_unichr) try: return space.wrap(self._digit(code)) @@ -170,7 +170,7 @@ return w_default raise OperationError(space.w_ValueError, space.wrap('not a digit')) - def numeric(self, space, w_unichr, w_default=NoneNotWrapped): + def numeric(self, space, w_unichr, w_default=None): code = unichr_to_code_w(space, w_unichr) try: return space.wrap(self._numeric(code)) From noreply at buildbot.pypy.org Wed Oct 10 19:28:47 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 19:28:47 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: An extra assert. Message-ID: <20121010172847.166721C0E82@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57984:88341d339b59 Date: 2012-10-10 19:19 +0200 http://bitbucket.org/pypy/pypy/changeset/88341d339b59/ Log: An extra assert. diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -866,6 +866,7 @@ argname = code._argnames[i] if isinstance(spec, tuple) and spec[0] is W_Root: w_default = eval(spec[1], {'space': space}) + assert isinstance(w_default, W_Root) assert argname.startswith('w_') argname = argname[2:] j = self._code.sig[0].index(argname) From noreply at buildbot.pypy.org Wed Oct 10 19:28:48 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 10 Oct 2012 19:28:48 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge heads Message-ID: <20121010172848.5BA691C0E82@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r57985:ef338e0987e1 Date: 2012-10-10 19:28 +0200 http://bitbucket.org/pypy/pypy/changeset/ef338e0987e1/ Log: merge heads diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -9,7 +9,7 @@ `import` statements:: from pypy.interpreter.baseobjspace import Wrappable - from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -343,7 +343,7 @@ def fget_func_defaults(self, space): values_w = self.defs_w # the `None in values_w` check here is to ensure that interp-level - # functions with a default of NoneNotWrapped do not get their defaults + # functions with a default of None do not get their defaults # exposed at applevel if not values_w or None in values_w: return space.w_None diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py --- a/pypy/interpreter/test/test_function.py +++ b/pypy/interpreter/test/test_function.py @@ -760,7 +760,7 @@ def test_func_defaults(self): from pypy.interpreter import gateway - def g(w_a=gateway.NoneNotWrapped): + def g(w_a=None): pass app_g = gateway.interp2app_temp(g) space = self.space diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -5,7 +5,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped, interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.typedef import TypeDef from pypy.rlib import jit from pypy.rlib.objectmodel import specialize @@ -47,7 +47,8 @@ n = 0 return n -def range_int(space, w_x, w_y=None, w_step=1): + at unwrap_spec(w_step = (W_Root, 'space.wrap(1)')) +def range_int(space, w_x, w_y=None, w_step=None): """Return a list of integers in arithmetic position from start (defaults to zero) to stop - 1 by step (defaults to 1). Use a negative step to get a list in decending order.""" diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -388,8 +388,9 @@ def make_decoder_wrapper(name): rname = "str_decode_%s" % (name.replace("_decode", ""), ) assert hasattr(runicode, rname) - @unwrap_spec(string='bufferstr', errors='str_or_None') - def wrap_decoder(space, string, errors="strict", w_final=False): + @unwrap_spec(string='bufferstr', errors='str_or_None', + w_final=(W_Root, 'space.w_False')) + def wrap_decoder(space, string, errors="strict", w_final=None): if errors is None: errors = 'strict' final = space.is_true(w_final) @@ -447,8 +448,9 @@ allow_surrogates=True) return space.newtuple([space.wrap(result), space.wrap(len(uni))]) - at unwrap_spec(string='bufferstr', errors='str_or_None') -def utf_8_decode(space, string, errors="strict", w_final=False): + at unwrap_spec(string='bufferstr', errors='str_or_None', + w_final = (W_Root, 'space.w_False')) +def utf_8_decode(space, string, errors="strict", w_final=None): if errors is None: errors = 'strict' final = space.is_true(w_final) @@ -459,8 +461,9 @@ allow_surrogates=True) return space.newtuple([space.wrap(result), space.wrap(consumed)]) - at unwrap_spec(data=str, errors='str_or_None', byteorder=int) -def utf_16_ex_decode(space, data, errors='strict', byteorder=0, w_final=False): + at unwrap_spec(data=str, errors='str_or_None', byteorder=int, + w_final=(W_Root, 'space.w_False')) +def utf_16_ex_decode(space, data, errors='strict', byteorder=0, w_final=None): if errors is None: errors = 'strict' final = space.is_true(w_final) @@ -479,8 +482,9 @@ return space.newtuple([space.wrap(res), space.wrap(consumed), space.wrap(byteorder)]) - at unwrap_spec(data=str, errors='str_or_None', byteorder=int) -def utf_32_ex_decode(space, data, errors='strict', byteorder=0, w_final=False): + at unwrap_spec(data=str, errors='str_or_None', byteorder=int, + w_final=(W_Root, 'space.w_False')) +def utf_32_ex_decode(space, data, errors='strict', byteorder=0, w_final=None): final = space.is_true(w_final) state = space.fromcache(CodecState) if byteorder == 0: @@ -660,13 +664,13 @@ return -1 return space.int_w(w_code) - at unwrap_spec(string='bufferstr', errors='str_or_None') -def unicode_escape_decode(space, string, errors="strict", w_final=False): + at unwrap_spec(string='bufferstr', errors='str_or_None', + w_final=(W_Root, 'space.w_False')) +def unicode_escape_decode(space, string, errors="strict", w_final=None): if errors is None: errors = 'strict' final = space.is_true(w_final) state = space.fromcache(CodecState) - errorhandler=state.decode_error_handler unicode_name_handler = state.get_unicodedata_handler(space) diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py --- a/pypy/module/_collections/interp_deque.py +++ b/pypy/module/_collections/interp_deque.py @@ -3,7 +3,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.interpreter.typedef import GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError from pypy.rlib.debug import check_nonneg @@ -80,7 +80,7 @@ self.space.w_RuntimeError, self.space.wrap("deque mutated during iteration")) - def init(self, w_iterable=NoneNotWrapped, w_maxlen=None): + def init(self, w_iterable=None, w_maxlen=None): space = self.space if space.is_w(w_maxlen, space.w_None): maxlen = sys.maxint diff --git a/pypy/module/_csv/interp_csv.py b/pypy/module/_csv/interp_csv.py --- a/pypy/module/_csv/interp_csv.py +++ b/pypy/module/_csv/interp_csv.py @@ -2,7 +2,7 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.interpreter.typedef import GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE = range(4) @@ -116,15 +116,15 @@ dialect.quoting = tmp_quoting return dialect -def W_Dialect___new__(space, w_subtype, w_dialect = NoneNotWrapped, - w_delimiter = NoneNotWrapped, - w_doublequote = NoneNotWrapped, - w_escapechar = NoneNotWrapped, - w_lineterminator = NoneNotWrapped, - w_quotechar = NoneNotWrapped, - w_quoting = NoneNotWrapped, - w_skipinitialspace = NoneNotWrapped, - w_strict = NoneNotWrapped, +def W_Dialect___new__(space, w_subtype, w_dialect = None, + w_delimiter = None, + w_doublequote = None, + w_escapechar = None, + w_lineterminator = None, + w_quotechar = None, + w_quoting = None, + w_skipinitialspace = None, + w_strict = None, ): dialect = _build_dialect(space, w_dialect, w_delimiter, w_doublequote, w_escapechar, w_lineterminator, w_quotechar, diff --git a/pypy/module/_csv/interp_reader.py b/pypy/module/_csv/interp_reader.py --- a/pypy/module/_csv/interp_reader.py +++ b/pypy/module/_csv/interp_reader.py @@ -1,7 +1,7 @@ from pypy.rlib.rstring import StringBuilder from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped, unwrap_spec +from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.typedef import TypeDef, interp2app from pypy.interpreter.typedef import interp_attrproperty_w, interp_attrproperty from pypy.module._csv.interp_csv import _build_dialect @@ -213,15 +213,15 @@ return w_result -def csv_reader(space, w_iterator, w_dialect=NoneNotWrapped, - w_delimiter = NoneNotWrapped, - w_doublequote = NoneNotWrapped, - w_escapechar = NoneNotWrapped, - w_lineterminator = NoneNotWrapped, - w_quotechar = NoneNotWrapped, - w_quoting = NoneNotWrapped, - w_skipinitialspace = NoneNotWrapped, - w_strict = NoneNotWrapped, +def csv_reader(space, w_iterator, w_dialect=None, + w_delimiter = None, + w_doublequote = None, + w_escapechar = None, + w_lineterminator = None, + w_quotechar = None, + w_quoting = None, + w_skipinitialspace = None, + w_strict = None, ): """ csv_reader = reader(iterable [, dialect='excel'] diff --git a/pypy/module/_csv/interp_writer.py b/pypy/module/_csv/interp_writer.py --- a/pypy/module/_csv/interp_writer.py +++ b/pypy/module/_csv/interp_writer.py @@ -1,7 +1,6 @@ from pypy.rlib.rstring import StringBuilder from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.typedef import TypeDef, interp2app from pypy.interpreter.typedef import interp_attrproperty_w from pypy.module._csv.interp_csv import _build_dialect @@ -131,15 +130,15 @@ self.writerow(w_seq) -def csv_writer(space, w_fileobj, w_dialect=NoneNotWrapped, - w_delimiter = NoneNotWrapped, - w_doublequote = NoneNotWrapped, - w_escapechar = NoneNotWrapped, - w_lineterminator = NoneNotWrapped, - w_quotechar = NoneNotWrapped, - w_quoting = NoneNotWrapped, - w_skipinitialspace = NoneNotWrapped, - w_strict = NoneNotWrapped, +def csv_writer(space, w_fileobj, w_dialect=None, + w_delimiter = None, + w_doublequote = None, + w_escapechar = None, + w_lineterminator = None, + w_quotechar = None, + w_quoting = None, + w_skipinitialspace = None, + w_strict = None, ): """ csv_writer = csv.writer(fileobj [, dialect='excel'] diff --git a/pypy/module/_lsprof/interp_lsprof.py b/pypy/module/_lsprof/interp_lsprof.py --- a/pypy/module/_lsprof/interp_lsprof.py +++ b/pypy/module/_lsprof/interp_lsprof.py @@ -3,7 +3,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.interpreter.function import Method, Function -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import (TypeDef, GetSetProperty, interp_attrproperty) from pypy.rlib import jit @@ -266,8 +266,8 @@ return timer_size_int(0) return read_timestamp() - def enable(self, space, w_subcalls=NoneNotWrapped, - w_builtins=NoneNotWrapped): + def enable(self, space, w_subcalls=None, + w_builtins=None): if self.is_enabled: return # ignored if w_subcalls is not None: @@ -378,7 +378,7 @@ factor) @unwrap_spec(time_unit=float, subcalls=bool, builtins=bool) -def descr_new_profile(space, w_type, w_callable=NoneNotWrapped, time_unit=0.0, +def descr_new_profile(space, w_type, w_callable=None, time_unit=0.0, subcalls=True, builtins=True): p = space.allocate_instance(W_Profiler, w_type) p.__init__(space, w_callable, time_unit, subcalls, builtins) diff --git a/pypy/module/_random/interp_random.py b/pypy/module/_random/interp_random.py --- a/pypy/module/_random/interp_random.py +++ b/pypy/module/_random/interp_random.py @@ -1,6 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.gateway import NoneNotWrapped, interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.baseobjspace import Wrappable from pypy.rlib.rarithmetic import r_uint, intmask from pypy.rlib import rrandom @@ -22,7 +22,7 @@ def random(self, space): return space.newfloat(self._rnd.random()) - def seed(self, space, w_n=NoneNotWrapped): + def seed(self, space, w_n=None): if w_n is None: w_n = space.newint(int(time.time())) else: diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, make_weakref_descr,\ interp_attrproperty -from pypy.interpreter.gateway import NoneNotWrapped, interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.rlib.rarithmetic import intmask from pypy.rlib import rsocket from pypy.rlib.rsocket import RSocket, AF_INET, SOCK_STREAM @@ -121,7 +121,7 @@ raise converted_error(space, e) @unwrap_spec(level=int, optname=int) - def getsockopt_w(self, space, level, optname, w_buflen=NoneNotWrapped): + def getsockopt_w(self, space, level, optname, w_buflen=None): """getsockopt(level, option[, buffersize]) -> value Get a socket option. See the Unix manual for level and option. @@ -228,7 +228,7 @@ raise converted_error(space, e) @unwrap_spec(data='bufferstr') - def sendto_w(self, space, data, w_param2, w_param3=NoneNotWrapped): + def sendto_w(self, space, data, w_param2, w_param3=None): """sendto(data[, flags], address) -> count Like send(data, flags) but allows specifying the destination address. diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -3,7 +3,7 @@ from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.typedef import make_weakref_descr -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import intmask from pypy.tool.pairtype import extendabletype @@ -387,13 +387,16 @@ return space.call_method(w_re, '_expand', space.wrap(self.srepat), space.wrap(self), w_template) - def start_w(self, w_groupnum=0): + @unwrap_spec(w_groupnum = (W_Root, 'space.wrap(0)')) + def start_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[0]) - def end_w(self, w_groupnum=0): + @unwrap_spec(w_groupnum = (W_Root, 'space.wrap(0)')) + def end_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[1]) - def span_w(self, w_groupnum=0): + @unwrap_spec(w_groupnum = (W_Root, 'space.wrap(0)')) + def span_w(self, w_groupnum): start, end = self.do_span(w_groupnum) return self.space.newtuple([self.space.wrap(start), self.space.wrap(end)]) diff --git a/pypy/module/_warnings/interp_warnings.py b/pypy/module/_warnings/interp_warnings.py --- a/pypy/module/_warnings/interp_warnings.py +++ b/pypy/module/_warnings/interp_warnings.py @@ -1,4 +1,4 @@ -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, W_Root from pypy.interpreter.error import OperationError def create_filter(space, w_category, action): @@ -343,7 +343,9 @@ w_source_line = space.getitem(w_source_list, space.wrap(lineno - 1)) return w_source_line - at unwrap_spec(lineno=int) + at unwrap_spec(lineno=int, w_module = (W_Root, 'space.w_None'), + w_registry = (W_Root, 'space.w_None'), + w_module_globals = (W_Root, 'space.w_None')) def warn_explicit(space, w_message, w_category, w_filename, lineno, w_module=None, w_registry=None, w_module_globals=None): diff --git a/pypy/module/cmath/interp_cmath.py b/pypy/module/cmath/interp_cmath.py --- a/pypy/module/cmath/interp_cmath.py +++ b/pypy/module/cmath/interp_cmath.py @@ -2,7 +2,6 @@ from pypy.rlib.objectmodel import specialize from pypy.tool.sourcetools import func_with_new_name from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped from pypy.module.cmath import names_and_docstrings from pypy.rlib import rcomplex @@ -75,7 +74,7 @@ _inner_wrapped_log = wrapped_log -def wrapped_log(space, w_z, w_base=NoneNotWrapped): +def wrapped_log(space, w_z, w_base=None): w_logz = _inner_wrapped_log(space, w_z) if w_base is not None: w_logbase = _inner_wrapped_log(space, w_base) diff --git a/pypy/module/marshal/interp_marshal.py b/pypy/module/marshal/interp_marshal.py --- a/pypy/module/marshal/interp_marshal.py +++ b/pypy/module/marshal/interp_marshal.py @@ -1,4 +1,5 @@ from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import W_Root, unwrap_spec from pypy.rlib.rarithmetic import intmask from pypy.rlib import rstackovf from pypy.module._file.interp_file import W_File @@ -6,7 +7,8 @@ Py_MARSHAL_VERSION = 2 -def dump(space, w_data, w_f, w_version=Py_MARSHAL_VERSION): + at unwrap_spec(w_version = (W_Root, 'space.wrap(%d)' % Py_MARSHAL_VERSION)) +def dump(space, w_data, w_f, w_version): """Write the 'data' object into the open file 'f'.""" # special case real files for performance file = space.interpclass_w(w_f) @@ -23,7 +25,8 @@ finally: writer.finished() -def dumps(space, w_data, w_version=Py_MARSHAL_VERSION): + at unwrap_spec(w_version = (W_Root, 'space.wrap(%d)' % Py_MARSHAL_VERSION)) +def dumps(space, w_data, w_version): """Return the string that would have been written to a file by dump(data, file).""" m = StringMarshaller(space, space.int_w(w_version)) 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 @@ -3,7 +3,6 @@ from pypy.rlib import rfloat, unroll from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped class State: def __init__(self, space): @@ -204,7 +203,7 @@ space.wrap('math domain error')) return space.wrap(result) -def log(space, w_x, w_base=NoneNotWrapped): +def log(space, w_x, w_base=None): """log(x[, base]) -> the logarithm of x to the given base. If the base not specified, returns the natural logarithm (base e) of x. """ diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -1,7 +1,7 @@ from pypy.interpreter.error import OperationError, wrap_oserror from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.rlib import rmmap, rarithmetic from pypy.rlib.rmmap import RValueError, RTypeError @@ -35,7 +35,7 @@ return self.space.wrap(self.mmap.read(num)) @unwrap_spec(tofind='bufferstr') - def find(self, tofind, w_start=NoneNotWrapped, w_end=NoneNotWrapped): + def find(self, tofind, w_start=None, w_end=None): space = self.space if w_start is None: start = self.mmap.pos @@ -48,7 +48,7 @@ return space.wrap(self.mmap.find(tofind, start, end)) @unwrap_spec(tofind='bufferstr') - def rfind(self, tofind, w_start=NoneNotWrapped, w_end=NoneNotWrapped): + def rfind(self, tofind, w_start=None, w_end=None): space = self.space if w_start is None: start = self.mmap.pos diff --git a/pypy/module/oracle/interp_connect.py b/pypy/module/oracle/interp_connect.py --- a/pypy/module/oracle/interp_connect.py +++ b/pypy/module/oracle/interp_connect.py @@ -1,13 +1,11 @@ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.typedef import (TypeDef, interp_attrproperty_w, GetSetProperty) from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import rffi, lltype -Null = NoneNotWrapped - from pypy.module.oracle import roci, interp_error from pypy.module.oracle.config import string_w, StringBuffer, MAX_STRING_CHARS from pypy.module.oracle.interp_environ import Environment @@ -35,18 +33,18 @@ threaded=bool, twophase=bool, events=bool, purity=bool) def descr_new(space, w_subtype, - w_user=NoneNotWrapped, - w_password=NoneNotWrapped, - w_dsn=NoneNotWrapped, + w_user=None, + w_password=None, + w_dsn=None, mode=roci.OCI_DEFAULT, handle=0, # XXX should be a ptr type - w_pool=Null, + w_pool=None, threaded=False, twophase=False, events=False, - w_cclass=Null, + w_cclass=None, purity=0, - w_newpassword=Null): + w_newpassword=None): self = space.allocate_instance(W_Connection, w_subtype) W_Connection.__init__(self) diff --git a/pypy/module/oracle/interp_pool.py b/pypy/module/oracle/interp_pool.py --- a/pypy/module/oracle/interp_pool.py +++ b/pypy/module/oracle/interp_pool.py @@ -1,14 +1,11 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.argument import Arguments, Signature -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import rffi, lltype -Null = NoneNotWrapped - from pypy.module.oracle import roci, config from pypy.module.oracle import interp_error, interp_environ from pypy.module.oracle.interp_error import get @@ -22,7 +19,7 @@ def descr_new(space, w_subtype, w_user, w_password, w_dsn, min, max, increment, - w_connectiontype=Null, + w_connectiontype=None, threaded=False, getmode=roci.OCI_SPOOL_ATTRVAL_NOWAIT, events=False, diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -5,7 +5,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, W_Root from pypy.rlib import jit from pypy.rlib.runicode import MAXUNICODE @@ -20,7 +20,8 @@ "trying to change the builtin-in module %r" % (name,)) space.setitem(w_modules, space.wrap(name), w_module) -def _getframe(space, w_depth=0): + at unwrap_spec(w_depth = (W_Root, 'space.wrap(0)')) +def _getframe(space, w_depth): """Return a frame object from the call stack. If optional integer depth is given, return the frame object that many calls below the top of the stack. If that is deeper than the call stack, ValueError is raised. The default 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 @@ -5,7 +5,7 @@ from pypy.module.thread import ll_thread as thread from pypy.module.thread.error import wrap_thread_error from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import unwrap_spec, NoneNotWrapped, Arguments +from pypy.interpreter.gateway import unwrap_spec, Arguments # Here are the steps performed to start a new thread: # @@ -152,7 +152,7 @@ space.call_method(w_threading, "_after_fork") -def start_new_thread(space, w_callable, w_args, w_kwargs=NoneNotWrapped): +def start_new_thread(space, w_callable, w_args, w_kwargs=None): """Start a new thread and return its identifier. The thread will call the function with positional arguments from the tuple args and keyword arguments taken from the optional dictionary kwargs. The thread exits when the diff --git a/pypy/module/unicodedata/interp_ucd.py b/pypy/module/unicodedata/interp_ucd.py --- a/pypy/module/unicodedata/interp_ucd.py +++ b/pypy/module/unicodedata/interp_ucd.py @@ -1,7 +1,7 @@ """ Implementation of the interpreter-level functions in the module unicodedata. """ -from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, interp_attrproperty @@ -139,7 +139,7 @@ raise OperationError(space.w_KeyError, msg) return space.wrap(code_to_unichr(code)) - def name(self, space, w_unichr, w_default=NoneNotWrapped): + def name(self, space, w_unichr, w_default=None): code = unichr_to_code_w(space, w_unichr) try: name = self._name(code) @@ -150,7 +150,7 @@ return space.wrap(name) - def decimal(self, space, w_unichr, w_default=NoneNotWrapped): + def decimal(self, space, w_unichr, w_default=None): code = unichr_to_code_w(space, w_unichr) try: return space.wrap(self._decimal(code)) @@ -160,7 +160,7 @@ return w_default raise OperationError(space.w_ValueError, space.wrap('not a decimal')) - def digit(self, space, w_unichr, w_default=NoneNotWrapped): + def digit(self, space, w_unichr, w_default=None): code = unichr_to_code_w(space, w_unichr) try: return space.wrap(self._digit(code)) @@ -170,7 +170,7 @@ return w_default raise OperationError(space.w_ValueError, space.wrap('not a digit')) - def numeric(self, space, w_unichr, w_default=NoneNotWrapped): + def numeric(self, space, w_unichr, w_default=None): code = unichr_to_code_w(space, w_unichr) try: return space.wrap(self._numeric(code)) From noreply at buildbot.pypy.org Wed Oct 10 21:03:57 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 10 Oct 2012 21:03:57 +0200 (CEST) Subject: [pypy-commit] pypy default: update comment Message-ID: <20121010190357.CDC621C01CA@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r57986:09c4d1749dc2 Date: 2012-10-10 12:03 -0700 http://bitbucket.org/pypy/pypy/changeset/09c4d1749dc2/ Log: update comment diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -45,8 +45,8 @@ # string to the rest of the code. XXX not entirely sure if these three # functions are the only way for non-string objects to reach # space.{get,set,del}attr()... - # Note that if w_name is already a string (or a subclass of str), - # it must be returned unmodified (and not e.g. unwrapped-rewrapped). + # Note that if w_name is already an exact string it must be returned + # unmodified (and not e.g. unwrapped-rewrapped). if not space.is_w(space.type(w_name), space.w_str): name = space.str_w(w_name) # typecheck w_name = space.wrap(name) # rewrap as a real string From noreply at buildbot.pypy.org Wed Oct 10 21:44:30 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 10 Oct 2012 21:44:30 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Disable closure creation in RPython Message-ID: <20121010194430.CFE921C002D@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57987:e1b4d5fe6b2d Date: 2012-10-10 20:28 +0100 http://bitbucket.org/pypy/pypy/changeset/e1b4d5fe6b2d/ Log: Disable closure creation in RPython * Trying to build the flow graph of a function whose code object contains cellvars (i.e. a function that creates closures, possibly in unreachable code) now raises an error up front. * Explicitly disable closure-supporting opcodes LOAD_CLOSURE, MAKE_CLOSURE, and STORE_DEREF. * Xfail tests for closure support (don't delete them yet as they are a bit tricky to get right). diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -38,23 +38,8 @@ self.co_firstlineno = firstlineno self.co_lnotab = lnotab self.signature = cpython_code_signature(self) - self._initialize() - - def _initialize(self): - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = {} - if self.co_cellvars: - # Cell vars could shadow already-set arguments. - # See comment in PyCode._initialize() - argvars = self.co_varnames - cellvars = self.co_cellvars - for i in range(len(cellvars)): - cellname = cellvars[i] - for j in range(self.formalargcount): - if cellname == argvars[j]: - # argument j has the same name as the cell var i - self._args_as_cellvars[i] = j + raise ValueError("RPython functions cannot create closures") @classmethod def _from_code(cls, code): diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -252,16 +252,8 @@ def restore_locals_stack(self, items_w): self.locals_stack_w[:len(items_w)] = items_w - self.init_cells() self.dropvaluesuntil(len(items_w)) - def init_cells(self): - if self.cells is None: - return - args_to_copy = self.pycode._args_as_cellvars - for cellnum, argnum in args_to_copy.iteritems(): - self.cells[cellnum].set(self.locals_stack_w[argnum]) - def getstate(self): # getfastscope() can return real None, for undefined locals data = self.save_locals_stack() @@ -712,6 +704,12 @@ def MAP_ADD(self, oparg, next_instr): raise NotImplementedError("MAP_ADD") + # Closures + + STORE_DEREF = BAD_OPCODE + LOAD_CLOSURE = BAD_OPCODE + MAKE_CLOSURE = BAD_OPCODE + def make_arguments(self, nargs): return ArgumentsForTranslation(self.space, self.peekvalues(nargs)) def argument_factory(self, *args): diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1054,6 +1054,7 @@ with py.test.raises(FlowingError): self.codetest(f) + @py.test.mark.xfail(reason="closures aren't supported") def test_cellvar_store(self): def f(): x = 5 @@ -1063,6 +1064,7 @@ assert len(graph.startblock.exits) == 1 assert graph.startblock.exits[0].target == graph.returnblock + @py.test.mark.xfail(reason="closures aren't supported") def test_arg_as_cellvar(self): def f(x, y, z): a, b, c = 1, 2, 3 @@ -1101,6 +1103,25 @@ with py.test.raises(FlowingError): self.codetest(f2) + @py.test.mark.xfail(reason="closures aren't supported") + def test_closure(self): + def f(): + m = 5 + return lambda n: m * n + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + g = graph.startblock.exits[0].args[0].value + assert g(4) == 20 + + def test_closure_error(self): + def f(): + m = 5 + return lambda n: m * n + with py.test.raises(ValueError) as excinfo: + self.codetest(f) + assert "closure" in str(excinfo.value) + DATA = {'x': 5, 'y': 6} From noreply at buildbot.pypy.org Wed Oct 10 21:44:31 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Wed, 10 Oct 2012 21:44:31 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Consolidate RPythonicity checks at the beginning of build_flow() Message-ID: <20121010194431.EB4941C002D@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r57988:e0c6bf5e3dbf Date: 2012-10-10 20:43 +0100 http://bitbucket.org/pypy/pypy/changeset/e0c6bf5e3dbf/ Log: Consolidate RPythonicity checks at the beginning of build_flow() diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -38,8 +38,6 @@ self.co_firstlineno = firstlineno self.co_lnotab = lnotab self.signature = cpython_code_signature(self) - if self.co_cellvars: - raise ValueError("RPython functions cannot create closures") @classmethod def _from_code(cls, code): @@ -72,9 +70,6 @@ closure = [Cell(Constant(c.cell_contents)) for c in closure] else: closure = [] - if not (self.co_flags & CO_NEWLOCALS): - raise ValueError("The code object for a function should have " - "the flag CO_NEWLOCALS set.") if len(closure) != len(self.co_freevars): raise ValueError("code object received a closure with " "an unexpected number of free variables") diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -2,6 +2,8 @@ import __builtin__ import sys import types +from inspect import CO_NEWLOCALS + from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.argument import ArgumentsForTranslation from pypy.objspace.flow.model import (Constant, Variable, WrapException, @@ -41,6 +43,17 @@ } } +def _assert_rpythonic(func): + """Raise ValueError if ``func`` is obviously not RPython""" + if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): + raise ValueError("%r is tagged as NOT_RPYTHON" % (func,)) + if func.func_code.co_cellvars: + raise ValueError("RPython functions cannot create closures") + if not (func.func_code.co_flags & CO_NEWLOCALS): + raise ValueError("The code object for a RPython function should have " + "the flag CO_NEWLOCALS set.") + + # ______________________________________________________________________ class FlowObjSpace(object): """NOT_RPYTHON. @@ -248,8 +261,7 @@ def build_flow(self, func): """ """ - if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): - raise Exception, "%r is tagged as NOT_RPYTHON" % (func,) + _assert_rpythonic(func) code = HostCode._from_code(func.func_code) if (code.is_generator and not hasattr(func, '_generator_next_method_of_')): From noreply at buildbot.pypy.org Wed Oct 10 22:18:28 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 22:18:28 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix some more stuff Message-ID: <20121010201828.76DC71C0FCB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57989:c7b80d289313 Date: 2012-10-10 22:17 +0200 http://bitbucket.org/pypy/pypy/changeset/c7b80d289313/ Log: fix some more stuff diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -205,11 +205,11 @@ code = space.interp_w(Code, w_code) if not space.is_true(space.isinstance(w_globals, space.w_dict)): raise OperationError(space.w_TypeError, space.wrap("expected dict")) - if not space.is_w(w_name, space.w_None): + if not space.is_none(w_name): name = space.str_w(w_name) else: name = None - if not space.is_w(w_argdefs, space.w_None): + if not space.is_none(w_argdefs): defs_w = space.fixedview(w_argdefs) else: defs_w = [] @@ -217,7 +217,7 @@ from pypy.interpreter.pycode import PyCode if isinstance(code, PyCode): nfreevars = len(code.co_freevars) - if space.is_w(w_closure, space.w_None) and nfreevars == 0: + if space.is_none(w_closure) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) @@ -428,8 +428,8 @@ """functionobject.__get__(obj[, type]) -> method""" # this is not defined as a method on Function because it's generally # useful logic: w_function can be any callable. It is used by Method too. - asking_for_bound = (space.is_w(w_cls, space.w_None) or - not space.is_w(w_obj, space.w_None) or + asking_for_bound = (space.is_none(w_cls) or + not space.is_none(w_obj) or space.is_w(w_cls, space.type(space.w_None))) if asking_for_bound: return space.wrap(Method(space, w_function, w_obj, w_cls)) @@ -445,12 +445,15 @@ self.space = space self.w_function = w_function self.w_instance = w_instance # or None + if w_class is None: + w_class = space.w_None self.w_class = w_class # possibly space.w_None - def descr_method__new__(space, w_subtype, w_function, w_instance, w_class=None): + def descr_method__new__(space, w_subtype, w_function, w_instance, + w_class=None): if space.is_w(w_instance, space.w_None): w_instance = None - if w_instance is None and space.is_w(w_class, space.w_None): + if w_instance is None and space.is_none(w_class): raise OperationError(space.w_TypeError, space.wrap("unbound methods must have class")) method = space.allocate_instance(Method, w_subtype) diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -91,6 +91,8 @@ def descr_throw(self, w_type, w_val=None, w_tb=None): """x.throw(typ[,val[,tb]]) -> raise exception in generator, return next yielded value or raise StopIteration.""" + if w_val is None: + w_val = self.space.w_None return self.throw(w_type, w_val, w_tb) @@ -99,7 +101,7 @@ space = self.space msg = "throw() third argument must be a traceback object" - if space.is_w(w_tb, space.w_None): + if space.is_none(w_tb): tb = None else: tb = check_traceback(space, w_tb, msg) diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -3,7 +3,8 @@ """ import py -from pypy.interpreter.gateway import interp2app, BuiltinCode +from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ + W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt @@ -456,6 +457,7 @@ self.objclass_getter = objclass_getter self.use_closure = use_closure + @unwrap_spec(w_cls = (W_Root, 'space.w_None')) def descr_property_get(self, space, w_obj, w_cls=None): """property.__get__(obj[, type]) -> value Read the value of the property of the given obj.""" @@ -553,7 +555,7 @@ self.w_cls.name, space.type(w_obj).getname(space)) - def descr_member_get(self, space, w_obj, w_w_cls=None): + def descr_member_get(self, space, w_obj, w_cls=None): """member.__get__(obj[, type]) -> value Read the slot 'member' of the given 'obj'.""" if space.is_w(w_obj, space.w_None): diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -124,8 +124,8 @@ NDIGITS_MAX = int((rfloat.DBL_MANT_DIG - rfloat.DBL_MIN_EXP) * 0.30103) NDIGITS_MIN = -int((rfloat.DBL_MAX_EXP + 1) * 0.30103) - at unwrap_spec(number=float) -def round(space, number, w_ndigits=0): + at unwrap_spec(number=float, w_ndigits = (W_Root, 'space.wrap(0)')) +def round(space, number, w_ndigits): """round(number[, ndigits]) -> floating point number Round a number to a given precision in decimal digits (default 0 digits). @@ -234,6 +234,7 @@ function). Note that classes are callable.""" return space.callable(w_object) -def format(space, w_obj, w_format_spec=""): + at unwrap_spec(w_format_spec = (W_Root, 'space.wrap("")')) +def format(space, w_obj, w_format_spec): """Format a obj according to format_spec""" return space.format(w_obj, w_format_spec) From noreply at buildbot.pypy.org Wed Oct 10 22:18:29 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 22:18:29 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121010201829.C42121C0FCB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57990:673ea32b2cfe Date: 2012-10-10 22:18 +0200 http://bitbucket.org/pypy/pypy/changeset/673ea32b2cfe/ Log: merge diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -866,6 +866,7 @@ argname = code._argnames[i] if isinstance(spec, tuple) and spec[0] is W_Root: w_default = eval(spec[1], {'space': space}) + assert isinstance(w_default, W_Root) assert argname.startswith('w_') argname = argname[2:] j = self._code.sig[0].index(argname) From noreply at buildbot.pypy.org Wed Oct 10 22:24:49 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 22:24:49 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fixes to socket Message-ID: <20121010202449.0DD7A1C0FCB@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57991:4a0c4724828d Date: 2012-10-10 22:24 +0200 http://bitbucket.org/pypy/pypy/changeset/4a0c4724828d/ Log: fixes to socket diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -1,4 +1,4 @@ -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, W_Root from pypy.module._socket.interp_socket import converted_error, W_RSocket from pypy.rlib import rsocket from pypy.rlib.rsocket import SocketError, INVALID_SOCKET diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, make_weakref_descr,\ interp_attrproperty -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.rlib.rarithmetic import intmask from pypy.rlib import rsocket from pypy.rlib.rsocket import RSocket, AF_INET, SOCK_STREAM @@ -160,7 +160,9 @@ except SocketError, e: raise converted_error(space, e) - def makefile_w(self, space, w_mode="r", w_buffsize=-1): + @unwrap_spec(w_mode = (W_Root, 'space.wrap("r")'), + w_buffsize = (W_Root, 'space.wrap(-1)')) + def makefile_w(self, space, w_mode=None, w_buffsize=None): """makefile([mode[, buffersize]]) -> file object Return a regular file object corresponding to the socket. From noreply at buildbot.pypy.org Wed Oct 10 22:50:51 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 10 Oct 2012 22:50:51 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: too bad, it works if we pass None (and people rely on it) Message-ID: <20121010205051.BEDDF1C002D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r57992:84caf75df304 Date: 2012-10-10 22:50 +0200 http://bitbucket.org/pypy/pypy/changeset/84caf75df304/ Log: too bad, it works if we pass None (and people rely on it) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -720,7 +720,6 @@ # expected programming style where we say "if x is None" or # "if x is object"). assert w_two is not None - assert w_one is not None return w_two.is_w(self, w_one) def is_none(self, w_obj): From noreply at buildbot.pypy.org Wed Oct 10 23:47:57 2012 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 10 Oct 2012 23:47:57 +0200 (CEST) Subject: [pypy-commit] pypy default: remove TypeError, add failing test (missing res_type rule coerce_float for real, imag, abs) Message-ID: <20121010214757.1F2061C01CA@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r57993:3157376a59f8 Date: 2012-10-10 23:47 +0200 http://bitbucket.org/pypy/pypy/changeset/3157376a59f8/ Log: remove TypeError, add failing test (missing res_type rule coerce_float for real, imag, abs) 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 @@ -43,9 +43,6 @@ self.imag = imag def convert_to(self, dtype): - from pypy.module.micronumpy.types import ComplexFloating - if not isinstance(dtype.itemtype, ComplexFloating): - raise TypeError('cannot convert %r to complex' % dtype) return dtype.box_complex(self.real, self.imag) def convert_real_to(self, dtype): @@ -77,12 +74,7 @@ return space.wrap(box.value) def descr_float(self, space): - try: - box = self.convert_to(W_Float64Box._get_dtype(space)) - except TypeError: - raise OperationError(space.w_TypeError, - space.wrap("Cannot convert %s to float" % self._get_dtype(space).name)) - + box = self.convert_to(W_Float64Box._get_dtype(space)) assert isinstance(box, W_Float64Box) return space.wrap(box.value) 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 @@ -468,13 +468,16 @@ assert c[i] == max(a[i], b[i]) def test_basic(self): - from _numpypy import (complex128, complex64, add, + from _numpypy import (complex128, complex64, add, array, dtype, subtract as sub, multiply, divide, negative, abs, floor_divide, - reciprocal, real, imag, sign) + real, imag, sign) from _numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) assert real(4.0) == 4.0 assert imag(0.0) == 0.0 + a = array([complex(3.0, 4.0)]) + b = a.real + assert b.dtype == dtype(float) for complex_ in complex64, complex128: O = complex(0, 0) From noreply at buildbot.pypy.org Wed Oct 10 23:57:55 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 10 Oct 2012 23:57:55 +0200 (CEST) Subject: [pypy-commit] pypy default: run the getattr tests under the getattributeshortcut optimization too Message-ID: <20121010215755.434F51C01CA@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r57994:a858967c9ad0 Date: 2012-10-10 14:57 -0700 http://bitbucket.org/pypy/pypy/changeset/a858967c9ad0/ Log: run the getattr tests under the getattributeshortcut optimization too 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 @@ -172,28 +172,6 @@ assert f() == {} assert g() == {'a':0, 'b':0, 'c':0} - def test_getattr(self): - class a(object): - i = 5 - assert getattr(a, 'i') == 5 - raises(AttributeError, getattr, a, 'k') - assert getattr(a, 'k', 42) == 42 - assert getattr(a, u'i') == 5 - raises(AttributeError, getattr, a, u'k') - assert getattr(a, u'k', 42) == 42 - - def test_getattr_typecheck(self): - class A(object): - def __getattribute__(self, name): - pass - def __setattr__(self, name, value): - pass - def __delattr__(self, name): - pass - raises(TypeError, getattr, A(), 42) - raises(TypeError, setattr, A(), 42, 'x') - raises(TypeError, delattr, A(), 42) - def test_sum(self): assert sum([]) ==0 assert sum([42]) ==42 @@ -661,6 +639,39 @@ assert vars(C_get_vars()) == {'a':2} +class AppTestGetattr: + OPTIONS = {} + + def setup_class(cls): + cls.space = conftest.gettestobjspace(**cls.OPTIONS) + + def test_getattr(self): + class a(object): + i = 5 + assert getattr(a, 'i') == 5 + raises(AttributeError, getattr, a, 'k') + assert getattr(a, 'k', 42) == 42 + assert getattr(a, u'i') == 5 + raises(AttributeError, getattr, a, u'k') + assert getattr(a, u'k', 42) == 42 + + def test_getattr_typecheck(self): + class A(object): + def __getattribute__(self, name): + pass + def __setattr__(self, name, value): + pass + def __delattr__(self, name): + pass + raises(TypeError, getattr, A(), 42) + raises(TypeError, setattr, A(), 42, 'x') + raises(TypeError, delattr, A(), 42) + + +class AppTestGetattrWithGetAttributeShortcut(AppTestGetattr): + OPTIONS = {"objspace.std.getattributeshortcut": True} + + class TestInternal: def test_execfile(self, space): from pypy.tool.udir import udir From noreply at buildbot.pypy.org Thu Oct 11 00:02:48 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 11 Oct 2012 00:02:48 +0200 (CEST) Subject: [pypy-commit] pypy py3k: switch to builtin next Message-ID: <20121010220248.E2B691C01CA@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r57995:10baee3314ed Date: 2012-10-09 18:17 -0700 http://bitbucket.org/pypy/pypy/changeset/10baee3314ed/ Log: switch to builtin next diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -92,7 +92,7 @@ import itertools r = itertools.repeat('a', 15) - r.next() + next(r) raises(TypeError, "len(itertools.repeat('xkcd'))") def test_takewhile(self): @@ -618,12 +618,12 @@ def test_tee_bug1(self): import itertools a, b = itertools.tee('abcde') - x = a.next() + x = next(a) assert x == 'a' c, d = itertools.tee(a) - x = c.next() + x = next(c) assert x == 'b' - x = d.next() + x = next(d) assert x == 'b' From noreply at buildbot.pypy.org Thu Oct 11 00:53:38 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 11 Oct 2012 00:53:38 +0200 (CEST) Subject: [pypy-commit] pypy default: Issue1285: Python2 allows lone surrogates, also in string literals which appear in marshalled code. Message-ID: <20121010225338.D13791C0117@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r57996:ce4e0ff9862b Date: 2012-10-11 00:51 +0200 http://bitbucket.org/pypy/pypy/changeset/ce4e0ff9862b/ Log: Issue1285: Python2 allows lone surrogates, also in string literals which appear in marshalled code. Also use more direct code for functions that are often used. diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -3,7 +3,6 @@ from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.pyopcode import LoopBlock from pypy.rlib import jit -from pypy.rlib.objectmodel import specialize class GeneratorIterator(Wrappable): diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -1,10 +1,62 @@ +from pypy.interpreter.error import OperationError +from pypy.rlib.objectmodel import specialize +from pypy.rlib import runicode from pypy.module._codecs import interp_codecs + at specialize.memo() +def decode_error_handler(space): + def raise_unicode_exception_decode(errors, encoding, msg, s, + startingpos, endingpos): + raise OperationError(space.w_UnicodeDecodeError, + space.newtuple([space.wrap(encoding), + space.wrap(s), + space.wrap(startingpos), + space.wrap(endingpos), + space.wrap(msg)])) + return raise_unicode_exception_decode + + at specialize.memo() +def encode_error_handler(space): + def raise_unicode_exception_encode(errors, encoding, msg, u, + startingpos, endingpos): + raise OperationError(space.w_UnicodeEncodeError, + space.newtuple([space.wrap(encoding), + space.wrap(u), + space.wrap(startingpos), + space.wrap(endingpos), + space.wrap(msg)])) + return raise_unicode_exception_encode + +# ____________________________________________________________ + def PyUnicode_AsEncodedString(space, w_data, w_encoding): return interp_codecs.encode(space, w_data, w_encoding) # These functions take and return unwrapped rpython strings and unicodes -PyUnicode_DecodeUnicodeEscape = interp_codecs.make_raw_decoder('unicode_escape') -PyUnicode_DecodeRawUnicodeEscape = interp_codecs.make_raw_decoder('raw_unicode_escape') -PyUnicode_DecodeUTF8 = interp_codecs.make_raw_decoder('utf_8') -PyUnicode_EncodeUTF8 = interp_codecs.make_raw_encoder('utf_8') +def PyUnicode_DecodeUnicodeEscape(space, string): + state = space.fromcache(interp_codecs.CodecState) + unicodedata_handler = state.get_unicodedata_handler(space) + result, consumed = runicode.str_decode_unicode_escape( + string, len(string), "strict", + final=True, errorhandler=decode_error_handler(space), + unicodedata_handler=unicodedata_handler) + return result + +def PyUnicode_DecodeRawUnicodeEscape(space, string): + result, consumed = runicode.str_decode_raw_unicode_escape( + string, len(string), "strict", + final=True, errorhandler=decode_error_handler(space)) + return result + +def PyUnicode_DecodeUTF8(space, string): + result, consumed = runicode.str_decode_utf_8( + string, len(string), "strict", + final=True, errorhandler=decode_error_handler(space), + allow_surrogates=True) + return result + +def PyUnicode_EncodeUTF8(space, uni): + return runicode.unicode_encode_utf_8( + uni, len(uni), "strict", + errorhandler=encode_error_handler(space), + allow_surrogates=True) diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -339,38 +339,6 @@ from pypy.rlib import runicode -def make_raw_encoder(name): - rname = "unicode_encode_%s" % (name.replace("_encode", ""), ) - assert hasattr(runicode, rname) - def raw_encoder(space, uni): - state = space.fromcache(CodecState) - func = getattr(runicode, rname) - errors = "strict" - return func(uni, len(uni), errors, state.encode_error_handler) - raw_encoder.func_name = rname - return raw_encoder - -def make_raw_decoder(name): - rname = "str_decode_%s" % (name.replace("_decode", ""), ) - assert hasattr(runicode, rname) - def raw_decoder(space, string): - final = True - errors = "strict" - state = space.fromcache(CodecState) - func = getattr(runicode, rname) - kwargs = {} - if name == 'unicode_escape': - unicodedata_handler = state.get_unicodedata_handler(space) - result, consumed = func(string, len(string), errors, - final, state.decode_error_handler, - unicodedata_handler=unicodedata_handler) - else: - result, consumed = func(string, len(string), errors, - final, state.decode_error_handler) - return result - raw_decoder.func_name = rname - return raw_decoder - def make_encoder_wrapper(name): rname = "unicode_encode_%s" % (name.replace("_encode", ""), ) assert hasattr(runicode, rname) diff --git a/pypy/module/marshal/test/test_marshal.py b/pypy/module/marshal/test/test_marshal.py --- a/pypy/module/marshal/test/test_marshal.py +++ b/pypy/module/marshal/test/test_marshal.py @@ -163,6 +163,7 @@ def test_unicode(self): import marshal, sys self.marshal_check(u'\uFFFF') + self.marshal_check(u'\ud800') self.marshal_check(unichr(sys.maxunicode)) diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter import gateway +from pypy.interpreter import gateway, unicodehelper from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.register_all import register_all from pypy.objspace.std.basestringtype import basestring_typedef @@ -186,32 +186,6 @@ # ____________________________________________________________ -def decode_error_handler(space): - def raise_unicode_exception_decode(errors, encoding, msg, s, - startingpos, endingpos): - raise OperationError(space.w_UnicodeDecodeError, - space.newtuple([space.wrap(encoding), - space.wrap(s), - space.wrap(startingpos), - space.wrap(endingpos), - space.wrap(msg)])) - return raise_unicode_exception_decode -decode_error_handler._annspecialcase_ = 'specialize:memo' - -def encode_error_handler(space): - def raise_unicode_exception_encode(errors, encoding, msg, u, - startingpos, endingpos): - raise OperationError(space.w_UnicodeEncodeError, - space.newtuple([space.wrap(encoding), - space.wrap(u), - space.wrap(startingpos), - space.wrap(endingpos), - space.wrap(msg)])) - return raise_unicode_exception_encode -encode_error_handler._annspecialcase_ = 'specialize:memo' - -# ____________________________________________________________ - def getdefaultencoding(space): return space.sys.defaultencoding @@ -235,12 +209,12 @@ if errors is None or errors == 'strict': if encoding == 'ascii': u = space.unicode_w(w_object) - eh = encode_error_handler(space) + eh = unicodehelper.encode_error_handler(space) return space.wrap(unicode_encode_ascii( u, len(u), None, errorhandler=eh)) if encoding == 'utf-8': u = space.unicode_w(w_object) - eh = encode_error_handler(space) + eh = unicodehelper.encode_error_handler(space) return space.wrap(unicode_encode_utf_8( u, len(u), None, errorhandler=eh, allow_surrogates=True)) @@ -265,12 +239,12 @@ if encoding == 'ascii': # XXX error handling s = space.bufferstr_w(w_obj) - eh = decode_error_handler(space) + eh = unicodehelper.decode_error_handler(space) return space.wrap(str_decode_ascii( s, len(s), None, final=True, errorhandler=eh)[0]) if encoding == 'utf-8': s = space.bufferstr_w(w_obj) - eh = decode_error_handler(space) + eh = unicodehelper.decode_error_handler(space) return space.wrap(str_decode_utf_8( s, len(s), None, final=True, errorhandler=eh, allow_surrogates=True)[0]) From noreply at buildbot.pypy.org Thu Oct 11 00:59:20 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 11 Oct 2012 00:59:20 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix getattr unit tests. Message-ID: <20121010225920.86ECE1C0117@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57997:4c065fffe139 Date: 2012-10-10 21:57 +0200 http://bitbucket.org/pypy/pypy/changeset/4c065fffe139/ Log: Fix getattr unit tests. diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -50,8 +50,8 @@ # Note that if w_name is already a string (or a subclass of str), # it must be returned unmodified (and not e.g. unwrapped-rewrapped). if not space.is_w(space.type(w_name), space.w_text): - name = space.str_w(w_name) # typecheck - w_name = space.wrap(name) # rewrap as a real string + name = space.unicode_w(w_name) # typecheck + w_name = space.wrap(name) # rewrap as a real string return w_name def delattr(space, w_object, w_name): From noreply at buildbot.pypy.org Thu Oct 11 00:59:21 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 11 Oct 2012 00:59:21 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix test_chr to pass with -A (CPython 3.2) Message-ID: <20121010225921.CB1041C0117@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57998:18e23a442a38 Date: 2012-10-10 22:03 +0200 http://bitbucket.org/pypy/pypy/changeset/18e23a442a38/ Log: Fix test_chr to pass with -A (CPython 3.2) 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 @@ -116,11 +116,11 @@ assert chr(0x9876) == '\u9876' if sys.maxunicode > 0xFFFF: assert chr(sys.maxunicode) == '\U0010FFFF' - assert chr(0x10000) == '\U00010000' else: assert chr(sys.maxunicode) == '\uFFFF' + assert chr(0x00010000) == '\U00010000' + assert chr(0x0010ffff) == '\U0010FFFF' raises(ValueError, chr, -1) - raises(ValueError, chr, sys.maxunicode+1) def test_globals(self): d = {"foo":"bar"} From noreply at buildbot.pypy.org Thu Oct 11 00:59:23 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 11 Oct 2012 00:59:23 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix many tests for execution with -A. Message-ID: <20121010225923.2D7A01C0117@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r57999:77f2578283bd Date: 2012-10-10 22:26 +0200 http://bitbucket.org/pypy/pypy/changeset/77f2578283bd/ Log: Fix many tests for execution with -A. 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 @@ -298,7 +298,7 @@ raises(TypeError, enumerate, 1) raises(TypeError, enumerate, None) enum = enumerate(range(5), 2) - assert list(enum) == zip(range(2, 7), range(5)) + assert list(enum) == list(zip(range(2, 7), range(5))) def test_next(self): x = iter(['a', 'b', 'c']) @@ -340,7 +340,7 @@ raises(ValueError, range, 0, 1, 0) def test_range_repr(self): - assert repr(range(1)) == 'range(1)' + assert repr(range(1)) == 'range(0, 1)' assert repr(range(1,2)) == 'range(1, 2)' assert repr(range(1,2,3)) == 'range(1, 2, 3)' @@ -506,7 +506,7 @@ def test_unicode_encoding_compile(self): code = "# -*- coding: utf-8 -*-\npass\n" - raises(SyntaxError, compile, code, "tmp", "exec") + compile(code, "tmp", "exec") def test_bytes_compile(self): code = b"# -*- coding: utf-8 -*-\npass\n" @@ -641,9 +641,11 @@ raises(TypeError, pr, sep=42) def test_round(self): - assert round(11.234) == 11.0 - assert round(11.234, -1) == 10.0 - assert round(11.234, 0) == 11.0 + assert round(11.234) == 11 + assert type(round(11.234)) is int + assert round(11.234, -1) == 10 + assert type(round(11.234, -1)) is float + assert round(11.234, 0) == 11 assert round(11.234, 1) == 11.2 # assert round(5e15-1) == 5e15-1 @@ -652,11 +654,10 @@ assert round(-5e15) == -5e15 # inf = 1e200 * 1e200 - assert round(inf) == inf - assert round(-inf) == -inf + raises(OverflowError, round, inf) + raises(OverflowError, round, -inf) nan = inf / inf - assert repr(round(nan)) == repr(nan) - # + raises(ValueError, round, nan) raises(OverflowError, round, 1.6e308, -308) # assert round(562949953421312.5, 1) == 562949953421312.5 diff --git a/pypy/module/__builtin__/test/test_descriptor.py b/pypy/module/__builtin__/test/test_descriptor.py --- a/pypy/module/__builtin__/test/test_descriptor.py +++ b/pypy/module/__builtin__/test/test_descriptor.py @@ -323,7 +323,7 @@ for attr in "__doc__", "fget", "fset", "fdel": try: setattr(raw, attr, 42) - except TypeError as msg: + except AttributeError as msg: if str(msg).find('readonly') < 0: raise Exception("when setting readonly attr %r on a " "property, got unexpected TypeError " diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py --- a/pypy/module/__builtin__/test/test_functional.py +++ b/pypy/module/__builtin__/test/test_functional.py @@ -4,18 +4,19 @@ class AppTestMap: def test_trivial_map_one_seq(self): - assert map(lambda x: x+2, [1, 2, 3, 4]) == [3, 4, 5, 6] + assert list(map(lambda x: x+2, [1, 2, 3, 4])) == [3, 4, 5, 6] def test_trivial_map_one_seq_2(self): - assert map(str, [1, 2, 3, 4]) == ['1', '2', '3', '4'] + assert list(map(str, [1, 2, 3, 4])) == ['1', '2', '3', '4'] def test_trivial_map_two_seq(self): - assert map(lambda x,y: x+y, - [1, 2, 3, 4],[1, 2, 3, 4]) == ( + assert list(map(lambda x,y: x+y, + [1, 2, 3, 4],[1, 2, 3, 4])) == ( [2, 4, 6, 8]) - def test_trivial_map_sizes_dont_match_and_should(self): - raises(TypeError, map, lambda x,y: x+y, [1, 2, 3, 4], [1, 2, 3]) + def test_trivial_map_sizes_dont_match(self): + assert list(map(lambda x,y: x+y, [1, 2, 3, 4], [1, 2, 3])) == ( + [2, 4, 6]) def test_trivial_map_no_arguments(self): raises(TypeError, map) @@ -23,43 +24,29 @@ def test_trivial_map_no_function_no_seq(self): raises(TypeError, map, None) - def test_trivial_map_no_fuction_one_seq(self): - assert map(None, [1, 2, 3]) == [1, 2, 3] - - def test_trivial_map_no_function(self): - assert map(None, [1,2,3], [4,5,6], [7,8], [1]) == ( - [(1, 4, 7, 1), (2, 5, 8, None), (3, 6, None, None)]) + def test_trivial_map_no_fuction(self): + m = map(None, [1, 2, 3]) # Don't crash here... + raises(TypeError, next, m) # ...but only on first item. def test_map_identity1(self): a = ['1', 2, 3, 'b', None] b = a[:] - assert map(lambda x: x, a) == a - assert a == b - - def test_map_None(self): - a = ['1', 2, 3, 'b', None] - b = a[:] - assert map(None, a) == a + assert list(map(lambda x: x, a)) == a assert a == b def test_map_badoperation(self): a = ['1', 2, 3, 'b', None] - raises(TypeError, map, lambda x: x+1, a) - - def test_map_multiply_identity(self): - a = ['1', 2, 3, 'b', None] - b = [ 2, 3, 4, 5, 6] - assert map(None, a, b) == [('1', 2), (2, 3), (3, 4), ('b', 5), (None, 6)] + raises(TypeError, list, map, lambda x: x+1, a) def test_map_add(self): a = [1, 2, 3, 4] b = [0, 1, 1, 1] - assert map(lambda x, y: x+y, a, b) == [1, 3, 4, 5] + assert list(map(lambda x, y: x+y, a, b)) == [1, 3, 4, 5] def test_map_first_item(self): a = [1, 2, 3, 4, 5] - b = [] - assert map(lambda x, y: x, a, b) == a + b = [6, 7, 8, 9, 10] + assert list(map(lambda x, y: x, a, b)) == a def test_map_iterables(self): class A(object): @@ -74,18 +61,23 @@ self.n -= 1 if self.n == 0: raise StopIteration return self.n - result = map(None, A(3), A(8)) + result = map(lambda *x:x, A(3), A(8)) # this also checks that B.next() is not called any more after it # raised StopIteration once - assert result == [(2, 7), (1, 6), (None, 5), (None, 4), - (None, 3), (None, 2), (None, 1)] + assert list(result) == [(2, 7), (1, 6)] + + def test_repr(self): + assert repr(map(1, [2])).startswith(' Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58000:0fc04c38ab33 Date: 2012-10-10 23:24 +0200 http://bitbucket.org/pypy/pypy/changeset/0fc04c38ab33/ Log: map(), filter(), zip() now return iterators. Move the code and tests from the itertool module. Most of the tests now pass with and without -A. diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py --- a/pypy/module/__builtin__/__init__.py +++ b/pypy/module/__builtin__/__init__.py @@ -19,9 +19,6 @@ 'any' : 'app_functional.any', 'all' : 'app_functional.all', 'sum' : 'app_functional.sum', - 'map' : 'app_functional.map', - 'filter' : 'app_functional.filter', - 'zip' : 'app_functional.zip', 'vars' : 'app_inspect.vars', 'dir' : 'app_inspect.dir', @@ -75,6 +72,9 @@ 'range' : 'functional.W_Range', 'enumerate' : 'functional.W_Enumerate', + 'map' : 'functional.W_Map', + 'filter' : 'functional.W_Filter', + 'zip' : 'functional.W_Zip', 'min' : 'functional.min', 'max' : 'functional.max', 'reversed' : 'functional.reversed', diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py --- a/pypy/module/__builtin__/app_functional.py +++ b/pypy/module/__builtin__/app_functional.py @@ -44,55 +44,6 @@ last = last + x return last -def map(func, *collections): - """map(function, sequence[, sequence, ...]) -> list - -Return a list of the results of applying the function to the items of -the argument sequence(s). If more than one sequence is given, the -function is called with an argument list consisting of the corresponding -item of each sequence, substituting None for missing values when not all -sequences have the same length. If the function is None, return a list of -the items of the sequence (or a list of tuples if more than one sequence).""" - if not collections: - raise TypeError("map() requires at least two arguments") - num_collections = len(collections) - none_func = func is None - if num_collections == 1: - if none_func: - return list(collections[0]) - else: - # Special case for the really common case of a single collection, - # this can be eliminated if we could unroll that loop that creates - # `args` based on whether or not len(collections) was constant - result = [] - for item in collections[0]: - result.append(func(item)) - return result - result = [] - # Pair of (iterator, has_finished) - iterators = [(iter(seq), False) for seq in collections] - while True: - cont = False - args = [] - for idx, (iterator, has_finished) in enumerate(iterators): - val = None - if not has_finished: - try: - val = next(iterator) - except StopIteration: - iterators[idx] = (None, True) - else: - cont = True - args.append(val) - args = tuple(args) - if cont: - if none_func: - result.append(args) - else: - result.append(func(*args)) - else: - return result - def filter(func, seq): """filter(function or None, sequence) -> list, tuple, or string @@ -107,20 +58,3 @@ for item in iterator: if func(item): yield item - -def zip(*sequences): - """zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)] - -Return a list of tuples, where each tuple contains the i-th element -from each of the argument sequences. The returned list is truncated -in length to the length of the shortest argument sequence.""" - if not sequences: - return [] - result = [] - iterators = [iter(seq) for seq in sequences] - while True: - try: - items = [next(it) for it in iterators] - except StopIteration: - return result - result.append(tuple(items)) diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -471,3 +471,142 @@ __next__ = interp2app(W_RangeIterator.descr_next), __reduce__ = interp2app(W_RangeIterator.descr_reduce), ) + + +class W_Map(Wrappable): + _error_name = "map" + _immutable_fields_ = ["w_fun", "iterators_w"] + + def __init__(self, space, w_fun, args_w): + self.space = space + self.w_fun = w_fun + + iterators_w = [] + i = 0 + for iterable_w in args_w: + try: + iterator_w = space.iter(iterable_w) + except OperationError, e: + if e.match(self.space, self.space.w_TypeError): + raise OperationError(space.w_TypeError, space.wrap(self._error_name + " argument #" + str(i + 1) + " must support iteration")) + else: + raise + else: + iterators_w.append(iterator_w) + + i += 1 + + self.iterators_w = iterators_w + + def iter_w(self): + return self.space.wrap(self) + + def next_w(self): + # common case: 1 or 2 arguments + iterators_w = self.iterators_w + length = len(iterators_w) + if length == 1: + objects = [self.space.next(iterators_w[0])] + elif length == 2: + objects = [self.space.next(iterators_w[0]), + self.space.next(iterators_w[1])] + else: + objects = self._get_objects() + w_objects = self.space.newtuple(objects) + if self.w_fun is None: + return w_objects + else: + return self.space.call(self.w_fun, w_objects) + + def _get_objects(self): + # the loop is out of the way of the JIT + return [self.space.next(w_elem) for w_elem in self.iterators_w] + + +def W_Map___new__(space, w_subtype, w_fun, args_w): + if len(args_w) == 0: + raise OperationError(space.w_TypeError, + space.wrap("map() must have at least two arguments")) + r = space.allocate_instance(W_Map, w_subtype) + r.__init__(space, w_fun, args_w) + return space.wrap(r) + +W_Map.typedef = TypeDef( + 'map', + __new__ = interp2app(W_Map___new__), + __iter__ = interp2app(W_Map.iter_w), + __next__ = interp2app(W_Map.next_w), + __doc__ = """\ +Make an iterator that computes the function using arguments from +each of the iterables. Stops when the shortest iterable is exhausted.""") + +class W_Filter(Wrappable): + reverse = False + + def __init__(self, space, w_predicate, w_iterable): + self.space = space + if space.is_w(w_predicate, space.w_None): + self.no_predicate = True + else: + self.no_predicate = False + self.w_predicate = w_predicate + self.iterable = space.iter(w_iterable) + + def iter_w(self): + return self.space.wrap(self) + + def next_w(self): + while True: + w_obj = self.space.next(self.iterable) # may raise w_StopIteration + if self.no_predicate: + pred = self.space.is_true(w_obj) + else: + w_pred = self.space.call_function(self.w_predicate, w_obj) + pred = self.space.is_true(w_pred) + if pred ^ self.reverse: + return w_obj + + +def W_Filter___new__(space, w_subtype, w_predicate, w_iterable): + r = space.allocate_instance(W_Filter, w_subtype) + r.__init__(space, w_predicate, w_iterable) + return space.wrap(r) + +W_Filter.typedef = TypeDef( + 'filter', + __new__ = interp2app(W_Filter___new__), + __iter__ = interp2app(W_Filter.iter_w), + __next__ = interp2app(W_Filter.next_w), + __doc__ = """\ +Return an iterator yielding those items of iterable for which function(item) +is true. If function is None, return the items that are true.""") + + +class W_Zip(W_Map): + _error_name = "zip" + + def next_w(self): + # argh. zip(*args) is almost like map(None, *args) except + # that the former needs a special case for len(args)==0 + # while the latter just raises a TypeError in this situation. + if len(self.iterators_w) == 0: + raise OperationError(self.space.w_StopIteration, self.space.w_None) + return W_Map.next_w(self) + +def W_Zip___new__(space, w_subtype, args_w): + r = space.allocate_instance(W_Zip, w_subtype) + r.__init__(space, None, args_w) + return space.wrap(r) + +W_Zip.typedef = TypeDef( + 'zip', + __new__ = interp2app(W_Zip___new__), + __iter__ = interp2app(W_Zip.iter_w), + __next__ = interp2app(W_Zip.next_w), + __doc__ = """\ +Return a zip object whose .__next__() method returns a tuple where +the i-th element comes from the i-th iterable argument. The .__next__() +method continues until the shortest iterable in the argument sequence +is exhausted and then it raises StopIteration.""") + + diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py --- a/pypy/module/__builtin__/test/test_functional.py +++ b/pypy/module/__builtin__/test/test_functional.py @@ -69,6 +69,45 @@ def test_repr(self): assert repr(map(1, [2])).startswith('= 0 + else: + fail("TypeError expected") + diff --git a/pypy/module/itertools/__init__.py b/pypy/module/itertools/__init__.py --- a/pypy/module/itertools/__init__.py +++ b/pypy/module/itertools/__init__.py @@ -14,7 +14,6 @@ ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False islice(seq, [start,] stop [, step]) --> elements from seq[start:stop:step] - imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ... starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ... tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... @@ -32,9 +31,7 @@ 'cycle' : 'interp_itertools.W_Cycle', 'dropwhile' : 'interp_itertools.W_DropWhile', 'groupby' : 'interp_itertools.W_GroupBy', - 'ifilter' : 'interp_itertools.W_IFilter', - 'ifilterfalse' : 'interp_itertools.W_IFilterFalse', - 'imap' : 'interp_itertools.W_IMap', + 'filterfalse' : 'interp_itertools.W_FilterFalse', 'islice' : 'interp_itertools.W_ISlice', 'permutations' : 'interp_itertools.W_Permutations', 'product' : 'interp_itertools.W_Product', diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -3,6 +3,8 @@ from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.module.__builtin__.functional import W_Filter, W_Map + class W_Count(Wrappable): def __init__(self, space, w_firstval, w_step): @@ -240,81 +242,27 @@ yield x """) -class _IFilterBase(Wrappable): +class W_FilterFalse(W_Filter): + reverse = True - def __init__(self, space, w_predicate, w_iterable): - self.space = space - if space.is_w(w_predicate, space.w_None): - self.no_predicate = True - else: - self.no_predicate = False - self.w_predicate = w_predicate - self.iterable = space.iter(w_iterable) - - def iter_w(self): - return self.space.wrap(self) - - def next_w(self): - while True: - w_obj = self.space.next(self.iterable) # may raise w_StopIteration - if self.no_predicate: - pred = self.space.is_true(w_obj) - else: - w_pred = self.space.call_function(self.w_predicate, w_obj) - pred = self.space.is_true(w_pred) - if pred ^ self.reverse: - return w_obj - - -class W_IFilter(_IFilterBase): - reverse = False - -def W_IFilter___new__(space, w_subtype, w_predicate, w_iterable): - r = space.allocate_instance(W_IFilter, w_subtype) +def W_FilterFalse___new__(space, w_subtype, w_predicate, w_iterable): + r = space.allocate_instance(W_FilterFalse, w_subtype) r.__init__(space, w_predicate, w_iterable) return space.wrap(r) -W_IFilter.typedef = TypeDef( - 'ifilter', - __module__ = 'itertools', - __new__ = interp2app(W_IFilter___new__), - __iter__ = interp2app(W_IFilter.iter_w), - __next__ = interp2app(W_IFilter.next_w), - __doc__ = """Make an iterator that filters elements from iterable returning - only those for which the predicate is True. If predicate is - None, return the items that are true. - - Equivalent to : - - def ifilter: - if predicate is None: - predicate = bool - for x in iterable: - if predicate(x): - yield x - """) - -class W_IFilterFalse(_IFilterBase): - reverse = True - -def W_IFilterFalse___new__(space, w_subtype, w_predicate, w_iterable): - r = space.allocate_instance(W_IFilterFalse, w_subtype) - r.__init__(space, w_predicate, w_iterable) - return space.wrap(r) - -W_IFilterFalse.typedef = TypeDef( +W_FilterFalse.typedef = TypeDef( 'ifilterfalse', __module__ = 'itertools', - __new__ = interp2app(W_IFilterFalse___new__), - __iter__ = interp2app(W_IFilterFalse.iter_w), - __next__ = interp2app(W_IFilterFalse.next_w), + __new__ = interp2app(W_FilterFalse___new__), + __iter__ = interp2app(W_FilterFalse.iter_w), + __next__ = interp2app(W_FilterFalse.next_w), __doc__ = """Make an iterator that filters elements from iterable returning only those for which the predicate is False. If predicate is None, return the items that are false. Equivalent to : - def ifilterfalse(predicate, iterable): + def filterfalse(predicate, iterable): if predicate is None: predicate = bool for x in iterable: @@ -489,97 +437,8 @@ yield element """) -class W_IMap(Wrappable): - _error_name = "imap" - _immutable_fields_ = ["w_fun", "iterators_w"] - def __init__(self, space, w_fun, args_w): - self.space = space - if self.space.is_w(w_fun, space.w_None): - self.w_fun = None - else: - self.w_fun = w_fun - - iterators_w = [] - i = 0 - for iterable_w in args_w: - try: - iterator_w = space.iter(iterable_w) - except OperationError, e: - if e.match(self.space, self.space.w_TypeError): - raise OperationError(space.w_TypeError, space.wrap(self._error_name + " argument #" + str(i + 1) + " must support iteration")) - else: - raise - else: - iterators_w.append(iterator_w) - - i += 1 - - self.iterators_w = iterators_w - - def iter_w(self): - return self.space.wrap(self) - - def next_w(self): - # common case: 1 or 2 arguments - iterators_w = self.iterators_w - length = len(iterators_w) - if length == 1: - objects = [self.space.next(iterators_w[0])] - elif length == 2: - objects = [self.space.next(iterators_w[0]), - self.space.next(iterators_w[1])] - else: - objects = self._get_objects() - w_objects = self.space.newtuple(objects) - if self.w_fun is None: - return w_objects - else: - return self.space.call(self.w_fun, w_objects) - - def _get_objects(self): - # the loop is out of the way of the JIT - return [self.space.next(w_elem) for w_elem in self.iterators_w] - - -def W_IMap___new__(space, w_subtype, w_fun, args_w): - if len(args_w) == 0: - raise OperationError(space.w_TypeError, - space.wrap("imap() must have at least two arguments")) - r = space.allocate_instance(W_IMap, w_subtype) - r.__init__(space, w_fun, args_w) - return space.wrap(r) - -W_IMap.typedef = TypeDef( - 'imap', - __module__ = 'itertools', - __new__ = interp2app(W_IMap___new__), - __iter__ = interp2app(W_IMap.iter_w), - __next__ = interp2app(W_IMap.next_w), - __doc__ = """Make an iterator that computes the function using arguments - from each of the iterables. If function is set to None, then - imap() returns the arguments as a tuple. Like map() but stops - when the shortest iterable is exhausted instead of filling in - None for shorter iterables. The reason for the difference is that - infinite iterator arguments are typically an error for map() - (because the output is fully evaluated) but represent a common - and useful way of supplying arguments to imap(). - - Equivalent to : - - def imap(function, *iterables): - iterables = map(iter, iterables) - while True: - args = [i.next() for i in iterables] - if function is None: - yield tuple(args) - else: - yield function(*args) - - """) - - -class W_ZipLongest(W_IMap): +class W_ZipLongest(W_Map): _error_name = "zip_longest" def next_w(self): diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -71,7 +71,7 @@ import itertools import sys - raises(OverflowError, itertools.repeat, None, sys.maxint + 1) + raises(OverflowError, itertools.repeat, None, sys.maxsize + 1) def test_repeat_repr(self): import itertools @@ -144,40 +144,13 @@ raises(TypeError, itertools.dropwhile, bool, None) - def test_ifilter(self): + def test_filterfalse(self): import itertools - it = itertools.ifilter(None, []) + it = itertools.filterfalse(None, []) raises(StopIteration, next, it) - it = itertools.ifilter(None, [1, 0, 2, 3, 0]) - for x in [1, 2, 3]: - assert next(it) == x - raises(StopIteration, next, it) - - def is_odd(arg): - return (arg % 2 == 1) - - it = itertools.ifilter(is_odd, [1, 2, 3, 4, 5, 6]) - for x in [1, 3, 5]: - assert next(it) == x - raises(StopIteration, next, it) - - def test_ifilter_wrongargs(self): - import itertools - - it = itertools.ifilter(0, [1]) - raises(TypeError, next, it) - - raises(TypeError, itertools.ifilter, bool, None) - - def test_ifilterfalse(self): - import itertools - - it = itertools.ifilterfalse(None, []) - raises(StopIteration, next, it) - - it = itertools.ifilterfalse(None, [1, 0, 2, 3, 0]) + it = itertools.filterfalse(None, [1, 0, 2, 3, 0]) for x in [0, 0]: assert next(it) == x raises(StopIteration, next, it) @@ -185,18 +158,18 @@ def is_odd(arg): return (arg % 2 == 1) - it = itertools.ifilterfalse(is_odd, [1, 2, 3, 4, 5, 6]) + it = itertools.filterfalse(is_odd, [1, 2, 3, 4, 5, 6]) for x in [2, 4, 6]: assert next(it) == x raises(StopIteration, next, it) - def test_ifilterfalse_wrongargs(self): + def test_filterfalse_wrongargs(self): import itertools - it = itertools.ifilterfalse(0, [1]) + it = itertools.filterfalse(0, [1]) raises(TypeError, next, it) - raises(TypeError, itertools.ifilterfalse, bool, None) + raises(TypeError, itertools.filterfalse, bool, None) def test_islice(self): import itertools @@ -284,7 +257,7 @@ import itertools import sys raises((OverflowError, ValueError), # ValueError on top of CPython - itertools.islice, [], sys.maxint + 1) + itertools.islice, [], sys.maxsize + 1) def test_islice_wrongargs(self): import itertools @@ -322,47 +295,6 @@ assert next(it) == 1 raises(StopIteration, next, it) - def test_imap(self): - import itertools - - obj_list = [object(), object(), object()] - it = itertools.imap(None, obj_list) - for x in obj_list: - assert next(it) == (x, ) - raises(StopIteration, next, it) - - it = itertools.imap(None, [1, 2, 3], [4], [5, 6]) - assert next(it) == (1, 4, 5) - raises(StopIteration, next, it) - - it = itertools.imap(None, [], [], [1], []) - raises(StopIteration, next, it) - - it = itertools.imap(str, [0, 1, 0, 1]) - for x in ['0', '1', '0', '1']: - assert next(it) == x - raises(StopIteration, next, it) - - import operator - it = itertools.imap(operator.add, [1, 2, 3], [4, 5, 6]) - for x in [5, 7, 9]: - assert next(it) == x - raises(StopIteration, next, it) - - def test_imap_wrongargs(self): - import itertools - - # Duplicate python 2.4 behaviour for invalid arguments - it = itertools.imap(0, []) - raises(StopIteration, next, it) - it = itertools.imap(0, [0]) - raises(TypeError, next, it) - raises(TypeError, itertools.imap, None, 0) - - raises(TypeError, itertools.imap, None) - raises(TypeError, itertools.imap, bool) - raises(TypeError, itertools.imap, 42) - def test_cycle(self): import itertools @@ -569,9 +501,7 @@ itertools.cycle([]), itertools.dropwhile(bool, []), itertools.groupby([]), - itertools.ifilter(None, []), - itertools.ifilterfalse(None, []), - itertools.imap(None, []), + itertools.filterfalse(None, []), itertools.islice([], 0), itertools.repeat(None), itertools.starmap(bool, []), @@ -596,9 +526,7 @@ itertools.cycle, itertools.dropwhile, itertools.groupby, - itertools.ifilter, - itertools.ifilterfalse, - itertools.imap, + itertools.filterfalse, itertools.islice, itertools.repeat, itertools.starmap, @@ -637,26 +565,26 @@ def test_count_overflow(self): import itertools, sys - it = itertools.count(sys.maxint - 1) - assert next(it) == sys.maxint - 1 - assert next(it) == sys.maxint - assert next(it) == sys.maxint + 1 - it = itertools.count(sys.maxint + 1) - assert next(it) == sys.maxint + 1 - assert next(it) == sys.maxint + 2 - it = itertools.count(-sys.maxint-2) - assert next(it) == -sys.maxint - 2 - assert next(it) == -sys.maxint - 1 - assert next(it) == -sys.maxint - assert next(it) == -sys.maxint + 1 - it = itertools.count(0, sys.maxint) - assert next(it) == sys.maxint * 0 - assert next(it) == sys.maxint * 1 - assert next(it) == sys.maxint * 2 - it = itertools.count(0, sys.maxint + 1) - assert next(it) == (sys.maxint + 1) * 0 - assert next(it) == (sys.maxint + 1) * 1 - assert next(it) == (sys.maxint + 1) * 2 + it = itertools.count(sys.maxsize - 1) + assert next(it) == sys.maxsize - 1 + assert next(it) == sys.maxsize + assert next(it) == sys.maxsize + 1 + it = itertools.count(sys.maxsize + 1) + assert next(it) == sys.maxsize + 1 + assert next(it) == sys.maxsize + 2 + it = itertools.count(-sys.maxsize-2) + assert next(it) == -sys.maxsize - 2 + assert next(it) == -sys.maxsize - 1 + assert next(it) == -sys.maxsize + assert next(it) == -sys.maxsize + 1 + it = itertools.count(0, sys.maxsize) + assert next(it) == sys.maxsize * 0 + assert next(it) == sys.maxsize * 1 + assert next(it) == sys.maxsize * 2 + it = itertools.count(0, sys.maxsize + 1) + assert next(it) == (sys.maxsize + 1) * 0 + assert next(it) == (sys.maxsize + 1) * 1 + assert next(it) == (sys.maxsize + 1) * 2 def test_chain_fromiterable(self): import itertools @@ -695,14 +623,14 @@ # take 3 from infinite input assert (list(islice(zip_longest('abcdef', count()),3)) == - zip('abcdef', range(3))) + list(zip('abcdef', range(3)))) - assert list(zip_longest()) == zip() - assert list(zip_longest([])) == zip([]) - assert list(zip_longest('abcdef')) == zip('abcdef') + assert list(zip_longest()) == list(zip()) + assert list(zip_longest([])) == list(zip([])) + assert list(zip_longest('abcdef')) == list(zip('abcdef')) assert (list(zip_longest('abc', 'defg', **{})) == - zip(list('abc') + [None], 'defg')) # empty keyword dict + list(zip(list('abc') + [None], 'defg'))) # empty keyword dict raises(TypeError, zip_longest, 3) raises(TypeError, zip_longest, range(3), 3) @@ -945,17 +873,13 @@ assert type(A(lambda x: True, [])) is A class A(itertools.dropwhile): pass assert type(A(lambda x: True, [])) is A - class A(itertools.ifilter): pass - assert type(A(lambda x: True, [])) is A - class A(itertools.ifilterfalse): pass + class A(itertools.filterfalse): pass assert type(A(lambda x: True, [])) is A class A(itertools.islice): pass assert type(A([], 0)) is A class A(itertools.chain): pass assert type(A([], [])) is A assert type(A.from_iterable([])) is A - class A(itertools.imap): pass - assert type(A(lambda: 5, [])) is A class A(itertools.zip_longest): pass assert type(A([], [])) is A class A(itertools.cycle): pass @@ -975,8 +899,8 @@ def test_copy_pickle(self): import itertools, copy, pickle, sys - for value in [42, -sys.maxint*99]: - for step in [1, sys.maxint*42, 5.5]: + for value in [42, -sys.maxsize*99]: + for step in [1, sys.maxsize*42, 5.5]: expected = [value, value+step, value+2*step] c = itertools.count(value, step) assert list(itertools.islice(c, 3)) == expected From noreply at buildbot.pypy.org Thu Oct 11 01:24:36 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 11 Oct 2012 01:24:36 +0200 (CEST) Subject: [pypy-commit] pypy default: isfinite already lives in rfloat Message-ID: <20121010232436.7C3C91C0117@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r58001:07b46876b954 Date: 2012-10-10 16:19 -0700 http://bitbucket.org/pypy/pypy/changeset/07b46876b954/ Log: isfinite already lives in rfloat diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py --- a/pypy/rlib/rcomplex.py +++ b/pypy/rlib/rcomplex.py @@ -1,12 +1,12 @@ import math from math import fabs, pi, e -from pypy.rlib.rfloat import copysign, asinh, log1p, isinf, isnan +from pypy.rlib.rfloat import copysign, asinh, log1p, isfinite, isinf, isnan from pypy.rlib.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN from pypy.rlib.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG from pypy.rlib.constant import M_LN2, M_LN10 from pypy.rlib.constant import CM_SQRT_LARGE_DOUBLE, CM_SQRT_DBL_MIN from pypy.rlib.constant import CM_LOG_LARGE_DOUBLE -from pypy.rlib.special_value import isfinite, special_type, INF, NAN +from pypy.rlib.special_value import special_type, INF, NAN from pypy.rlib.special_value import sqrt_special_values from pypy.rlib.special_value import acos_special_values from pypy.rlib.special_value import acosh_special_values diff --git a/pypy/rlib/special_value.py b/pypy/rlib/special_value.py --- a/pypy/rlib/special_value.py +++ b/pypy/rlib/special_value.py @@ -32,9 +32,6 @@ else: return ST_NZERO -def isfinite(d): - return not isinf(d) and not isnan(d) - P = math.pi P14 = 0.25 * math.pi From noreply at buildbot.pypy.org Thu Oct 11 02:07:54 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 11 Oct 2012 02:07:54 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20121011000754.BD3731C0117@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58002:35eee26a2f3f Date: 2012-10-10 17:07 -0700 http://bitbucket.org/pypy/pypy/changeset/35eee26a2f3f/ Log: merge default diff too long, truncating to 2000 out of 12584 lines diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,11 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - libpath = ctypes.util.find_library('db-4.5') - if not libpath: + for c in '56789': + libpath = ctypes.util.find_library('db-4.%s' % c) + if libpath: + break + else: raise ImportError("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' diff --git a/py/_io/capture.py b/py/_io/capture.py --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -176,7 +176,7 @@ class StdCaptureFD(Capture): - """ This class allows to capture writes to FD1 and FD2 + """ This class allows capturing writes to FD1 and FD2 and may connect a NULL file to FD0 (and prevent reads from sys.stdin). If any of the 0,1,2 file descriptors is invalid it will not be captured. @@ -267,8 +267,8 @@ return l class StdCapture(Capture): - """ This class allows to capture writes to sys.stdout|stderr "in-memory" - and will raise errors on tries to read from sys.stdin. It only + """ This class allows capturing writes to sys.stdout|stderr "in-memory" + and will raise errors on read attempts from sys.stdin. It only modifies sys.stdout|stderr|stdin attributes and does not touch underlying File Descriptors (use StdCaptureFD for that). """ diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -3859,6 +3859,14 @@ a = self.RPythonAnnotator() py.test.raises(Exception, a.build_types, fn, []) + def test_lower_char(self): + def fn(c): + return c.lower() + a = self.RPythonAnnotator() + s = a.build_types(fn, [annmodel.SomeChar()]) + assert s == annmodel.SomeChar() + + def g(n): return [0,1,2,n] diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -587,6 +587,12 @@ def method_isupper(chr): return s_Bool + def method_lower(chr): + return chr + + def method_upper(chr): + return chr + class __extend__(SomeIterator): def iter(itr): diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -2,9 +2,9 @@ """ Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME -Print a report for the static data informations contained in FILENAME +Print a report for the static data information contained in FILENAME -The static data informations are saved in the file staticdata.info when +The static data information is saved in the file staticdata.info when passing --dump_static_data_info to translate.py. Options: diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -238,7 +238,7 @@ interpreter`_. .. _`documentation index`: index.html#project-documentation -.. _`getting-started`: getting-started.html +.. _`getting-started`: getting-started-dev.html .. _`PyPy's approach to virtual machine construction`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dls2006/pypy-vm-construction.pdf .. _`the translation document`: translation.html .. _`RPython toolchain`: translation.html diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -41,9 +41,6 @@ llexternal functions. For a typical usage, see `pypy.rlib.rsocket.RSocket.getsockopt_int`. -- Support context managers and the `with` statement. This could be a workaround - before the previous point is available. - Extensible type system for llexternal ------------------------------------- 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 @@ -36,6 +36,10 @@ .. branch: stdlib-2.7.3 The stdlib was updated to version 2.7.3 +.. branch: numpypy-complex2 +Complex dtype support for numpy + + .. "uninteresting" branches that we should just ignore for the whatsnew: .. branch: slightly-shorter-c diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -3,7 +3,6 @@ from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.pyopcode import LoopBlock from pypy.rlib import jit -from pypy.rlib.objectmodel import specialize class GeneratorIterator(Wrappable): diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -1,10 +1,62 @@ +from pypy.interpreter.error import OperationError +from pypy.rlib.objectmodel import specialize +from pypy.rlib import runicode from pypy.module._codecs import interp_codecs + at specialize.memo() +def decode_error_handler(space): + def raise_unicode_exception_decode(errors, encoding, msg, s, + startingpos, endingpos): + raise OperationError(space.w_UnicodeDecodeError, + space.newtuple([space.wrap(encoding), + space.wrapbytes(s), + space.wrap(startingpos), + space.wrap(endingpos), + space.wrap(msg)])) + return raise_unicode_exception_decode + + at specialize.memo() +def encode_error_handler(space): + def raise_unicode_exception_encode(errors, encoding, msg, u, + startingpos, endingpos): + raise OperationError(space.w_UnicodeEncodeError, + space.newtuple([space.wrap(encoding), + space.wrap(u), + space.wrap(startingpos), + space.wrap(endingpos), + space.wrap(msg)])) + return raise_unicode_exception_encode + +# ____________________________________________________________ + def PyUnicode_AsEncodedString(space, w_data, w_encoding): return interp_codecs.encode(space, w_data, w_encoding) # These functions take and return unwrapped rpython strings and unicodes -PyUnicode_DecodeUnicodeEscape = interp_codecs.make_raw_decoder('unicode_escape') -PyUnicode_DecodeRawUnicodeEscape = interp_codecs.make_raw_decoder('raw_unicode_escape') -PyUnicode_DecodeUTF8 = interp_codecs.make_raw_decoder('utf_8') -PyUnicode_EncodeUTF8 = interp_codecs.make_raw_encoder('utf_8') +def PyUnicode_DecodeUnicodeEscape(space, string): + state = space.fromcache(interp_codecs.CodecState) + unicodedata_handler = state.get_unicodedata_handler(space) + result, consumed = runicode.str_decode_unicode_escape( + string, len(string), "strict", + final=True, errorhandler=decode_error_handler(space), + unicodedata_handler=unicodedata_handler) + return result + +def PyUnicode_DecodeRawUnicodeEscape(space, string): + result, consumed = runicode.str_decode_raw_unicode_escape( + string, len(string), "strict", + final=True, errorhandler=decode_error_handler(space)) + return result + +def PyUnicode_DecodeUTF8(space, string): + result, consumed = runicode.str_decode_utf_8( + string, len(string), "strict", + final=True, errorhandler=decode_error_handler(space), + allow_surrogates=True) + return result + +def PyUnicode_EncodeUTF8(space, uni): + return runicode.unicode_encode_utf_8( + uni, len(uni), "strict", + errorhandler=encode_error_handler(space), + allow_surrogates=True) diff --git a/pypy/jit/backend/cli/methodfactory.py b/pypy/jit/backend/cli/methodfactory.py --- a/pypy/jit/backend/cli/methodfactory.py +++ b/pypy/jit/backend/cli/methodfactory.py @@ -27,7 +27,7 @@ return self.dynmeth.CreateDelegate(delegatetype, consts) -# the assemblyData singleton contains the informations about the +# the assemblyData singleton contains the information about the # assembly we are currently writing to class AssemblyData: assembly = None diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -97,7 +97,7 @@ 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 informations about it. + ``compiled_loop`` for more information about it. """ raise NotImplementedError diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -317,7 +317,7 @@ except BadVirtualState: raise InvalidLoop('The state of the optimizer at the end of ' + 'peeled loop is inconsistent with the ' + - 'VirtualState at the begining of the peeled ' + + 'VirtualState at the beginning of the peeled ' + 'loop') jumpop.initarglist(jumpargs) diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -47,8 +47,8 @@ # string to the rest of the code. XXX not entirely sure if these three # functions are the only way for non-string objects to reach # space.{get,set,del}attr()... - # Note that if w_name is already a string (or a subclass of str), - # it must be returned unmodified (and not e.g. unwrapped-rewrapped). + # Note that if w_name is already an exact string it must be returned + # unmodified (and not e.g. unwrapped-rewrapped). if not space.is_w(space.type(w_name), space.w_text): name = space.unicode_w(w_name) # typecheck w_name = space.wrap(name) # rewrap as a real string 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 @@ -218,27 +218,6 @@ assert f() == {} assert g() == {'a':0, 'b':0, 'c':0} - def test_getattr(self): - class a(object): - i = 5 - assert getattr(a, 'i') == 5 - raises(AttributeError, getattr, a, 'k') - assert getattr(a, 'k', 42) == 42 - raises(TypeError, getattr, a, b'i') - raises(TypeError, getattr, a, b'k', 42) - - def test_getattr_typecheck(self): - class A(object): - def __getattribute__(self, name): - pass - def __setattr__(self, name, value): - pass - def __delattr__(self, name): - pass - raises(TypeError, getattr, A(), 42) - raises(TypeError, setattr, A(), 42, 'x') - raises(TypeError, delattr, A(), 42) - def test_sum(self): assert sum([]) ==0 assert sum([42]) ==42 @@ -339,7 +318,7 @@ raises(ValueError, range, 0, 1, 0) - def test_range_repr(self): + def test_range_repr(self): assert repr(range(1)) == 'range(0, 1)' assert repr(range(1,2)) == 'range(1, 2)' assert repr(range(1,2,3)) == 'range(1, 2, 3)' @@ -669,3 +648,35 @@ return {'a':2} __dict__ = property(fget=getDict) assert vars(C_get_vars()) == {'a':2} + + +class AppTestGetattr: + OPTIONS = {} + + def setup_class(cls): + cls.space = conftest.gettestobjspace(**cls.OPTIONS) + + def test_getattr(self): + class a(object): + i = 5 + assert getattr(a, 'i') == 5 + raises(AttributeError, getattr, a, 'k') + assert getattr(a, 'k', 42) == 42 + raises(TypeError, getattr, a, b'i') + raises(TypeError, getattr, a, b'k', 42) + + def test_getattr_typecheck(self): + class A(object): + def __getattribute__(self, name): + pass + def __setattr__(self, name, value): + pass + def __delattr__(self, name): + pass + raises(TypeError, getattr, A(), 42) + raises(TypeError, setattr, A(), 42, 'x') + raises(TypeError, delattr, A(), 42) + + +class AppTestGetattrWithGetAttributeShortcut(AppTestGetattr): + OPTIONS = {"objspace.std.getattributeshortcut": True} 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 @@ -133,8 +133,7 @@ # manual inlining and tweaking of # W_CTypePrimitiveSigned.convert_from_object() in order # to write a whole 'ffi_arg'. - value = misc.as_long_long(space, w_res) - value = r_ulonglong(value) + value = misc.as_long(space, w_res) misc.write_raw_integer_data(ll_res, value, SIZE_OF_FFI_ARG) return else: diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -4,7 +4,7 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rlib.objectmodel import keepalive_until_here +from pypy.rlib.objectmodel import keepalive_until_here, specialize from pypy.rlib import objectmodel, rgc from pypy.tool.sourcetools import func_with_new_name @@ -190,6 +190,7 @@ def iter(self): return self.ctype.iter(self) + @specialize.argtype(1) def write_raw_integer_data(self, source): misc.write_raw_integer_data(self._cdata, source, self.ctype.size) keepalive_until_here(self) diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -45,7 +45,7 @@ return w_result def convert_to_object(self, cdata): - value = intmask(misc.read_raw_signed_data(cdata, self.size)) + value = misc.read_raw_long_data(cdata, self.size) try: enumerator = self.enumvalues2erators[value] except KeyError: diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -4,7 +4,7 @@ from pypy.interpreter.error import operationerrfmt from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rlib.rarithmetic import r_ulonglong +from pypy.rlib.rarithmetic import r_uint, r_ulonglong, intmask from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib import jit @@ -164,9 +164,10 @@ W_CTypePrimitive.__init__(self, *args) self.value_fits_long = self.size <= rffi.sizeof(lltype.Signed) if self.size < rffi.sizeof(lltype.SignedLongLong): + assert self.value_fits_long sh = self.size * 8 - self.vmin = r_ulonglong(-1) << (sh - 1) - self.vrangemax = (r_ulonglong(1) << sh) - 1 + self.vmin = r_uint(-1) << (sh - 1) + self.vrangemax = (r_uint(1) << sh) - 1 def int(self, cdata): # enums: really call convert_to_object() just below, @@ -182,12 +183,15 @@ return self.space.wrap(value) # r_longlong => on 32-bit, 'long' def convert_from_object(self, cdata, w_ob): - value = misc.as_long_long(self.space, w_ob) - if self.size < rffi.sizeof(lltype.SignedLongLong): - if r_ulonglong(value) - self.vmin > self.vrangemax: - self._overflow(w_ob) - value = r_ulonglong(value) - misc.write_raw_integer_data(cdata, value, self.size) + if self.value_fits_long: + value = misc.as_long(self.space, w_ob) + if self.size < rffi.sizeof(lltype.Signed): + if r_uint(value) - self.vmin > self.vrangemax: + self._overflow(w_ob) + misc.write_raw_integer_data(cdata, value, self.size) + else: + value = misc.as_long_long(self.space, w_ob) + misc.write_raw_integer_data(cdata, value, self.size) def get_vararg_type(self): if self.size < rffi.sizeof(rffi.INT): @@ -197,34 +201,42 @@ class W_CTypePrimitiveUnsigned(W_CTypePrimitive): - _attrs_ = ['value_fits_long', 'vrangemax'] - _immutable_fields_ = ['value_fits_long', 'vrangemax'] + _attrs_ = ['value_fits_long', 'value_fits_ulong', 'vrangemax'] + _immutable_fields_ = ['value_fits_long', 'value_fits_ulong', 'vrangemax'] is_primitive_integer = True def __init__(self, *args): W_CTypePrimitive.__init__(self, *args) self.value_fits_long = self.size < rffi.sizeof(lltype.Signed) - if self.size < rffi.sizeof(lltype.SignedLongLong): + self.value_fits_ulong = self.size <= rffi.sizeof(lltype.Unsigned) + if self.value_fits_long: self.vrangemax = self._compute_vrange_max() def _compute_vrange_max(self): sh = self.size * 8 - return (r_ulonglong(1) << sh) - 1 + return (r_uint(1) << sh) - 1 def int(self, cdata): return self.convert_to_object(cdata) def convert_from_object(self, cdata, w_ob): - value = misc.as_unsigned_long_long(self.space, w_ob, strict=True) - if self.size < rffi.sizeof(lltype.SignedLongLong): - if value > self.vrangemax: - self._overflow(w_ob) - misc.write_raw_integer_data(cdata, value, self.size) + if self.value_fits_ulong: + value = misc.as_unsigned_long(self.space, w_ob, strict=True) + if self.value_fits_long: + if value > self.vrangemax: + self._overflow(w_ob) + misc.write_raw_integer_data(cdata, value, self.size) + else: + value = misc.as_unsigned_long_long(self.space, w_ob, strict=True) + misc.write_raw_integer_data(cdata, value, self.size) def convert_to_object(self, cdata): - if self.value_fits_long: + if self.value_fits_ulong: value = misc.read_raw_ulong_data(cdata, self.size) - return self.space.wrap(value) + if self.value_fits_long: + return self.space.wrap(intmask(value)) + else: + return self.space.wrap(value) # r_uint => 'long' object else: value = misc.read_raw_unsigned_data(cdata, self.size) return self.space.wrap(value) # r_ulonglong => 'long' object @@ -240,7 +252,7 @@ _attrs_ = [] def _compute_vrange_max(self): - return r_ulonglong(1) + return r_uint(1) def _cast_result(self, intvalue): return r_ulonglong(intvalue != 0) 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 @@ -53,7 +53,7 @@ isinstance(ob.ctype, W_CTypePtrOrArray)): value = ob._cdata else: - value = misc.as_unsigned_long_long(space, w_ob, strict=False) + value = misc.as_unsigned_long(space, w_ob, strict=False) value = rffi.cast(rffi.CCHARP, value) return cdataobj.W_CData(space, value, self) diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -3,11 +3,11 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.rpython.lltypesystem import rffi +from pypy.rpython.lltypesystem import lltype, rffi from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty from pypy.rlib.objectmodel import keepalive_until_here -from pypy.rlib.rarithmetic import r_ulonglong, r_longlong, intmask +from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask from pypy.rlib import jit from pypy.module._cffi_backend.ctypeobj import W_CType @@ -195,30 +195,43 @@ space = ctype.space # if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned): - value = r_ulonglong(misc.read_raw_signed_data(cdata, ctype.size)) - valuemask = (r_ulonglong(1) << self.bitsize) - 1 - shiftforsign = r_ulonglong(1) << (self.bitsize - 1) - value = ((value >> self.bitshift) + shiftforsign) & valuemask - result = r_longlong(value) - r_longlong(shiftforsign) if ctype.value_fits_long: - return space.wrap(intmask(result)) + value = r_uint(misc.read_raw_long_data(cdata, ctype.size)) + valuemask = (r_uint(1) << self.bitsize) - 1 + shiftforsign = r_uint(1) << (self.bitsize - 1) + value = ((value >> self.bitshift) + shiftforsign) & valuemask + result = intmask(value) - intmask(shiftforsign) + return space.wrap(result) else: + value = misc.read_raw_unsigned_data(cdata, ctype.size) + valuemask = (r_ulonglong(1) << self.bitsize) - 1 + shiftforsign = r_ulonglong(1) << (self.bitsize - 1) + value = ((value >> self.bitshift) + shiftforsign) & valuemask + result = r_longlong(value) - r_longlong(shiftforsign) return space.wrap(result) # if isinstance(ctype, ctypeprim.W_CTypePrimitiveUnsigned): value_fits_long = ctype.value_fits_long + value_fits_ulong = ctype.value_fits_ulong elif isinstance(ctype, ctypeprim.W_CTypePrimitiveCharOrUniChar): value_fits_long = True + value_fits_ulong = True else: raise NotImplementedError # - value = misc.read_raw_unsigned_data(cdata, ctype.size) - valuemask = (r_ulonglong(1) << self.bitsize) - 1 - value = (value >> self.bitshift) & valuemask - if value_fits_long: - return space.wrap(intmask(value)) + if value_fits_ulong: + value = misc.read_raw_ulong_data(cdata, ctype.size) + valuemask = (r_uint(1) << self.bitsize) - 1 + value = (value >> self.bitshift) & valuemask + if value_fits_long: + return space.wrap(intmask(value)) + else: + return space.wrap(value) # uint => wrapped long object else: - return space.wrap(value) + value = misc.read_raw_unsigned_data(cdata, ctype.size) + valuemask = (r_ulonglong(1) << self.bitsize) - 1 + value = (value >> self.bitshift) & valuemask + return space.wrap(value) # ulonglong => wrapped long object def convert_bitfield_from_object(self, cdata, w_ob): ctype = self.ctype 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 @@ -1,9 +1,9 @@ from __future__ import with_statement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib.rarithmetic import r_ulonglong +from pypy.rlib.rarithmetic import r_uint, r_ulonglong from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.objectmodel import keepalive_until_here +from pypy.rlib.objectmodel import keepalive_until_here, specialize from pypy.rlib import jit from pypy.translator.tool.cbuild import ExternalCompilationInfo @@ -49,8 +49,8 @@ def read_raw_ulong_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): - assert rffi.sizeof(TP) < rffi.sizeof(lltype.Signed) - return rffi.cast(lltype.Signed, rffi.cast(TPP,target)[0]) + assert rffi.sizeof(TP) <= rffi.sizeof(lltype.Unsigned) + return rffi.cast(lltype.Unsigned, rffi.cast(TPP,target)[0]) raise NotImplementedError("bad integer size") def read_raw_float_data(target, size): @@ -62,6 +62,7 @@ def read_raw_longdouble_data(target): return rffi.cast(rffi.LONGDOUBLEP, target)[0] + at specialize.argtype(1) def write_raw_integer_data(target, source, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): @@ -156,6 +157,23 @@ except OverflowError: raise OperationError(space.w_OverflowError, space.wrap(ovf_msg)) +def as_long(space, w_ob): + # Same as as_long_long(), but returning an int instead. + if space.is_w(space.type(w_ob), space.w_int): # shortcut + return space.int_w(w_ob) + try: + bigint = space.bigint_w(w_ob) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + if _is_a_float(space, w_ob): + raise + bigint = space.bigint_w(space.int(w_ob)) + try: + return bigint.toint() + except OverflowError: + raise OperationError(space.w_OverflowError, space.wrap(ovf_msg)) + def as_unsigned_long_long(space, w_ob, strict): # (possibly) convert and cast a Python object to an unsigned long long. # This accepts a Python int too, and does convertions from other types of @@ -189,6 +207,31 @@ else: return bigint.ulonglongmask() +def as_unsigned_long(space, w_ob, strict): + # same as as_unsigned_long_long(), but returning just an Unsigned + if space.is_w(space.type(w_ob), space.w_int): # shortcut + value = space.int_w(w_ob) + if strict and value < 0: + raise OperationError(space.w_OverflowError, space.wrap(neg_msg)) + return r_uint(value) + try: + bigint = space.bigint_w(w_ob) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + if strict and _is_a_float(space, w_ob): + raise + bigint = space.bigint_w(space.int(w_ob)) + if strict: + try: + return bigint.touint() + except ValueError: + raise OperationError(space.w_OverflowError, space.wrap(neg_msg)) + except OverflowError: + raise OperationError(space.w_OverflowError, space.wrap(ovf_msg)) + else: + return bigint.uintmask() + neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -248,7 +248,17 @@ raise OperationError(space.w_ValueError, space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] - enumvalues = [space.int_w(w) for w in enumvalues_w] + enumvalues = [] + try: + for w in enumvalues_w: + enumvalues.append(space.c_int_w(w)) + except OperationError, e: + if not e.match(space, space.w_OverflowError): + raise + i = len(enumvalues) + raise operationerrfmt(space.w_OverflowError, + "enum '%s' declaration for '%s' does not fit an int", + name, enumerators[i]) ctype = ctypeenum.W_CTypeEnum(space, name, enumerators, enumvalues) return ctype 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 @@ -1156,6 +1156,13 @@ e = py.test.raises(TypeError, newp, BStructPtr, [None]) assert "must be a str or int, not NoneType" in str(e.value) +def test_enum_overflow(): + for ovf in (2**63, -2**63-1, 2**31, -2**31-1): + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (5, ovf)) + assert str(e.value) == ( + "enum 'foo' declaration for 'b' does not fit an int") + def test_callback_returning_enum(): BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) @@ -2123,9 +2130,9 @@ py.test.raises(OverflowError, newp, BBoolP, 2) py.test.raises(OverflowError, newp, BBoolP, -1) BCharP = new_pointer_type(new_primitive_type("char")) - p = newp(BCharP, 'X') + p = newp(BCharP, b'X') q = cast(BBoolP, p) - assert q[0] == ord('X') + assert q[0] == ord(b'X') py.test.raises(TypeError, string, cast(BBool, False)) BDouble = new_primitive_type("double") assert int(cast(BBool, cast(BDouble, 0.1))) == 1 diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -389,38 +389,6 @@ from pypy.rlib import runicode -def make_raw_encoder(name): - rname = "unicode_encode_%s" % (name.replace("_encode", ""), ) - assert hasattr(runicode, rname) - def raw_encoder(space, uni): - state = space.fromcache(CodecState) - func = getattr(runicode, rname) - errors = "strict" - return func(uni, len(uni), errors, state.encode_error_handler) - raw_encoder.func_name = rname - return raw_encoder - -def make_raw_decoder(name): - rname = "str_decode_%s" % (name.replace("_decode", ""), ) - assert hasattr(runicode, rname) - def raw_decoder(space, string): - final = True - errors = "strict" - state = space.fromcache(CodecState) - func = getattr(runicode, rname) - kwargs = {} - if name == 'unicode_escape': - unicodedata_handler = state.get_unicodedata_handler(space) - result, consumed = func(string, len(string), errors, - final, state.decode_error_handler, - unicodedata_handler=unicodedata_handler) - else: - result, consumed = func(string, len(string), errors, - final, state.decode_error_handler) - return result - raw_decoder.func_name = rname - return raw_decoder - def make_encoder_wrapper(name): rname = "unicode_encode_%s" % (name.replace("_encode", ""), ) assert hasattr(runicode, rname) diff --git a/pypy/module/cmath/interp_cmath.py b/pypy/module/cmath/interp_cmath.py --- a/pypy/module/cmath/interp_cmath.py +++ b/pypy/module/cmath/interp_cmath.py @@ -1,21 +1,11 @@ import math -from math import fabs - +from pypy.rlib.objectmodel import specialize +from pypy.tool.sourcetools import func_with_new_name from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import NoneNotWrapped from pypy.module.cmath import names_and_docstrings -from pypy.module.cmath.constant import (DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN, - CM_LARGE_DOUBLE, DBL_MANT_DIG, M_LN2, M_LN10, CM_SQRT_LARGE_DOUBLE, - CM_SQRT_DBL_MIN, CM_LOG_LARGE_DOUBLE) -from pypy.module.cmath.special_value import (special_type, INF, NAN, - sqrt_special_values, acos_special_values, acosh_special_values, - asinh_special_values, atanh_special_values, log_special_values, - exp_special_values, cosh_special_values, sinh_special_values, - tanh_special_values, rect_special_values) -from pypy.rlib.objectmodel import specialize -from pypy.rlib.rfloat import copysign, asinh, log1p, isinf, isnan, isfinite -from pypy.tool.sourcetools import func_with_new_name - +from pypy.rlib.rfloat import isfinite +from pypy.rlib import rcomplex pi = math.pi e = math.e @@ -48,235 +38,40 @@ def c_neg(x, y): - return (-x, -y) + return rcomplex.c_neg(x,y) @unaryfn def c_sqrt(x, y): - # Method: use symmetries to reduce to the case when x = z.real and y - # = z.imag are nonnegative. Then the real part of the result is - # given by - # - # s = sqrt((x + hypot(x, y))/2) - # - # and the imaginary part is - # - # d = (y/2)/s - # - # If either x or y is very large then there's a risk of overflow in - # computation of the expression x + hypot(x, y). We can avoid this - # by rewriting the formula for s as: - # - # s = 2*sqrt(x/8 + hypot(x/8, y/8)) - # - # This costs us two extra multiplications/divisions, but avoids the - # overhead of checking for x and y large. - # - # If both x and y are subnormal then hypot(x, y) may also be - # subnormal, so will lack full precision. We solve this by rescaling - # x and y by a sufficiently large power of 2 to ensure that x and y - # are normal. - - if not isfinite(x) or not isfinite(y): - return sqrt_special_values[special_type(x)][special_type(y)] - - if x == 0. and y == 0.: - return (0., y) - - ax = fabs(x) - ay = fabs(y) - - if ax < DBL_MIN and ay < DBL_MIN and (ax > 0. or ay > 0.): - # here we catch cases where hypot(ax, ay) is subnormal - ax = math.ldexp(ax, CM_SCALE_UP) - ay1= math.ldexp(ay, CM_SCALE_UP) - s = math.ldexp(math.sqrt(ax + math.hypot(ax, ay1)), - CM_SCALE_DOWN) - else: - ax /= 8. - s = 2.*math.sqrt(ax + math.hypot(ax, ay/8.)) - - d = ay/(2.*s) - - if x >= 0.: - return (s, copysign(d, y)) - else: - return (d, copysign(s, y)) - + return rcomplex.c_sqrt(x,y) @unaryfn def c_acos(x, y): - if not isfinite(x) or not isfinite(y): - return acos_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - # avoid unnecessary overflow for large arguments - real = math.atan2(fabs(y), x) - # split into cases to make sure that the branch cut has the - # correct continuity on systems with unsigned zeros - if x < 0.: - imag = -copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., y) - else: - imag = copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., -y) - else: - s1x, s1y = c_sqrt(1.-x, -y) - s2x, s2y = c_sqrt(1.+x, y) - real = 2.*math.atan2(s1x, s2x) - imag = asinh(s2x*s1y - s2y*s1x) - return (real, imag) - + return rcomplex.c_acos(x,y) @unaryfn def c_acosh(x, y): - # XXX the following two lines seem unnecessary at least on Linux; - # the tests pass fine without them - if not isfinite(x) or not isfinite(y): - return acosh_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - # avoid unnecessary overflow for large arguments - real = math.log(math.hypot(x/2., y/2.)) + M_LN2*2. - imag = math.atan2(y, x) - else: - s1x, s1y = c_sqrt(x - 1., y) - s2x, s2y = c_sqrt(x + 1., y) - real = asinh(s1x*s2x + s1y*s2y) - imag = 2.*math.atan2(s1y, s2x) - return (real, imag) - + return rcomplex.c_acosh(x,y) @unaryfn def c_asin(x, y): - # asin(z) = -i asinh(iz) - sx, sy = c_asinh(-y, x) - return (sy, -sx) - + return rcomplex.c_asin(x,y) @unaryfn def c_asinh(x, y): - if not isfinite(x) or not isfinite(y): - return asinh_special_values[special_type(x)][special_type(y)] - - if fabs(x) > CM_LARGE_DOUBLE or fabs(y) > CM_LARGE_DOUBLE: - if y >= 0.: - real = copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., x) - else: - real = -copysign(math.log(math.hypot(x/2., y/2.)) + - M_LN2*2., -x) - imag = math.atan2(y, fabs(x)) - else: - s1x, s1y = c_sqrt(1.+y, -x) - s2x, s2y = c_sqrt(1.-y, x) - real = asinh(s1x*s2y - s2x*s1y) - imag = math.atan2(y, s1x*s2x - s1y*s2y) - return (real, imag) - + return rcomplex.c_asinh(x,y) @unaryfn def c_atan(x, y): - # atan(z) = -i atanh(iz) - sx, sy = c_atanh(-y, x) - return (sy, -sx) - + return rcomplex.c_atan(x,y) @unaryfn def c_atanh(x, y): - if not isfinite(x) or not isfinite(y): - return atanh_special_values[special_type(x)][special_type(y)] - - # Reduce to case where x >= 0., using atanh(z) = -atanh(-z). - if x < 0.: - return c_neg(*c_atanh(*c_neg(x, y))) - - ay = fabs(y) - if x > CM_SQRT_LARGE_DOUBLE or ay > CM_SQRT_LARGE_DOUBLE: - # if abs(z) is large then we use the approximation - # atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign - # of y - h = math.hypot(x/2., y/2.) # safe from overflow - real = x/4./h/h - # the two negations in the next line cancel each other out - # except when working with unsigned zeros: they're there to - # ensure that the branch cut has the correct continuity on - # systems that don't support signed zeros - imag = -copysign(math.pi/2., -y) - elif x == 1. and ay < CM_SQRT_DBL_MIN: - # C99 standard says: atanh(1+/-0.) should be inf +/- 0i - if ay == 0.: - raise ValueError("math domain error") - #real = INF - #imag = y - else: - real = -math.log(math.sqrt(ay)/math.sqrt(math.hypot(ay, 2.))) - imag = copysign(math.atan2(2., -ay) / 2, y) - else: - real = log1p(4.*x/((1-x)*(1-x) + ay*ay))/4. - imag = -math.atan2(-2.*y, (1-x)*(1+x) - ay*ay) / 2. - return (real, imag) - + return rcomplex.c_atanh(x,y) @unaryfn def c_log(x, y): - # The usual formula for the real part is log(hypot(z.real, z.imag)). - # There are four situations where this formula is potentially - # problematic: - # - # (1) the absolute value of z is subnormal. Then hypot is subnormal, - # so has fewer than the usual number of bits of accuracy, hence may - # have large relative error. This then gives a large absolute error - # in the log. This can be solved by rescaling z by a suitable power - # of 2. - # - # (2) the absolute value of z is greater than DBL_MAX (e.g. when both - # z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX) - # Again, rescaling solves this. - # - # (3) the absolute value of z is close to 1. In this case it's - # difficult to achieve good accuracy, at least in part because a - # change of 1ulp in the real or imaginary part of z can result in a - # change of billions of ulps in the correctly rounded answer. - # - # (4) z = 0. The simplest thing to do here is to call the - # floating-point log with an argument of 0, and let its behaviour - # (returning -infinity, signaling a floating-point exception, setting - # errno, or whatever) determine that of c_log. So the usual formula - # is fine here. - - # XXX the following two lines seem unnecessary at least on Linux; - # the tests pass fine without them - if not isfinite(x) or not isfinite(y): - return log_special_values[special_type(x)][special_type(y)] - - ax = fabs(x) - ay = fabs(y) - - if ax > CM_LARGE_DOUBLE or ay > CM_LARGE_DOUBLE: - real = math.log(math.hypot(ax/2., ay/2.)) + M_LN2 - elif ax < DBL_MIN and ay < DBL_MIN: - if ax > 0. or ay > 0.: - # catch cases where hypot(ax, ay) is subnormal - real = math.log(math.hypot(math.ldexp(ax, DBL_MANT_DIG), - math.ldexp(ay, DBL_MANT_DIG))) - real -= DBL_MANT_DIG*M_LN2 - else: - # log(+/-0. +/- 0i) - raise ValueError("math domain error") - #real = -INF - #imag = atan2(y, x) - else: - h = math.hypot(ax, ay) - if 0.71 <= h and h <= 1.73: - am = max(ax, ay) - an = min(ax, ay) - real = log1p((am-1)*(am+1) + an*an) / 2. - else: - real = math.log(h) - imag = math.atan2(y, x) - return (real, imag) - + return rcomplex.c_log(x,y) _inner_wrapped_log = wrapped_log @@ -292,196 +87,38 @@ @unaryfn def c_log10(x, y): - rx, ry = c_log(x, y) - return (rx / M_LN10, ry / M_LN10) - + return rcomplex.c_log10(x,y) @unaryfn def c_exp(x, y): - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = copysign(0., math.cos(y)) - imag = copysign(0., math.sin(y)) - r = (real, imag) - else: - r = exp_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN and not -infinity - if isinf(y) and (isfinite(x) or (isinf(x) and x > 0)): - raise ValueError("math domain error") - return r - - if x > CM_LOG_LARGE_DOUBLE: - l = math.exp(x-1.) - real = l * math.cos(y) * math.e - imag = l * math.sin(y) * math.e - else: - l = math.exp(x) - real = l * math.cos(y) - imag = l * math.sin(y) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - + return rcomplex.c_exp(x,y) @unaryfn def c_cosh(x, y): - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = copysign(INF, math.cos(y)) - imag = -copysign(INF, math.sin(y)) - r = (real, imag) - else: - r = cosh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN - if isinf(y) and not isnan(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - # deal correctly with cases where cosh(x) overflows but - # cosh(z) does not. - x_minus_one = x - copysign(1., x) - real = math.cos(y) * math.cosh(x_minus_one) * math.e - imag = math.sin(y) * math.sinh(x_minus_one) * math.e - else: - real = math.cos(y) * math.cosh(x) - imag = math.sin(y) * math.sinh(x) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - + return rcomplex.c_cosh(x,y) @unaryfn def c_sinh(x, y): - # special treatment for sinh(+/-inf + iy) if y is finite and nonzero - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - else: - real = -copysign(INF, math.cos(y)) - imag = copysign(INF, math.sin(y)) - r = (real, imag) - else: - r = sinh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/- infinity and x is not - # a NaN - if isinf(y) and not isnan(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - x_minus_one = x - copysign(1., x) - real = math.cos(y) * math.sinh(x_minus_one) * math.e - imag = math.sin(y) * math.cosh(x_minus_one) * math.e - else: - real = math.cos(y) * math.sinh(x) - imag = math.sin(y) * math.cosh(x) - if isinf(real) or isinf(imag): - raise OverflowError("math range error") - return real, imag - + return rcomplex.c_sinh(x,y) @unaryfn def c_tanh(x, y): - # Formula: - # - # tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) / - # (1+tan(y)^2 tanh(x)^2) - # - # To avoid excessive roundoff error, 1-tanh(x)^2 is better computed - # as 1/cosh(x)^2. When abs(x) is large, we approximate 1-tanh(x)^2 - # by 4 exp(-2*x) instead, to avoid possible overflow in the - # computation of cosh(x). - - if not isfinite(x) or not isfinite(y): - if isinf(x) and isfinite(y) and y != 0.: - if x > 0: - real = 1.0 # vv XXX why is the 2. there? - imag = copysign(0., 2. * math.sin(y) * math.cos(y)) - else: - real = -1.0 - imag = copysign(0., 2. * math.sin(y) * math.cos(y)) - r = (real, imag) - else: - r = tanh_special_values[special_type(x)][special_type(y)] - - # need to raise ValueError if y is +/-infinity and x is finite - if isinf(y) and isfinite(x): - raise ValueError("math domain error") - return r - - if fabs(x) > CM_LOG_LARGE_DOUBLE: - real = copysign(1., x) - imag = 4. * math.sin(y) * math.cos(y) * math.exp(-2.*fabs(x)) - else: - tx = math.tanh(x) - ty = math.tan(y) - cx = 1. / math.cosh(x) - txty = tx * ty - denom = 1. + txty * txty - real = tx * (1. + ty*ty) / denom - imag = ((ty / denom) * cx) * cx - return real, imag - + return rcomplex.c_tanh(x,y) @unaryfn def c_cos(x, y): - # cos(z) = cosh(iz) - return c_cosh(-y, x) + return rcomplex.c_cos(x,y) @unaryfn def c_sin(x, y): - # sin(z) = -i sinh(iz) - sx, sy = c_sinh(-y, x) - return sy, -sx + return rcomplex.c_sin(x,y) @unaryfn def c_tan(x, y): - # tan(z) = -i tanh(iz) - sx, sy = c_tanh(-y, x) - return sy, -sx - + return rcomplex.c_tan(x,y) def c_rect(r, phi): - if not isfinite(r) or not isfinite(phi): - # if r is +/-infinity and phi is finite but nonzero then - # result is (+-INF +-INF i), but we need to compute cos(phi) - # and sin(phi) to figure out the signs. - if isinf(r) and isfinite(phi) and phi != 0.: - if r > 0: - real = copysign(INF, math.cos(phi)) - imag = copysign(INF, math.sin(phi)) - else: - real = -copysign(INF, math.cos(phi)) - imag = -copysign(INF, math.sin(phi)) - z = (real, imag) - else: - z = rect_special_values[special_type(r)][special_type(phi)] - - # need to raise ValueError if r is a nonzero number and phi - # is infinite - if r != 0. and not isnan(r) and isinf(phi): - raise ValueError("math domain error") - return z - - real = r * math.cos(phi) - imag = r * math.sin(phi) - return real, imag + return rcomplex.c_rect(r,phi) def wrapped_rect(space, w_x, w_y): x = space.float_w(w_x) @@ -492,28 +129,7 @@ def c_phase(x, y): - # Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't - # follow C99 for atan2(0., 0.). - if isnan(x) or isnan(y): - return NAN - if isinf(y): - if isinf(x): - if copysign(1., x) == 1.: - # atan2(+-inf, +inf) == +-pi/4 - return copysign(0.25 * math.pi, y) - else: - # atan2(+-inf, -inf) == +-pi*3/4 - return copysign(0.75 * math.pi, y) - # atan2(+-inf, x) == +-pi/2 for finite x - return copysign(0.5 * math.pi, y) - if isinf(x) or y == 0.: - if copysign(1., x) == 1.: - # atan2(+-y, +inf) = atan2(+-0, +x) = +-0. - return copysign(0., y) - else: - # atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. - return copysign(math.pi, y) - return math.atan2(y, x) + return rcomplex.c_phase(x,y) def wrapped_phase(space, w_z): x, y = space.unpackcomplex(w_z) @@ -523,28 +139,10 @@ def c_abs(x, y): - if not isfinite(x) or not isfinite(y): - # C99 rules: if either the real or the imaginary part is an - # infinity, return infinity, even if the other part is a NaN. - if isinf(x): - return INF - if isinf(y): - return INF - - # either the real or imaginary part is a NaN, - # and neither is infinite. Result should be NaN. - return NAN - - result = math.hypot(x, y) - if not isfinite(result): - raise OverflowError("math range error") - return result - + return rcomplex.c_abs(x,y) def c_polar(x, y): - phi = c_phase(x, y) - r = c_abs(x, y) - return r, phi + return rcomplex.c_polar(x,y) def wrapped_polar(space, w_z): x, y = space.unpackcomplex(w_z) @@ -554,7 +152,7 @@ def c_isinf(x, y): - return isinf(x) or isinf(y) + return rcomplex.c_isinf(x,y) def wrapped_isinf(space, w_z): x, y = space.unpackcomplex(w_z) @@ -564,7 +162,7 @@ def c_isnan(x, y): - return isnan(x) or isnan(y) + return rcomplex.c_isnan(x,y) def wrapped_isnan(space, w_z): x, y = space.unpackcomplex(w_z) diff --git a/pypy/module/cmath/special_value.py b/pypy/module/cmath/special_value.py deleted file mode 100644 --- a/pypy/module/cmath/special_value.py +++ /dev/null @@ -1,169 +0,0 @@ -import math -from pypy.rlib.rfloat import isnan, isinf, copysign - -# code to deal with special values (infinities, NaNs, ...) -# -# The special types can be: -ST_NINF = 0 # negative infinity -ST_NEG = 1 # negative finite number (nonzero) -ST_NZERO = 2 # -0. -ST_PZERO = 3 # +0. -ST_POS = 4 # positive finite number (nonzero) -ST_PINF = 5 # positive infinity -ST_NAN = 6 # Not a Number - -def special_type(d): - if isnan(d): - return ST_NAN - elif isinf(d): - if d > 0.0: - return ST_PINF - else: - return ST_NINF - else: - if d != 0.0: - if d > 0.0: - return ST_POS - else: - return ST_NEG - else: - if copysign(1., d) == 1.: - return ST_PZERO - else: - return ST_NZERO - - -P = math.pi -P14 = 0.25 * math.pi -P12 = 0.5 * math.pi -P34 = 0.75 * math.pi -INF = 1e200 * 1e200 -N = INF / INF -U = -9.5426319407711027e33 # unlikely value, used as placeholder -Z = 0.0 # defined here instead of in the tuples below, because of a bug - # in pypy releases < 1.5 -NAN = N - -def build_table(lst): - table = [] - assert len(lst) == 49 - it = iter(lst) - for j in range(7): - row = [] - for i in range(7): - (x, y) = it.next() - row.append((x, y)) - table.append(row) - return table - -acos_special_values = build_table([ - (P34,INF), (P,INF), (P,INF), (P,-INF), (P,-INF), (P34,-INF), (N,INF), - (P12,INF), (U,U), (U,U), (U,U), (U,U), (P12,-INF), (N,N), - (P12,INF), (U,U), (P12,Z), (P12,-Z), (U,U), (P12,-INF), (P12,N), - (P12,INF), (U,U), (P12,Z), (P12,-Z), (U,U), (P12,-INF), (P12,N), - (P12,INF), (U,U), (U,U), (U,U), (U,U), (P12,-INF), (N,N), - (P14,INF), (Z,INF), (Z,INF), (Z,-INF), (Z,-INF), (P14,-INF), (N,INF), - (N,INF), (N,N), (N,N), (N,N), (N,N), (N,-INF), (N,N), - ]) - -acosh_special_values = build_table([ - (INF,-P34), (INF,-P), (INF,-P), (INF,P), (INF,P), (INF,P34), (INF,N), - (INF,-P12), (U,U), (U,U), (U,U), (U,U), (INF,P12), (N,N), - (INF,-P12), (U,U), (Z,-P12), (Z,P12), (U,U), (INF,P12), (N,N), - (INF,-P12), (U,U), (Z,-P12), (Z,P12), (U,U), (INF,P12), (N,N), - (INF,-P12), (U,U), (U,U), (U,U), (U,U), (INF,P12), (N,N), - (INF,-P14), (INF,-Z), (INF,-Z), (INF,Z), (INF,Z), (INF,P14), (INF,N), - (INF,N), (N,N), (N,N), (N,N), (N,N), (INF,N), (N,N), - ]) - -asinh_special_values = build_table([ - (-INF,-P14), (-INF,-Z), (-INF,-Z),(-INF,Z), (-INF,Z), (-INF,P14), (-INF,N), - (-INF,-P12), (U,U), (U,U), (U,U), (U,U), (-INF,P12), (N,N), - (-INF,-P12), (U,U), (-Z,-Z), (-Z,Z), (U,U), (-INF,P12), (N,N), - (INF,-P12), (U,U), (Z,-Z), (Z,Z), (U,U), (INF,P12), (N,N), - (INF,-P12), (U,U), (U,U), (U,U), (U,U), (INF,P12), (N,N), - (INF,-P14), (INF,-Z), (INF,-Z), (INF,Z), (INF,Z), (INF,P14), (INF,N), - (INF,N), (N,N), (N,-Z), (N,Z), (N,N), (INF,N), (N,N), - ]) - -atanh_special_values = build_table([ - (-Z,-P12), (-Z,-P12), (-Z,-P12), (-Z,P12), (-Z,P12), (-Z,P12), (-Z,N), - (-Z,-P12), (U,U), (U,U), (U,U), (U,U), (-Z,P12), (N,N), - (-Z,-P12), (U,U), (-Z,-Z), (-Z,Z), (U,U), (-Z,P12), (-Z,N), - (Z,-P12), (U,U), (Z,-Z), (Z,Z), (U,U), (Z,P12), (Z,N), - (Z,-P12), (U,U), (U,U), (U,U), (U,U), (Z,P12), (N,N), - (Z,-P12), (Z,-P12), (Z,-P12), (Z,P12), (Z,P12), (Z,P12), (Z,N), - (Z,-P12), (N,N), (N,N), (N,N), (N,N), (Z,P12), (N,N), - ]) - -log_special_values = build_table([ - (INF,-P34), (INF,-P), (INF,-P), (INF,P), (INF,P), (INF,P34), (INF,N), - (INF,-P12), (U,U), (U,U), (U,U), (U,U), (INF,P12), (N,N), - (INF,-P12), (U,U), (-INF,-P), (-INF,P), (U,U), (INF,P12), (N,N), - (INF,-P12), (U,U), (-INF,-Z), (-INF,Z), (U,U), (INF,P12), (N,N), - (INF,-P12), (U,U), (U,U), (U,U), (U,U), (INF,P12), (N,N), - (INF,-P14), (INF,-Z), (INF,-Z), (INF,Z), (INF,Z), (INF,P14), (INF,N), - (INF,N), (N,N), (N,N), (N,N), (N,N), (INF,N), (N,N), - ]) - -sqrt_special_values = build_table([ - (INF,-INF), (Z,-INF), (Z,-INF), (Z,INF), (Z,INF), (INF,INF), (N,INF), - (INF,-INF), (U,U), (U,U), (U,U), (U,U), (INF,INF), (N,N), - (INF,-INF), (U,U), (Z,-Z), (Z,Z), (U,U), (INF,INF), (N,N), - (INF,-INF), (U,U), (Z,-Z), (Z,Z), (U,U), (INF,INF), (N,N), - (INF,-INF), (U,U), (U,U), (U,U), (U,U), (INF,INF), (N,N), - (INF,-INF), (INF,-Z), (INF,-Z), (INF,Z), (INF,Z), (INF,INF), (INF,N), - (INF,-INF), (N,N), (N,N), (N,N), (N,N), (INF,INF), (N,N), - ]) - -exp_special_values = build_table([ - (Z,Z), (U,U), (Z,-Z), (Z,Z), (U,U), (Z,Z), (Z,Z), - (N,N), (U,U), (U,U), (U,U), (U,U), (N,N), (N,N), - (N,N), (U,U), (1.,-Z), (1.,Z), (U,U), (N,N), (N,N), - (N,N), (U,U), (1.,-Z), (1.,Z), (U,U), (N,N), (N,N), - (N,N), (U,U), (U,U), (U,U), (U,U), (N,N), (N,N), - (INF,N), (U,U), (INF,-Z), (INF,Z), (U,U), (INF,N), (INF,N), - (N,N), (N,N), (N,-Z), (N,Z), (N,N), (N,N), (N,N), - ]) - -cosh_special_values = build_table([ - (INF,N), (U,U), (INF,Z), (INF,-Z), (U,U), (INF,N), (INF,N), - (N,N), (U,U), (U,U), (U,U), (U,U), (N,N), (N,N), - (N,Z), (U,U), (1.,Z), (1.,-Z), (U,U), (N,Z), (N,Z), - (N,Z), (U,U), (1.,-Z), (1.,Z), (U,U), (N,Z), (N,Z), - (N,N), (U,U), (U,U), (U,U), (U,U), (N,N), (N,N), - (INF,N), (U,U), (INF,-Z), (INF,Z), (U,U), (INF,N), (INF,N), - (N,N), (N,N), (N,Z), (N,Z), (N,N), (N,N), (N,N), - ]) - -sinh_special_values = build_table([ - (INF,N), (U,U), (-INF,-Z), (-INF,Z), (U,U), (INF,N), (INF,N), - (N,N), (U,U), (U,U), (U,U), (U,U), (N,N), (N,N), - (Z,N), (U,U), (-Z,-Z), (-Z,Z), (U,U), (Z,N), (Z,N), - (Z,N), (U,U), (Z,-Z), (Z,Z), (U,U), (Z,N), (Z,N), - (N,N), (U,U), (U,U), (U,U), (U,U), (N,N), (N,N), - (INF,N), (U,U), (INF,-Z), (INF,Z), (U,U), (INF,N), (INF,N), - (N,N), (N,N), (N,-Z), (N,Z), (N,N), (N,N), (N,N), - ]) - -tanh_special_values = build_table([ - (-1.,Z), (U,U), (-1.,-Z), (-1.,Z), (U,U), (-1.,Z), (-1.,Z), - (N,N), (U,U), (U,U), (U,U), (U,U), (N,N), (N,N), - (N,N), (U,U), (-Z,-Z), (-Z,Z), (U,U), (N,N), (N,N), - (N,N), (U,U), (Z,-Z), (Z,Z), (U,U), (N,N), (N,N), - (N,N), (U,U), (U,U), (U,U), (U,U), (N,N), (N,N), - (1.,Z), (U,U), (1.,-Z), (1.,Z), (U,U), (1.,Z), (1.,Z), - (N,N), (N,N), (N,-Z), (N,Z), (N,N), (N,N), (N,N), - ]) - -rect_special_values = build_table([ - (INF,N), (U,U), (-INF,Z), (-INF,-Z), (U,U), (INF,N), (INF,N), - (N,N), (U,U), (U,U), (U,U), (U,U), (N,N), (N,N), - (Z,Z), (U,U), (-Z,Z), (-Z,-Z), (U,U), (Z,Z), (Z,Z), - (Z,Z), (U,U), (Z,-Z), (Z,Z), (U,U), (Z,Z), (Z,Z), - (N,N), (U,U), (U,U), (U,U), (U,U), (N,N), (N,N), - (INF,N), (U,U), (INF,-Z), (INF,Z), (U,U), (INF,N), (INF,N), - (N,N), (N,N), (N,Z), (N,Z), (N,N), (N,N), (N,N), - ]) - -assert copysign(1., acosh_special_values[5][2][1]) == -1. diff --git a/pypy/module/cmath/test/test_cmath.py b/pypy/module/cmath/test/test_cmath.py --- a/pypy/module/cmath/test/test_cmath.py +++ b/pypy/module/cmath/test/test_cmath.py @@ -6,7 +6,7 @@ def test_special_values(): - from pypy.module.cmath.special_value import sqrt_special_values + from pypy.rlib.special_value import sqrt_special_values assert len(sqrt_special_values) == 7 assert len(sqrt_special_values[4]) == 7 assert isinstance(sqrt_special_values[5][1], tuple) @@ -127,7 +127,6 @@ Empty lines or lines starting with -- are ignored yields id, fn, arg_real, arg_imag, exp_real, exp_imag """ - fname = os.path.join(os.path.dirname(__file__), fname) with open(fname) as fp: for line in fp: # skip comment lines and blank lines @@ -198,8 +197,10 @@ def test_specific_values(): #if not float.__getformat__("double").startswith("IEEE"): # return - - for id, fn, ar, ai, er, ei, flags in parse_testfile('cmath_testcases.txt'): + + # too fragile... + fname = os.path.join(os.path.dirname(__file__), '../../../rlib/test', 'rcomplex_testcases.txt') + for id, fn, ar, ai, er, ei, flags in parse_testfile(fname): arg = (ar, ai) expected = (er, ei) function = getattr(interp_cmath, 'c_' + fn) diff --git a/pypy/module/cpyext/funcobject.py b/pypy/module/cpyext/funcobject.py --- a/pypy/module/cpyext/funcobject.py +++ b/pypy/module/cpyext/funcobject.py @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( - PyObjectFields, generic_cpy_call, CONST_STRING, CANNOT_FAIL, + PyObjectFields, generic_cpy_call, CONST_STRING, CANNOT_FAIL, Py_ssize_t, cpython_api, bootstrap_function, cpython_struct, build_type_checkers) from pypy.module.cpyext.pyobject import ( PyObject, make_ref, from_ref, Py_DecRef, make_typedescr, borrow_from) @@ -163,7 +163,7 @@ freevars=[], cellvars=[])) - at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) + at cpython_api([PyCodeObject], Py_ssize_t, error=CANNOT_FAIL) def PyCode_GetNumFree(space, w_co): """Return the number of free variables in co.""" co = space.interp_w(PyCode, w_co) diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py --- a/pypy/module/cpyext/object.py +++ b/pypy/module/cpyext/object.py @@ -444,7 +444,7 @@ PyBUF_WRITABLE = 0x0001 # Copied from object.h @cpython_api([lltype.Ptr(Py_buffer), PyObject, rffi.VOIDP, Py_ssize_t, - lltype.Signed, lltype.Signed], rffi.INT, error=CANNOT_FAIL) + lltype.Signed, lltype.Signed], rffi.INT, error=-1) def PyBuffer_FillInfo(space, view, obj, buf, length, readonly, flags): """ Fills in a buffer-info structure correctly for an exporter that can only @@ -454,15 +454,16 @@ This is not a complete re-implementation of the CPython API; it only provides a subset of CPython's behavior. """ + if flags & PyBUF_WRITABLE and readonly: + raise OperationError( + space.w_ValueError, space.wrap( + "Object is not writable")) view.c_buf = buf view.c_len = length view.c_obj = obj Py_IncRef(space, obj) view.c_itemsize = 1 - if flags & PyBUF_WRITABLE: - rffi.setintfield(view, 'c_readonly', 0) - else: - rffi.setintfield(view, 'c_readonly', 1) + rffi.setintfield(view, 'c_readonly', readonly) rffi.setintfield(view, 'c_ndim', 0) view.c_format = lltype.nullptr(rffi.CCHARP.TO) view.c_shape = lltype.nullptr(Py_ssize_tP.TO) diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py --- a/pypy/module/cpyext/test/test_object.py +++ b/pypy/module/cpyext/test/test_object.py @@ -319,6 +319,29 @@ assert b"hello, world." == result + def test_fillReadonly(self): + """ + PyBuffer_FillInfo fails if WRITABLE is passed but object is readonly. + """ + module = self.import_extension('foo', [ + ("fillinfo", "METH_VARARGS", + """ + Py_buffer buf; + PyObject *str = PyString_FromString("hello, world."); + PyObject *result; + + if (PyBuffer_FillInfo(&buf, str, PyString_AsString(str), 13, + 1, PyBUF_WRITABLE)) { + Py_DECREF(str); + return NULL; + } + Py_DECREF(str); + PyBuffer_Release(&buf); + Py_RETURN_NONE; + """)]) + raises(ValueError, module.fillinfo) + + class AppTestPyBuffer_Release(AppTestCpythonExtensionBase): """ PyBuffer_Release releases the resources held by a Py_buffer. diff --git a/pypy/module/marshal/test/test_marshal.py b/pypy/module/marshal/test/test_marshal.py --- a/pypy/module/marshal/test/test_marshal.py +++ b/pypy/module/marshal/test/test_marshal.py @@ -163,6 +163,7 @@ def test_unicode(self): import marshal, sys self.marshal_check('\uFFFF') + self.marshal_check('\ud800') self.marshal_check(chr(sys.maxunicode)) diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -132,7 +132,7 @@ def test_mtestfile(self): import math - import abc + import zipfile import os import struct def _parse_mtestfile(fname): @@ -209,8 +209,8 @@ fail_fmt = "{}:{}({!r}): expected {!r}, got {!r}" failures = [] - math_testcases = os.path.join(os.path.dirname(abc.__file__), - "test", "math_testcases.txt") + math_testcases = os.path.join(os.path.dirname(zipfile.__file__), "test", + "math_testcases.txt") for id, fn, arg, expected, flags in _parse_mtestfile(math_testcases): func = getattr(math, fn) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -64,6 +64,10 @@ 'str_': 'interp_boxes.W_StringBox', 'unicode_': 'interp_boxes.W_UnicodeBox', 'void': 'interp_boxes.W_VoidBox', + 'complexfloating': 'interp_boxes.W_ComplexFloatingBox', + 'complex_': 'interp_boxes.W_Complex128Box', + 'complex128': 'interp_boxes.W_Complex128Box', + 'complex64': 'interp_boxes.W_Complex64Box', } # ufuncs @@ -78,6 +82,8 @@ ("arccosh", "arccosh"), ("arcsinh", "arcsinh"), ("arctanh", "arctanh"), + ("conj", "conjugate"), + ("conjugate", "conjugate"), ("copysign", "copysign"), ("cos", "cos"), ("cosh", "cosh"), @@ -141,6 +147,8 @@ ('floor_divide', 'floor_divide'), ('logaddexp', 'logaddexp'), ('logaddexp2', 'logaddexp2'), + ('real', 'real'), + ('imag', 'imag'), ]: interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl 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 @@ -56,7 +56,8 @@ w_slice = "slice" w_str = "str" w_unicode = "unicode" - + w_complex = "complex" + def __init__(self): """NOT_RPYTHON""" self.fromcache = InternalSpaceCache(self).getorbuild @@ -107,6 +108,9 @@ def newlist(self, items): return ListObject(items) + def newcomplex(self, r, i): + return ComplexObject(r, i) + def listview(self, obj): assert isinstance(obj, ListObject) return obj.items @@ -131,6 +135,11 @@ raise OperationError(self.w_TypeError, self.wrap("slice.")) raise NotImplementedError + def unpackcomplex(self, w_obj): + if isinstance(w_obj, ComplexObject): + return w_obj.r, w_obj.i + raise NotImplementedError + def index(self, w_obj): return self.wrap(self.int_w(w_obj)) @@ -226,6 +235,12 @@ def __init__(self, v): self.v = v +class ComplexObject(W_Root): + tp = FakeSpace.w_complex + def __init__(self, r, i): + self.r = r + self.i = i + class InterpreterState(object): def __init__(self, code): self.code = code @@ -343,6 +358,20 @@ def execute(self, interp): return interp.space.wrap(self.v) +class ComplexConstant(Node): + def __init__(self, r, i): + self.r = float(r) + self.i = float(i) + + def __repr__(self): + return 'ComplexConst(%s, %s)' % (self.r, self.i) + + def wrap(self, space): + return space.newcomplex(self.r, self.i) + + def execute(self, interp): + return self.wrap(interp.space) + class RangeConstant(Node): def __init__(self, v): self.v = int(v) @@ -373,8 +402,7 @@ def execute(self, interp): w_list = self.wrap(interp.space) - dtype = get_dtype_cache(interp.space).w_float64dtype - return array(interp.space, w_list, w_dtype=dtype, w_order=None) + return array(interp.space, w_list) def __repr__(self): return "[" + ", ".join([repr(item) for item in self.items]) + "]" @@ -607,6 +635,8 @@ stack.append(RangeConstant(tokens.pop().v)) end = tokens.pop() assert end.name == 'pipe' + elif token.name == 'paren_left': + stack.append(self.parse_complex_constant(tokens)) elif accept_comma and token.name == 'comma': continue else: @@ -630,6 +660,15 @@ args += self.parse_expression(tokens, accept_comma=True) return FunctionCall(name, args) + def parse_complex_constant(self, tokens): + r = tokens.pop() + assert r.name == 'number' + assert tokens.pop().name == 'comma' + i = tokens.pop() + assert i.name == 'number' + assert tokens.pop().name == 'paren_right' + return ComplexConstant(r.v, i.v) + def parse_array_const(self, tokens): elems = [] while True: @@ -638,6 +677,8 @@ elems.append(FloatConstant(token.v)) elif token.name == 'array_left': elems.append(ArrayConstant(self.parse_array_const(tokens))) + elif token.name == 'paren_left': + elems.append(self.parse_complex_constant(tokens)) else: raise BadToken() token = tokens.pop() diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -1,11 +1,12 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import operationerrfmt, OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, GetSetProperty 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.complextype import complex_typedef from pypy.rlib.rarithmetic import LONG_BIT from pypy.tool.sourcetools import func_with_new_name from pypy.module.micronumpy.arrayimpl.voidbox import VoidBoxStorage @@ -34,6 +35,22 @@ def convert_to(self, dtype): return dtype.box(self.value) +class ComplexBox(object): + _mixin_ = True + + def __init__(self, real, imag=0.): + self.real = real + self.imag = imag + + def convert_to(self, dtype): + return dtype.box_complex(self.real, self.imag) + + def convert_real_to(self, dtype): + return dtype.box(self.real) + + def convert_imag_to(self, dtype): + return dtype.box(self.imag) + class W_GenericBox(Wrappable): _attrs_ = () @@ -220,6 +237,7 @@ def descr_index(space, self): return space.index(self.item(space)) + class W_VoidBox(W_FlexibleBox): @unwrap_spec(item=str) def descr_getitem(self, space, item): @@ -266,6 +284,32 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) + +class W_ComplexFloatingBox(W_InexactBox): + _attrs_ = () + def descr_get_real(self, space): + dtype = self._COMPONENTS_BOX._get_dtype(space) + box = self.convert_real_to(dtype) + assert isinstance(box, self._COMPONENTS_BOX) + return space.wrap(box) + + def descr_get_imag(self, space): + dtype = self._COMPONENTS_BOX._get_dtype(space) + box = self.convert_imag_to(dtype) + assert isinstance(box, self._COMPONENTS_BOX) + return space.wrap(box) + + +class W_Complex64Box(ComplexBox, W_ComplexFloatingBox): + descr__new__, _get_dtype = new_dtype_getter("complex64") + _COMPONENTS_BOX = W_Float32Box + + +class W_Complex128Box(ComplexBox, W_ComplexFloatingBox): + descr__new__, _get_dtype = new_dtype_getter("complex128") + _COMPONENTS_BOX = W_Float64Box + + W_GenericBox.typedef = TypeDef("generic", __module__ = "numpypy", @@ -448,3 +492,21 @@ __new__ = interp2app(W_UnicodeBox.descr__new__unicode_box.im_func), ) +W_ComplexFloatingBox.typedef = TypeDef("complexfloating", W_InexactBox.typedef, + __module__ = "numpypy", +) + + +W_Complex128Box.typedef = TypeDef("complex128", (W_ComplexFloatingBox.typedef, complex_typedef), + __module__ = "numpypy", + __new__ = interp2app(W_Complex128Box.descr__new__.im_func), + real = GetSetProperty(W_ComplexFloatingBox.descr_get_real), + imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), +) + +W_Complex64Box.typedef = TypeDef("complex64", (W_ComplexFloatingBox.typedef), + __module__ = "numpypy", + __new__ = interp2app(W_Complex64Box.descr__new__.im_func), + real = GetSetProperty(W_ComplexFloatingBox .descr_get_real), + imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), +) 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 @@ -46,6 +46,11 @@ def box(self, value): return self.itemtype.box(value) + @specialize.argtype(1, 2) + def box_complex(self, real, imag): + return self.itemtype.box_complex(real, imag) + + def coerce(self, space, w_item): return self.itemtype.coerce(space, self, w_item) @@ -121,6 +126,9 @@ def is_signed(self): return self.kind == SIGNEDLTR + def is_complex_type(self): + return (self.num == 14 or self.num == 15) + def is_bool_type(self): return self.kind == BOOLLTR @@ -393,6 +401,31 @@ alternate_constructors=[space.w_float], aliases=["float"], ) + # self.w_float128dtype = W_Dtype( + # types.Float128(), + # num=13, + # kind=FLOATINGLTR, + # name="float128", + # ... + # ) + self.w_complex64dtype = W_Dtype( + types.Complex64(), + num=14, + kind=FLOATINGLTR, + name="complex64", + char="F", + w_box_type = space.gettypefor(interp_boxes.W_Complex64Box), + ) + self.w_complex128dtype = W_Dtype( + types.Complex128(), + num=15, + kind=FLOATINGLTR, + name="complex128", + char="D", + w_box_type = space.gettypefor(interp_boxes.W_Complex128Box), + alternate_constructors=[space.w_complex], + aliases=["complex"], + ) self.w_stringdtype = W_Dtype( types.StringType(1), num=18, @@ -426,8 +459,9 @@ self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype, self.w_int64dtype, self.w_uint64dtype, - self.w_float32dtype, - self.w_float64dtype, self.w_stringdtype, self.w_unicodedtype, + self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, + self.w_complex128dtype, + self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, ] self.float_dtypes_by_num_bytes = sorted( 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 @@ -383,6 +383,8 @@ descr_neg = _unaryop_impl("negative") descr_abs = _unaryop_impl("absolute") descr_invert = _unaryop_impl("invert") + descr_get_real = _unaryop_impl("real") + descr_get_imag = _unaryop_impl("imag") def descr_nonzero(self, space): if self.get_size() > 1: @@ -629,6 +631,8 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), + real = GetSetProperty(W_NDimArray.descr_get_real), + imag = GetSetProperty(W_NDimArray.descr_get_imag), __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) @@ -663,8 +667,9 @@ for w_elem in elems_w: dtype = interp_ufuncs.find_dtype_for_scalar(space, w_elem, dtype) - if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: - break + #if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: + # break + if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if ndmin > len(shape): diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -17,14 +17,15 @@ return not dtype.itemtype.bool(val) From noreply at buildbot.pypy.org Thu Oct 11 02:14:59 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 11 Oct 2012 02:14:59 +0200 (CEST) Subject: [pypy-commit] pypy py3k: move py3's isfinite into rcomplex with the rest of the impls Message-ID: <20121011001459.816AE1C0117@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58003:b8c3b51ce509 Date: 2012-10-10 17:15 -0700 http://bitbucket.org/pypy/pypy/changeset/b8c3b51ce509/ Log: move py3's isfinite into rcomplex with the rest of the impls diff --git a/pypy/module/cmath/interp_cmath.py b/pypy/module/cmath/interp_cmath.py --- a/pypy/module/cmath/interp_cmath.py +++ b/pypy/module/cmath/interp_cmath.py @@ -4,7 +4,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import NoneNotWrapped from pypy.module.cmath import names_and_docstrings -from pypy.rlib.rfloat import isfinite from pypy.rlib import rcomplex pi = math.pi @@ -171,7 +170,7 @@ wrapped_isnan.func_doc = names_and_docstrings['isnan'] def c_isfinite(x, y): - return isfinite(x) and isfinite(y) + return rcomplex.c_isfinite(x, y) def wrapped_isfinite(space, w_z): x, y = space.unpackcomplex(w_z) diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py --- a/pypy/rlib/rcomplex.py +++ b/pypy/rlib/rcomplex.py @@ -563,3 +563,6 @@ def c_isnan(r, i): return isnan(r) or isnan(i) + +def c_isfinite(r, i): + return isfinite(r) and isfinite(i) From noreply at buildbot.pypy.org Thu Oct 11 02:45:19 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 11 Oct 2012 02:45:19 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fill in missing export for RPyThreadAcquireLockTimed Message-ID: <20121011004519.75B491C0117@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58004:fb00d62a9993 Date: 2012-10-10 17:45 -0700 http://bitbucket.org/pypy/pypy/changeset/fb00d62a9993/ Log: fill in missing export for RPyThreadAcquireLockTimed diff --git a/pypy/module/thread/ll_thread.py b/pypy/module/thread/ll_thread.py --- a/pypy/module/thread/ll_thread.py +++ b/pypy/module/thread/ll_thread.py @@ -17,9 +17,9 @@ separate_module_sources = [''], include_dirs = [str(py.path.local(autopath.pypydir).join('translator', 'c'))], export_symbols = ['RPyThreadGetIdent', 'RPyThreadLockInit', - 'RPyThreadAcquireLock', 'RPyThreadReleaseLock', - 'RPyGilAllocate', 'RPyGilYieldThread', - 'RPyGilRelease', 'RPyGilAcquire', + 'RPyThreadAcquireLock', 'RPyThreadAcquireLockTimed', + 'RPyThreadReleaseLock', 'RPyGilAllocate', + 'RPyGilYieldThread', 'RPyGilRelease', 'RPyGilAcquire', 'RPyThreadGetStackSize', 'RPyThreadSetStackSize', 'RPyOpaqueDealloc_ThreadLock', 'RPyThreadAfterFork'] From noreply at buildbot.pypy.org Thu Oct 11 09:35:06 2012 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 11 Oct 2012 09:35:06 +0200 (CEST) Subject: [pypy-commit] pypy default: fix for failing test Message-ID: <20121011073506.E731A1C04E7@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r58005:a7f5a71b05d1 Date: 2012-10-11 07:36 +0200 http://bitbucket.org/pypy/pypy/changeset/a7f5a71b05d1/ Log: fix for failing test diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -17,15 +17,18 @@ return not dtype.itemtype.bool(val) class W_Ufunc(Wrappable): - _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", "allow_complex"] - _immutable_fields_ = ["promote_to_float", "promote_bools", "name", "allow_complex"] + _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", + "allow_complex", "complex_to_float"] + _immutable_fields_ = ["promote_to_float", "promote_bools", "name", + "allow_complex", "complex_to_float"] def __init__(self, name, promote_to_float, promote_bools, identity, - int_only, allow_complex): + int_only, allow_complex, complex_to_float): self.name = name self.promote_to_float = promote_to_float self.promote_bools = promote_bools self.allow_complex = allow_complex + self.complex_to_float = complex_to_float self.identity = identity self.int_only = int_only @@ -216,10 +219,11 @@ _immutable_fields_ = ["func", "name"] def __init__(self, func, name, promote_to_float=False, promote_bools=False, - identity=None, bool_result=False, int_only=False, allow_complex=True): + identity=None, bool_result=False, int_only=False, + allow_complex=True, complex_to_float=False): W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity, - int_only, allow_complex) + int_only, allow_complex, complex_to_float) self.func = func self.bool_result = bool_result @@ -248,6 +252,11 @@ res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype else: res_dtype = calc_dtype + if self.complex_to_float and calc_dtype.is_complex_type(): + if calc_dtype.name == 'complex64': + res_dtype = interp_dtype.get_dtype_cache(space).w_float32dtype + else: + res_dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if w_obj.is_scalar(): w_val = self.func(calc_dtype, w_obj.get_scalar_value().convert_to(calc_dtype)) @@ -269,10 +278,11 @@ argcount = 2 def __init__(self, func, name, promote_to_float=False, promote_bools=False, - identity=None, comparison_func=False, int_only=False, allow_complex=True): + identity=None, comparison_func=False, int_only=False, + allow_complex=True, complex_to_float=False): W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity, - int_only, allow_complex) + int_only, allow_complex, complex_to_float) self.func = func self.comparison_func = comparison_func if name == 'logical_and': @@ -534,14 +544,14 @@ ("positive", "pos", 1), ("negative", "neg", 1), - ("absolute", "abs", 1), + ("absolute", "abs", 1, {"complex_to_float": True}), ("sign", "sign", 1, {"promote_bools": True}), ("signbit", "signbit", 1, {"bool_result": True, "allow_complex": False}), ("reciprocal", "reciprocal", 1), ("conjugate", "conj", 1), - ("real", "real", 1), - ("imag", "imag", 1), + ("real", "real", 1, {"complex_to_float": True}), + ("imag", "imag", 1, {"complex_to_float": True}), ("fabs", "fabs", 1, {"promote_to_float": True, "allow_complex": False}), From noreply at buildbot.pypy.org Thu Oct 11 09:40:41 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 11 Oct 2012 09:40:41 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix test_descriptor Message-ID: <20121011074041.8A4A51C0035@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58006:5ef114da6d50 Date: 2012-10-11 09:40 +0200 http://bitbucket.org/pypy/pypy/changeset/5ef114da6d50/ Log: fix test_descriptor diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -424,12 +424,13 @@ w_res = space.w_None return w_res + def descr_function_get(space, w_function, w_obj, w_cls=None): """functionobject.__get__(obj[, type]) -> method""" # this is not defined as a method on Function because it's generally # useful logic: w_function can be any callable. It is used by Method too. asking_for_bound = (space.is_none(w_cls) or - not space.is_none(w_obj) or + not space.is_w(w_obj, space.w_None) or space.is_w(w_cls, space.type(space.w_None))) if asking_for_bound: return space.wrap(Method(space, w_function, w_obj, w_cls)) @@ -613,7 +614,7 @@ self.w_function = w_function def descr_classmethod_get(self, space, w_obj, w_klass=None): - if space.is_w(w_klass, space.w_None): + if space.is_none(w_klass): w_klass = space.type(w_obj) return space.wrap(Method(space, self.w_function, w_klass, space.w_None)) diff --git a/pypy/module/__builtin__/descriptor.py b/pypy/module/__builtin__/descriptor.py --- a/pypy/module/__builtin__/descriptor.py +++ b/pypy/module/__builtin__/descriptor.py @@ -50,6 +50,7 @@ def descr_new_super(space, w_subtype, w_starttype, w_obj_or_type=None): if space.is_none(w_obj_or_type): w_type = None # unbound super object + w_obj_or_type = space.w_None else: w_objtype = space.type(w_obj_or_type) if space.is_true(space.issubtype(w_objtype, space.w_type)) and \ From noreply at buildbot.pypy.org Thu Oct 11 13:31:26 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 11 Oct 2012 13:31:26 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Kill HostCode.co_cellvars Message-ID: <20121011113126.D4E7D1C1C3A@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58007:cee5218b458b Date: 2012-10-11 05:40 +0100 http://bitbucket.org/pypy/pypy/changeset/cee5218b458b/ Log: Kill HostCode.co_cellvars diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -19,7 +19,7 @@ def __init__(self, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, - name, firstlineno, lnotab, freevars, cellvars): + name, firstlineno, lnotab, freevars): """Initialize a new code object""" self.co_name = name assert nlocals >= 0 @@ -32,7 +32,6 @@ self.names = names self.co_varnames = varnames self.co_freevars = freevars - self.co_cellvars = cellvars self.co_filename = filename self.co_name = name self.co_firstlineno = firstlineno @@ -55,8 +54,7 @@ code.co_name, code.co_firstlineno, code.co_lnotab, - list(code.co_freevars), - list(code.co_cellvars)) + list(code.co_freevars)) @property def formalargcount(self): @@ -73,7 +71,7 @@ if len(closure) != len(self.co_freevars): raise ValueError("code object received a closure with " "an unexpected number of free variables") - return [Cell() for _ in self.co_cellvars] + closure + return closure def read(self, pos): From noreply at buildbot.pypy.org Thu Oct 11 13:31:28 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 11 Oct 2012 13:31:28 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Don't wrap closure vars in Cell objects Message-ID: <20121011113128.0AE581C1C3A@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58008:4ef541073dfa Date: 2012-10-11 06:16 +0100 http://bitbucket.org/pypy/pypy/changeset/4ef541073dfa/ Log: Don't wrap closure vars in Cell objects diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -8,7 +8,6 @@ HAVE_ARGUMENT) from pypy.interpreter.astcompiler.consts import (CO_GENERATOR, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS) -from pypy.interpreter.nestedscope import Cell from pypy.objspace.flow.model import Constant class HostCode(object): @@ -62,18 +61,6 @@ and **varkwarg, if they exist.""" return self.signature.scope_length() - def make_cells(self, closure): - """Convert a Python closure object into a list of Cells""" - if closure is not None: - closure = [Cell(Constant(c.cell_contents)) for c in closure] - else: - closure = [] - if len(closure) != len(self.co_freevars): - raise ValueError("code object received a closure with " - "an unexpected number of free variables") - return closure - - def read(self, pos): """ Decode the instruction starting at position ``next_instr``. diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -3,7 +3,6 @@ from pypy.tool.error import source_lines from pypy.interpreter import pyframe -from pypy.interpreter.nestedscope import Cell from pypy.interpreter.argument import ArgumentsForTranslation from pypy.interpreter.pyopcode import Return, BytecodeCorruption from pypy.objspace.flow.model import (Constant, Variable, Block, Link, @@ -229,7 +228,7 @@ self.w_globals = Constant(func.func_globals) self.lastblock = None - self.cells = code.make_cells(func.func_closure) + self.init_closure(func.func_closure) self.f_lineno = code.co_firstlineno self.last_instr = 0 @@ -238,6 +237,13 @@ self.joinpoints = {} + def init_closure(self, closure): + if closure is None: + self.closure = [] + else: + self.closure = [self.space.wrap(c.cell_contents) for c in closure] + assert len(self.closure) == len(self.pycode.co_freevars) + def init_locals_stack(self, code): """ Initialize the locals and the stack. @@ -676,6 +682,9 @@ self.pushvalue(w_value) LOOKUP_METHOD = LOAD_ATTR + def LOAD_DEREF(self, varindex, next_instr): + self.pushvalue(self.closure[varindex]) + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. From noreply at buildbot.pypy.org Thu Oct 11 13:31:29 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 11 Oct 2012 13:31:29 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: cleanup imports Message-ID: <20121011113129.3D4151C1C3A@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58009:d0b2441778aa Date: 2012-10-11 06:25 +0100 http://bitbucket.org/pypy/pypy/changeset/d0b2441778aa/ Log: cleanup imports diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,14 +1,11 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from types import CodeType -from pypy.interpreter.pycode import (BytecodeCorruption, cpython_magic, +from pypy.interpreter.pycode import (BytecodeCorruption, cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) -from pypy.interpreter.astcompiler.consts import (CO_GENERATOR, CO_NEWLOCALS, - CO_VARARGS, CO_VARKEYWORDS) -from pypy.objspace.flow.model import Constant +from pypy.interpreter.astcompiler.consts import CO_GENERATOR class HostCode(object): """ diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -6,11 +6,9 @@ from pypy.interpreter.argument import ArgumentsForTranslation from pypy.interpreter.pyopcode import Return, BytecodeCorruption from pypy.objspace.flow.model import (Constant, Variable, Block, Link, - UnwrapException, SpaceOperation, FunctionGraph, c_last_exception) + UnwrapException, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, recursively_flatten) -from pypy.objspace.flow.bytecode import HostCode -from pypy.objspace.flow.pygraph import PyGraph from pypy.objspace.flow.specialcase import (rpython_print_item, rpython_print_newline) diff --git a/pypy/objspace/flow/generator.py b/pypy/objspace/flow/generator.py --- a/pypy/objspace/flow/generator.py +++ b/pypy/objspace/flow/generator.py @@ -1,5 +1,5 @@ from pypy.objspace.flow.model import Block, Link, SpaceOperation, checkgraph -from pypy.objspace.flow.model import Variable, Constant, FunctionGraph +from pypy.objspace.flow.model import Variable, Constant from pypy.translator.unsimplify import insert_empty_startblock from pypy.translator.unsimplify import split_block from pypy.translator.simplify import eliminate_empty_blocks, simplify_graph diff --git a/pypy/objspace/flow/test/test_generator.py b/pypy/objspace/flow/test/test_generator.py --- a/pypy/objspace/flow/test/test_generator.py +++ b/pypy/objspace/flow/test/test_generator.py @@ -1,10 +1,8 @@ from pypy.conftest import option from pypy.objspace.flow.objspace import FlowObjSpace from pypy.objspace.flow.model import Variable -from pypy.interpreter.argument import Signature from pypy.objspace.flow.generator import (make_generatoriterator_class, - replace_graph_with_bootstrap, get_variable_names, - tweak_generator_body_graph, attach_next_method) + replace_graph_with_bootstrap, get_variable_names, attach_next_method) from pypy.translator.simplify import join_blocks From noreply at buildbot.pypy.org Thu Oct 11 13:31:38 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Thu, 11 Oct 2012 13:31:38 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: kill some more pyobj related code Message-ID: <20121011113138.2069C1C1C3A@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r58010:95aad8cc8f1d Date: 2012-10-11 04:31 -0700 http://bitbucket.org/pypy/pypy/changeset/95aad8cc8f1d/ Log: kill some more pyobj related code diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -496,7 +496,7 @@ vars.append(op.result) for v in vars: - TYPE = getattr(v, 'concretetype', None) + TYPE = v.concretetype if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc': roots.append(_address_of_local_var(self, v)) diff --git a/pypy/translator/backendopt/support.py b/pypy/translator/backendopt/support.py --- a/pypy/translator/backendopt/support.py +++ b/pypy/translator/backendopt/support.py @@ -32,12 +32,8 @@ return c def var_needsgc(var): - if hasattr(var, 'concretetype'): - vartype = var.concretetype - return isinstance(vartype, lltype.Ptr) and vartype._needsgc() - else: - # assume PyObjPtr - return True + vartype = var.concretetype + return isinstance(vartype, lltype.Ptr) and vartype._needsgc() def find_calls_from(translator, graph, memo=None): if memo and graph in memo: diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py --- a/pypy/translator/c/gc.py +++ b/pypy/translator/c/gc.py @@ -64,16 +64,6 @@ def rtti_type(self): return '' - def OP_GC_PUSH_ALIVE_PYOBJ(self, funcgen, op): - expr = funcgen.expr(op.args[0]) - if expr == 'NULL': - return '' - return 'Py_XINCREF(%s);' % expr - - def OP_GC_POP_ALIVE_PYOBJ(self, funcgen, op): - expr = funcgen.expr(op.args[0]) - return 'Py_XDECREF(%s);' % expr - def OP_GC_SET_MAX_HEAP_SIZE(self, funcgen, op): return '' From noreply at buildbot.pypy.org Thu Oct 11 14:08:06 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Thu, 11 Oct 2012 14:08:06 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: fill the slides with a first rough draft Message-ID: <20121011120806.C29811C15FC@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4846:cfdba0fcd517 Date: 2012-10-11 14:07 +0200 http://bitbucket.org/pypy/extradoc/changeset/cfdba0fcd517/ Log: fill the slides with a first rough draft diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -90,6 +90,7 @@ \begin{itemize} \item for interesting, commonly executed code paths \item produces a linear list of operations (trace) + \item automatically does (potentially deep) inlining \end{itemize} \item trace is optimized and then turned into machine code \end{itemize} @@ -97,7 +98,19 @@ \begin{frame} \frametitle{Guards} - + \begin{itemize} + \item Points of control flow divergence are marked with guards + \item Operations that check whether conditions are still true + \item When a guard fails, execution of the trace stops and continues in the interpreter + \pause + \begin{block}{Guard Characteristics} + \begin{itemize} + \item lots of them, up to 20\% guards + \item most never fail + \item costly to implement + \end{itemize} + \end{block} + \end{itemize} \end{frame} % this talk wants to go over a lot of details that are usually glossed over as @@ -105,10 +118,21 @@ \begin{frame} \frametitle{Bridges} + \begin{itemize} + \item When a trace fails often, it becomes worth to attach a new trace to it + \item This is called a bridge + \item The bridge is attached by patching the guard machine code + \item when this guard fails in the future, the new trace is executed instead + \end{itemize} \end{frame} \begin{frame} \frametitle{RPython and PyPy} + \begin{itemize} + \item Context: RPython + \item a generic tracing JIT, applicable to many languages + \item main use: PyPy, an efficient Python interpreter + \end{itemize} \end{frame} \begin{frame} @@ -119,14 +143,38 @@ \begin{frame} \frametitle{Symbolic Frame Capturing} + \begin{itemize} + \item Guard can fail deep inside inlined function + \item when going back to the interpreter, call stack needs to be re-created + \item done with the help of symbolic frame stacks + \item these show how trace trace variables fill the to-be-built stack frames + \end{itemize} \end{frame} \begin{frame} \frametitle{Symbolic Frame Compression} + \begin{itemize} + \item There are \emph{a lot of} guards + \item Naively storing symbolic frames would be costly in terms of memory + \item need to store them compactly + \item observation: from one guard to the next, the non-top stack frames don't change + \item share these between subsequent guards + \pause + \item also need a byte-saving binary representation, but that's just boring work + \end{itemize} \end{frame} \begin{frame} \frametitle{Interaction with Optimization} + \begin{itemize} + \item Some optimizations make it necessary to store extra information in symbolic frames + \item examples: + \begin{itemize} + \item delayed heap stores (need to do stores before resuming interpreter) + \item allocation remvoal (need to allocate objects before resuming) + \end{itemize} + \item can be compressed using similar techniques + \end{itemize} \end{frame} \begin{frame} From noreply at buildbot.pypy.org Thu Oct 11 16:44:44 2012 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 11 Oct 2012 16:44:44 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: typo Message-ID: <20121011144444.31A6D1C0035@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4847:9e013a7e52b9 Date: 2012-10-11 11:42 -0300 http://bitbucket.org/pypy/extradoc/changeset/9e013a7e52b9/ Log: typo diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -69,7 +69,7 @@ % If you wish to uncover everything in a step-wise fashion, uncomment -% the following command: +% the following command: %\beamerdefaultoverlayspecification{<+->} @@ -147,7 +147,7 @@ \item Guard can fail deep inside inlined function \item when going back to the interpreter, call stack needs to be re-created \item done with the help of symbolic frame stacks - \item these show how trace trace variables fill the to-be-built stack frames + \item these show how trace variables fill the to-be-built stack frames \end{itemize} \end{frame} From noreply at buildbot.pypy.org Thu Oct 11 16:44:45 2012 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 11 Oct 2012 16:44:45 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: typo Message-ID: <20121011144445.727361C04FF@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4848:5321fa88c545 Date: 2012-10-11 11:44 -0300 http://bitbucket.org/pypy/extradoc/changeset/5321fa88c545/ Log: typo diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -171,7 +171,7 @@ \item examples: \begin{itemize} \item delayed heap stores (need to do stores before resuming interpreter) - \item allocation remvoal (need to allocate objects before resuming) + \item allocation removal (need to allocate objects before resuming) \end{itemize} \item can be compressed using similar techniques \end{itemize} From noreply at buildbot.pypy.org Thu Oct 11 20:13:44 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 11 Oct 2012 20:13:44 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix cffi backend tests Message-ID: <20121011181344.4DB5D1C15FC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58011:95c6721ee480 Date: 2012-10-11 09:42 +0200 http://bitbucket.org/pypy/pypy/changeset/95c6721ee480/ Log: fix cffi backend tests diff --git a/pypy/module/_cffi_backend/test/test_c.py b/pypy/module/_cffi_backend/test/test_c.py --- a/pypy/module/_cffi_backend/test/test_c.py +++ b/pypy/module/_cffi_backend/test/test_c.py @@ -36,7 +36,9 @@ testfuncs_w = [] keepalive_funcs = [] - def find_and_load_library_for_test(space, w_name, w_is_global=0): + def find_and_load_library_for_test(space, w_name, w_is_global=None): + if w_is_global is None: + w_is_global = space.wrap(0) if space.is_w(w_name, space.w_None): path = None else: From noreply at buildbot.pypy.org Thu Oct 11 20:13:45 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 11 Oct 2012 20:13:45 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix continuation Message-ID: <20121011181345.8A40F1C15FC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58012:f346535f69fa Date: 2012-10-11 10:05 +0200 http://bitbucket.org/pypy/pypy/changeset/f346535f69fa/ Log: fix continuation diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -811,7 +811,7 @@ interpreter class (a subclass of Wrappable). """ assert RequiredClass is not None - if can_be_None and self.is_w(w_obj, self.w_None): + if can_be_None and self.is_none(w_obj): return None obj = self.interpclass_w(w_obj) if not isinstance(obj, RequiredClass): # or obj is None diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py --- a/pypy/module/_collections/interp_deque.py +++ b/pypy/module/_collections/interp_deque.py @@ -82,7 +82,7 @@ def init(self, w_iterable=None, w_maxlen=None): space = self.space - if space.is_w(w_maxlen, space.w_None): + if space.is_none(w_maxlen): maxlen = sys.maxint else: maxlen = space.gateway_nonnegint_w(w_maxlen) diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -4,7 +4,7 @@ from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.gateway import interp2app +from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root from pypy.interpreter.pycode import PyCode from pypy.interpreter.pyframe import PyFrame @@ -90,16 +90,21 @@ h = sthread.switch(global_state.destination.h) return post_switch(sthread, h) + @unwrap_spec(w_value = (W_Root, 'space.w_None'), + w_to = (W_Root, 'space.w_None')) def descr_switch(self, w_value=None, w_to=None): global_state.w_value = w_value return self.switch(w_to) + @unwrap_spec(w_val = (W_Root, 'space.w_None'), + w_tb = (W_Root, 'space.w_None'), + w_to = (W_Root, 'space.w_None')) def descr_throw(self, w_type, w_val=None, w_tb=None, w_to=None): from pypy.interpreter.pytraceback import check_traceback space = self.space # msg = "throw() third argument must be a traceback object" - if space.is_w(w_tb, space.w_None): + if space.is_none(w_tb): tb = None else: tb = check_traceback(space, w_tb, msg) From noreply at buildbot.pypy.org Thu Oct 11 20:13:46 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 11 Oct 2012 20:13:46 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (arigo, fijal) fix the annotation of isinstance Message-ID: <20121011181346.C27861C15FC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58013:99362c4bde4d Date: 2012-10-11 20:12 +0200 http://bitbucket.org/pypy/pypy/changeset/99362c4bde4d/ Log: (arigo, fijal) fix the annotation of isinstance diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -150,7 +150,7 @@ def builtin_isinstance(s_obj, s_type, variables=None): - r = SomeBool() + r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): @@ -189,7 +189,7 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if isinstance(s_type, SomePBC): + if isinstance(s_obj, SomeInstance) and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -3790,6 +3790,24 @@ s = a.build_types(fn, [annmodel.SomeChar()]) assert s == annmodel.SomeChar() + def test_isinstance_double_const(self): + class X(object): + def _freeze_(self): + return True + + x = X() + + def f(i): + if i: + x1 = x + else: + x1 = None + print "hello" # this is to force the merge of blocks + return isinstance(x1, X) + + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeBool) def g(n): return [0,1,2,n] From noreply at buildbot.pypy.org Thu Oct 11 20:13:47 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 11 Oct 2012 20:13:47 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121011181347.EB67C1C15FC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58014:875dd99dd21d Date: 2012-10-11 20:13 +0200 http://bitbucket.org/pypy/pypy/changeset/875dd99dd21d/ Log: merge diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -496,7 +496,7 @@ vars.append(op.result) for v in vars: - TYPE = getattr(v, 'concretetype', None) + TYPE = v.concretetype if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc': roots.append(_address_of_local_var(self, v)) diff --git a/pypy/translator/backendopt/support.py b/pypy/translator/backendopt/support.py --- a/pypy/translator/backendopt/support.py +++ b/pypy/translator/backendopt/support.py @@ -32,12 +32,8 @@ return c def var_needsgc(var): - if hasattr(var, 'concretetype'): - vartype = var.concretetype - return isinstance(vartype, lltype.Ptr) and vartype._needsgc() - else: - # assume PyObjPtr - return True + vartype = var.concretetype + return isinstance(vartype, lltype.Ptr) and vartype._needsgc() def find_calls_from(translator, graph, memo=None): if memo and graph in memo: diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py --- a/pypy/translator/c/gc.py +++ b/pypy/translator/c/gc.py @@ -64,16 +64,6 @@ def rtti_type(self): return '' - def OP_GC_PUSH_ALIVE_PYOBJ(self, funcgen, op): - expr = funcgen.expr(op.args[0]) - if expr == 'NULL': - return '' - return 'Py_XINCREF(%s);' % expr - - def OP_GC_POP_ALIVE_PYOBJ(self, funcgen, op): - expr = funcgen.expr(op.args[0]) - return 'Py_XDECREF(%s);' % expr - def OP_GC_SET_MAX_HEAP_SIZE(self, funcgen, op): return '' From noreply at buildbot.pypy.org Thu Oct 11 21:13:06 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 11 Oct 2012 21:13:06 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Raise FlowingError for run-time UnboundLocalError Message-ID: <20121011191306.D60E61C04FF@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58015:76950b0447c5 Date: 2012-10-11 14:39 +0100 http://bitbucket.org/pypy/pypy/changeset/76950b0447c5/ Log: Raise FlowingError for run-time UnboundLocalError diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -668,6 +668,12 @@ else: self.space.call_function(w_exitfunc, w_None, w_None, w_None) + def LOAD_FAST(self, varindex, next_instr): + w_value = self.locals_stack_w[varindex] + if w_value is None: + raise FlowingError(self, "Local variable referenced before assignment") + self.pushvalue(w_value) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1122,6 +1122,12 @@ self.codetest(f) assert "closure" in str(excinfo.value) + def test_unbound_local(self): + def f(): + x += 1 + with py.test.raises(FlowingError): + self.codetest(f) + DATA = {'x': 5, 'y': 6} From noreply at buildbot.pypy.org Thu Oct 11 23:04:31 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 11 Oct 2012 23:04:31 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix tests for _cffi_backend Message-ID: <20121011210431.102BA1C04E7@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58016:8f44495db914 Date: 2012-10-11 18:43 +0200 http://bitbucket.org/pypy/pypy/changeset/8f44495db914/ Log: Fix tests for _cffi_backend diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -209,11 +209,6 @@ def as_unsigned_long(space, w_ob, strict): # same as as_unsigned_long_long(), but returning just an Unsigned - if space.is_w(space.type(w_ob), space.w_int): # shortcut - value = space.int_w(w_ob) - if strict and value < 0: - raise OperationError(space.w_OverflowError, space.wrap(neg_msg)) - return r_uint(value) try: bigint = space.bigint_w(w_ob) except OperationError, e: @@ -242,8 +237,6 @@ def _standard_object_as_bool(space, w_ob): if space.isinstance_w(w_ob, space.w_int): - return space.int_w(w_ob) != 0 - if space.isinstance_w(w_ob, space.w_long): return space.bigint_w(w_ob).tobool() if space.isinstance_w(w_ob, space.w_float): return space.float_w(w_ob) != 0.0 From noreply at buildbot.pypy.org Thu Oct 11 23:04:32 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 11 Oct 2012 23:04:32 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix range.__repr__, test passes._ Message-ID: <20121011210432.584431C04E7@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58017:b35694b4c086 Date: 2012-10-11 23:03 +0200 http://bitbucket.org/pypy/pypy/changeset/b35694b4c086/ Log: Fix range.__repr__, test passes._ diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -309,9 +309,6 @@ return space.mod(space.wrap("range(%d, %d, %d)"), space.newtuple([self.w_start, self.w_stop, self.w_step])) - elif space.is_true(space.eq(self.w_start, space.newint(0))): - return space.mod(space.wrap("range(%d)"), - space.newtuple([self.w_stop])) else: return space.mod(space.wrap("range(%d, %d)"), space.newtuple([self.w_start, self.w_stop])) From noreply at buildbot.pypy.org Thu Oct 11 23:33:48 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 11 Oct 2012 23:33:48 +0200 (CEST) Subject: [pypy-commit] pypy py3k: thread -> _thread Message-ID: <20121011213348.A9C1D1C04FF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58018:ab80024fd8fd Date: 2012-10-11 14:32 -0700 http://bitbucket.org/pypy/pypy/changeset/ab80024fd8fd/ Log: thread -> _thread 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 @@ -1336,7 +1336,7 @@ cls.w_tmppath = cls.space.wrap(str(udir)) def test_multithreaded_import(self): - import sys, thread, time + import sys, _thread, time oldpath = sys.path[:] try: sys.path.insert(0, self.tmppath) @@ -1347,7 +1347,7 @@ got.append(getattr(test_multithreaded_imp, 'x', '?')) for i in range(5): - thread.start_new_thread(check, ()) + _thread.start_new_thread(check, ()) for n in range(100): for i in range(105): time.sleep(0.001) From noreply at buildbot.pypy.org Thu Oct 11 23:33:49 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 11 Oct 2012 23:33:49 +0200 (CEST) Subject: [pypy-commit] pypy py3k: move the older py2 range tests (adapted to py3) into test_functional, they were Message-ID: <20121011213349.EC3451C04FF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58019:86c7aad53f10 Date: 2012-10-11 14:32 -0700 http://bitbucket.org/pypy/pypy/changeset/86c7aad53f10/ Log: move the older py2 range tests (adapted to py3) into test_functional, they were misplaced into test__functools instead of reduce's tests. restore those too diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py --- a/pypy/module/__builtin__/test/test_functional.py +++ b/pypy/module/__builtin__/test/test_functional.py @@ -168,6 +168,66 @@ # test again, to make sure that range() is not its own iterator assert list(x) == [2, 5, 8] + def test_range_toofew(self): + raises(TypeError, range) + + def test_range_toomany(self): + raises(TypeError, range, 1, 2, 3, 4) + + def test_range_one(self): + assert list(range(1)) == [0] + + def test_range_posstartisstop(self): + assert list(range(1, 1)) == [] + + def test_range_negstartisstop(self): + assert list(range(-1, -1)) == [] + + def test_range_zero(self): + assert list(range(0)) == [] + + def test_range_twoargs(self): + assert list(range(1, 2)) == [1] + + def test_range_decreasingtwoargs(self): + assert list(range(3, 1)) == [] + + def test_range_negatives(self): + assert list(range(-3)) == [] + + def test_range_decreasing_negativestep(self): + assert list(range(5, -2, -1)) == [5, 4, 3, 2, 1, 0 , -1] + + def test_range_posfencepost1(self): + assert list(range(1, 10, 3)) == [1, 4, 7] + + def test_range_posfencepost2(self): + assert list(range(1, 11, 3)) == [1, 4, 7, 10] + + def test_range_posfencepost3(self): + assert list(range(1, 12, 3)) == [1, 4, 7, 10] + + def test_range_negfencepost1(self): + assert list(range(-1, -10, -3)) == [-1, -4, -7] + + def test_range_negfencepost2(self): + assert list(range(-1, -11, -3)) == [-1, -4, -7, -10] + + def test_range_negfencepost3(self): + assert list(range(-1, -12, -3)) == [-1, -4, -7, -10] + + def test_range_decreasing_negativelargestep(self): + assert list(range(5, -2, -3)) == [5, 2, -1] + + def test_range_increasing_positivelargestep(self): + assert list(range(-5, 2, 3)) == [-5, -2, 1] + + def test_range_zerostep(self): + raises(ValueError, range, 1, 5, 0) + + def test_range_wrong_type(self): + raises(TypeError, range, "42") + def test_range_iter(self): x = range(2, 9, 3) it = iter(x) @@ -194,14 +254,93 @@ raises(TypeError, range, A2()) def test_range_float(self): - raises(TypeError, "range(0.1, 2.0, 1.1)") + raises(TypeError, range, 0.1) + raises(TypeError, range, 0.1, 0) + raises(TypeError, range, 0, 0.1) + raises(TypeError, range, 0.1, 0, 0) + raises(TypeError, range, 0, 0.1, 0) + raises(TypeError, range, 0, 0, 0.1) + raises(TypeError, range, 0.1, 2.0, 1.1) def test_range_long(self): import sys + assert list(range(-2**100)) == [] + assert list(range(0, -2**100)) == [] + assert list(range(0, 2**100, -1)) == [] + assert list(range(0, 2**100, -1)) == [] + a = 10 * sys.maxsize assert range(a)[-1] == a-1 assert range(0, a)[-1] == a-1 assert range(0, 1, a)[-1] == 0 + assert list(range(a, a+2)) == [a, a+1] + assert list(range(a+2, a, -1)) == [a+2, a+1] + assert list(range(a+4, a, -2)) == [a+4, a+2] + assert list(range(a, a*5, a)) == [a, 2*a, 3*a, 4*a] + + def test_range_cases(self): + import sys + for start in [10, 10 * sys.maxsize]: + for stop in [start-4, start-1, start, start+1, start+4]: + for step in [1, 2, 3, 4]: + lst = list(range(start, stop, step)) + expected = [] + a = start + while a < stop: + expected.append(a) + a += step + assert lst == expected + for step in [-1, -2, -3, -4]: + lst = list(range(start, stop, step)) + expected = [] + a = start + while a > stop: + expected.append(a) + a += step + assert lst == expected + + def test_range_contains(self): + assert 3 in range(5) + assert 3 not in range(3) + assert 3 not in range(4, 5) + assert 3 in range(1, 5, 2) + assert 3 not in range(0, 5, 2) + assert '3' not in range(5) + + def test_range_count(self): + assert range(5).count(3) == 1 + assert type(range(5).count(3)) is int + assert range(0, 5, 2).count(3) == 0 + assert range(5).count(3.0) == 1 + assert range(5).count('3') == 0 + + def test_range_getitem(self): + assert range(6)[3] == 3 + assert range(6)[-1] == 5 + raises(IndexError, range(6).__getitem__, 6) + + def test_range_slice(self): + # range objects don't implement equality in 3.2, use the repr + assert repr(range(6)[2:5]) == 'range(2, 5)' + assert repr(range(6)[-1:-3:-2]) == 'range(5, 3, -2)' + + def test_large_range(self): + import sys + def _range_len(x): + try: + length = len(x) + except OverflowError: + step = x[1] - x[0] + length = 1 + ((x[-1] - x[0]) // step) + return length + a = -sys.maxsize + b = sys.maxsize + expected_len = b - a + x = range(a, b) + assert a in x + assert b not in x + raises(OverflowError, len, x) + assert _range_len(x) == expected_len def test_range_reduce(self): x = range(2, 9, 3) diff --git a/pypy/module/test_lib_pypy/test__functools.py b/pypy/module/test_lib_pypy/test__functools.py --- a/pypy/module/test_lib_pypy/test__functools.py +++ b/pypy/module/test_lib_pypy/test__functools.py @@ -1,157 +1,37 @@ -from _functools import reduce +class AppTestReduce: -class TestRange: + def test_None(self): + from _functools import reduce + raises(TypeError, reduce, lambda x, y: x+y, [1,2,3], None) - def test_range_toofew(self): - raises(TypeError, range) + def test_sum(self): + from _functools import reduce + assert reduce(lambda x, y: x+y, [1,2,3,4], 0) == 10 + assert reduce(lambda x, y: x+y, [1,2,3,4]) == 10 - def test_range_toomany(self): - raises(TypeError, range, 1, 2, 3, 4) + def test_minus(self): + from _functools import reduce + assert reduce(lambda x, y: x-y, [10, 2, 8]) == 0 + assert reduce(lambda x, y: x-y, [2, 8], 10) == 0 - def test_range_one(self): - assert list(range(1)) == [0] + def test_from_cpython(self): + from _functools import reduce + class SequenceClass(object): + def __init__(self, n): + self.n = n + def __getitem__(self, i): + if 0 <= i < self.n: + return i + else: + raise IndexError - def test_range_posstartisstop(self): - assert list(range(1, 1)) == [] + from operator import add + assert reduce(add, SequenceClass(5)) == 10 + assert reduce(add, SequenceClass(5), 42) == 52 + raises(TypeError, reduce, add, SequenceClass(0)) + assert reduce(add, SequenceClass(0), 42) == 42 + assert reduce(add, SequenceClass(1)) == 0 + assert reduce(add, SequenceClass(1), 42) == 42 - def test_range_negstartisstop(self): - assert list(range(-1, -1)) == [] - - def test_range_zero(self): - assert list(range(0)) == [] - - def test_range_twoargs(self): - assert list(range(1, 2)) == [1] - - def test_range_decreasingtwoargs(self): - assert list(range(3, 1)) == [] - - def test_range_negatives(self): - assert list(range(-3)) == [] - - def test_range_decreasing_negativestep(self): - assert list(range(5, -2, -1)) == [5, 4, 3, 2, 1, 0 , -1] - - def test_range_posfencepost1(self): - assert list(range(1, 10, 3)) == [1, 4, 7] - - def test_range_posfencepost2(self): - assert list(range(1, 11, 3)) == [1, 4, 7, 10] - - def test_range_posfencepost3(self): - assert list(range(1, 12, 3)) == [1, 4, 7, 10] - - def test_range_negfencepost1(self): - assert list(range(-1, -10, -3)) == [-1, -4, -7] - - def test_range_negfencepost2(self): - assert list(range(-1, -11, -3)) == [-1, -4, -7, -10] - - def test_range_negfencepost3(self): - assert list(range(-1, -12, -3)) == [-1, -4, -7, -10] - - def test_range_decreasing_negativelargestep(self): - assert list(range(5, -2, -3)) == [5, 2, -1] - - def test_range_increasing_positivelargestep(self): - assert list(range(-5, 2, 3)) == [-5, -2, 1] - - def test_range_zerostep(self): - raises(ValueError, range, 1, 5, 0) - - def test_range_float(self): - raises(TypeError, range, 0.1) - raises(TypeError, range, 0.1, 0) - raises(TypeError, range, 0, 0.1) - raises(TypeError, range, 0.1, 0, 0) - raises(TypeError, range, 0, 0.1, 0) - raises(TypeError, range, 0, 0, 0.1) - - def test_range_wrong_type(self): - raises(TypeError, range, "42") - - def test_range_object_with___index__(self): - class A(object): - def __index__(self): - return 5 - - assert list(range(A())) == [0, 1, 2, 3, 4] - assert list(range(0, A())) == [0, 1, 2, 3, 4] - assert list(range(0, 10, A())) == [0, 5] - - def test_range_long(self): - import sys - assert list(range(-2**100)) == [] - assert list(range(0, -2**100)) == [] - assert list(range(0, 2**100, -1)) == [] - assert list(range(0, 2**100, -1)) == [] - - a = 10 * sys.maxsize - assert list(range(a, a+2)) == [a, a+1] - assert list(range(a+2, a, -1)) == [a+2, a+1] - assert list(range(a+4, a, -2)) == [a+4, a+2] - assert list(range(a, a*5, a)) == [a, 2*a, 3*a, 4*a] - - def test_range_cases(self): - import sys - for start in [10, 10 * sys.maxsize]: - for stop in [start-4, start-1, start, start+1, start+4]: - for step in [1, 2, 3, 4]: - lst = list(range(start, stop, step)) - expected = [] - a = start - while a < stop: - expected.append(a) - a += step - assert lst == expected - for step in [-1, -2, -3, -4]: - lst = list(range(start, stop, step)) - expected = [] - a = start - while a > stop: - expected.append(a) - a += step - assert lst == expected - - def test_range_contains(self): - assert 3 in range(5) - assert 3 not in range(3) - assert 3 not in range(4, 5) - assert 3 in range(1, 5, 2) - assert 3 not in range(0, 5, 2) - assert '3' not in range(5) - - def test_range_count(self): - assert range(5).count(3) == 1 - assert type(range(5).count(3)) is int - assert range(0, 5, 2).count(3) == 0 - assert range(5).count(3.0) == 1 - assert range(5).count('3') == 0 - - def test_range_getitem(self): - assert range(6)[3] == 3 - assert range(6)[-1] == 5 - raises(IndexError, range(6).__getitem__, 6) - - def test_range_slice(self): - # range objects don't implement equality in 3.2, use the repr - assert repr(range(6)[2:5]) == 'range(2, 5)' - assert repr(range(6)[-1:-3:-2]) == 'range(5, 3, -2)' - - def test_large_range(self): - import sys - def _range_len(x): - try: - length = len(x) - except OverflowError: - step = x[1] - x[0] - length = 1 + ((x[-1] - x[0]) // step) - return length - a = -sys.maxsize - b = sys.maxsize - expected_len = b - a - x = range(a, b) - assert a in x - assert b not in x - raises(OverflowError, len, x) - assert _range_len(x) == expected_len + d = {"one": 1, "two": 2, "three": 3} + assert reduce(add, d) == "".join(d.keys()) From noreply at buildbot.pypy.org Thu Oct 11 23:33:51 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 11 Oct 2012 23:33:51 +0200 (CEST) Subject: [pypy-commit] pypy py3k: __getslice__ -> __getitem__ Message-ID: <20121011213351.1FFE41C04FF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58020:d5ac2d8225b7 Date: 2012-10-11 14:32 -0700 http://bitbucket.org/pypy/pypy/changeset/d5ac2d8225b7/ Log: __getslice__ -> __getitem__ diff --git a/pypy/module/test_lib_pypy/test_tputil.py b/pypy/module/test_lib_pypy/test_tputil.py --- a/pypy/module/test_lib_pypy/test_tputil.py +++ b/pypy/module/test_lib_pypy/test_tputil.py @@ -30,7 +30,7 @@ tp = make_proxy(l.append, type=list) x = tp[0:1] assert len(l) == 1 - assert l[0].opname == '__getslice__' + assert l[0].opname == '__getitem__' def test_simple(self): from tputil import make_proxy From noreply at buildbot.pypy.org Thu Oct 11 23:33:52 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 11 Oct 2012 23:33:52 +0200 (CEST) Subject: [pypy-commit] pypy py3k: o all classes are newstyle now and thus cachable Message-ID: <20121011213352.4C9731C04FF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58021:d2423af68642 Date: 2012-10-11 14:33 -0700 http://bitbucket.org/pypy/pypy/changeset/d2423af68642/ Log: o all classes are newstyle now and thus cachable o py3 exception fix for test_change_methods diff --git a/pypy/objspace/std/test/test_methodcache.py b/pypy/objspace/std/test/test_methodcache.py --- a/pypy/objspace/std/test/test_methodcache.py +++ b/pypy/objspace/std/test/test_methodcache.py @@ -27,31 +27,6 @@ assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30 - def test_class_that_cannot_be_cached(self): - import __pypy__ - class X: - pass - class Y(object): - pass - class A(Y, X): - def f(self): - return 42 - - class B(object): - def f(self): - return 43 - class C(object): - def f(self): - return 44 - l = [A(), B(), C()] * 10 - __pypy__.reset_method_cache_counter() - for i, a in enumerate(l): - assert a.f() == 42 + i % 3 - cache_counter = __pypy__.method_cache_counter("f") - assert cache_counter[0] >= 9 - assert cache_counter[1] >= 2 # should be (18, 2) - assert sum(cache_counter) == 20 - def test_change_methods(self): # this test fails because of the following line in typeobject.py:427 # if cached_name is name: @@ -118,6 +93,7 @@ def test_many_names(self): import __pypy__ + laste = None for j in range(20): class A(object): foo = 5 @@ -145,10 +121,10 @@ for name, count in zip(names, names_counters): assert count == (9, 1), str((name, count)) break - except AssertionError: - pass + except AssertionError as e: + laste = e else: - raise + raise laste def test_mutating_bases(self): class C(object): From noreply at buildbot.pypy.org Fri Oct 12 10:12:50 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 10:12:50 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: use newer shinier interface a bit everywhere Message-ID: <20121012081250.1306A1C0182@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58022:5a165e778471 Date: 2012-10-12 10:12 +0200 http://bitbucket.org/pypy/pypy/changeset/5a165e778471/ Log: use newer shinier interface a bit everywhere diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -61,9 +61,9 @@ if el[0] == 'INTERNAL:self': self.visit_self(el[1], *args) else: - assert len(el) == 2 # 2nd arg is str that evals to 'default' - assert el[0] is W_Root # for now - self.visit__W_Root(W_Root, *args) + assert False, "not supported any more, use WrappedDefault" + elif isinstance(el, WrappedDefault): + self.visit__W_Root(W_Root, *args) elif isinstance(el, type): for typ in self.bases_order: if issubclass(el, typ): @@ -278,6 +278,8 @@ if isinstance(el, tuple): parts.append(''.join([getattr(subel, '__name__', subel) for subel in el])) + elif isinstance(el, WrappedDefault): + parts.append('W_Root') else: parts.append(getattr(el, '__name__', el)) label = '_'.join(parts) @@ -460,6 +462,13 @@ return func return decorator +class WrappedDefault(object): + """ Can be used inside unwrap_spec as WrappedDefault(3) which means + it'll be treated as W_Root, but fed with default which will be a wrapped + argument to constructor. + """ + def __init__(self, default_value): + self.default_value = default_value def build_unwrap_spec(func, argnames, self_type=None): """build the list of parameter unwrap spec for the function. @@ -865,7 +874,10 @@ spec = code._unwrap_spec[i] argname = code._argnames[i] if isinstance(spec, tuple) and spec[0] is W_Root: - w_default = eval(spec[1], {'space': space}) + assert False, "use WrappedDefault" + if isinstance(spec, WrappedDefault): + w_default = eval('space.wrap(%r)' % (spec.default_value,), + {'space': space}) assert isinstance(w_default, W_Root) assert argname.startswith('w_') argname = argname[2:] 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 @@ -3,7 +3,7 @@ from pypy.conftest import gettestobjspace from pypy.interpreter import gateway, argument -from pypy.interpreter.gateway import ObjSpace, W_Root +from pypy.interpreter.gateway import ObjSpace, W_Root, WrappedDefault import py import sys @@ -573,7 +573,7 @@ def test_unwrap_spec_default_applevel(self): space = self.space - @gateway.unwrap_spec(w_x = (W_Root, 'space.wrap(42)')) + @gateway.unwrap_spec(w_x = WrappedDefault(42)) def g(space, w_x): return w_x w_g = space.wrap(gateway.interp2app_temp(g)) @@ -587,7 +587,7 @@ def test_unwrap_spec_default_applevel_2(self): space = self.space - @gateway.unwrap_spec(w_x = (W_Root, 'space.wrap(42)'), y=int) + @gateway.unwrap_spec(w_x = (WrappedDefault(42)), y=int) def g(space, w_x, y=10): return space.add(w_x, space.wrap(y)) w_g = space.wrap(gateway.interp2app_temp(g)) @@ -605,7 +605,7 @@ def test_unwrap_spec_default_applevel_bogus(self): space = self.space - @gateway.unwrap_spec(w_x = (W_Root, 'space.wrap(42)'), y=int) + @gateway.unwrap_spec(w_x = WrappedDefault(42), y=int) def g(space, w_x, y): never_called py.test.raises(AssertionError, space.wrap, gateway.interp2app_temp(g)) diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -4,7 +4,7 @@ """ import py from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ - W_Root + WrappedDefault from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt @@ -457,7 +457,7 @@ self.objclass_getter = objclass_getter self.use_closure = use_closure - @unwrap_spec(w_cls = (W_Root, 'space.w_None')) + @unwrap_spec(w_cls = WrappedDefault(None)) def descr_property_get(self, space, w_obj, w_cls=None): """property.__get__(obj[, type]) -> value Read the value of the property of the given obj.""" diff --git a/pypy/module/__builtin__/descriptor.py b/pypy/module/__builtin__/descriptor.py --- a/pypy/module/__builtin__/descriptor.py +++ b/pypy/module/__builtin__/descriptor.py @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.interpreter.function import StaticMethod, ClassMethod -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.typedef import (TypeDef, interp_attrproperty_w, generic_new_descr) from pypy.objspace.descroperation import object_getattribute @@ -97,10 +97,10 @@ def __init__(self, space): pass - @unwrap_spec(w_fget = (W_Root, 'space.w_None'), - w_fset = (W_Root, 'space.w_None'), - w_fdel = (W_Root, 'space.w_None'), - w_doc = (W_Root, 'space.w_None')) + @unwrap_spec(w_fget = WrappedDefault(None), + w_fset = WrappedDefault(None), + w_fdel = WrappedDefault(None), + w_doc = WrappedDefault(None)) def init(self, space, w_fget=None, w_fset=None, w_fdel=None, w_doc=None): self.w_fget = w_fget self.w_fset = w_fset diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -5,7 +5,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.typedef import TypeDef from pypy.rlib import jit from pypy.rlib.objectmodel import specialize @@ -47,7 +47,7 @@ n = 0 return n - at unwrap_spec(w_step = (W_Root, 'space.wrap(1)')) + at unwrap_spec(w_step = WrappedDefault(1)) def range_int(space, w_x, w_y=None, w_step=None): """Return a list of integers in arithmetic position from start (defaults to zero) to stop - 1 by step (defaults to 1). Use a negative step to diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -4,7 +4,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import unwrap_spec, W_Root +from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.rlib.runicode import UNICHR from pypy.rlib.rfloat import isnan, isinf, round_double from pypy.rlib import rfloat @@ -124,7 +124,7 @@ NDIGITS_MAX = int((rfloat.DBL_MANT_DIG - rfloat.DBL_MIN_EXP) * 0.30103) NDIGITS_MIN = -int((rfloat.DBL_MAX_EXP + 1) * 0.30103) - at unwrap_spec(number=float, w_ndigits = (W_Root, 'space.wrap(0)')) + at unwrap_spec(number=float, w_ndigits = WrappedDefault(0)) def round(space, number, w_ndigits): """round(number[, ndigits]) -> floating point number @@ -201,7 +201,7 @@ """Return the integer ordinal of a character.""" return space.ord(w_val) - at unwrap_spec(w_modulus = (W_Root, 'space.w_None')) + at unwrap_spec(w_modulus = WrappedDefault(None)) def pow(space, w_base, w_exponent, w_modulus): """With two arguments, equivalent to ``base**exponent''. With three arguments, equivalent to ``(base**exponent) % modulus'', @@ -234,7 +234,7 @@ function). Note that classes are callable.""" return space.callable(w_object) - at unwrap_spec(w_format_spec = (W_Root, 'space.wrap("")')) + at unwrap_spec(w_format_spec = WrappedDefault("")) def format(space, w_obj, w_format_spec): """Format a obj according to format_spec""" return space.format(w_obj, w_format_spec) diff --git a/pypy/module/_cffi_backend/func.py b/pypy/module/_cffi_backend/func.py --- a/pypy/module/_cffi_backend/func.py +++ b/pypy/module/_cffi_backend/func.py @@ -1,11 +1,11 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import unwrap_spec, W_Root +from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.module._cffi_backend import ctypeobj, cdataobj # ____________________________________________________________ - at unwrap_spec(ctype=ctypeobj.W_CType, w_init=(W_Root, 'space.w_None')) + at unwrap_spec(ctype=ctypeobj.W_CType, w_init=WrappedDefault(None)) def newp(space, ctype, w_init): return ctype.newp(w_init) diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.rlib.rstring import UnicodeBuilder from pypy.rlib.objectmodel import we_are_translated @@ -389,7 +389,7 @@ rname = "str_decode_%s" % (name.replace("_decode", ""), ) assert hasattr(runicode, rname) @unwrap_spec(string='bufferstr', errors='str_or_None', - w_final=(W_Root, 'space.w_False')) + w_final=WrappedDefault(False)) def wrap_decoder(space, string, errors="strict", w_final=None): if errors is None: errors = 'strict' @@ -449,7 +449,7 @@ return space.newtuple([space.wrap(result), space.wrap(len(uni))]) @unwrap_spec(string='bufferstr', errors='str_or_None', - w_final = (W_Root, 'space.w_False')) + w_final = WrappedDefault(False)) def utf_8_decode(space, string, errors="strict", w_final=None): if errors is None: errors = 'strict' @@ -462,7 +462,7 @@ return space.newtuple([space.wrap(result), space.wrap(consumed)]) @unwrap_spec(data=str, errors='str_or_None', byteorder=int, - w_final=(W_Root, 'space.w_False')) + w_final=WrappedDefault(False)) def utf_16_ex_decode(space, data, errors='strict', byteorder=0, w_final=None): if errors is None: errors = 'strict' @@ -483,7 +483,7 @@ space.wrap(byteorder)]) @unwrap_spec(data=str, errors='str_or_None', byteorder=int, - w_final=(W_Root, 'space.w_False')) + w_final=WrappedDefault(False)) def utf_32_ex_decode(space, data, errors='strict', byteorder=0, w_final=None): final = space.is_true(w_final) state = space.fromcache(CodecState) @@ -665,7 +665,7 @@ return space.int_w(w_code) @unwrap_spec(string='bufferstr', errors='str_or_None', - w_final=(W_Root, 'space.w_False')) + w_final=WrappedDefault(False)) def unicode_escape_decode(space, string, errors="strict", w_final=None): if errors is None: errors = 'strict' diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py --- a/pypy/module/_continuation/interp_continuation.py +++ b/pypy/module/_continuation/interp_continuation.py @@ -4,7 +4,7 @@ from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.pycode import PyCode from pypy.interpreter.pyframe import PyFrame @@ -90,15 +90,15 @@ h = sthread.switch(global_state.destination.h) return post_switch(sthread, h) - @unwrap_spec(w_value = (W_Root, 'space.w_None'), - w_to = (W_Root, 'space.w_None')) + @unwrap_spec(w_value = WrappedDefault(None), + w_to = WrappedDefault(None)) def descr_switch(self, w_value=None, w_to=None): global_state.w_value = w_value return self.switch(w_to) - @unwrap_spec(w_val = (W_Root, 'space.w_None'), - w_tb = (W_Root, 'space.w_None'), - w_to = (W_Root, 'space.w_None')) + @unwrap_spec(w_val = WrappedDefault(None), + w_tb = WrappedDefault(None), + w_to = WrappedDefault(None)) def descr_throw(self, w_type, w_val=None, w_tb=None, w_to=None): from pypy.interpreter.pytraceback import check_traceback space = self.space diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -1,7 +1,7 @@ from __future__ import with_statement from pypy.interpreter.typedef import ( TypeDef, GetSetProperty, generic_new_descr, interp_attrproperty_w) -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.buffer import RWBuffer from pypy.rlib.rstring import StringBuilder @@ -387,7 +387,7 @@ self._check_init(space) return space.call_method(self.w_raw, "fileno") - @unwrap_spec(w_size = (W_Root, 'space.w_None')) + @unwrap_spec(w_size = WrappedDefault(None)) def truncate_w(self, space, w_size): self._check_init(space) with self.lock: diff --git a/pypy/module/_io/interp_stringio.py b/pypy/module/_io/interp_stringio.py --- a/pypy/module/_io/interp_stringio.py +++ b/pypy/module/_io/interp_stringio.py @@ -1,6 +1,6 @@ from pypy.interpreter.typedef import ( TypeDef, generic_new_descr, GetSetProperty) -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError, operationerrfmt from pypy.module._io.interp_textio import W_TextIOBase, W_IncrementalNewlineDecoder from pypy.module._io.interp_iobase import convert_size @@ -12,7 +12,7 @@ self.buf = [] self.pos = 0 - @unwrap_spec(w_newline = (W_Root, 'space.wrap("\\n")')) + @unwrap_spec(w_newline = WrappedDefault("\n")) def descr_init(self, space, w_initvalue=None, w_newline=None): # In case __init__ is called multiple times self.buf = [] diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -2,7 +2,7 @@ from pypy.interpreter.typedef import ( TypeDef, GetSetProperty, interp_attrproperty_w, interp_attrproperty, generic_new_descr) -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import intmask, r_ulonglong, r_uint @@ -483,7 +483,7 @@ self._writeflush(space) space.call_method(self.w_buffer, "flush") - @unwrap_spec(w_pos = (W_Root, 'space.w_None')) + @unwrap_spec(w_pos = WrappedDefault(None)) def truncate_w(self, space, w_pos=None): self._check_init(space) diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -1,4 +1,4 @@ -from pypy.interpreter.gateway import unwrap_spec, W_Root +from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.module._socket.interp_socket import converted_error, W_RSocket from pypy.rlib import rsocket from pypy.rlib.rsocket import SocketError, INVALID_SOCKET @@ -61,7 +61,7 @@ raise converted_error(space, e) return common_wrapgethost(space, res) - at unwrap_spec(name=str, w_proto = (W_Root, 'space.w_None')) + at unwrap_spec(name=str, w_proto = WrappedDefault(None)) def getservbyname(space, name, w_proto): """getservbyname(servicename[, protocolname]) -> integer @@ -79,7 +79,7 @@ raise converted_error(space, e) return space.wrap(port) - at unwrap_spec(port=int, w_proto = (W_Root, 'space.w_None')) + at unwrap_spec(port=int, w_proto = WrappedDefault(None)) def getservbyport(space, port, w_proto): """getservbyport(port[, protocolname]) -> string diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, make_weakref_descr,\ interp_attrproperty -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.rlib.rarithmetic import intmask from pypy.rlib import rsocket from pypy.rlib.rsocket import RSocket, AF_INET, SOCK_STREAM @@ -160,8 +160,8 @@ except SocketError, e: raise converted_error(space, e) - @unwrap_spec(w_mode = (W_Root, 'space.wrap("r")'), - w_buffsize = (W_Root, 'space.wrap(-1)')) + @unwrap_spec(w_mode = WrappedDefault("r"), + w_buffsize = WrappedDefault(-1)) def makefile_w(self, space, w_mode=None, w_buffsize=None): """makefile([mode[, buffersize]]) -> file object diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -3,7 +3,7 @@ from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.typedef import make_weakref_descr -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import intmask from pypy.tool.pairtype import extendabletype @@ -387,15 +387,15 @@ return space.call_method(w_re, '_expand', space.wrap(self.srepat), space.wrap(self), w_template) - @unwrap_spec(w_groupnum = (W_Root, 'space.wrap(0)')) + @unwrap_spec(w_groupnum = WrappedDefault(0)) def start_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[0]) - @unwrap_spec(w_groupnum = (W_Root, 'space.wrap(0)')) + @unwrap_spec(w_groupnum = WrappedDefault(0)) def end_w(self, w_groupnum): return self.space.wrap(self.do_span(w_groupnum)[1]) - @unwrap_spec(w_groupnum = (W_Root, 'space.wrap(0)')) + @unwrap_spec(w_groupnum = WrappedDefault(0)) def span_w(self, w_groupnum): start, end = self.do_span(w_groupnum) return self.space.newtuple([self.space.wrap(start), diff --git a/pypy/module/_warnings/interp_warnings.py b/pypy/module/_warnings/interp_warnings.py --- a/pypy/module/_warnings/interp_warnings.py +++ b/pypy/module/_warnings/interp_warnings.py @@ -1,4 +1,4 @@ -from pypy.interpreter.gateway import unwrap_spec, W_Root +from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError def create_filter(space, w_category, action): @@ -343,9 +343,9 @@ w_source_line = space.getitem(w_source_list, space.wrap(lineno - 1)) return w_source_line - at unwrap_spec(lineno=int, w_module = (W_Root, 'space.w_None'), - w_registry = (W_Root, 'space.w_None'), - w_module_globals = (W_Root, 'space.w_None')) + at unwrap_spec(lineno=int, w_module = WrappedDefault(None), + w_registry = WrappedDefault(None), + w_module_globals = WrappedDefault(None)) def warn_explicit(space, w_message, w_category, w_filename, lineno, w_module=None, w_registry=None, w_module_globals=None): diff --git a/pypy/module/marshal/interp_marshal.py b/pypy/module/marshal/interp_marshal.py --- a/pypy/module/marshal/interp_marshal.py +++ b/pypy/module/marshal/interp_marshal.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import W_Root, unwrap_spec +from pypy.interpreter.gateway import WrappedDefault, unwrap_spec from pypy.rlib.rarithmetic import intmask from pypy.rlib import rstackovf from pypy.module._file.interp_file import W_File @@ -7,7 +7,7 @@ Py_MARSHAL_VERSION = 2 - at unwrap_spec(w_version = (W_Root, 'space.wrap(%d)' % Py_MARSHAL_VERSION)) + at unwrap_spec(w_version = WrappedDefault(Py_MARSHAL_VERSION)) def dump(space, w_data, w_f, w_version): """Write the 'data' object into the open file 'f'.""" # special case real files for performance @@ -25,7 +25,7 @@ finally: writer.finished() - at unwrap_spec(w_version = (W_Root, 'space.wrap(%d)' % Py_MARSHAL_VERSION)) + at unwrap_spec(w_version = WrappedDefault(Py_MARSHAL_VERSION)) def dumps(space, w_data, w_version): """Return the string that would have been written to a file by dump(data, file).""" 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 @@ -1,7 +1,7 @@ from pypy.interpreter.error import operationerrfmt, OperationError from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\ ArrayArgumentException from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes @@ -478,12 +478,12 @@ return loop.multidim_dot(space, self, other, result, dtype, other_critical_dim) - @unwrap_spec(w_axis = (W_Root, 'space.w_None')) + @unwrap_spec(w_axis = WrappedDefault(None)) def descr_var(self, space, w_axis): return get_appbridge_cache(space).call_method(space, '_var', self, w_axis) - @unwrap_spec(w_axis = (W_Root, 'space.w_None')) + @unwrap_spec(w_axis = WrappedDefault(None)) def descr_std(self, space, w_axis): return get_appbridge_cache(space).call_method(space, '_std', self, w_axis) diff --git a/pypy/module/micronumpy/interp_support.py b/pypy/module/micronumpy/interp_support.py --- a/pypy/module/micronumpy/interp_support.py +++ b/pypy/module/micronumpy/interp_support.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import unwrap_spec, is_none, W_Root +from pypy.interpreter.gateway import unwrap_spec, is_none, WrappedDefault from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy import interp_dtype, loop from pypy.objspace.std.strutil import strip_spaces @@ -75,7 +75,7 @@ loop.fromstring_loop(a, dtype, itemsize, s) return space.wrap(a) - at unwrap_spec(s=str, count=int, sep=str, w_dtype=(W_Root, 'space.w_None')) + at unwrap_spec(s=str, count=int, sep=str, w_dtype=WrappedDefault(None)) def fromstring(space, s, w_dtype=None, count=-1, sep=''): dtype = space.interp_w(interp_dtype.W_Dtype, space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype) diff --git a/pypy/module/select/interp_kqueue.py b/pypy/module/select/interp_kqueue.py --- a/pypy/module/select/interp_kqueue.py +++ b/pypy/module/select/interp_kqueue.py @@ -1,6 +1,6 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt, exception_from_errno -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.typedef import TypeDef, generic_new_descr, GetSetProperty from pypy.rlib._rsocket_rffi import socketclose from pypy.rlib.rarithmetic import r_uint @@ -143,7 +143,7 @@ def descr_close(self, space): self.close() - @unwrap_spec(max_events=int, w_timeout = (W_Root, 'space.w_None')) + @unwrap_spec(max_events=int, w_timeout = WrappedDefault(None)) def descr_control(self, space, w_changelist, max_events, w_timeout): self.check_closed(space) diff --git a/pypy/module/select/interp_select.py b/pypy/module/select/interp_select.py --- a/pypy/module/select/interp_select.py +++ b/pypy/module/select/interp_select.py @@ -1,6 +1,6 @@ from pypy.interpreter.typedef import TypeDef from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError, wrap_oserror from pypy.rlib import rpoll import errno @@ -41,7 +41,7 @@ raise OperationError(space.w_KeyError, space.wrap(fd)) # XXX should this maybe be w_fd? - @unwrap_spec(w_timeout = (W_Root, 'space.w_None')) + @unwrap_spec(w_timeout = WrappedDefault(None)) def poll(self, space, w_timeout): if space.is_w(w_timeout, space.w_None): timeout = -1 @@ -101,7 +101,7 @@ reslist_w.append(list_w[i]) - at unwrap_spec(w_timeout = (W_Root, 'space.w_None')) + at unwrap_spec(w_timeout = WrappedDefault(None)) def select(space, w_iwtd, w_owtd, w_ewtd, w_timeout): """Wait until one or more file descriptors are ready for some kind of I/O. The first three arguments are sequences of file descriptors to be waited for: diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -5,7 +5,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import unwrap_spec, W_Root +from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.rlib import jit from pypy.rlib.runicode import MAXUNICODE @@ -20,7 +20,7 @@ "trying to change the builtin-in module %r" % (name,)) space.setitem(w_modules, space.wrap(name), w_module) - at unwrap_spec(w_depth = (W_Root, 'space.wrap(0)')) + at unwrap_spec(w_depth = WrappedDefault(0)) def _getframe(space, w_depth): """Return a frame object from the call stack. If optional integer depth is given, return the frame object that many calls below the top of the stack. diff --git a/pypy/objspace/std/booltype.py b/pypy/objspace/std/booltype.py --- a/pypy/objspace/std/booltype.py +++ b/pypy/objspace/std/booltype.py @@ -1,8 +1,8 @@ -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +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 = (W_Root, 'space.w_False')) + 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): diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py --- a/pypy/objspace/std/complextype.py +++ b/pypy/objspace/std/complextype.py @@ -1,4 +1,4 @@ -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.register_all import register_all from pypy.objspace.std.strutil import string_to_float, ParseStringError @@ -115,7 +115,7 @@ return realpart, imagpart - at unwrap_spec(w_real = (W_Root, 'space.wrap("0.0")')) + at unwrap_spec(w_real = WrappedDefault(0.0)) def descr__new__(space, w_complextype, w_real, w_imag=None): from pypy.objspace.std.complexobject import W_ComplexObject diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py --- a/pypy/objspace/std/floattype.py +++ b/pypy/objspace/std/floattype.py @@ -3,7 +3,7 @@ from pypy.rlib.unroll import unrolling_iterable from pypy.rlib import rfloat, rarithmetic from pypy.interpreter import typedef -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError from pypy.objspace.std.register_all import register_all @@ -22,7 +22,7 @@ register_all(vars(), globals()) - at unwrap_spec(w_x = (W_Root, 'space.wrap(0.0)')) + at unwrap_spec(w_x = WrappedDefault(0.0)) def descr__new__(space, w_floattype, w_x): from pypy.objspace.std.floatobject import W_FloatObject w_value = w_x # 'x' is the keyword argument name in CPython diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py --- a/pypy/objspace/std/inttype.py +++ b/pypy/objspace/std/inttype.py @@ -1,5 +1,5 @@ from pypy.interpreter import typedef -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.buffer import Buffer from pypy.objspace.std.register_all import register_all @@ -89,7 +89,7 @@ from pypy.objspace.std.longobject import newlong return newlong(space, bigint) - at unwrap_spec(w_x = (W_Root, 'space.wrap(0)')) + 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 diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py --- a/pypy/objspace/std/longtype.py +++ b/pypy/objspace/std/longtype.py @@ -1,6 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter import typedef -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.strutil import string_to_bigint, ParseStringError @@ -9,7 +9,7 @@ return space.long(w_int) - at unwrap_spec(w_x = (W_Root, 'space.wrap(0)')) + at unwrap_spec(w_x = WrappedDefault(0)) def descr__new__(space, w_longtype, w_x, w_base=None): from pypy.objspace.std.longobject import W_LongObject from pypy.rlib.rbigint import rbigint diff --git a/pypy/objspace/std/stdtypedef.py b/pypy/objspace/std/stdtypedef.py --- a/pypy/objspace/std/stdtypedef.py +++ b/pypy/objspace/std/stdtypedef.py @@ -189,8 +189,7 @@ unwrap_spec_kwds = {} for app_default in app_defaults: name = wrapper_signature[i] - unwrap_spec_kwds[name] = (gateway.W_Root, - 'space.wrap(%r)' % (app_default,)) + unwrap_spec_kwds[name] = gateway.WrappedDefault(app_default) i += 1 wrapper_signature.insert(0, wrapper_signature.pop(selfindex)) diff --git a/pypy/objspace/std/stringtype.py b/pypy/objspace/std/stringtype.py --- a/pypy/objspace/std/stringtype.py +++ b/pypy/objspace/std/stringtype.py @@ -1,4 +1,4 @@ -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.basestringtype import basestring_typedef from pypy.objspace.std.register_all import register_all @@ -290,7 +290,7 @@ # ____________________________________________________________ - at unwrap_spec(w_object = (W_Root, 'space.wrap("")')) + at unwrap_spec(w_object = WrappedDefault("")) def descr__new__(space, w_stringtype, w_object): # NB. the default value of w_object is really a *wrapped* empty string: # there is gateway magic at work diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.register_all import register_all from pypy.objspace.std.basestringtype import basestring_typedef @@ -335,7 +335,7 @@ w_encoding, w_errors) - at unwrap_spec(w_string = (W_Root, 'space.wrap("")')) + at unwrap_spec(w_string = WrappedDefault("")) def descr_new_(space, w_unicodetype, w_string, w_encoding=None, w_errors=None): # NB. the default value of w_obj is really a *wrapped* empty string: # there is gateway magic at work From noreply at buildbot.pypy.org Fri Oct 12 10:32:02 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 10:32:02 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix some modules Message-ID: <20121012083202.420AD1C0182@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58023:4ed34f124429 Date: 2012-10-12 10:19 +0200 http://bitbucket.org/pypy/pypy/changeset/4ed34f124429/ Log: fix some modules diff --git a/pypy/module/_multiprocessing/interp_connection.py b/pypy/module/_multiprocessing/interp_connection.py --- a/pypy/module/_multiprocessing/interp_connection.py +++ b/pypy/module/_multiprocessing/interp_connection.py @@ -1,7 +1,7 @@ from __future__ import with_statement from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import ( OperationError, wrap_oserror, operationerrfmt) from pypy.rpython.lltypesystem import rffi, lltype @@ -163,7 +163,8 @@ return w_unpickled - def poll(self, space, w_timeout=0.0): + @unwrap_spec(w_timeout=WrappedDefault(0.0)) + def poll(self, space, w_timeout): self._check_readable(space) if space.is_w(w_timeout, space.w_None): timeout = -1.0 # block forever 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 @@ -318,7 +318,7 @@ def semlock_acquire(self, space, block, w_timeout): if not block: deadline = lltype.nullptr(TIMESPECP.TO) - elif space.is_w(w_timeout, space.w_None): + elif space.is_none(w_timeout): deadline = lltype.nullptr(TIMESPECP.TO) else: timeout = space.float_w(w_timeout) From noreply at buildbot.pypy.org Fri Oct 12 10:32:03 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 10:32:03 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix fix fix Message-ID: <20121012083203.9FD671C0182@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58024:327fa32d5cc9 Date: 2012-10-12 10:31 +0200 http://bitbucket.org/pypy/pypy/changeset/327fa32d5cc9/ Log: fix fix fix diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -856,7 +856,7 @@ if name.startswith('w_'): assert defaultval is None, ( "%s: default value for '%s' can only be None; " - "use unwrap_spec(...=(W_Root, 'default_expr'))" % ( + "use unwrap_spec(...=WrappedDefault(default))" % ( self._code.identifier, name)) defs_w.append(None) else: diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -285,7 +285,8 @@ return w_item, n - at unwrap_spec(flags=int, groups=int) + at unwrap_spec(flags=int, groups=int, w_groupindex=WrappedDefault(None), + w_indexgroup=WrappedDefault(None)) def SRE_Pattern__new__(space, w_subtype, w_pattern, flags, w_code, groups=0, w_groupindex=None, w_indexgroup=None): n = space.len_w(w_code) @@ -358,11 +359,13 @@ results[i] = slice_w(space, ctx, start, end, space.w_None) return space.newtuple(results) + @unwrap_spec(w_default=WrappedDefault(None)) def groups_w(self, w_default=None): fmarks = self.flatten_marks() num_groups = self.srepat.num_groups return allgroups_w(self.space, self.ctx, fmarks, num_groups, w_default) + @unwrap_spec(w_default=WrappedDefault(None)) def groupdict_w(self, w_default=None): space = self.space w_dict = space.newdict() diff --git a/pypy/module/_warnings/interp_warnings.py b/pypy/module/_warnings/interp_warnings.py --- a/pypy/module/_warnings/interp_warnings.py +++ b/pypy/module/_warnings/interp_warnings.py @@ -57,7 +57,7 @@ # Get category if space.isinstance_w(w_message, space.w_Warning): w_category = space.type(w_message) - elif space.is_w(w_category, space.w_None): + elif space.is_none(w_category): w_category = space.w_UserWarning # Validate category 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 @@ -1,7 +1,7 @@ from pypy.rpython.tool import rffi_platform as platform from pypy.rpython.lltypesystem import rffi, lltype from pypy.interpreter.error import OperationError, wrap_oserror -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.rlib import rposix from pypy.translator.tool.cbuild import ExternalCompilationInfo import sys @@ -89,8 +89,8 @@ l.c_l_type = rffi.cast(rffi.SHORT, l_type) return l - at unwrap_spec(op=int) -def fcntl(space, w_fd, op, w_arg=0): + at unwrap_spec(op=int, w_arg=WrappedDefault(0)) +def fcntl(space, w_fd, op, w_arg): """fcntl(fd, op, [arg]) Perform the requested operation on file descriptor fd. The operation @@ -206,8 +206,8 @@ finally: lltype.free(l, flavor='raw') - at unwrap_spec(op=int, mutate_flag=int) -def ioctl(space, w_fd, op, w_arg=0, mutate_flag=-1): + at unwrap_spec(op=int, mutate_flag=int, w_arg=WrappedDefault(0)) +def ioctl(space, w_fd, op, w_arg, mutate_flag=-1): """ioctl(fd, opt[, arg[, mutate_flag]]) Perform the requested operation on file descriptor fd. The operation is diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, make_weakref_descr -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault class W_Count(Wrappable): @@ -49,7 +49,8 @@ raise OperationError(space.w_TypeError, space.wrap("expected a number")) -def W_Count___new__(space, w_subtype, w_start=0, w_step=1): + at unwrap_spec(w_start=WrappedDefault(0), w_step=WrappedDefault(1)) +def W_Count___new__(space, w_subtype, w_start, w_step): check_number(space, w_start) check_number(space, w_step) r = space.allocate_instance(W_Count, w_subtype) From noreply at buildbot.pypy.org Fri Oct 12 13:48:06 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 12 Oct 2012 13:48:06 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: make this code more beautiful Message-ID: <20121012114806.9ED7F1C0035@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r58025:056e20ad5589 Date: 2012-10-12 04:47 -0700 http://bitbucket.org/pypy/pypy/changeset/056e20ad5589/ Log: make this code more beautiful diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -876,8 +876,7 @@ if isinstance(spec, tuple) and spec[0] is W_Root: assert False, "use WrappedDefault" if isinstance(spec, WrappedDefault): - w_default = eval('space.wrap(%r)' % (spec.default_value,), - {'space': space}) + w_default = space.wrap(spec.default_value) assert isinstance(w_default, W_Root) assert argname.startswith('w_') argname = argname[2:] From noreply at buildbot.pypy.org Fri Oct 12 14:46:02 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 14:46:02 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix math Message-ID: <20121012124602.8F3DE1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58026:b078bdbf485e Date: 2012-10-12 13:37 +0200 http://bitbucket.org/pypy/pypy/changeset/b078bdbf485e/ Log: fix math diff --git a/pypy/module/math/test/test_translated.py b/pypy/module/math/test/test_translated.py --- a/pypy/module/math/test/test_translated.py +++ b/pypy/module/math/test/test_translated.py @@ -1,10 +1,15 @@ -import py from pypy.translator.c.test.test_genc import compile from pypy.module.math.interp_math import _gamma def test_gamma_overflow(): - f = compile(_gamma, [float]) + def wrapper(arg): + try: + return _gamma(arg) + except OverflowError: + return -42 + + f = compile(wrapper, [float]) assert f(10.0) == 362880.0 - py.test.raises(OverflowError, f, 1720.0) - py.test.raises(OverflowError, f, 172.0) + assert f(1720.0) == -42 + assert f(172.0) == -42 From noreply at buildbot.pypy.org Fri Oct 12 14:46:03 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 14:46:03 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: (arigo, fijal) Message-ID: <20121012124603.E065D1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58027:c4813b21659f Date: 2012-10-12 14:44 +0200 http://bitbucket.org/pypy/pypy/changeset/c4813b21659f/ Log: (arigo, fijal) Rename _freeze_ returning False to _cleanup_, now we can have hasattr(x, '_freeze_') without strange hacks to check for frozen PBCs. diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -148,7 +148,6 @@ self.descs = {} # map Python objects to their XxxDesc wrappers self.methoddescs = {} # map (funcdesc, classdef) to the MethodDesc self.classdefs = [] # list of all ClassDefs - self.pbctypes = {} self.seen_mutable = {} self.listdefs = {} # map position_keys to ListDefs self.dictdefs = {} # map position_keys to DictDefs @@ -461,7 +460,8 @@ result = None if result is None: result = SomePBC([self.getdesc(x)]) - elif hasattr(x, '_freeze_') and x._freeze_(): + elif hasattr(x, '_freeze_'): + assert x._freeze_() is True # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method # returns True, the instance is considered immutable and becomes @@ -469,6 +469,8 @@ result = SomePBC([self.getdesc(x)]) elif hasattr(x, '__class__') \ and x.__class__.__module__ != '__builtin__': + if hasattr(x, '_cleanup_'): + x._cleanup_() self.see_mutable(x) result = SomeInstance(self.getuniqueclassdef(x.__class__)) elif x is None: @@ -502,8 +504,10 @@ elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) - elif (hasattr(pyobj.im_self, '_freeze_') and - pyobj.im_self._freeze_()): # method of frozen + if hasattr(pyobj.im_self, '_cleanup_'): + pyobj.im_self._cleanup_() + if hasattr(pyobj.im_self, '_freeze_'): # method of frozen + assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc(self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc @@ -522,9 +526,9 @@ name) else: # must be a frozen pre-built constant, but let's check - try: - assert pyobj._freeze_() - except AttributeError: + if hasattr(pyobj, '_freeze_'): + assert pyobj._freeze_() is True + else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: @@ -544,11 +548,7 @@ return False def getfrozen(self, pyobj): - result = description.FrozenDesc(self, pyobj) - cls = result.knowntype - if cls not in self.pbctypes: - self.pbctypes[cls] = True - return result + return description.FrozenDesc(self, pyobj) def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, flags={}): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -189,7 +189,8 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if isinstance(s_obj, SomeInstance) and isinstance(s_type, SomePBC): + + if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -83,11 +83,11 @@ elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) - elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes: + elif t is type: + return SomeType() + elif bookkeeper and not hasattr(t, '_freeze_'): classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) - elif t is type: - return SomeType() else: raise AssertionError("annotationoftype(%r)" % (t,)) diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -763,19 +763,25 @@ def test_freeze_protocol(self): class Stuff: - def __init__(self, flag): + def __init__(self): self.called = False - self.flag = flag def _freeze_(self): self.called = True - return self.flag - myobj = Stuff(True) + return True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - myobj = Stuff(False) + + def test_cleanup_protocol(self): + class Stuff: + def __init__(self): + self.called = False + def _cleanup_(self): + self.called = True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -244,7 +244,7 @@ # delicate _all = {'': None} - def _freeze_(self): + def _cleanup_(self): from pypy.interpreter.gateway import BuiltinCode if isinstance(self.code, BuiltinCode): # we have been seen by other means so rtyping should not choke diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -121,14 +121,11 @@ self.w_initialdict = space.call_method(self.w_dict, 'items') return self.w_dict - def _freeze_(self): + def _cleanup_(self): self.getdict(self.space) self.w_initialdict = None self.startup_called = False self._frozen = True - # hint for the annotator: Modules can hold state, so they are - # not constant - return False def buildloaders(cls): """ NOT_RPYTHON """ diff --git a/pypy/interpreter/test/test_appinterp.py b/pypy/interpreter/test/test_appinterp.py --- a/pypy/interpreter/test/test_appinterp.py +++ b/pypy/interpreter/test/test_appinterp.py @@ -172,8 +172,8 @@ # Uncomment this line for a workaround # space.getattr(w_ssl, space.wrap('SSLError')) - w_socket._freeze_() + w_socket._cleanup_() assert w_socket.startup_called == False - w_ssl._freeze_() # w_ssl.appleveldefs['SSLError'] imports _socket + w_ssl._cleanup_() # w_ssl.appleveldefs['SSLError'] imports _socket assert w_socket.startup_called == False diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -121,9 +121,8 @@ self._future_values = [] self._descrs = {} - def _freeze_(self): + def _cleanup_(self): assert self.translate_support_code - return False def getdescr(self, ofs, typeinfo='?', extrainfo=None, name=None, arg_types=None, count_fields_if_immut=-1, ffi_flags=0, width=-1): diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -50,11 +50,10 @@ self.setup_descrs(asm.descrs) self.metainterp_sd = metainterp_sd self.num_interpreters = 0 - self._freeze_() + self._cleanup_() - def _freeze_(self): + def _cleanup_(self): self.blackholeinterps = [] - return False def setup_insns(self, insns): assert len(insns) <= 256, "too many instructions!" diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -69,9 +69,8 @@ self.unicodedata_handler = UnicodeData_Handler(space, w_getcode) return self.unicodedata_handler - def _freeze_(self): + def _cleanup_(self): assert not self.codec_search_path - return False def register_codec(space, w_search_function): """register(search_function) diff --git a/pypy/module/_file/interp_stream.py b/pypy/module/_file/interp_stream.py --- a/pypy/module/_file/interp_stream.py +++ b/pypy/module/_file/interp_stream.py @@ -58,12 +58,11 @@ self.space.wrap("stream lock is not held")) self._release_lock() - def _freeze_(self): + def _cleanup_(self): # remove the lock object, which will be created again as needed at # run-time. self.slock = None assert self.slockowner is None - return False def stream_read(self, n): """ 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 @@ -196,7 +196,7 @@ def __init__(self, space): self.counter = 0 - def _freeze_(self): + def _cleanup_(self): self.counter = 0 def getCount(self): diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py --- a/pypy/module/cpyext/pyobject.py +++ b/pypy/module/cpyext/pyobject.py @@ -150,10 +150,9 @@ # For tests self.non_heaptypes_w = [] - def _freeze_(self): + def _cleanup_(self): assert self.borrow_mapping == {None: {}} self.py_objects_r2w.clear() # is not valid anymore after translation - return False def init_r2w_from_w2r(self): """Rebuilds the dict py_objects_r2w on startup""" 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 @@ -121,9 +121,8 @@ PyCode__initialize(self) self.jit_cells = {} - def _freeze_(self): + def _cleanup_(self): self.jit_cells = {} - return False # ____________________________________________________________ # 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 @@ -87,7 +87,7 @@ def __init__(self, space): self.main_thread = 0 - def _freeze_(self): + def _cleanup_(self): self.main_thread = 0 globalState.init() diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py --- a/pypy/module/thread/gil.py +++ b/pypy/module/thread/gil.py @@ -62,10 +62,9 @@ class SpaceState: - def _freeze_(self): + def _cleanup_(self): self.action_after_thread_switch = None # ^^^ set by AsyncAction.fire_after_thread_switch() - return False def after_thread_switch(self): # this is support logic for the signal module, to help it deliver @@ -76,7 +75,7 @@ action.fire() spacestate = SpaceState() -spacestate._freeze_() +spacestate._cleanup_() # Fragile code below. We have to preserve the C-level errno manually... 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 @@ -75,9 +75,8 @@ bootstrapper.w_callable = None bootstrapper.args = None - def _freeze_(self): + def _cleanup_(self): self.reinit() - return False def bootstrap(): # Note that when this runs, we already hold the GIL. This is ensured diff --git a/pypy/module/thread/test/test_ll_thread.py b/pypy/module/thread/test/test_ll_thread.py --- a/pypy/module/thread/test/test_ll_thread.py +++ b/pypy/module/thread/test/test_ll_thread.py @@ -9,7 +9,7 @@ # In this module, we assume that ll_thread.start_new_thread() is not # providing us with a GIL equivalent, except in test_gc_locking # which installs its own aroundstate. - rffi.aroundstate._freeze_() + rffi.aroundstate._cleanup_() def test_lock(): l = allocate_lock() @@ -149,7 +149,7 @@ try: fn = self.getcompiled(f, []) finally: - rffi.aroundstate._freeze_() + rffi.aroundstate._cleanup_() answers = fn() assert answers == expected diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -9,14 +9,13 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} - self._freeze_() + self._cleanup_() - def _freeze_(self): + def _cleanup_(self): self._valuedict.clear() self._mainthreadident = 0 self._mostrecentkey = 0 # fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case - return False def getvalue(self): ident = thread.get_ident() diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -152,8 +152,10 @@ if (not isinstance(to_check, (type, types.ClassType, types.ModuleType)) and # classes/types/modules are assumed immutable hasattr(to_check, '__class__') and to_check.__class__.__module__ != '__builtin__'): - frozen = hasattr(to_check, '_freeze_') and to_check._freeze_() - if not frozen: + frozen = hasattr(to_check, '_freeze_') + if frozen: + assert to_check._freeze_() is True + else: # cannot count on it not mutating at runtime! raise UnwrapException return obj 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 @@ -318,7 +318,7 @@ def deldictvalue(w_self, space, key): if w_self.lazyloaders: - w_self._freeze_() # force un-lazification + w_self._cleanup_() # force un-lazification if (not space.config.objspace.std.mutable_builtintypes and not w_self.is_heaptype()): msg = "can't delete attributes on type object '%s'" @@ -457,19 +457,18 @@ w_self.name, w_subtype.name, w_subtype.name) return w_subtype - def _freeze_(w_self): + def _cleanup_(w_self): "NOT_RPYTHON. Forces the lazy attributes to be computed." if 'lazyloaders' in w_self.__dict__: for attr in w_self.lazyloaders.keys(): w_self.getdictvalue(w_self.space, attr) del w_self.lazyloaders - return False def getdict(w_self, space): # returning a dict-proxy! from pypy.objspace.std.dictproxyobject import DictProxyStrategy from pypy.objspace.std.dictmultiobject import W_DictMultiObject if w_self.lazyloaders: - w_self._freeze_() # force un-lazification + w_self._cleanup_() # force un-lazification strategy = space.fromcache(DictProxyStrategy) storage = strategy.erase(w_self) return W_DictMultiObject(space, strategy, storage) diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -502,7 +502,7 @@ elif (hasattr(value, '__class__') and value.__class__.__module__ != '__builtin__'): if hasattr(value, '_freeze_'): - continue # value._freeze_() is better not called + kind = "1:INT" elif getattr(value, '_alloc_flavor_', 'gc') == 'gc': kind = '2:REF' else: diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py --- a/pypy/rlib/rgc.py +++ b/pypy/rlib/rgc.py @@ -254,12 +254,9 @@ return False # don't keep any type if isinstance(x, (list, dict, str)): return True # keep lists and dicts and strings - try: - return not x._freeze_() # don't keep any frozen object - except AttributeError: - return type(x).__module__ != '__builtin__' # keep non-builtins - except Exception: - return False # don't keep objects whose _freeze_() method explodes + if hasattr(x, '_freeze_'): + return False + return type(x).__module__ != '__builtin__' # keep non-builtins def add_memory_pressure(estimate): """Add memory pressure for OpaquePtrs.""" diff --git a/pypy/rlib/rope.py b/pypy/rlib/rope.py --- a/pypy/rlib/rope.py +++ b/pypy/rlib/rope.py @@ -131,7 +131,7 @@ def __add__(self, other): return concatenate(self, other) - def _freeze_(self): + def _cleanup_(self): self.additional_info() class LiteralNode(StringNode): diff --git a/pypy/rlib/rstacklet.py b/pypy/rlib/rstacklet.py --- a/pypy/rlib/rstacklet.py +++ b/pypy/rlib/rstacklet.py @@ -100,9 +100,8 @@ def __init__(self): self.sthread = None self.active = [] - def _freeze_(self): + def _cleanup_(self): self.__init__() - return False def add(self, h): if not self.sthread.is_empty_handle(h): if h == self.sthread.get_null_handle(): diff --git a/pypy/rlib/timer.py b/pypy/rlib/timer.py --- a/pypy/rlib/timer.py +++ b/pypy/rlib/timer.py @@ -18,7 +18,7 @@ self.levels = {} self.timingorder = [] - def _freeze_(self): + def _cleanup_(self): self.reset() def start(self, timer): diff --git a/pypy/rpython/lltypesystem/llarena.py b/pypy/rpython/lltypesystem/llarena.py --- a/pypy/rpython/lltypesystem/llarena.py +++ b/pypy/rpython/lltypesystem/llarena.py @@ -433,7 +433,8 @@ class LinuxPageSize: def __init__(self): self.pagesize = 0 - _freeze_ = __init__ + def _cleanup_(self): + self.pagesize = 0 linuxpagesize = LinuxPageSize() def clear_large_memory_chunk(baseaddr, size): diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py --- a/pypy/rpython/lltypesystem/rffi.py +++ b/pypy/rpython/lltypesystem/rffi.py @@ -319,19 +319,18 @@ AroundFnPtr = lltype.Ptr(lltype.FuncType([], lltype.Void)) class AroundState: - def _freeze_(self): + def _cleanup_(self): self.before = None # or a regular RPython function self.after = None # or a regular RPython function - return False aroundstate = AroundState() -aroundstate._freeze_() +aroundstate._cleanup_() class StackCounter: - def _freeze_(self): + def _cleanup_(self): self.stacks_counter = 1 # number of "stack pieces": callbacks - return False # and threads increase it by one + # and threads increase it by one stackcounter = StackCounter() -stackcounter._freeze_() +stackcounter._cleanup_() def llexternal_use_eci(compilation_info): """Return a dummy function that, if called in a RPython program, From noreply at buildbot.pypy.org Fri Oct 12 14:46:05 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 14:46:05 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121012124605.1C6D11C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58028:cf588d1cd5f3 Date: 2012-10-12 14:45 +0200 http://bitbucket.org/pypy/pypy/changeset/cf588d1cd5f3/ Log: merge diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -876,8 +876,7 @@ if isinstance(spec, tuple) and spec[0] is W_Root: assert False, "use WrappedDefault" if isinstance(spec, WrappedDefault): - w_default = eval('space.wrap(%r)' % (spec.default_value,), - {'space': space}) + w_default = space.wrap(spec.default_value) assert isinstance(w_default, W_Root) assert argname.startswith('w_') argname = argname[2:] From noreply at buildbot.pypy.org Fri Oct 12 14:56:28 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 12 Oct 2012 14:56:28 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Make pyexpact use the new API Message-ID: <20121012125628.A8D6E1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r58029:da5dc7152de3 Date: 2012-10-12 05:56 -0700 http://bitbucket.org/pypy/pypy/changeset/da5dc7152de3/ Log: Make pyexpact use the new API diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -1,6 +1,6 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError from pypy.rlib import rgc from pypy.rpython.lltypesystem import rffi, lltype @@ -444,7 +444,8 @@ was successful.""" XML_SetParamEntityParsing(self.itself, flag) - def UseForeignDTD(self, space, w_flag=True): + @unwrap_spec(w_flag=WrappedDefault(True)) + def UseForeignDTD(self, space, w_flag): """UseForeignDTD([flag]) Allows the application to provide an artificial external subset if one is not specified as part of the document instance. This readily allows the From noreply at buildbot.pypy.org Fri Oct 12 15:30:45 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 15:30:45 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: ootype fix Message-ID: <20121012133045.D6AA61C0FE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58030:a0a3d5a831b2 Date: 2012-10-12 15:30 +0200 http://bitbucket.org/pypy/pypy/changeset/a0a3d5a831b2/ Log: ootype fix diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -145,8 +145,12 @@ assert isinstance(exc, LLException) klass, inst = exc.args[0], exc.args[1] for cls in enumerate_exceptions_top_down(): - if "".join(klass.name).rstrip("\0") == cls.__name__: - return cls + if hasattr(klass, 'name'): # lltype + if "".join(klass.name).rstrip("\0") == cls.__name__: + return cls + else: # ootype + if klass._INSTANCE._name.split('.')[-1] == cls.__name__: + return cls raise ValueError("couldn't match exception, maybe it" " has RPython attributes like OSError?") From noreply at buildbot.pypy.org Fri Oct 12 15:32:51 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 15:32:51 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix micornumpy Message-ID: <20121012133251.CE4F61C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58031:c4839889e18f Date: 2012-10-12 14:48 +0200 http://bitbucket.org/pypy/pypy/changeset/c4839889e18f/ Log: fix micornumpy 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 @@ -65,6 +65,9 @@ def _freeze_(self): return True + def is_none(self, w_obj): + return w_obj is None or w_obj is self.w_None + def issequence_w(self, w_obj): return isinstance(w_obj, ListObject) or isinstance(w_obj, W_NDimArray) 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 @@ -2,7 +2,7 @@ import sys from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import interp2app, unwrap_spec, is_none +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import (TypeDef, GetSetProperty, interp_attrproperty, interp_attrproperty_w) from pypy.module.micronumpy import types, interp_boxes @@ -19,7 +19,7 @@ UNICODELTR = 'U' def decode_w_dtype(space, w_dtype): - if is_none(space, w_dtype): + if space.is_none(w_dtype): return None return space.interp_w(W_Dtype, space.call_function(space.gettypefor(W_Dtype), w_dtype)) @@ -208,7 +208,7 @@ def descr__new__(space, w_subtype, w_dtype): cache = get_dtype_cache(space) - if is_none(space, w_dtype): + if space.is_none(w_dtype): return cache.w_float64dtype elif space.isinstance_w(w_dtype, w_subtype): return w_dtype diff --git a/pypy/module/micronumpy/interp_support.py b/pypy/module/micronumpy/interp_support.py --- a/pypy/module/micronumpy/interp_support.py +++ b/pypy/module/micronumpy/interp_support.py @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.gateway import unwrap_spec, is_none, WrappedDefault +from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy import interp_dtype, loop from pypy.objspace.std.strutil import strip_spaces @@ -87,7 +87,7 @@ return _fromstring_text(space, s, count, sep, length, dtype) def unwrap_axis_arg(space, shapelen, w_axis): - if is_none(space, w_axis): + if space.is_none(w_axis): axis = maxint else: axis = space.int_w(w_axis) From noreply at buildbot.pypy.org Fri Oct 12 15:32:53 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 15:32:53 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix pyexpat Message-ID: <20121012133253.1338E1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58032:4f690387ead8 Date: 2012-10-12 14:50 +0200 http://bitbucket.org/pypy/pypy/changeset/4f690387ead8/ Log: fix pyexpat diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -1,6 +1,6 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.gateway import interp2app, unwrap_spec, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.interpreter.error import OperationError from pypy.rlib import rgc from pypy.rpython.lltypesystem import rffi, lltype @@ -444,7 +444,8 @@ was successful.""" XML_SetParamEntityParsing(self.itself, flag) - def UseForeignDTD(self, space, w_flag=True): + @unwrap_spec(w_flag=WrappedDefault(True)) + def UseForeignDTD(self, space, w_flag): """UseForeignDTD([flag]) Allows the application to provide an artificial external subset if one is not specified as part of the document instance. This readily allows the From noreply at buildbot.pypy.org Fri Oct 12 15:32:54 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 15:32:54 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: revert the jit.py modification Message-ID: <20121012133254.3937B1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58033:a0e46ecd2134 Date: 2012-10-12 14:54 +0200 http://bitbucket.org/pypy/pypy/changeset/a0e46ecd2134/ Log: revert the jit.py modification diff --git a/pypy/module/pypyjit/interp_resop.py b/pypy/module/pypyjit/interp_resop.py --- a/pypy/module/pypyjit/interp_resop.py +++ b/pypy/module/pypyjit/interp_resop.py @@ -2,7 +2,7 @@ from pypy.interpreter.typedef import (TypeDef, GetSetProperty, interp_attrproperty, interp_attrproperty_w) from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import unwrap_spec, interp2app, NoneNotWrapped +from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.pycode import PyCode from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import lltype, llmemory diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -502,7 +502,7 @@ elif (hasattr(value, '__class__') and value.__class__.__module__ != '__builtin__'): if hasattr(value, '_freeze_'): - kind = "1:INT" + continue # value._freeze_() is better not called elif getattr(value, '_alloc_flavor_', 'gc') == 'gc': kind = '2:REF' else: From noreply at buildbot.pypy.org Fri Oct 12 15:32:55 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 15:32:55 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix someobject in jit Message-ID: <20121012133255.5BA6E1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58034:9adfe97b9a6a Date: 2012-10-12 15:04 +0200 http://bitbucket.org/pypy/pypy/changeset/9adfe97b9a6a/ Log: fix someobject in jit diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -770,11 +770,11 @@ def compute_result_annotation(self, s_driver, s_name, s_value): from pypy.annotation import model as annmodel assert s_name.is_constant() - if annmodel.s_None.contains(s_value): - if s_name.const == 'enable_opts': - assert annmodel.SomeString(can_be_None=True).contains(s_value) - else: - assert annmodel.SomeInteger().contains(s_value) + if s_name.const == 'enable_opts': + assert annmodel.SomeString(can_be_None=True).contains(s_value) + else: + assert (s_value == annmodel.s_None or + annmodel.SomeInteger().contains(s_value)) return annmodel.s_None def specialize_call(self, hop): From noreply at buildbot.pypy.org Fri Oct 12 15:32:56 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 15:32:56 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix tests Message-ID: <20121012133256.844301C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58035:66fc020fbd16 Date: 2012-10-12 15:10 +0200 http://bitbucket.org/pypy/pypy/changeset/66fc020fbd16/ Log: fix tests diff --git a/pypy/rlib/parsing/test/test_tree.py b/pypy/rlib/parsing/test/test_tree.py --- a/pypy/rlib/parsing/test/test_tree.py +++ b/pypy/rlib/parsing/test/test_tree.py @@ -56,9 +56,12 @@ def foo(): tree = Nonterminal(symbol="a", children=[]) - return tree.getsourcepos() + try: + return tree.getsourcepos() + except IndexError: + return -42 f = self.compile(foo) - py.test.raises(IndexError, f) + assert f() == -42 def test_nonterminal_nested_empty(self): def foo(): @@ -70,9 +73,12 @@ children=[Nonterminal(symbol="c", children=[Nonterminal(symbol="c", children=[])])])])])])]) - return tree.getsourcepos() + try: + return tree.getsourcepos() + except IndexError: + return -42 f = self.compile(foo) - py.test.raises(IndexError, f) + assert f() == -42 class TestTreeTranslatedLLType(BaseTestTreeTranslated): From noreply at buildbot.pypy.org Fri Oct 12 15:32:57 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 15:32:57 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix the logic for handling infs and nans Message-ID: <20121012133257.A34C81C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58036:35d3dbad86d9 Date: 2012-10-12 15:27 +0200 http://bitbucket.org/pypy/pypy/changeset/35d3dbad86d9/ Log: fix the logic for handling infs and nans diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -2,6 +2,7 @@ import py +from pypy.rlib.rfloat import NAN, INFINITY from pypy.rlib.entrypoint import entrypoint from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint, intmask @@ -71,7 +72,14 @@ assert a == 'False' args += (False,) elif argtype is float: - args += (float(a),) + if a == 'inf': + args += (INFINITY,) + elif a == '-inf': + args += (-INFINITY,) + elif a == 'nan': + args += (NAN,) + else: + args += (float(a),) else: args += (a,) res = fn(*args) @@ -84,13 +92,19 @@ t.disable(["backendopt_lltype"]) t.driver.config.translation.countmallocs = True t.annotate() - t.compile_c() - ll_res = graphof(t.context, fn).getreturnvar().concretetype try: if py.test.config.option.view: t.view() except AttributeError: pass + t.rtype() + try: + if py.test.config.option.view: + t.view() + except AttributeError: + pass + t.compile_c() + ll_res = graphof(t.context, fn).getreturnvar().concretetype def f(*args, **kwds): expected_extra_mallocs = kwds.pop('expected_extra_mallocs', 0) From noreply at buildbot.pypy.org Fri Oct 12 15:32:58 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 15:32:58 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fixes Message-ID: <20121012133258.C7B9C1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58037:f761c7259467 Date: 2012-10-12 15:32 +0200 http://bitbucket.org/pypy/pypy/changeset/f761c7259467/ Log: fixes diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -550,9 +550,9 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - raise Exception("cannot take the union of a tuple of length %d " - "and a tuple of length %d" % (len(tup1.items), - len(tup2.items))) + raise UnionError("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) diff --git a/pypy/rlib/test/test_rmarshal.py b/pypy/rlib/test/test_rmarshal.py --- a/pypy/rlib/test/test_rmarshal.py +++ b/pypy/rlib/test/test_rmarshal.py @@ -169,7 +169,7 @@ assert st2.st_mode == st.st_mode assert st2[9] == st[9] return buf - fn = compile(f, [annmodel.s_Str0]) + fn = compile(f, [str]) res = fn('.') st = os.stat('.') sttuple = marshal.loads(res) From noreply at buildbot.pypy.org Fri Oct 12 15:33:00 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 15:33:00 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121012133300.1F1441C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58038:5c41421dec55 Date: 2012-10-12 15:32 +0200 http://bitbucket.org/pypy/pypy/changeset/5c41421dec55/ Log: merge diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -145,8 +145,12 @@ assert isinstance(exc, LLException) klass, inst = exc.args[0], exc.args[1] for cls in enumerate_exceptions_top_down(): - if "".join(klass.name).rstrip("\0") == cls.__name__: - return cls + if hasattr(klass, 'name'): # lltype + if "".join(klass.name).rstrip("\0") == cls.__name__: + return cls + else: # ootype + if klass._INSTANCE._name.split('.')[-1] == cls.__name__: + return cls raise ValueError("couldn't match exception, maybe it" " has RPython attributes like OSError?") From noreply at buildbot.pypy.org Fri Oct 12 15:36:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 15:36:34 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Don't print unescaped strings to stdout. Message-ID: <20121012133634.1E8591C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58039:d6eb09e626e3 Date: 2012-10-12 15:36 +0200 http://bitbucket.org/pypy/pypy/changeset/d6eb09e626e3/ Log: Don't print unescaped strings to stdout. diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -117,7 +117,13 @@ stdout = t.driver.cbuilder.cmdexec( " ".join([llrepr_in(arg) for arg in args]), expect_crash=(expected_exception_name is not None)) - print stdout + # + for line in stdout.splitlines(False): + if len(repr(line)) == len(line) + 2: # no escaped char + print line + else: + print 'REPR:', repr(line) + # if expected_exception_name is not None: stdout, stderr = stdout stderr, lastline, empty = stderr.rsplit('\n', 2) From noreply at buildbot.pypy.org Fri Oct 12 15:49:11 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 15:49:11 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix test Message-ID: <20121012134911.41FCA1C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58040:d00679079994 Date: 2012-10-12 15:48 +0200 http://bitbucket.org/pypy/pypy/changeset/d00679079994/ Log: Fix test diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -159,8 +159,17 @@ elif ll_res == lltype.Void: return None raise NotImplementedError("parsing %s" % (ll_res,)) - f.__name__ = fn.__name__ - return f + + class CompilationResult(object): + def __repr__(self): + return 'CompilationResult(%s)' % (fn.__name__,) + def __call__(self, *args, **kwds): + return f(*args, **kwds) + + cr = CompilationResult() + cr.t = t + cr.builder = t.driver.cbuilder + return cr def test_simple(): diff --git a/pypy/translator/tool/test/test_staticsizereport.py b/pypy/translator/tool/test/test_staticsizereport.py --- a/pypy/translator/tool/test/test_staticsizereport.py +++ b/pypy/translator/tool/test/test_staticsizereport.py @@ -1,8 +1,8 @@ -from pypy.translator.c.test.test_typed import CompilationTestCase +from pypy.translator.c.test.test_genc import compile from pypy.translator.tool.staticsizereport import group_static_size, guess_size from pypy.rpython.lltypesystem import llmemory, lltype, rffi -class TestStaticSizeReport(CompilationTestCase): +class TestStaticSizeReport(object): def test_simple(self): class A: def __init__(self, n): @@ -16,8 +16,9 @@ if x: return a.key return a.next.key - func = self.getcompiled(f, [int]) - size, num = group_static_size(self.builder.db, self.builder.db.globalcontainers()) + func = compile(f, [int]) + size, num = group_static_size(func.builder.db, + func.builder.db.globalcontainers()) for key, value in num.iteritems(): if "staticsizereport.A" in str(key) and "vtable" not in str(key): assert value == 101 @@ -39,8 +40,8 @@ if x > 42: dynlist.append(x) return d[x].x + fixlist[x] + d_small[x] + reverse_dict[test_dict[x]] - func = self.getcompiled(f, [int]) - db = self.builder.db + func = compile(f, [int]) + db = func.builder.db gcontainers = list(db.globalcontainers()) t = db.translator rtyper = t.rtyper @@ -55,11 +56,11 @@ S = rffi.sizeof(lltype.Signed) P = rffi.sizeof(rffi.VOIDP) B = 1 # bool - assert guess_size(self.builder.db, dictvalnode, set()) > 100 - assert guess_size(self.builder.db, dictvalnode2, set()) == 2 * S + 1 * P + 1 * S + 8 * (2*S + 1 * B) + assert guess_size(func.builder.db, dictvalnode, set()) > 100 + assert guess_size(func.builder.db, dictvalnode2, set()) == 2 * S + 1 * P + 1 * S + 8 * (2*S + 1 * B) r_set = set() dictnode_size = guess_size(db, test_dictnode, r_set) assert dictnode_size == 2 * S + 1 * P + 1 * S + (4096-256) * (1*S+1*P + (1 * S + 1*P + 5)) + (8192-4096+256) * (1*S+1*P) - assert guess_size(self.builder.db, fixarrayvalnode, set()) == 100 * rffi.sizeof(lltype.Signed) + 1 * rffi.sizeof(lltype.Signed) - assert guess_size(self.builder.db, dynarrayvalnode, set()) == 100 * rffi.sizeof(lltype.Signed) + 2 * rffi.sizeof(lltype.Signed) + 1 * rffi.sizeof(rffi.VOIDP) + assert guess_size(func.builder.db, fixarrayvalnode, set()) == 100 * rffi.sizeof(lltype.Signed) + 1 * rffi.sizeof(lltype.Signed) + assert guess_size(func.builder.db, dynarrayvalnode, set()) == 100 * rffi.sizeof(lltype.Signed) + 2 * rffi.sizeof(lltype.Signed) + 1 * rffi.sizeof(rffi.VOIDP) From noreply at buildbot.pypy.org Fri Oct 12 15:58:56 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 15:58:56 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix fix fix Message-ID: <20121012135856.9191A1C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58041:b88eeb32a971 Date: 2012-10-12 15:58 +0200 http://bitbucket.org/pypy/pypy/changeset/b88eeb32a971/ Log: Fix fix fix diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -106,6 +106,13 @@ t.compile_c() ll_res = graphof(t.context, fn).getreturnvar().concretetype + def output(stdout): + for line in stdout.splitlines(False): + if len(repr(line)) == len(line) + 2: # no escaped char + print line + else: + print 'REPR:', repr(line) + def f(*args, **kwds): expected_extra_mallocs = kwds.pop('expected_extra_mallocs', 0) expected_exception_name = kwds.pop('expected_exception_name', None) @@ -118,19 +125,20 @@ " ".join([llrepr_in(arg) for arg in args]), expect_crash=(expected_exception_name is not None)) # - for line in stdout.splitlines(False): - if len(repr(line)) == len(line) + 2: # no escaped char - print line - else: - print 'REPR:', repr(line) - # if expected_exception_name is not None: stdout, stderr = stdout + print '--- stdout ---' + output(stdout) + print '--- stderr ---' + output(stderr) + print '--------------' stderr, lastline, empty = stderr.rsplit('\n', 2) assert empty == '' assert lastline == ('Fatal RPython error: ' + expected_exception_name) return None + + output(stdout) stdout, lastline, empty = stdout.rsplit('\n', 2) assert empty == '' assert lastline.startswith('MALLOC COUNTERS: ') diff --git a/pypy/translator/test/test_exceptiontransform.py b/pypy/translator/test/test_exceptiontransform.py --- a/pypy/translator/test/test_exceptiontransform.py +++ b/pypy/translator/test/test_exceptiontransform.py @@ -64,6 +64,8 @@ assert f() == 1 def test_passthrough(self): + if self.type_system == 'ootype': + py.test.skip("XXX") def one(x): if x: raise ValueError() @@ -73,7 +75,7 @@ one(1) t, g = self.transform_func(foo, []) f = self.compile(foo, []) - py.test.raises(ValueError, f) + f(expected_exception_name='ValueError') def test_catches(self): def one(x): @@ -142,6 +144,8 @@ assert result == 2 def test_raises(self): + if self.type_system == 'ootype': + py.test.skip("XXX") def foo(x): if x: raise ValueError() @@ -149,7 +153,7 @@ assert len(list(g.iterblocks())) == 3 f = self.compile(foo, [int]) f(0) - py.test.raises(ValueError, f, 1) + f(1, expected_exception_name='ValueError') def test_no_multiple_transform(self): From noreply at buildbot.pypy.org Fri Oct 12 16:01:34 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 12 Oct 2012 16:01:34 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: kill some obscure commented out code Message-ID: <20121012140134.A1ECA1C1C59@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r58042:3555b3495486 Date: 2012-10-12 07:01 -0700 http://bitbucket.org/pypy/pypy/changeset/3555b3495486/ Log: kill some obscure commented out code diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py --- a/pypy/objspace/flow/model.py +++ b/pypy/objspace/flow/model.py @@ -257,13 +257,6 @@ class Variable(object): __slots__ = ["_name", "_nr", "concretetype"] -## def getter(x): return x._ct -## def setter(x, ct): -## if repr(ct) == '<* PyObject>': -## import pdb; pdb.set_trace() -## x._ct = ct -## concretetype = property(getter, setter) - dummyname = 'v' namesdict = {dummyname : (dummyname, 0)} From noreply at buildbot.pypy.org Fri Oct 12 16:01:35 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 12 Oct 2012 16:01:35 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merged upstream Message-ID: <20121012140135.DEFCD1C1C59@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: kill-someobject Changeset: r58043:6aca8686fd6f Date: 2012-10-12 07:01 -0700 http://bitbucket.org/pypy/pypy/changeset/6aca8686fd6f/ Log: merged upstream diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -106,6 +106,13 @@ t.compile_c() ll_res = graphof(t.context, fn).getreturnvar().concretetype + def output(stdout): + for line in stdout.splitlines(False): + if len(repr(line)) == len(line) + 2: # no escaped char + print line + else: + print 'REPR:', repr(line) + def f(*args, **kwds): expected_extra_mallocs = kwds.pop('expected_extra_mallocs', 0) expected_exception_name = kwds.pop('expected_exception_name', None) @@ -118,19 +125,20 @@ " ".join([llrepr_in(arg) for arg in args]), expect_crash=(expected_exception_name is not None)) # - for line in stdout.splitlines(False): - if len(repr(line)) == len(line) + 2: # no escaped char - print line - else: - print 'REPR:', repr(line) - # if expected_exception_name is not None: stdout, stderr = stdout + print '--- stdout ---' + output(stdout) + print '--- stderr ---' + output(stderr) + print '--------------' stderr, lastline, empty = stderr.rsplit('\n', 2) assert empty == '' assert lastline == ('Fatal RPython error: ' + expected_exception_name) return None + + output(stdout) stdout, lastline, empty = stdout.rsplit('\n', 2) assert empty == '' assert lastline.startswith('MALLOC COUNTERS: ') diff --git a/pypy/translator/test/test_exceptiontransform.py b/pypy/translator/test/test_exceptiontransform.py --- a/pypy/translator/test/test_exceptiontransform.py +++ b/pypy/translator/test/test_exceptiontransform.py @@ -64,6 +64,8 @@ assert f() == 1 def test_passthrough(self): + if self.type_system == 'ootype': + py.test.skip("XXX") def one(x): if x: raise ValueError() @@ -73,7 +75,7 @@ one(1) t, g = self.transform_func(foo, []) f = self.compile(foo, []) - py.test.raises(ValueError, f) + f(expected_exception_name='ValueError') def test_catches(self): def one(x): @@ -142,6 +144,8 @@ assert result == 2 def test_raises(self): + if self.type_system == 'ootype': + py.test.skip("XXX") def foo(x): if x: raise ValueError() @@ -149,7 +153,7 @@ assert len(list(g.iterblocks())) == 3 f = self.compile(foo, [int]) f(0) - py.test.raises(ValueError, f, 1) + f(1, expected_exception_name='ValueError') def test_no_multiple_transform(self): From noreply at buildbot.pypy.org Fri Oct 12 16:08:43 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 16:08:43 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: finish fixing rlib Message-ID: <20121012140843.6FA601C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58044:1ddd28420277 Date: 2012-10-12 15:53 +0200 http://bitbucket.org/pypy/pypy/changeset/1ddd28420277/ Log: finish fixing rlib diff --git a/pypy/rlib/test/test_rmmap.py b/pypy/rlib/test/test_rmmap.py --- a/pypy/rlib/test/test_rmmap.py +++ b/pypy/rlib/test/test_rmmap.py @@ -426,7 +426,7 @@ m.close() return r - compile(func, [int]) + compile(func, [int], gcpolicy='boehm') def test_windows_crasher_1(self): if sys.platform != "win32": @@ -469,5 +469,5 @@ def test_compile_alloc_free(): from pypy.translator.c.test.test_genc import compile - fn = compile(test_alloc_free, []) + fn = compile(test_alloc_free, [], gcpolicy='boehm') fn() diff --git a/pypy/rlib/test/test_rstruct.py b/pypy/rlib/test/test_rstruct.py --- a/pypy/rlib/test/test_rstruct.py +++ b/pypy/rlib/test/test_rstruct.py @@ -43,9 +43,15 @@ def pack(x): result = [] ieee.pack_float(result, x, 8, False) - return ''.join(result) + l = [] + for x in result: + for c in x: + l.append(str(ord(c))) + return ','.join(l) c_pack = compile(pack, [float]) def unpack(s): + l = s.split(',') + s = ''.join([chr(int(x)) for x in l]) return ieee.unpack_float(s, False) c_unpack = compile(unpack, [str]) diff --git a/pypy/rlib/test/test_timer.py b/pypy/rlib/test/test_timer.py --- a/pypy/rlib/test/test_timer.py +++ b/pypy/rlib/test/test_timer.py @@ -23,4 +23,4 @@ def test_compile_timer(): policy = AnnotatorPolicy() f_compiled = compile(timer_user, [], annotatorpolicy=policy) - f_compiled(expected_extra_mallocs=2) + f_compiled() From noreply at buildbot.pypy.org Fri Oct 12 16:08:44 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 16:08:44 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121012140844.9C25A1C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58045:88dedebc91e5 Date: 2012-10-12 16:08 +0200 http://bitbucket.org/pypy/pypy/changeset/88dedebc91e5/ Log: merge diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py --- a/pypy/objspace/flow/model.py +++ b/pypy/objspace/flow/model.py @@ -257,13 +257,6 @@ class Variable(object): __slots__ = ["_name", "_nr", "concretetype"] -## def getter(x): return x._ct -## def setter(x, ct): -## if repr(ct) == '<* PyObject>': -## import pdb; pdb.set_trace() -## x._ct = ct -## concretetype = property(getter, setter) - dummyname = 'v' namesdict = {dummyname : (dummyname, 0)} diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -106,6 +106,13 @@ t.compile_c() ll_res = graphof(t.context, fn).getreturnvar().concretetype + def output(stdout): + for line in stdout.splitlines(False): + if len(repr(line)) == len(line) + 2: # no escaped char + print line + else: + print 'REPR:', repr(line) + def f(*args, **kwds): expected_extra_mallocs = kwds.pop('expected_extra_mallocs', 0) expected_exception_name = kwds.pop('expected_exception_name', None) @@ -118,19 +125,20 @@ " ".join([llrepr_in(arg) for arg in args]), expect_crash=(expected_exception_name is not None)) # - for line in stdout.splitlines(False): - if len(repr(line)) == len(line) + 2: # no escaped char - print line - else: - print 'REPR:', repr(line) - # if expected_exception_name is not None: stdout, stderr = stdout + print '--- stdout ---' + output(stdout) + print '--- stderr ---' + output(stderr) + print '--------------' stderr, lastline, empty = stderr.rsplit('\n', 2) assert empty == '' assert lastline == ('Fatal RPython error: ' + expected_exception_name) return None + + output(stdout) stdout, lastline, empty = stdout.rsplit('\n', 2) assert empty == '' assert lastline.startswith('MALLOC COUNTERS: ') @@ -159,8 +167,17 @@ elif ll_res == lltype.Void: return None raise NotImplementedError("parsing %s" % (ll_res,)) - f.__name__ = fn.__name__ - return f + + class CompilationResult(object): + def __repr__(self): + return 'CompilationResult(%s)' % (fn.__name__,) + def __call__(self, *args, **kwds): + return f(*args, **kwds) + + cr = CompilationResult() + cr.t = t + cr.builder = t.driver.cbuilder + return cr def test_simple(): diff --git a/pypy/translator/test/test_exceptiontransform.py b/pypy/translator/test/test_exceptiontransform.py --- a/pypy/translator/test/test_exceptiontransform.py +++ b/pypy/translator/test/test_exceptiontransform.py @@ -64,6 +64,8 @@ assert f() == 1 def test_passthrough(self): + if self.type_system == 'ootype': + py.test.skip("XXX") def one(x): if x: raise ValueError() @@ -73,7 +75,7 @@ one(1) t, g = self.transform_func(foo, []) f = self.compile(foo, []) - py.test.raises(ValueError, f) + f(expected_exception_name='ValueError') def test_catches(self): def one(x): @@ -142,6 +144,8 @@ assert result == 2 def test_raises(self): + if self.type_system == 'ootype': + py.test.skip("XXX") def foo(x): if x: raise ValueError() @@ -149,7 +153,7 @@ assert len(list(g.iterblocks())) == 3 f = self.compile(foo, [int]) f(0) - py.test.raises(ValueError, f, 1) + f(1, expected_exception_name='ValueError') def test_no_multiple_transform(self): diff --git a/pypy/translator/tool/test/test_staticsizereport.py b/pypy/translator/tool/test/test_staticsizereport.py --- a/pypy/translator/tool/test/test_staticsizereport.py +++ b/pypy/translator/tool/test/test_staticsizereport.py @@ -1,8 +1,8 @@ -from pypy.translator.c.test.test_typed import CompilationTestCase +from pypy.translator.c.test.test_genc import compile from pypy.translator.tool.staticsizereport import group_static_size, guess_size from pypy.rpython.lltypesystem import llmemory, lltype, rffi -class TestStaticSizeReport(CompilationTestCase): +class TestStaticSizeReport(object): def test_simple(self): class A: def __init__(self, n): @@ -16,8 +16,9 @@ if x: return a.key return a.next.key - func = self.getcompiled(f, [int]) - size, num = group_static_size(self.builder.db, self.builder.db.globalcontainers()) + func = compile(f, [int]) + size, num = group_static_size(func.builder.db, + func.builder.db.globalcontainers()) for key, value in num.iteritems(): if "staticsizereport.A" in str(key) and "vtable" not in str(key): assert value == 101 @@ -39,8 +40,8 @@ if x > 42: dynlist.append(x) return d[x].x + fixlist[x] + d_small[x] + reverse_dict[test_dict[x]] - func = self.getcompiled(f, [int]) - db = self.builder.db + func = compile(f, [int]) + db = func.builder.db gcontainers = list(db.globalcontainers()) t = db.translator rtyper = t.rtyper @@ -55,11 +56,11 @@ S = rffi.sizeof(lltype.Signed) P = rffi.sizeof(rffi.VOIDP) B = 1 # bool - assert guess_size(self.builder.db, dictvalnode, set()) > 100 - assert guess_size(self.builder.db, dictvalnode2, set()) == 2 * S + 1 * P + 1 * S + 8 * (2*S + 1 * B) + assert guess_size(func.builder.db, dictvalnode, set()) > 100 + assert guess_size(func.builder.db, dictvalnode2, set()) == 2 * S + 1 * P + 1 * S + 8 * (2*S + 1 * B) r_set = set() dictnode_size = guess_size(db, test_dictnode, r_set) assert dictnode_size == 2 * S + 1 * P + 1 * S + (4096-256) * (1*S+1*P + (1 * S + 1*P + 5)) + (8192-4096+256) * (1*S+1*P) - assert guess_size(self.builder.db, fixarrayvalnode, set()) == 100 * rffi.sizeof(lltype.Signed) + 1 * rffi.sizeof(lltype.Signed) - assert guess_size(self.builder.db, dynarrayvalnode, set()) == 100 * rffi.sizeof(lltype.Signed) + 2 * rffi.sizeof(lltype.Signed) + 1 * rffi.sizeof(rffi.VOIDP) + assert guess_size(func.builder.db, fixarrayvalnode, set()) == 100 * rffi.sizeof(lltype.Signed) + 1 * rffi.sizeof(lltype.Signed) + assert guess_size(func.builder.db, dynarrayvalnode, set()) == 100 * rffi.sizeof(lltype.Signed) + 2 * rffi.sizeof(lltype.Signed) + 1 * rffi.sizeof(rffi.VOIDP) From noreply at buildbot.pypy.org Fri Oct 12 16:19:39 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Fri, 12 Oct 2012 16:19:39 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: start working on the dls talk Message-ID: <20121012141939.58A8A1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4849:206fd730526a Date: 2012-10-12 15:23 +0200 http://bitbucket.org/pypy/extradoc/changeset/206fd730526a/ Log: start working on the dls talk diff --git a/talk/dls2012/presentation/talk.tex b/talk/dls2012/presentation/talk.tex new file mode 100644 --- /dev/null +++ b/talk/dls2012/presentation/talk.tex @@ -0,0 +1,144 @@ +\documentclass[utf8x]{beamer} + +% This file is a solution template for: + +% - Talk at a conference/colloquium. +% - Talk length is about 20min. +% - Style is ornate. + +\mode +{ + \usetheme{Warsaw} + % or ... + + %\setbeamercovered{transparent} + % or whatever (possibly just delete it) +} + + +\usepackage[english]{babel} +\usepackage{listings} +\usepackage{ulem} +\usepackage{color} +\usepackage{alltt} + +\usepackage[utf8x]{inputenc} + + +\newcommand\redsout[1]{{\color{red}\sout{\hbox{\color{black}{#1}}}}} + +% or whatever + +% Or whatever. Note that the encoding and the font should match. If T1 +% does not look nice, try deleting the line with the fontenc. + + +\title{Loop-Aware Optimizations in PyPy’s Tracing JIT} + +\author[Ardö, Bolz, Fijałkowski]{Håkan Ardö$^1$ \and \emph{Carl Friedrich Bolz}$^2$ \and Maciej Fijałkowski} +% - Give the names in the same order as the appear in the paper. +% - Use the \inst{?} command only if the authors have different +% affiliation. + +\institute[Lund, Düsseldorf]{ +$^1$Centre for Mathematical Sciences, Lund University \and +$^2$Heinrich-Heine-Universität Düsseldorf, STUPS Group, Germany +} + +\date{2012 DLS, 22nd of October, 2012} +% - Either use conference name or its abbreviation. +% - Not really informative to the audience, more for people (including +% yourself) who are reading the slides online + + +% If you have a file called "university-logo-filename.xxx", where xxx +% is a graphic format that can be processed by latex or pdflatex, +% resp., then you can add a logo as follows: + + + + +% Delete this, if you do not want the table of contents to pop up at +% the beginning of each subsection: +%\AtBeginSubsection[] +%{ +% \begin{frame} +% \frametitle{Outline} +% \tableofcontents[currentsection,currentsubsection] +% \end{frame} +%} + + +% If you wish to uncover everything in a step-wise fashion, uncomment +% the following command: + +%\beamerdefaultoverlayspecification{<+->} + + +\begin{document} + +\begin{frame} + \titlepage +\end{frame} + +\begin{frame} + \frametitle{Why do tracing JITs work?} + \begin{itemize} + \item They are good at selecting interesting and common code paths + \item both through user program and through the runtime + \item the latter is particularly important for dynamic languages + \pause + \item traces are trivial to optimize + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Optimizing traces} + \begin{itemize} + \item Traces trivial to optimize, because there's no control flow + \item most optimizations are one forward pass + \item optimizers are often like symbolic executors + \item can do optimizations that are untractable with full control flow + \item XXX example + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Problems with this approach} + \begin{itemize} + \item most traces actually are loops + \item naive foward passes ignore this bit of control flow optimization available + \item how to fix that without sacrifing simplicity? + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Idea for solution} + \begin{itemize} + \item idea first proposed and implemented in LuaJIT by Mike Pall + \item this talk presents the implementation of the same approach in RPython's tracing JIT + \end{itemize} + \pause + \begin{block}{Approach} + \begin{itemize} + \item do a pre-processing step on the traces + \item apply the unchanged forward-pass optimizations + \item do some post-processing + \item pre-processing is done in such a way that the normal optimizations become loop-aware + \item intuition: give the optimizations a second iteration of context to work with + \end{itemize} + \end{block} +\end{frame} + +\begin{frame} + \frametitle{Pre-processing the loops} + \begin{itemize} + \item pre-processing does loop unrolling + \item peels off one iteration of the loop, duplicating the trace + \item the optimizations optimize both iterations together + \item this yields loop-invariant code motion and related optimizations + \end{itemize} +\end{frame} + + +\end{document} From noreply at buildbot.pypy.org Fri Oct 12 16:24:29 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 16:24:29 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: "Hum". A fix that I don't fully understand, but then it's in test_refcounting, Message-ID: <20121012142429.43F141C0FE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58046:501921387b66 Date: 2012-10-12 16:12 +0200 http://bitbucket.org/pypy/pypy/changeset/501921387b66/ Log: "Hum". A fix that I don't fully understand, but then it's in test_refcounting, so well. diff --git a/pypy/rpython/memory/gctransform/test/test_transform.py b/pypy/rpython/memory/gctransform/test/test_transform.py --- a/pypy/rpython/memory/gctransform/test/test_transform.py +++ b/pypy/rpython/memory/gctransform/test/test_transform.py @@ -143,7 +143,7 @@ etrafo = ExceptionTransformer(t) etrafo.transform_completely() graphs_borrowed = {} - for graph in t.graphs: + for graph in t.graphs[:]: graphs_borrowed[graph] = transformer.transform_graph(graph) if conftest.option.view: t.view() From noreply at buildbot.pypy.org Fri Oct 12 16:24:30 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 16:24:30 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fixes Message-ID: <20121012142430.91FE61C0FE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58047:fd2b3741425d Date: 2012-10-12 16:24 +0200 http://bitbucket.org/pypy/pypy/changeset/fd2b3741425d/ Log: Fixes diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -271,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -327,6 +327,7 @@ "Stands for an instance of a (user-defined) class." def __init__(self, classdef, can_be_None=False, flags={}): + assert classdef is not None self.classdef = classdef self.knowntype = classdef or object self.can_be_None = can_be_None diff --git a/pypy/rpython/memory/gctransform/test/test_transform.py b/pypy/rpython/memory/gctransform/test/test_transform.py --- a/pypy/rpython/memory/gctransform/test/test_transform.py +++ b/pypy/rpython/memory/gctransform/test/test_transform.py @@ -275,12 +275,16 @@ class A: def __init__(self, obj): self.x = obj - def f(v): + class B: + def __init__(self, i): + self.i = i + def f(i): + v = B(i) inst = A(v) llop.setfield(lltype.Void, inst, 'x', v) llop.bare_setfield(lltype.Void, inst, 'x', v) - t, transformer = rtype_and_transform(f, [object], _TestGCTransformer, + t, transformer = rtype_and_transform(f, [int], _TestGCTransformer, check=False) ops = getops(graphof(t, f)) - assert len(ops.get('getfield', [])) == 1 + # xxx no checking done any more From noreply at buildbot.pypy.org Fri Oct 12 16:24:31 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 16:24:31 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge heads Message-ID: <20121012142431.EAC9E1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58048:b6bfa9703196 Date: 2012-10-12 16:24 +0200 http://bitbucket.org/pypy/pypy/changeset/b6bfa9703196/ Log: merge heads diff --git a/pypy/rlib/test/test_rmmap.py b/pypy/rlib/test/test_rmmap.py --- a/pypy/rlib/test/test_rmmap.py +++ b/pypy/rlib/test/test_rmmap.py @@ -426,7 +426,7 @@ m.close() return r - compile(func, [int]) + compile(func, [int], gcpolicy='boehm') def test_windows_crasher_1(self): if sys.platform != "win32": @@ -469,5 +469,5 @@ def test_compile_alloc_free(): from pypy.translator.c.test.test_genc import compile - fn = compile(test_alloc_free, []) + fn = compile(test_alloc_free, [], gcpolicy='boehm') fn() diff --git a/pypy/rlib/test/test_rstruct.py b/pypy/rlib/test/test_rstruct.py --- a/pypy/rlib/test/test_rstruct.py +++ b/pypy/rlib/test/test_rstruct.py @@ -43,9 +43,15 @@ def pack(x): result = [] ieee.pack_float(result, x, 8, False) - return ''.join(result) + l = [] + for x in result: + for c in x: + l.append(str(ord(c))) + return ','.join(l) c_pack = compile(pack, [float]) def unpack(s): + l = s.split(',') + s = ''.join([chr(int(x)) for x in l]) return ieee.unpack_float(s, False) c_unpack = compile(unpack, [str]) diff --git a/pypy/rlib/test/test_timer.py b/pypy/rlib/test/test_timer.py --- a/pypy/rlib/test/test_timer.py +++ b/pypy/rlib/test/test_timer.py @@ -23,4 +23,4 @@ def test_compile_timer(): policy = AnnotatorPolicy() f_compiled = compile(timer_user, [], annotatorpolicy=policy) - f_compiled(expected_extra_mallocs=2) + f_compiled() From noreply at buildbot.pypy.org Fri Oct 12 16:36:58 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 16:36:58 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix sandbox tests Message-ID: <20121012143658.CAAFF1C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58049:83bcc2a81571 Date: 2012-10-12 16:36 +0200 http://bitbucket.org/pypy/pypy/changeset/83bcc2a81571/ Log: Fix sandbox tests diff --git a/pypy/translator/sandbox/test/test_pypy_interact.py b/pypy/translator/sandbox/test/test_pypy_interact.py --- a/pypy/translator/sandbox/test/test_pypy_interact.py +++ b/pypy/translator/sandbox/test/test_pypy_interact.py @@ -72,8 +72,7 @@ def setup_module(mod): - t = Translation(mini_pypy_like_entry_point, backend='c', - standalone=True, sandbox=True) + t = Translation(mini_pypy_like_entry_point, backend='c', sandbox=True) mod.executable = str(t.compile()) diff --git a/pypy/translator/sandbox/test/test_sandbox.py b/pypy/translator/sandbox/test/test_sandbox.py --- a/pypy/translator/sandbox/test/test_sandbox.py +++ b/pypy/translator/sandbox/test/test_sandbox.py @@ -21,7 +21,7 @@ g.flush() def compile(f, gc='ref'): - t = Translation(f, backend='c', standalone=True, sandbox=True, gc=gc, + t = Translation(f, backend='c', sandbox=True, gc=gc, check_str_without_nul=True) return str(t.compile()) From noreply at buildbot.pypy.org Fri Oct 12 16:42:38 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 16:42:38 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix test_os Message-ID: <20121012144238.46C361C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58050:d7b6ce9b6a02 Date: 2012-10-12 16:12 +0200 http://bitbucket.org/pypy/pypy/changeset/d7b6ce9b6a02/ Log: fix test_os diff --git a/pypy/rpython/module/test/test_ll_os.py b/pypy/rpython/module/test/test_ll_os.py --- a/pypy/rpython/module/test/test_ll_os.py +++ b/pypy/rpython/module/test/test_ll_os.py @@ -31,7 +31,7 @@ five-tuple giving float-representations (seconds, effectively) of the four fields from the underlying struct tms and the return value. """ - times = compile(lambda: os.times(), ())() + times = eval(compile(lambda: str(os.times()), ())()) assert isinstance(times, tuple) assert len(times) == 5 for value in times: From noreply at buildbot.pypy.org Fri Oct 12 16:42:39 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 16:42:39 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: small fixes Message-ID: <20121012144239.88E091C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58051:a317cb5950c9 Date: 2012-10-12 16:29 +0200 http://bitbucket.org/pypy/pypy/changeset/a317cb5950c9/ Log: small fixes diff --git a/pypy/tool/test/test_error.py b/pypy/tool/test/test_error.py --- a/pypy/tool/test/test_error.py +++ b/pypy/tool/test/test_error.py @@ -72,5 +72,5 @@ try: compile_function(fn, [int]) except UnionError, e: - assert 'function one' in e.args[2] - assert 'function two' in e.args[2] + assert 'function one' in str(e) + assert 'function two' in str(e) diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -19,7 +19,7 @@ unsigned_ffffffff = r_ulonglong(0xffffffff) def llrepr_in(v): - if isinstance(v, r_ulonglong): + if r_uint is not r_ulonglong and isinstance(v, r_ulonglong): return "%d:%d" % (intmask(v >> 32), intmask(v & unsigned_ffffffff)) elif isinstance(v, r_longlong): return "%d:%d" % (intmask(v >> 32), intmask(v & signed_ffffffff)) @@ -98,6 +98,8 @@ except AttributeError: pass t.rtype() + if backendopt: + t.backendopt() try: if py.test.config.option.view: t.view() @@ -132,8 +134,10 @@ print '--- stderr ---' output(stderr) print '--------------' - stderr, lastline, empty = stderr.rsplit('\n', 2) + stderr, prevline, lastline, empty = stderr.rsplit('\n', 3) assert empty == '' + if lastline == 'Aborted': + lastline = prevline assert lastline == ('Fatal RPython error: ' + expected_exception_name) return None From noreply at buildbot.pypy.org Fri Oct 12 16:42:40 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 16:42:40 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix few things Message-ID: <20121012144240.B20031C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58052:5c7390b01049 Date: 2012-10-12 16:41 +0200 http://bitbucket.org/pypy/pypy/changeset/5c7390b01049/ Log: fix few things diff --git a/pypy/translator/c/test/test_extfunc.py b/pypy/translator/c/test/test_extfunc.py --- a/pypy/translator/c/test/test_extfunc.py +++ b/pypy/translator/c/test/test_extfunc.py @@ -47,7 +47,7 @@ return fd f1 = compile(does_stuff, []) - py.test.raises(OSError, f1) + f1(expected_exception_name='OSError') assert not os.path.exists(tmpfile) def test_open_read_write_seek_close(): @@ -143,7 +143,7 @@ filename = str(py.path.local(__file__)) def call_access(path, mode): return os.access(path, mode) - f = compile(call_access, [annmodel.s_Str0, int]) + f = compile(call_access, [str, int]) for mode in os.R_OK, os.W_OK, os.X_OK, (os.R_OK | os.W_OK | os.X_OK): assert f(filename, mode) == os.access(filename, mode) @@ -157,14 +157,14 @@ res = (st[0], st.st_ino, st.st_ctime) if has_blksize: res += (st.st_blksize,) if has_blocks: res += (st.st_blocks,) - return res + return str(res) f = compile(call_stat, []) - res = f() + res = eval(f()) assert res[0] == os.stat(filename).st_mode assert res[1] == os.stat(filename).st_ino st_ctime = res[2] if isinstance(st_ctime, float): - assert st_ctime == os.stat(filename).st_ctime + assert (st_ctime - os.stat(filename).st_ctime) < 0.1 else: assert st_ctime == int(os.stat(filename).st_ctime) if has_blksize: @@ -193,15 +193,15 @@ fd = os.open(filename, os.O_RDONLY, 0777) st = os.fstat(fd) os.close(fd) - return (st.st_mode, st[1], st.st_mtime) + return str((st.st_mode, st[1], st.st_mtime)) f = compile(call_fstat, []) osstat = os.stat(filename) - st_mode, st_ino, st_mtime = f() + st_mode, st_ino, st_mtime = eval(f()) assert st_mode == osstat.st_mode if sys.platform != 'win32': assert st_ino == osstat.st_ino if isinstance(st_mtime, float): - assert st_mtime == osstat.st_mtime + assert (st_mtime - osstat.st_mtime) < 0.1 else: assert st_mtime == int(osstat.st_mtime) @@ -223,7 +223,7 @@ def test_system(): def does_stuff(cmd): return os.system(cmd) - f1 = compile(does_stuff, [annmodel.s_Str0]) + f1 = compile(does_stuff, [str]) res = f1("echo hello") assert res == 0 @@ -309,7 +309,7 @@ def test_chdir(): def does_stuff(path): os.chdir(path) - f1 = compile(does_stuff, [annmodel.s_Str0]) + f1 = compile(does_stuff, [str]) curdir = os.getcwd() try: os.chdir('..') @@ -323,7 +323,7 @@ os.rmdir(path) else: os.mkdir(path, 0777) - f1 = compile(does_stuff, [annmodel.s_Str0, bool]) + f1 = compile(does_stuff, [str, bool]) dirname = str(udir.join('test_mkdir_rmdir')) f1(dirname, False) assert os.path.exists(dirname) and os.path.isdir(dirname) @@ -627,7 +627,7 @@ return os.environ[s] except KeyError: return '--missing--' - func = compile(fn, [annmodel.s_Str0]) + func = compile(fn, [str]) os.environ.setdefault('USER', 'UNNAMED_USER') result = func('USER') assert result == os.environ['USER'] @@ -639,7 +639,7 @@ res = os.environ.get(s) if res is None: res = '--missing--' return res - func = compile(fn, [annmodel.s_Str0]) + func = compile(fn, [str]) os.environ.setdefault('USER', 'UNNAMED_USER') result = func('USER') assert result == os.environ['USER'] @@ -653,7 +653,7 @@ os.environ[s] = t3 os.environ[s] = t4 os.environ[s] = t5 - func = compile(fn, [annmodel.s_Str0] * 6) + func = compile(fn, [str] * 6) func('PYPY_TEST_DICTLIKE_ENVIRON', 'a', 'b', 'c', 'FOOBAR', '42', expected_extra_mallocs = (2, 3, 4)) # at least two, less than 5 assert _real_getenv('PYPY_TEST_DICTLIKE_ENVIRON') == '42' @@ -677,7 +677,7 @@ else: raise Exception("should have raised!") # os.environ[s5] stays - func = compile(fn, [annmodel.s_Str0] * 5) + func = compile(fn, [str] * 5) if hasattr(__import__(os.name), 'unsetenv'): expected_extra_mallocs = range(2, 10) # at least 2, less than 10: memory for s1, s2, s3, s4 should be freed @@ -742,7 +742,7 @@ raise AssertionError("should have failed!") result = os.listdir(s) return '/'.join(result) - func = compile(mylistdir, [annmodel.s_Str0]) + func = compile(mylistdir, [str]) for testdir in [str(udir), os.curdir]: result = func(testdir) result = result.split('/') @@ -773,7 +773,7 @@ os.execv(l[0], l) func = compile(does_stuff, []) - py.test.raises(OSError, "func()") + func(expected_exception_name='OSError') def test_execve(): filename = str(udir.join('test_execve.txt')) diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -25,6 +25,8 @@ return "%d:%d" % (intmask(v >> 32), intmask(v & signed_ffffffff)) elif isinstance(v, float): return repr(v) # extra precision than str(v) + elif isinstance(v, str): + return v + '.' return str(v) @specialize.argtype(0) @@ -81,7 +83,7 @@ else: args += (float(a),) else: - args += (a,) + args += (a[:-1],) res = fn(*args) print "THE RESULT IS:", llrepr_out(res), ";" return 0 From noreply at buildbot.pypy.org Fri Oct 12 16:42:41 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 16:42:41 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121012144241.EAA621C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58053:6f649ae2af81 Date: 2012-10-12 16:42 +0200 http://bitbucket.org/pypy/pypy/changeset/6f649ae2af81/ Log: merge diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -271,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -327,6 +327,7 @@ "Stands for an instance of a (user-defined) class." def __init__(self, classdef, can_be_None=False, flags={}): + assert classdef is not None self.classdef = classdef self.knowntype = classdef or object self.can_be_None = can_be_None diff --git a/pypy/rpython/memory/gctransform/test/test_transform.py b/pypy/rpython/memory/gctransform/test/test_transform.py --- a/pypy/rpython/memory/gctransform/test/test_transform.py +++ b/pypy/rpython/memory/gctransform/test/test_transform.py @@ -143,7 +143,7 @@ etrafo = ExceptionTransformer(t) etrafo.transform_completely() graphs_borrowed = {} - for graph in t.graphs: + for graph in t.graphs[:]: graphs_borrowed[graph] = transformer.transform_graph(graph) if conftest.option.view: t.view() @@ -275,12 +275,16 @@ class A: def __init__(self, obj): self.x = obj - def f(v): + class B: + def __init__(self, i): + self.i = i + def f(i): + v = B(i) inst = A(v) llop.setfield(lltype.Void, inst, 'x', v) llop.bare_setfield(lltype.Void, inst, 'x', v) - t, transformer = rtype_and_transform(f, [object], _TestGCTransformer, + t, transformer = rtype_and_transform(f, [int], _TestGCTransformer, check=False) ops = getops(graphof(t, f)) - assert len(ops.get('getfield', [])) == 1 + # xxx no checking done any more diff --git a/pypy/translator/sandbox/test/test_pypy_interact.py b/pypy/translator/sandbox/test/test_pypy_interact.py --- a/pypy/translator/sandbox/test/test_pypy_interact.py +++ b/pypy/translator/sandbox/test/test_pypy_interact.py @@ -72,8 +72,7 @@ def setup_module(mod): - t = Translation(mini_pypy_like_entry_point, backend='c', - standalone=True, sandbox=True) + t = Translation(mini_pypy_like_entry_point, backend='c', sandbox=True) mod.executable = str(t.compile()) diff --git a/pypy/translator/sandbox/test/test_sandbox.py b/pypy/translator/sandbox/test/test_sandbox.py --- a/pypy/translator/sandbox/test/test_sandbox.py +++ b/pypy/translator/sandbox/test/test_sandbox.py @@ -21,7 +21,7 @@ g.flush() def compile(f, gc='ref'): - t = Translation(f, backend='c', standalone=True, sandbox=True, gc=gc, + t = Translation(f, backend='c', sandbox=True, gc=gc, check_str_without_nul=True) return str(t.compile()) From noreply at buildbot.pypy.org Fri Oct 12 16:43:20 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 16:43:20 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix test_symbolic Message-ID: <20121012144320.10ED71C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58054:733a234965d2 Date: 2012-10-12 16:43 +0200 http://bitbucket.org/pypy/pypy/changeset/733a234965d2/ Log: fix test_symbolic diff --git a/pypy/translator/c/test/test_symbolic.py b/pypy/translator/c/test/test_symbolic.py --- a/pypy/translator/c/test/test_symbolic.py +++ b/pypy/translator/c/test/test_symbolic.py @@ -1,15 +1,9 @@ from pypy.translator.interactive import Translation +from pypy.translator.c.test.test_genc import compile from pypy import conftest from pypy.rpython.lltypesystem import llmemory, lltype from pypy.rlib.objectmodel import ComputedIntSymbolic -def getcompiled(f, args): - t = Translation(f, args) - fn = t.compile_c() - if conftest.option.view: - t.view() - return fn, t - def test_offsetof(): STRUCT = lltype.GcStruct("s", ("x", lltype.Signed), ("y", lltype.Signed)) offsetx = llmemory.offsetof(STRUCT, 'x') @@ -21,7 +15,7 @@ result = (adr + offsetx).signed[0] (adr + offsety).signed[0] = 2 return result * 10 + s.y - fn, t = getcompiled(f, []) + fn = compile(f, []) res = fn() assert res == 12 @@ -31,7 +25,7 @@ signedsize = llmemory.sizeof(lltype.Signed) def f(): return arraysize-signedsize*10 - fn, t = getcompiled(f, []) + fn = compile(f, []) res = fn() assert res == 0 @@ -51,7 +45,7 @@ for i in range(5): result = 10 * result + a[i] return result - fn, t = getcompiled(f, []) + fn = compile(f, []) res = fn() assert res == 1234501234 @@ -71,7 +65,7 @@ for i in range(5): result = 10 * result + a[i] return result - fn, t = getcompiled(f, []) + fn = compile(f, []) res = fn() assert res == 1234501234 @@ -88,7 +82,7 @@ result = (adr + offsety).signed[0] * 10 + int(offsety < sizeofs) llmemory.raw_free(adr) return result - fn, t = getcompiled(f, []) + fn = compile(f, []) res = fn() assert res == 51 @@ -98,7 +92,7 @@ assert not too_early return 7 k = ComputedIntSymbolic(compute_fn) - def f(): + def f(ignored): return k*6 t = Translation(f) @@ -106,6 +100,6 @@ if conftest.option.view: t.view() too_early = False - fn = t.compile_c() - res = fn() + fn = compile(f, [int]) + res = fn(0) assert res == 42 From noreply at buildbot.pypy.org Fri Oct 12 16:46:24 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 16:46:24 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix test_standalone Message-ID: <20121012144624.A566D1C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58055:928e2dc534be Date: 2012-10-12 16:45 +0200 http://bitbucket.org/pypy/pypy/changeset/928e2dc534be/ Log: Fix test_standalone diff --git a/pypy/translator/c/test/test_standalone.py b/pypy/translator/c/test/test_standalone.py --- a/pypy/translator/c/test/test_standalone.py +++ b/pypy/translator/c/test/test_standalone.py @@ -131,14 +131,14 @@ os.write(1, str(tot)) return 0 from pypy.translator.interactive import Translation - t = Translation(entry_point, backend='c', standalone=True) + t = Translation(entry_point, backend='c') # no counters t.backendopt(inline_threshold=100, profile_based_inline="500") exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2 - t = Translation(entry_point, backend='c', standalone=True) + t = Translation(entry_point, backend='c') # counters t.backendopt(inline_threshold=all.INLINE_THRESHOLD_FOR_TEST*0.5, profile_based_inline="500") @@ -171,13 +171,13 @@ return 0 from pypy.translator.interactive import Translation # XXX this is mostly a "does not crash option" - t = Translation(entry_point, backend='c', standalone=True, profopt="100") + t = Translation(entry_point, backend='c', profopt="100") # no counters t.backendopt() exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2 - t = Translation(entry_point, backend='c', standalone=True, profopt="100", + t = Translation(entry_point, backend='c', profopt="100", noprofopt=True) # no counters t.backendopt() @@ -208,12 +208,12 @@ return 0 from pypy.translator.interactive import Translation # XXX this is mostly a "does not crash option" - t = Translation(entry_point, backend='c', standalone=True, profopt="") + t = Translation(entry_point, backend='c', profopt="") # no counters t.backendopt() exe = t.compile() #py.process.cmdexec(exe) - t = Translation(entry_point, backend='c', standalone=True, profopt="", + t = Translation(entry_point, backend='c', profopt="", noprofopt=True) # no counters t.backendopt() From noreply at buildbot.pypy.org Fri Oct 12 16:46:25 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 16:46:25 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix test_rtagged Message-ID: <20121012144625.D65EE1C1C5A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58056:2375e0c42e82 Date: 2012-10-12 16:45 +0200 http://bitbucket.org/pypy/pypy/changeset/2375e0c42e82/ Log: Fix test_rtagged diff --git a/pypy/translator/c/test/test_rtagged.py b/pypy/translator/c/test/test_rtagged.py --- a/pypy/translator/c/test/test_rtagged.py +++ b/pypy/translator/c/test/test_rtagged.py @@ -67,7 +67,7 @@ from pypy import conftest def test_tagged_boehm(): - t = Translation(entry_point, standalone=True, gc='boehm', taggedpointers=True) + t = Translation(entry_point, gc='boehm', taggedpointers=True) try: exename = str(t.compile_c()) finally: From noreply at buildbot.pypy.org Fri Oct 12 16:55:29 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 16:55:29 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix test_refcount (and kill two of them, because I can't be bothered to care). Message-ID: <20121012145529.F34201C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58057:e73ffb6f5b8d Date: 2012-10-12 16:55 +0200 http://bitbucket.org/pypy/pypy/changeset/e73ffb6f5b8d/ Log: Fix test_refcount (and kill two of them, because I can't be bothered to care). diff --git a/pypy/translator/c/test/test_refcount.py b/pypy/translator/c/test/test_refcount.py --- a/pypy/translator/c/test/test_refcount.py +++ b/pypy/translator/c/test/test_refcount.py @@ -3,33 +3,12 @@ from pypy.translator.translator import TranslationContext from pypy.translator.c import genc +from pypy.translator.c.test.test_genc import compile from pypy.rpython.lltypesystem import lltype from pypy import conftest -def compile_func(fn, inputtypes, t=None, gcpolicy="ref"): - from pypy.config.pypyoption import get_pypy_config - config = get_pypy_config(translating=True) - config.translation.gc = gcpolicy - config.translation.countmallocs = True - if t is None: - t = TranslationContext(config=config) - if inputtypes is not None: - t.buildannotator().build_types(fn, inputtypes) - t.buildrtyper().specialize() - builder = genc.CExtModuleBuilder(t, fn, config=config) - builder.generate_source() - builder.compile() - if conftest.option.view: - t.view() - compiled_fn = builder.get_entry_point() - malloc_counters = builder.get_malloc_counters() - def checking_fn(*args, **kwds): - try: - return compiled_fn(*args, **kwds) - finally: - mallocs, frees = malloc_counters() - assert mallocs == frees - return checking_fn +def compile_func(func, args): + return compile(func, args, gcpolicy='ref') def test_something(): def f(): @@ -129,35 +108,35 @@ assert fn(0) == 5 def test_del_basic(): - for gcpolicy in ["ref"]: #, "framework"]: - S = lltype.GcStruct('S', ('x', lltype.Signed), rtti=True) - TRASH = lltype.GcStruct('TRASH', ('x', lltype.Signed)) - GLOBAL = lltype.Struct('GLOBAL', ('x', lltype.Signed)) - glob = lltype.malloc(GLOBAL, immortal=True) - def destructor(s): - glob.x = s.x + 1 - def type_info_S(s): - return lltype.getRuntimeTypeInfo(S) + py.test.skip("xxx fix or kill") + S = lltype.GcStruct('S', ('x', lltype.Signed), rtti=True) + TRASH = lltype.GcStruct('TRASH', ('x', lltype.Signed)) + GLOBAL = lltype.Struct('GLOBAL', ('x', lltype.Signed)) + glob = lltype.malloc(GLOBAL, immortal=True) + def destructor(s): + glob.x = s.x + 1 + def type_info_S(s): + return lltype.getRuntimeTypeInfo(S) - def g(n): - s = lltype.malloc(S) - s.x = n - # now 's' should go away - def entrypoint(n): - g(n) - # llop.gc__collect(lltype.Void) - return glob.x + def g(n): + s = lltype.malloc(S) + s.x = n + # now 's' should go away + def entrypoint(n): + g(n) + # llop.gc__collect(lltype.Void) + return glob.x - t = TranslationContext() - t.buildannotator().build_types(entrypoint, [int]) - rtyper = t.buildrtyper() - destrptr = rtyper.annotate_helper_fn(destructor, [lltype.Ptr(S)]) - rtyper.attachRuntimeTypeInfoFunc(S, type_info_S, destrptr=destrptr) - rtyper.specialize() - fn = compile_func(entrypoint, None, t, gcpolicy=gcpolicy) + t = TranslationContext() + t.buildannotator().build_types(entrypoint, [int]) + rtyper = t.buildrtyper() + destrptr = rtyper.annotate_helper_fn(destructor, [lltype.Ptr(S)]) + rtyper.attachRuntimeTypeInfoFunc(S, type_info_S, destrptr=destrptr) + rtyper.specialize() + fn = compile_func(entrypoint, None, t) - res = fn(123) - assert res == 124 + res = fn(123) + assert res == 124 def test_del_catches(): import os @@ -179,7 +158,7 @@ return a.b fn = compile_func(f, [int]) assert fn(0) == 1 - assert py.test.raises(TypeError, fn, 1) + fn(1, expected_exception_name="TypeError") def test_del_raises(): class B(object): @@ -210,29 +189,3 @@ fn = compile_func(f, [int]) res = fn(1) assert res == 1 - -def test_wrong_startblock_incref(): - class B(object): - pass - def g(b): - while True: - b.x -= 10 - if b.x < 0: - return b.x - def f(n): - b = B() - b.x = n - return g(b) - - # XXX obscure: remove the first empty block in the graph of 'g' - t = TranslationContext() - graph = t.buildflowgraph(g) - assert graph.startblock.operations == [] - graph.startblock = graph.startblock.exits[0].target - from pypy.objspace.flow.model import checkgraph - checkgraph(graph) - t._prebuilt_graphs[g] = graph - - fn = compile_func(f, [int], t) - res = fn(112) - assert res == -8 From noreply at buildbot.pypy.org Fri Oct 12 16:58:32 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 16:58:32 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: finish extfunc Message-ID: <20121012145832.B5FA31C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58058:e0f8a049181d Date: 2012-10-12 16:54 +0200 http://bitbucket.org/pypy/pypy/changeset/e0f8a049181d/ Log: finish extfunc diff --git a/pypy/rlib/rfloat.py b/pypy/rlib/rfloat.py --- a/pypy/rlib/rfloat.py +++ b/pypy/rlib/rfloat.py @@ -2,7 +2,7 @@ import math -from pypy.annotation.model import SomeString +from pypy.annotation.model import SomeString, SomeChar from pypy.rlib import objectmodel from pypy.rpython.extfunc import register_external from pypy.rpython.tool import rffi_platform @@ -152,6 +152,7 @@ return s + at objectmodel.enforceargs(float, SomeChar(), int, int) def formatd(x, code, precision, flags=0): if USE_SHORT_FLOAT_REPR: from pypy.rlib.rdtoa import dtoa_formatd diff --git a/pypy/translator/c/test/test_extfunc.py b/pypy/translator/c/test/test_extfunc.py --- a/pypy/translator/c/test/test_extfunc.py +++ b/pypy/translator/c/test/test_extfunc.py @@ -309,13 +309,10 @@ def test_chdir(): def does_stuff(path): os.chdir(path) + return os.getcwd() f1 = compile(does_stuff, [str]) - curdir = os.getcwd() - try: - os.chdir('..') - except: pass # toplevel - f1(curdir) - assert curdir == os.getcwd() + # different on windows please + assert f1('/tmp') == '/tmp' def test_mkdir_rmdir(): def does_stuff(path, delete): @@ -440,7 +437,7 @@ return os.getpid() f1 = compile(does_stuff, []) res = f1() - assert res == os.getpid() + assert res != os.getpid() if hasattr(os, 'getpgrp'): def test_os_getpgrp(): @@ -653,10 +650,10 @@ os.environ[s] = t3 os.environ[s] = t4 os.environ[s] = t5 + return os.environ[s] func = compile(fn, [str] * 6) - func('PYPY_TEST_DICTLIKE_ENVIRON', 'a', 'b', 'c', 'FOOBAR', '42', - expected_extra_mallocs = (2, 3, 4)) # at least two, less than 5 - assert _real_getenv('PYPY_TEST_DICTLIKE_ENVIRON') == '42' + r = func('PYPY_TEST_DICTLIKE_ENVIRON', 'a', 'b', 'c', 'FOOBAR', '42') + assert r == '42' def test_dictlike_environ_delitem(): def fn(s1, s2, s3, s4, s5): @@ -678,26 +675,11 @@ raise Exception("should have raised!") # os.environ[s5] stays func = compile(fn, [str] * 5) - if hasattr(__import__(os.name), 'unsetenv'): - expected_extra_mallocs = range(2, 10) - # at least 2, less than 10: memory for s1, s2, s3, s4 should be freed - # (each kept-alive entry counts as two: the RPython string used as - # key in 'envkeepalive.byname' and the raw-allocated char* as value) - else: - expected_extra_mallocs = range(10, 18) - # at least 10, less than 18: memory for the initial s1, s2, s3, s4 - # should be freed, but replaced by new buffers for empty strings func('PYPY_TEST_DICTLIKE_ENVDEL1', 'PYPY_TEST_DICTLIKE_ENVDEL_X', 'PYPY_TEST_DICTLIKE_ENVDELFOO', 'PYPY_TEST_DICTLIKE_ENVDELBAR', - 'PYPY_TEST_DICTLIKE_ENVDEL5', - expected_extra_mallocs = expected_extra_mallocs) - assert not _real_getenv('PYPY_TEST_DICTLIKE_ENVDEL1') - assert not _real_getenv('PYPY_TEST_DICTLIKE_ENVDEL_X') - assert not _real_getenv('PYPY_TEST_DICTLIKE_ENVDELFOO') - assert not _real_getenv('PYPY_TEST_DICTLIKE_ENVDELBAR') - assert _real_getenv('PYPY_TEST_DICTLIKE_ENVDEL5') == 't5' + 'PYPY_TEST_DICTLIKE_ENVDEL5') def test_dictlike_environ_keys(): def fn(): @@ -768,12 +750,16 @@ def test_execv_raising(): def does_stuff(): - l = [] - l.append("asddsadw32eewdfwqdqwdqwd") - os.execv(l[0], l) + try: + l = [] + l.append("asddsadw32eewdfwqdqwdqwd") + os.execv(l[0], l) + return 1 + except OSError: + return -2 func = compile(does_stuff, []) - func(expected_exception_name='OSError') + assert func() == -2 def test_execve(): filename = str(udir.join('test_execve.txt')) From noreply at buildbot.pypy.org Fri Oct 12 16:58:33 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 16:58:33 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix the last 2 remaining tests, yay! Message-ID: <20121012145833.CEE371C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58059:2f8bacfaf76e Date: 2012-10-12 16:57 +0200 http://bitbucket.org/pypy/pypy/changeset/2f8bacfaf76e/ Log: fix the last 2 remaining tests, yay! diff --git a/pypy/translator/c/test/test_lladdresses.py b/pypy/translator/c/test/test_lladdresses.py --- a/pypy/translator/c/test/test_lladdresses.py +++ b/pypy/translator/c/test/test_lladdresses.py @@ -1,6 +1,5 @@ import py, sys from pypy.rpython.lltypesystem.llmemory import * -from pypy.annotation.model import SomeAddress, SomeChar from pypy.translator.c.test.test_genc import compile from pypy.rlib.objectmodel import free_non_gc_object @@ -67,20 +66,22 @@ def test_pointer_arithmetic(): def f(offset, char): + char = chr(char) addr = raw_malloc(10000) same_offset = (addr + 2 * offset - offset) - addr addr.char[offset] = char result = (addr + same_offset).char[0] raw_free(addr) return result - fc = compile(f, [int, SomeChar()]) - res = fc(10, "c") + fc = compile(f, [int, int]) + res = fc(10, ord("c")) assert res == "c" - res = fc(12, "x") + res = fc(12, ord("x")) assert res == "x" def test_pointer_arithmetic_inplace(): def f(offset, char): + char = chr(char) addr = raw_malloc(10000) addr += offset addr.char[-offset] = char @@ -88,8 +89,8 @@ result = addr.char[0] raw_free(addr) return result - fc = compile(f, [int, SomeChar()]) - res = fc(10, "c") + fc = compile(f, [int, int]) + res = fc(10, ord("c")) assert res == "c" def test_raw_memcopy(): From noreply at buildbot.pypy.org Fri Oct 12 16:58:34 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 16:58:34 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121012145834.F3ACD1C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58060:acc09674af79 Date: 2012-10-12 16:58 +0200 http://bitbucket.org/pypy/pypy/changeset/acc09674af79/ Log: merge diff --git a/pypy/translator/c/test/test_refcount.py b/pypy/translator/c/test/test_refcount.py --- a/pypy/translator/c/test/test_refcount.py +++ b/pypy/translator/c/test/test_refcount.py @@ -3,33 +3,12 @@ from pypy.translator.translator import TranslationContext from pypy.translator.c import genc +from pypy.translator.c.test.test_genc import compile from pypy.rpython.lltypesystem import lltype from pypy import conftest -def compile_func(fn, inputtypes, t=None, gcpolicy="ref"): - from pypy.config.pypyoption import get_pypy_config - config = get_pypy_config(translating=True) - config.translation.gc = gcpolicy - config.translation.countmallocs = True - if t is None: - t = TranslationContext(config=config) - if inputtypes is not None: - t.buildannotator().build_types(fn, inputtypes) - t.buildrtyper().specialize() - builder = genc.CExtModuleBuilder(t, fn, config=config) - builder.generate_source() - builder.compile() - if conftest.option.view: - t.view() - compiled_fn = builder.get_entry_point() - malloc_counters = builder.get_malloc_counters() - def checking_fn(*args, **kwds): - try: - return compiled_fn(*args, **kwds) - finally: - mallocs, frees = malloc_counters() - assert mallocs == frees - return checking_fn +def compile_func(func, args): + return compile(func, args, gcpolicy='ref') def test_something(): def f(): @@ -129,35 +108,35 @@ assert fn(0) == 5 def test_del_basic(): - for gcpolicy in ["ref"]: #, "framework"]: - S = lltype.GcStruct('S', ('x', lltype.Signed), rtti=True) - TRASH = lltype.GcStruct('TRASH', ('x', lltype.Signed)) - GLOBAL = lltype.Struct('GLOBAL', ('x', lltype.Signed)) - glob = lltype.malloc(GLOBAL, immortal=True) - def destructor(s): - glob.x = s.x + 1 - def type_info_S(s): - return lltype.getRuntimeTypeInfo(S) + py.test.skip("xxx fix or kill") + S = lltype.GcStruct('S', ('x', lltype.Signed), rtti=True) + TRASH = lltype.GcStruct('TRASH', ('x', lltype.Signed)) + GLOBAL = lltype.Struct('GLOBAL', ('x', lltype.Signed)) + glob = lltype.malloc(GLOBAL, immortal=True) + def destructor(s): + glob.x = s.x + 1 + def type_info_S(s): + return lltype.getRuntimeTypeInfo(S) - def g(n): - s = lltype.malloc(S) - s.x = n - # now 's' should go away - def entrypoint(n): - g(n) - # llop.gc__collect(lltype.Void) - return glob.x + def g(n): + s = lltype.malloc(S) + s.x = n + # now 's' should go away + def entrypoint(n): + g(n) + # llop.gc__collect(lltype.Void) + return glob.x - t = TranslationContext() - t.buildannotator().build_types(entrypoint, [int]) - rtyper = t.buildrtyper() - destrptr = rtyper.annotate_helper_fn(destructor, [lltype.Ptr(S)]) - rtyper.attachRuntimeTypeInfoFunc(S, type_info_S, destrptr=destrptr) - rtyper.specialize() - fn = compile_func(entrypoint, None, t, gcpolicy=gcpolicy) + t = TranslationContext() + t.buildannotator().build_types(entrypoint, [int]) + rtyper = t.buildrtyper() + destrptr = rtyper.annotate_helper_fn(destructor, [lltype.Ptr(S)]) + rtyper.attachRuntimeTypeInfoFunc(S, type_info_S, destrptr=destrptr) + rtyper.specialize() + fn = compile_func(entrypoint, None, t) - res = fn(123) - assert res == 124 + res = fn(123) + assert res == 124 def test_del_catches(): import os @@ -179,7 +158,7 @@ return a.b fn = compile_func(f, [int]) assert fn(0) == 1 - assert py.test.raises(TypeError, fn, 1) + fn(1, expected_exception_name="TypeError") def test_del_raises(): class B(object): @@ -210,29 +189,3 @@ fn = compile_func(f, [int]) res = fn(1) assert res == 1 - -def test_wrong_startblock_incref(): - class B(object): - pass - def g(b): - while True: - b.x -= 10 - if b.x < 0: - return b.x - def f(n): - b = B() - b.x = n - return g(b) - - # XXX obscure: remove the first empty block in the graph of 'g' - t = TranslationContext() - graph = t.buildflowgraph(g) - assert graph.startblock.operations == [] - graph.startblock = graph.startblock.exits[0].target - from pypy.objspace.flow.model import checkgraph - checkgraph(graph) - t._prebuilt_graphs[g] = graph - - fn = compile_func(f, [int], t) - res = fn(112) - assert res == -8 diff --git a/pypy/translator/c/test/test_rtagged.py b/pypy/translator/c/test/test_rtagged.py --- a/pypy/translator/c/test/test_rtagged.py +++ b/pypy/translator/c/test/test_rtagged.py @@ -67,7 +67,7 @@ from pypy import conftest def test_tagged_boehm(): - t = Translation(entry_point, standalone=True, gc='boehm', taggedpointers=True) + t = Translation(entry_point, gc='boehm', taggedpointers=True) try: exename = str(t.compile_c()) finally: diff --git a/pypy/translator/c/test/test_standalone.py b/pypy/translator/c/test/test_standalone.py --- a/pypy/translator/c/test/test_standalone.py +++ b/pypy/translator/c/test/test_standalone.py @@ -131,14 +131,14 @@ os.write(1, str(tot)) return 0 from pypy.translator.interactive import Translation - t = Translation(entry_point, backend='c', standalone=True) + t = Translation(entry_point, backend='c') # no counters t.backendopt(inline_threshold=100, profile_based_inline="500") exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2 - t = Translation(entry_point, backend='c', standalone=True) + t = Translation(entry_point, backend='c') # counters t.backendopt(inline_threshold=all.INLINE_THRESHOLD_FOR_TEST*0.5, profile_based_inline="500") @@ -171,13 +171,13 @@ return 0 from pypy.translator.interactive import Translation # XXX this is mostly a "does not crash option" - t = Translation(entry_point, backend='c', standalone=True, profopt="100") + t = Translation(entry_point, backend='c', profopt="100") # no counters t.backendopt() exe = t.compile() out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2 - t = Translation(entry_point, backend='c', standalone=True, profopt="100", + t = Translation(entry_point, backend='c', profopt="100", noprofopt=True) # no counters t.backendopt() @@ -208,12 +208,12 @@ return 0 from pypy.translator.interactive import Translation # XXX this is mostly a "does not crash option" - t = Translation(entry_point, backend='c', standalone=True, profopt="") + t = Translation(entry_point, backend='c', profopt="") # no counters t.backendopt() exe = t.compile() #py.process.cmdexec(exe) - t = Translation(entry_point, backend='c', standalone=True, profopt="", + t = Translation(entry_point, backend='c', profopt="", noprofopt=True) # no counters t.backendopt() diff --git a/pypy/translator/c/test/test_symbolic.py b/pypy/translator/c/test/test_symbolic.py --- a/pypy/translator/c/test/test_symbolic.py +++ b/pypy/translator/c/test/test_symbolic.py @@ -1,15 +1,9 @@ from pypy.translator.interactive import Translation +from pypy.translator.c.test.test_genc import compile from pypy import conftest from pypy.rpython.lltypesystem import llmemory, lltype from pypy.rlib.objectmodel import ComputedIntSymbolic -def getcompiled(f, args): - t = Translation(f, args) - fn = t.compile_c() - if conftest.option.view: - t.view() - return fn, t - def test_offsetof(): STRUCT = lltype.GcStruct("s", ("x", lltype.Signed), ("y", lltype.Signed)) offsetx = llmemory.offsetof(STRUCT, 'x') @@ -21,7 +15,7 @@ result = (adr + offsetx).signed[0] (adr + offsety).signed[0] = 2 return result * 10 + s.y - fn, t = getcompiled(f, []) + fn = compile(f, []) res = fn() assert res == 12 @@ -31,7 +25,7 @@ signedsize = llmemory.sizeof(lltype.Signed) def f(): return arraysize-signedsize*10 - fn, t = getcompiled(f, []) + fn = compile(f, []) res = fn() assert res == 0 @@ -51,7 +45,7 @@ for i in range(5): result = 10 * result + a[i] return result - fn, t = getcompiled(f, []) + fn = compile(f, []) res = fn() assert res == 1234501234 @@ -71,7 +65,7 @@ for i in range(5): result = 10 * result + a[i] return result - fn, t = getcompiled(f, []) + fn = compile(f, []) res = fn() assert res == 1234501234 @@ -88,7 +82,7 @@ result = (adr + offsety).signed[0] * 10 + int(offsety < sizeofs) llmemory.raw_free(adr) return result - fn, t = getcompiled(f, []) + fn = compile(f, []) res = fn() assert res == 51 @@ -98,7 +92,7 @@ assert not too_early return 7 k = ComputedIntSymbolic(compute_fn) - def f(): + def f(ignored): return k*6 t = Translation(f) @@ -106,6 +100,6 @@ if conftest.option.view: t.view() too_early = False - fn = t.compile_c() - res = fn() + fn = compile(f, [int]) + res = fn(0) assert res == 42 From noreply at buildbot.pypy.org Fri Oct 12 16:59:36 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 16:59:36 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge default Message-ID: <20121012145936.A3CF01C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58061:a67e4ca4ea5a Date: 2012-10-12 16:59 +0200 http://bitbucket.org/pypy/pypy/changeset/a67e4ca4ea5a/ Log: merge default diff --git a/py/_io/capture.py b/py/_io/capture.py --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -176,7 +176,7 @@ class StdCaptureFD(Capture): - """ This class allows to capture writes to FD1 and FD2 + """ This class allows capturing writes to FD1 and FD2 and may connect a NULL file to FD0 (and prevent reads from sys.stdin). If any of the 0,1,2 file descriptors is invalid it will not be captured. @@ -267,8 +267,8 @@ return l class StdCapture(Capture): - """ This class allows to capture writes to sys.stdout|stderr "in-memory" - and will raise errors on tries to read from sys.stdin. It only + """ This class allows capturing writes to sys.stdout|stderr "in-memory" + and will raise errors on read attempts from sys.stdin. It only modifies sys.stdout|stderr|stdin attributes and does not touch underlying File Descriptors (use StdCaptureFD for that). """ diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -2,9 +2,9 @@ """ Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME -Print a report for the static data informations contained in FILENAME +Print a report for the static data information contained in FILENAME -The static data informations are saved in the file staticdata.info when +The static data information is saved in the file staticdata.info when passing --dump_static_data_info to translate.py. Options: diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -238,7 +238,7 @@ interpreter`_. .. _`documentation index`: index.html#project-documentation -.. _`getting-started`: getting-started.html +.. _`getting-started`: getting-started-dev.html .. _`PyPy's approach to virtual machine construction`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dls2006/pypy-vm-construction.pdf .. _`the translation document`: translation.html .. _`RPython toolchain`: translation.html diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -2,7 +2,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.pyopcode import LoopBlock from pypy.rlib import jit -from pypy.rlib.objectmodel import specialize class GeneratorIterator(Wrappable): diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -1,10 +1,62 @@ +from pypy.interpreter.error import OperationError +from pypy.rlib.objectmodel import specialize +from pypy.rlib import runicode from pypy.module._codecs import interp_codecs + at specialize.memo() +def decode_error_handler(space): + def raise_unicode_exception_decode(errors, encoding, msg, s, + startingpos, endingpos): + raise OperationError(space.w_UnicodeDecodeError, + space.newtuple([space.wrap(encoding), + space.wrap(s), + space.wrap(startingpos), + space.wrap(endingpos), + space.wrap(msg)])) + return raise_unicode_exception_decode + + at specialize.memo() +def encode_error_handler(space): + def raise_unicode_exception_encode(errors, encoding, msg, u, + startingpos, endingpos): + raise OperationError(space.w_UnicodeEncodeError, + space.newtuple([space.wrap(encoding), + space.wrap(u), + space.wrap(startingpos), + space.wrap(endingpos), + space.wrap(msg)])) + return raise_unicode_exception_encode + +# ____________________________________________________________ + def PyUnicode_AsEncodedString(space, w_data, w_encoding): return interp_codecs.encode(space, w_data, w_encoding) # These functions take and return unwrapped rpython strings and unicodes -PyUnicode_DecodeUnicodeEscape = interp_codecs.make_raw_decoder('unicode_escape') -PyUnicode_DecodeRawUnicodeEscape = interp_codecs.make_raw_decoder('raw_unicode_escape') -PyUnicode_DecodeUTF8 = interp_codecs.make_raw_decoder('utf_8') -PyUnicode_EncodeUTF8 = interp_codecs.make_raw_encoder('utf_8') +def PyUnicode_DecodeUnicodeEscape(space, string): + state = space.fromcache(interp_codecs.CodecState) + unicodedata_handler = state.get_unicodedata_handler(space) + result, consumed = runicode.str_decode_unicode_escape( + string, len(string), "strict", + final=True, errorhandler=decode_error_handler(space), + unicodedata_handler=unicodedata_handler) + return result + +def PyUnicode_DecodeRawUnicodeEscape(space, string): + result, consumed = runicode.str_decode_raw_unicode_escape( + string, len(string), "strict", + final=True, errorhandler=decode_error_handler(space)) + return result + +def PyUnicode_DecodeUTF8(space, string): + result, consumed = runicode.str_decode_utf_8( + string, len(string), "strict", + final=True, errorhandler=decode_error_handler(space), + allow_surrogates=True) + return result + +def PyUnicode_EncodeUTF8(space, uni): + return runicode.unicode_encode_utf_8( + uni, len(uni), "strict", + errorhandler=encode_error_handler(space), + allow_surrogates=True) diff --git a/pypy/jit/backend/cli/methodfactory.py b/pypy/jit/backend/cli/methodfactory.py --- a/pypy/jit/backend/cli/methodfactory.py +++ b/pypy/jit/backend/cli/methodfactory.py @@ -27,7 +27,7 @@ return self.dynmeth.CreateDelegate(delegatetype, consts) -# the assemblyData singleton contains the informations about the +# the assemblyData singleton contains the information about the # assembly we are currently writing to class AssemblyData: assembly = None diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -97,7 +97,7 @@ 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 informations about it. + ``compiled_loop`` for more information about it. """ raise NotImplementedError diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -317,7 +317,7 @@ except BadVirtualState: raise InvalidLoop('The state of the optimizer at the end of ' + 'peeled loop is inconsistent with the ' + - 'VirtualState at the begining of the peeled ' + + 'VirtualState at the beginning of the peeled ' + 'loop') jumpop.initarglist(jumpargs) diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -44,8 +44,8 @@ # string to the rest of the code. XXX not entirely sure if these three # functions are the only way for non-string objects to reach # space.{get,set,del}attr()... - # Note that if w_name is already a string (or a subclass of str), - # it must be returned unmodified (and not e.g. unwrapped-rewrapped). + # Note that if w_name is already an exact string it must be returned + # unmodified (and not e.g. unwrapped-rewrapped). if not space.is_w(space.type(w_name), space.w_str): name = space.str_w(w_name) # typecheck w_name = space.wrap(name) # rewrap as a real string 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 @@ -172,28 +172,6 @@ assert f() == {} assert g() == {'a':0, 'b':0, 'c':0} - def test_getattr(self): - class a(object): - i = 5 - assert getattr(a, 'i') == 5 - raises(AttributeError, getattr, a, 'k') - assert getattr(a, 'k', 42) == 42 - assert getattr(a, u'i') == 5 - raises(AttributeError, getattr, a, u'k') - assert getattr(a, u'k', 42) == 42 - - def test_getattr_typecheck(self): - class A(object): - def __getattribute__(self, name): - pass - def __setattr__(self, name, value): - pass - def __delattr__(self, name): - pass - raises(TypeError, getattr, A(), 42) - raises(TypeError, setattr, A(), 42, 'x') - raises(TypeError, delattr, A(), 42) - def test_sum(self): assert sum([]) ==0 assert sum([42]) ==42 @@ -661,6 +639,39 @@ assert vars(C_get_vars()) == {'a':2} +class AppTestGetattr: + OPTIONS = {} + + def setup_class(cls): + cls.space = conftest.gettestobjspace(**cls.OPTIONS) + + def test_getattr(self): + class a(object): + i = 5 + assert getattr(a, 'i') == 5 + raises(AttributeError, getattr, a, 'k') + assert getattr(a, 'k', 42) == 42 + assert getattr(a, u'i') == 5 + raises(AttributeError, getattr, a, u'k') + assert getattr(a, u'k', 42) == 42 + + def test_getattr_typecheck(self): + class A(object): + def __getattribute__(self, name): + pass + def __setattr__(self, name, value): + pass + def __delattr__(self, name): + pass + raises(TypeError, getattr, A(), 42) + raises(TypeError, setattr, A(), 42, 'x') + raises(TypeError, delattr, A(), 42) + + +class AppTestGetattrWithGetAttributeShortcut(AppTestGetattr): + OPTIONS = {"objspace.std.getattributeshortcut": True} + + class TestInternal: def test_execfile(self, space): from pypy.tool.udir import udir diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -248,7 +248,17 @@ raise OperationError(space.w_ValueError, space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] - enumvalues = [space.int_w(w) for w in enumvalues_w] + enumvalues = [] + try: + for w in enumvalues_w: + enumvalues.append(space.c_int_w(w)) + except OperationError, e: + if not e.match(space, space.w_OverflowError): + raise + i = len(enumvalues) + raise operationerrfmt(space.w_OverflowError, + "enum '%s' declaration for '%s' does not fit an int", + name, enumerators[i]) ctype = ctypeenum.W_CTypeEnum(space, name, enumerators, enumvalues) return ctype 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 @@ -1156,6 +1156,13 @@ e = py.test.raises(TypeError, newp, BStructPtr, [None]) assert "must be a str or int, not NoneType" in str(e.value) +def test_enum_overflow(): + for ovf in (2**63, -2**63-1, 2**31, -2**31-1): + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (5, ovf)) + assert str(e.value) == ( + "enum 'foo' declaration for 'b' does not fit an int") + def test_callback_returning_enum(): BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) @@ -2123,9 +2130,9 @@ py.test.raises(OverflowError, newp, BBoolP, 2) py.test.raises(OverflowError, newp, BBoolP, -1) BCharP = new_pointer_type(new_primitive_type("char")) - p = newp(BCharP, 'X') + p = newp(BCharP, b'X') q = cast(BBoolP, p) - assert q[0] == ord('X') + assert q[0] == ord(b'X') py.test.raises(TypeError, string, cast(BBool, False)) BDouble = new_primitive_type("double") assert int(cast(BBool, cast(BDouble, 0.1))) == 1 diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -338,38 +338,6 @@ from pypy.rlib import runicode -def make_raw_encoder(name): - rname = "unicode_encode_%s" % (name.replace("_encode", ""), ) - assert hasattr(runicode, rname) - def raw_encoder(space, uni): - state = space.fromcache(CodecState) - func = getattr(runicode, rname) - errors = "strict" - return func(uni, len(uni), errors, state.encode_error_handler) - raw_encoder.func_name = rname - return raw_encoder - -def make_raw_decoder(name): - rname = "str_decode_%s" % (name.replace("_decode", ""), ) - assert hasattr(runicode, rname) - def raw_decoder(space, string): - final = True - errors = "strict" - state = space.fromcache(CodecState) - func = getattr(runicode, rname) - kwargs = {} - if name == 'unicode_escape': - unicodedata_handler = state.get_unicodedata_handler(space) - result, consumed = func(string, len(string), errors, - final, state.decode_error_handler, - unicodedata_handler=unicodedata_handler) - else: - result, consumed = func(string, len(string), errors, - final, state.decode_error_handler) - return result - raw_decoder.func_name = rname - return raw_decoder - def make_encoder_wrapper(name): rname = "unicode_encode_%s" % (name.replace("_encode", ""), ) assert hasattr(runicode, rname) diff --git a/pypy/module/marshal/test/test_marshal.py b/pypy/module/marshal/test/test_marshal.py --- a/pypy/module/marshal/test/test_marshal.py +++ b/pypy/module/marshal/test/test_marshal.py @@ -163,6 +163,7 @@ def test_unicode(self): import marshal, sys self.marshal_check(u'\uFFFF') + self.marshal_check(u'\ud800') self.marshal_check(unichr(sys.maxunicode)) 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 @@ -111,6 +111,9 @@ def newlist(self, items): return ListObject(items) + def newcomplex(self, r, i): + return ComplexObject(r, i) + def listview(self, obj): assert isinstance(obj, ListObject) return obj.items @@ -135,6 +138,11 @@ raise OperationError(self.w_TypeError, self.wrap("slice.")) raise NotImplementedError + def unpackcomplex(self, w_obj): + if isinstance(w_obj, ComplexObject): + return w_obj.r, w_obj.i + raise NotImplementedError + def index(self, w_obj): return self.wrap(self.int_w(w_obj)) @@ -230,6 +238,12 @@ def __init__(self, v): self.v = v +class ComplexObject(W_Root): + tp = FakeSpace.w_complex + def __init__(self, r, i): + self.r = r + self.i = i + class InterpreterState(object): def __init__(self, code): self.code = code @@ -347,6 +361,20 @@ def execute(self, interp): return interp.space.wrap(self.v) +class ComplexConstant(Node): + def __init__(self, r, i): + self.r = float(r) + self.i = float(i) + + def __repr__(self): + return 'ComplexConst(%s, %s)' % (self.r, self.i) + + def wrap(self, space): + return space.newcomplex(self.r, self.i) + + def execute(self, interp): + return self.wrap(interp.space) + class RangeConstant(Node): def __init__(self, v): self.v = int(v) @@ -377,8 +405,7 @@ def execute(self, interp): w_list = self.wrap(interp.space) - dtype = get_dtype_cache(interp.space).w_float64dtype - return array(interp.space, w_list, w_dtype=dtype, w_order=None) + return array(interp.space, w_list) def __repr__(self): return "[" + ", ".join([repr(item) for item in self.items]) + "]" @@ -611,6 +638,8 @@ stack.append(RangeConstant(tokens.pop().v)) end = tokens.pop() assert end.name == 'pipe' + elif token.name == 'paren_left': + stack.append(self.parse_complex_constant(tokens)) elif accept_comma and token.name == 'comma': continue else: @@ -634,6 +663,15 @@ args += self.parse_expression(tokens, accept_comma=True) return FunctionCall(name, args) + def parse_complex_constant(self, tokens): + r = tokens.pop() + assert r.name == 'number' + assert tokens.pop().name == 'comma' + i = tokens.pop() + assert i.name == 'number' + assert tokens.pop().name == 'paren_right' + return ComplexConstant(r.v, i.v) + def parse_array_const(self, tokens): elems = [] while True: @@ -642,6 +680,8 @@ elems.append(FloatConstant(token.v)) elif token.name == 'array_left': elems.append(ArrayConstant(self.parse_array_const(tokens))) + elif token.name == 'paren_left': + elems.append(self.parse_complex_constant(tokens)) else: raise BadToken() token = tokens.pop() 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 @@ -43,9 +43,6 @@ self.imag = imag def convert_to(self, dtype): - from pypy.module.micronumpy.types import ComplexFloating - if not isinstance(dtype.itemtype, ComplexFloating): - raise TypeError('cannot convert %r to complex' % dtype) return dtype.box_complex(self.real, self.imag) def convert_real_to(self, dtype): @@ -77,12 +74,7 @@ return space.wrap(box.value) def descr_float(self, space): - try: - box = self.convert_to(W_Float64Box._get_dtype(space)) - except TypeError: - raise OperationError(space.w_TypeError, - space.wrap("Cannot convert %s to float" % self._get_dtype(space).name)) - + box = self.convert_to(W_Float64Box._get_dtype(space)) assert isinstance(box, W_Float64Box) return space.wrap(box.value) diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -17,15 +17,18 @@ return not dtype.itemtype.bool(val) class W_Ufunc(Wrappable): - _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", "allow_complex"] - _immutable_fields_ = ["promote_to_float", "promote_bools", "name", "allow_complex"] + _attrs_ = ["name", "promote_to_float", "promote_bools", "identity", + "allow_complex", "complex_to_float"] + _immutable_fields_ = ["promote_to_float", "promote_bools", "name", + "allow_complex", "complex_to_float"] def __init__(self, name, promote_to_float, promote_bools, identity, - int_only, allow_complex): + int_only, allow_complex, complex_to_float): self.name = name self.promote_to_float = promote_to_float self.promote_bools = promote_bools self.allow_complex = allow_complex + self.complex_to_float = complex_to_float self.identity = identity self.int_only = int_only @@ -216,10 +219,11 @@ _immutable_fields_ = ["func", "name"] def __init__(self, func, name, promote_to_float=False, promote_bools=False, - identity=None, bool_result=False, int_only=False, allow_complex=True): + identity=None, bool_result=False, int_only=False, + allow_complex=True, complex_to_float=False): W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity, - int_only, allow_complex) + int_only, allow_complex, complex_to_float) self.func = func self.bool_result = bool_result @@ -248,6 +252,11 @@ res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype else: res_dtype = calc_dtype + if self.complex_to_float and calc_dtype.is_complex_type(): + if calc_dtype.name == 'complex64': + res_dtype = interp_dtype.get_dtype_cache(space).w_float32dtype + else: + res_dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if w_obj.is_scalar(): w_val = self.func(calc_dtype, w_obj.get_scalar_value().convert_to(calc_dtype)) @@ -269,10 +278,11 @@ argcount = 2 def __init__(self, func, name, promote_to_float=False, promote_bools=False, - identity=None, comparison_func=False, int_only=False, allow_complex=True): + identity=None, comparison_func=False, int_only=False, + allow_complex=True, complex_to_float=False): W_Ufunc.__init__(self, name, promote_to_float, promote_bools, identity, - int_only, allow_complex) + int_only, allow_complex, complex_to_float) self.func = func self.comparison_func = comparison_func if name == 'logical_and': @@ -534,14 +544,14 @@ ("positive", "pos", 1), ("negative", "neg", 1), - ("absolute", "abs", 1), + ("absolute", "abs", 1, {"complex_to_float": True}), ("sign", "sign", 1, {"promote_bools": True}), ("signbit", "signbit", 1, {"bool_result": True, "allow_complex": False}), ("reciprocal", "reciprocal", 1), ("conjugate", "conj", 1), - ("real", "real", 1), - ("imag", "imag", 1), + ("real", "real", 1, {"complex_to_float": True}), + ("imag", "imag", 1, {"complex_to_float": True}), ("fabs", "fabs", 1, {"promote_to_float": True, "allow_complex": False}), diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py --- a/pypy/module/micronumpy/test/test_compile.py +++ b/pypy/module/micronumpy/test/test_compile.py @@ -281,3 +281,13 @@ d -> 1 ''') assert interp.results[0].value == 0 + + def test_complex(self): + interp = self.run(''' + a = (0, 1) + b = [(0, 1), (1, 0)] + b -> 0 + ''') + assert interp.results[0].real == 0 + assert interp.results[0].imag == 1 + 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 @@ -468,13 +468,16 @@ assert c[i] == max(a[i], b[i]) def test_basic(self): - from _numpypy import (complex128, complex64, add, + from _numpypy import (complex128, complex64, add, array, dtype, subtract as sub, multiply, divide, negative, abs, floor_divide, - reciprocal, real, imag, sign) + real, imag, sign) from _numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) assert real(4.0) == 4.0 assert imag(0.0) == 0.0 + a = array([complex(3.0, 4.0)]) + b = a.real + assert b.dtype == dtype(float) for complex_ in complex64, complex128: O = complex(0, 0) 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 @@ -18,6 +18,7 @@ def setup_class(cls): default = """ a = [1,2,3,4] + z = (1, 2) c = a + b sum(c) -> 1::1 a -> 3:1:2 @@ -490,4 +491,3 @@ 'new_with_vtable': 1, 'int_add': 2, 'float_ne': 1}) - 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 @@ -1274,8 +1274,8 @@ @complex_unary_op def expm1(self, v): - #Duplicate exp() so in the future it will be easier - # to implement seterr + # duplicate exp() so in the future it will be easier + # to implement seterr if rfloat.isinf(v[1]): if rfloat.isinf(v[0]): if v[0] < 0: @@ -1286,8 +1286,8 @@ return rfloat.NAN, rfloat.NAN try: res = rcomplex.c_exp(*v) - res = (res[0]-1, res[1]) - return res + res = (res[0]-1, res[1]) + return res except OverflowError: if v[1] == 0: return rfloat.INFINITY, 0.0 diff --git a/pypy/module/posix/app_posix.py b/pypy/module/posix/app_posix.py --- a/pypy/module/posix/app_posix.py +++ b/pypy/module/posix/app_posix.py @@ -198,7 +198,7 @@ def wait3(options): """ wait3(options) -> (pid, status, rusage) - Wait for completion of a child process and provides resource usage informations + Wait for completion of a child process and provides resource usage information """ from _pypy_wait import wait3 return wait3(options) @@ -206,7 +206,7 @@ def wait4(pid, options): """ wait4(pid, options) -> (pid, status, rusage) - Wait for completion of the child process "pid" and provides resource usage informations + Wait for completion of the child process "pid" and provides resource usage information """ from _pypy_wait import wait4 return wait4(pid, options) diff --git a/pypy/module/pypyjit/interp_resop.py b/pypy/module/pypyjit/interp_resop.py --- a/pypy/module/pypyjit/interp_resop.py +++ b/pypy/module/pypyjit/interp_resop.py @@ -63,7 +63,7 @@ """ set_optimize_hook(hook) Set a compiling hook that will be called each time a loop is optimized, - but before assembler compilation. This allows to add additional + but before assembler compilation. This allows adding additional optimizations on Python level. The hook will be called with the pypyjit.JitLoopInfo object. Refer to it's diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -1,5 +1,4 @@ import operator -import sys from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.objspace.std import model, newformat @@ -13,7 +12,6 @@ isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd, DTSF_ADD_DOT_0, DTSF_STR_PRECISION) from pypy.rlib.rbigint import rbigint -from pypy.rlib.objectmodel import we_are_translated from pypy.rlib import rfloat from pypy.tool.sourcetools import func_with_new_name @@ -292,8 +290,6 @@ return space.wrap(_hash_float(space, w_value.floatval)) def _hash_float(space, v): - from pypy.objspace.std.longobject import hash__Long - if isnan(v): return 0 diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -1,5 +1,6 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault +from pypy.interpreter import unicodehelper from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.register_all import register_all from pypy.objspace.std.basestringtype import basestring_typedef @@ -186,32 +187,6 @@ # ____________________________________________________________ -def decode_error_handler(space): - def raise_unicode_exception_decode(errors, encoding, msg, s, - startingpos, endingpos): - raise OperationError(space.w_UnicodeDecodeError, - space.newtuple([space.wrap(encoding), - space.wrap(s), - space.wrap(startingpos), - space.wrap(endingpos), - space.wrap(msg)])) - return raise_unicode_exception_decode -decode_error_handler._annspecialcase_ = 'specialize:memo' - -def encode_error_handler(space): - def raise_unicode_exception_encode(errors, encoding, msg, u, - startingpos, endingpos): - raise OperationError(space.w_UnicodeEncodeError, - space.newtuple([space.wrap(encoding), - space.wrap(u), - space.wrap(startingpos), - space.wrap(endingpos), - space.wrap(msg)])) - return raise_unicode_exception_encode -encode_error_handler._annspecialcase_ = 'specialize:memo' - -# ____________________________________________________________ - def getdefaultencoding(space): return space.sys.defaultencoding @@ -235,12 +210,12 @@ if errors is None or errors == 'strict': if encoding == 'ascii': u = space.unicode_w(w_object) - eh = encode_error_handler(space) + eh = unicodehelper.encode_error_handler(space) return space.wrap(unicode_encode_ascii( u, len(u), None, errorhandler=eh)) if encoding == 'utf-8': u = space.unicode_w(w_object) - eh = encode_error_handler(space) + eh = unicodehelper.encode_error_handler(space) return space.wrap(unicode_encode_utf_8( u, len(u), None, errorhandler=eh, allow_surrogates=True)) @@ -265,12 +240,12 @@ if encoding == 'ascii': # XXX error handling s = space.bufferstr_w(w_obj) - eh = decode_error_handler(space) + eh = unicodehelper.decode_error_handler(space) return space.wrap(str_decode_ascii( s, len(s), None, final=True, errorhandler=eh)[0]) if encoding == 'utf-8': s = space.bufferstr_w(w_obj) - eh = decode_error_handler(space) + eh = unicodehelper.decode_error_handler(space) return space.wrap(str_decode_utf_8( s, len(s), None, final=True, errorhandler=eh, allow_surrogates=True)[0]) diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py --- a/pypy/rlib/rcomplex.py +++ b/pypy/rlib/rcomplex.py @@ -1,12 +1,12 @@ import math from math import fabs, pi, e -from pypy.rlib.rfloat import copysign, asinh, log1p, isinf, isnan +from pypy.rlib.rfloat import copysign, asinh, log1p, isfinite, isinf, isnan from pypy.rlib.constant import DBL_MIN, CM_SCALE_UP, CM_SCALE_DOWN from pypy.rlib.constant import CM_LARGE_DOUBLE, DBL_MANT_DIG from pypy.rlib.constant import M_LN2, M_LN10 from pypy.rlib.constant import CM_SQRT_LARGE_DOUBLE, CM_SQRT_DBL_MIN from pypy.rlib.constant import CM_LOG_LARGE_DOUBLE -from pypy.rlib.special_value import isfinite, special_type, INF, NAN +from pypy.rlib.special_value import special_type, INF, NAN from pypy.rlib.special_value import sqrt_special_values from pypy.rlib.special_value import acos_special_values from pypy.rlib.special_value import acosh_special_values diff --git a/pypy/rlib/special_value.py b/pypy/rlib/special_value.py --- a/pypy/rlib/special_value.py +++ b/pypy/rlib/special_value.py @@ -32,9 +32,6 @@ else: return ST_NZERO -def isfinite(d): - return not isinf(d) and not isnan(d) - P = math.pi P14 = 0.25 * math.pi diff --git a/pypy/tool/bench/htmlreport.py b/pypy/tool/bench/htmlreport.py --- a/pypy/tool/bench/htmlreport.py +++ b/pypy/tool/bench/htmlreport.py @@ -226,7 +226,7 @@ ) def render_revision_header(self, sample): - """return a header for a report with informations about + """return a header for a report with information about committer, messages, revision date. """ revision_id = pyhtml.li('Revision ID: %s' % (sample.revision_id,)) diff --git a/pypy/tool/bench/result.py b/pypy/tool/bench/result.py --- a/pypy/tool/bench/result.py +++ b/pypy/tool/bench/result.py @@ -13,7 +13,7 @@ class PerfResultCollection(object): - """Holds informations about several PerfResult objects. The + """Holds information about several PerfResult objects. The objects should have the same test_id and revision_id""" def __init__(self, results=None): @@ -166,7 +166,7 @@ count = py.std.itertools.count() def annotate(self, result): """Try to put extra information for each revision on the - PerfResult objects. These informations are retrieved from a + PerfResult objects. These information are retrieved from a branch object. """ #if self.branch is None: diff --git a/pypy/tool/memusage/log2gnumeric.py b/pypy/tool/memusage/log2gnumeric.py --- a/pypy/tool/memusage/log2gnumeric.py +++ b/pypy/tool/memusage/log2gnumeric.py @@ -7,7 +7,7 @@ $ PYPYLOG=gc-collect,jit-mem:logfile pypy your-program.py -This will produce "logfile", containing informations about the memory used by +This will produce "logfile", containing information about the memory used by the GC and the number of loops created/freed by the JIT. If you want, you can also measure the amout of used memory as seen by the OS diff --git a/pypy/tool/sourcetools.py b/pypy/tool/sourcetools.py --- a/pypy/tool/sourcetools.py +++ b/pypy/tool/sourcetools.py @@ -120,7 +120,7 @@ # various helper functions # class MyStr(str): - """ custom string which allows to add attributes. """ + """ custom string which allows adding attributes. """ def newcode(fromcode, **kwargs): names = [x for x in dir(fromcode) if x[:3] == 'co_'] diff --git a/pypy/translator/goal/timing.py b/pypy/translator/goal/timing.py --- a/pypy/translator/goal/timing.py +++ b/pypy/translator/goal/timing.py @@ -1,5 +1,5 @@ -""" Module for keeping detailed informations about +""" Module for keeping detailed information about times of certain driver parts """ diff --git a/pypy/translator/microbench/pybench/platform.py b/pypy/translator/microbench/pybench/platform.py --- a/pypy/translator/microbench/pybench/platform.py +++ b/pypy/translator/microbench/pybench/platform.py @@ -811,7 +811,7 @@ split=re.compile('[\s,]').split): """ Queries the given executable (defaults to the Python interpreter - binary) for various architecture informations. + binary) for various architecture information. Returns a tuple (bits,linkage) which contain information about the bit architecture and the linkage format used for the diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py --- a/pypy/translator/platform/__init__.py +++ b/pypy/translator/platform/__init__.py @@ -215,7 +215,7 @@ largs = self._link_args_from_eci(eci, standalone) return self._link(cc_link, ofiles, largs, standalone, exe_name) - # below are some detailed informations for platforms + # below are some detailed information for platforms def include_dirs_for_libffi(self): dirs = self._include_dirs_for_libffi() diff --git a/pypy/translator/tool/staticsizereport.py b/pypy/translator/tool/staticsizereport.py --- a/pypy/translator/tool/staticsizereport.py +++ b/pypy/translator/tool/staticsizereport.py @@ -201,7 +201,7 @@ f = infofile.open('w') pickle.dump(info, f) f.close() - log.info('static data informations dumped to %s' % infofile) + log.info('static data information dumped to %s' % infofile) return infofile From noreply at buildbot.pypy.org Fri Oct 12 17:05:31 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 17:05:31 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix for SomeChar in enforceargs() Message-ID: <20121012150531.3460E1C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58062:be3ce3c9720d Date: 2012-10-12 17:05 +0200 http://bitbucket.org/pypy/pypy/changeset/be3ce3c9720d/ Log: Fix for SomeChar in enforceargs() diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py --- a/pypy/rlib/objectmodel.py +++ b/pypy/rlib/objectmodel.py @@ -149,7 +149,7 @@ else: return type(arg) def typecheck(*args): - from pypy.annotation.model import SomeList, SomeDict + from pypy.annotation.model import SomeList, SomeDict, SomeChar for i, (expected_type, arg) in enumerate(zip(types, args)): if expected_type is None: continue @@ -160,6 +160,9 @@ continue if isinstance(s_expected, SomeDict) and arg == {}: continue + if isinstance(s_expected, SomeChar) and ( + isinstance(arg, str) and len(arg) == 1): # a char + continue # s_argtype = get_annotation(get_type_descr_of_argument(arg)) if not s_expected.contains(s_argtype): From noreply at buildbot.pypy.org Fri Oct 12 17:13:55 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 17:13:55 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: don't use object(). Ever Message-ID: <20121012151355.AE33A1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58063:7a071ab7fd87 Date: 2012-10-12 17:13 +0200 http://bitbucket.org/pypy/pypy/changeset/7a071ab7fd87/ Log: don't use object(). Ever 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 @@ -144,8 +144,12 @@ target.chmod(0444) # make the file read-only, to make sure that nobody # edits it by mistake -_NOT_SPECIFIED = object() -CANNOT_FAIL = object() +class NotSpecified(object): + pass +_NOT_SPECIFIED = NotSpecified() +class CannotFail(object): + pass +CANNOT_FAIL = CannotFail() # The same function can be called in three different contexts: # (1) from C code From noreply at buildbot.pypy.org Fri Oct 12 17:14:51 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 17:14:51 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Allow again SomeInstance(classdef=None) for corner cases. Used by normalizecalls.py. Message-ID: <20121012151451.D50791C0FE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58064:06b6e872e89a Date: 2012-10-12 17:14 +0200 http://bitbucket.org/pypy/pypy/changeset/06b6e872e89a/ Log: Allow again SomeInstance(classdef=None) for corner cases. Used by normalizecalls.py. diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -327,7 +327,6 @@ "Stands for an instance of a (user-defined) class." def __init__(self, classdef, can_be_None=False, flags={}): - assert classdef is not None self.classdef = classdef self.knowntype = classdef or object self.can_be_None = can_be_None From noreply at buildbot.pypy.org Fri Oct 12 17:26:22 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 17:26:22 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: fix Message-ID: <20121012152622.C609A1C1C5A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58065:9e6d6547fc22 Date: 2012-10-12 17:25 +0200 http://bitbucket.org/pypy/pypy/changeset/9e6d6547fc22/ Log: fix diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -125,11 +125,10 @@ from pypy.objspace.std.mapdict import init_mapdict_cache init_mapdict_cache(self) - def _freeze_(self): + def _cleanup_(self): if (self.magic == cpython_magic and '__pypy__' not in sys.builtin_module_names): raise Exception("CPython host codes should not be rendered") - return False def _init_flags(self): co_code = self.co_code From noreply at buildbot.pypy.org Fri Oct 12 17:26:23 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 17:26:23 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121012152623.EE0AE1C1C5A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58066:4ab49813431e Date: 2012-10-12 17:26 +0200 http://bitbucket.org/pypy/pypy/changeset/4ab49813431e/ Log: merge diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -327,7 +327,6 @@ "Stands for an instance of a (user-defined) class." def __init__(self, classdef, can_be_None=False, flags={}): - assert classdef is not None self.classdef = classdef self.knowntype = classdef or object self.can_be_None = can_be_None From noreply at buildbot.pypy.org Fri Oct 12 17:27:50 2012 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 12 Oct 2012 17:27:50 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: add figures for guard compilation Message-ID: <20121012152750.025101C1C5A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4850:37433ae7b010 Date: 2012-10-12 12:18 -0300 http://bitbucket.org/pypy/extradoc/changeset/37433ae7b010/ Log: add figures for guard compilation diff too long, truncating to 2000 out of 3906 lines diff --git a/talk/vmil2012/presentation/figures/bridge_compiled.graffle b/talk/vmil2012/presentation/figures/bridge_compiled.graffle new file mode 100644 --- /dev/null +++ b/talk/vmil2012/presentation/figures/bridge_compiled.graffle @@ -0,0 +1,1457 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGrafflePro + 139.16.0.171715 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {1118, 783}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2012-07-24 10:50:56 +0000 + Creator + David Schneider + DisplayScale + 1.000 cm = 1.000 cm + GraphDocumentVersion + 8 + GraphicsList + + + Class + LineGraphic + Head + + ID + 16 + Info + 1 + + ID + 63 + Points + + {427, 250} + {328, 162} + {188, 113} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 36 + + + + Class + LineGraphic + Head + + ID + 16 + Info + 1 + + ID + 62 + Points + + {188, 250} + {206, 184} + {188, 113} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 27 + + + + Class + LineGraphic + Head + + ID + 42 + + ID + 61 + Points + + {83, 205} + {42, 264.875} + {83, 334.75} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 24 + + + + Class + Group + Graphics + + + Bounds + {{232.00001379686913, 294.74999999999989}, {150.99998620313085, 93.5}} + Class + ShapedGraphic + ID + 59 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 read backend map\ +decode resume data\ +retrieve stack and register values\ +...\ +return to interpreter} + + + + Bounds + {{232, 261.25}, {151, 33.5}} + Class + ShapedGraphic + ID + 60 + Magnets + + {0, 1} + {0, -1} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 compensation code} + + + + ID + 58 + + + Class + LineGraphic + Head + + ID + 40 + + ID + 56 + Points + + {531, 333.75} + {555, 351} + {580.89735689328165, 373.74999618530273} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 44 + + + + Class + LineGraphic + Head + + ID + 41 + + ID + 55 + Points + + {531, 301.25} + {580, 278} + {580.415709839653, 277.88418648722006} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 43 + + + + Class + LineGraphic + Head + + ID + 39 + + ID + 54 + Points + + {82.536736108577472, 339.10023442863826} + {52, 351.5} + {34.428503435249759, 361.50264298468693} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 42 + Info + 2 + + + + Class + LineGraphic + Head + + ID + 38 + + ID + 53 + Points + + {83, 301.25} + {60, 286} + {33.993974985969523, 268.75} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 37 + + + + Class + LineGraphic + Head + + ID + 44 + + ID + 52 + Points + + {532, 205} + {566, 277} + {531, 333.75} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 34 + + + + Class + LineGraphic + Head + + ID + 43 + + ID + 51 + Points + + {532, 159} + {569, 211} + {531, 301.25} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 32 + + + + Class + LineGraphic + Head + + ID + 59 + + ID + 50 + Points + + {428, 301.25} + {404, 330} + {383, 341.49999999999989} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 43 + + + + Class + LineGraphic + Head + + ID + 59 + + ID + 49 + Points + + {479.5, 350.5} + {427, 385.25} + {383, 341.49999999999989} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 44 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 59 + + ID + 48 + Points + + {134.5, 351.5} + {186, 384} + {232.0000137968691, 341.49999999999989} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 42 + + + + Class + LineGraphic + Head + + ID + 59 + + ID + 47 + Points + + {186, 301.25} + {211, 307} + {232.0000137968691, 341.49999999999989} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 37 + + + + Class + LineGraphic + Head + + ID + 37 + + ID + 45 + Points + + {83, 159} + {42, 222} + {83, 301.25} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 18 + + + + Bounds + {{428, 317}, {103, 33.5}} + Class + ShapedGraphic + ID + 44 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Trampoline #4} + + + + Bounds + {{428, 284.5}, {103, 33.5}} + Class + ShapedGraphic + ID + 43 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Trampoline #3} + + + + Bounds + {{83, 318}, {103, 33.5}} + Class + ShapedGraphic + ID + 42 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Trampoline #2} + + + + Bounds + {{575.00001069962946, 254.25000040105692}, {85, 47}} + Class + ShapedGraphic + ID + 41 + Magnets + + {1, 0} + {-1, 0} + + Shape + Cloud + Style + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 backend map #3} + + + + Bounds + {{575, 350.24999618530273}, {85, 47}} + Class + ShapedGraphic + ID + 40 + Magnets + + {1, 0} + {-1, 0} + + Shape + Cloud + Style + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 backend map #4} + + + + Bounds + {{-46, 338.25}, {85, 47}} + Class + ShapedGraphic + ID + 39 + Magnets + + {1, 0} + {-1, 0} + + Shape + Cloud + Style + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 backend map #2} + + + + Bounds + {{-46, 245.25}, {85, 47}} + Class + ShapedGraphic + ID + 38 + Magnets + + {1, 0} + {-1, 0} + + Shape + Cloud + Style + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 backend map #1} + + + + Bounds + {{83, 284.5}, {103, 33.5}} + Class + ShapedGraphic + ID + 37 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Trampoline #1} + + + + Bounds + {{427, 238.5}, {105, 23}} + Class + ShapedGraphic + ID + 36 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 jump} + + + + Bounds + {{427, 215.5}, {105, 23}} + Class + ShapedGraphic + ID + 35 + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 operation} + + + + Bounds + {{427, 193.5}, {105, 23}} + Class + ShapedGraphic + ID + 34 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.4 + g + 0.8 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 guard #4} + + + + Bounds + {{427, 170.5}, {105, 23}} + Class + ShapedGraphic + ID + 33 + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 operation} + + + + Bounds + {{427, 147.5}, {105, 23}} + Class + ShapedGraphic + ID + 32 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.4 + g + 0.8 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 guard #3} + + + + Bounds + {{427, 124.5}, {105, 23}} + Class + ShapedGraphic + ID + 31 + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 operation} + + + + Bounds + {{427, 101.5}, {105, 23}} + Class + ShapedGraphic + ID + 30 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 operation} + + + + Bounds + {{404, 59}, {151, 24}} + Class + ShapedGraphic + FitText + Vertical + Flow + Resize + ID + 29 + Shape + Rectangle + Style + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Bridge from guard #2} + + + + Bounds + {{404, 83}, {151, 286}} + Class + ShapedGraphic + ID + 28 + Shape + Rectangle + + + Bounds + {{83, 238.5}, {105, 23}} + Class + ShapedGraphic + ID + 27 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 jump} + + + + Bounds + {{83, 215.5}, {105, 23}} + Class + ShapedGraphic + ID + 26 + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 operation} + + + + Bounds + {{83, 193.5}, {105, 23}} + Class + ShapedGraphic + ID + 24 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.4 + g + 0.8 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 guard #2} + + + + Bounds + {{83, 170.5}, {105, 23}} + Class + ShapedGraphic + ID + 19 + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 operation} + + + + Bounds + {{83, 147.5}, {105, 23}} + Class + ShapedGraphic + ID + 18 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.4 + g + 0.8 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 guard #1} + + + + Bounds + {{83, 124.5}, {105, 23}} + Class + ShapedGraphic + ID + 17 + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 operation} + + + + Bounds + {{83, 101.5}, {105, 23}} + Class + ShapedGraphic + ID + 16 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 operation} + + + + Bounds + {{60, 59}, {151, 24}} + Class + ShapedGraphic + FitText + Vertical + Flow + Resize + ID + 20 + Shape + Rectangle + Style + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Trace} + + + + Bounds + {{60, 83}, {151, 286}} + Class + ShapedGraphic + ID + 23 + Shape + Rectangle + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 2 + HorizontalGuides + + 244 + 384 + + ImageCounter + 1 + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2012-10-12 15:13:12 +0000 + Modifier + David Schneider + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {595, 842} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + Frame + {{223, 221}, {1457, 783}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{-125, 0}, {1322, 644}} + Zoom + 1 + ZoomValues + + + Canvas 1 + 1 + 1 + + + + + diff --git a/talk/vmil2012/presentation/figures/bridge_compiled.pdf b/talk/vmil2012/presentation/figures/bridge_compiled.pdf new file mode 100644 index 0000000000000000000000000000000000000000..613049949df6d0de91ae5b4b809b7e5de1db25ab GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/bridge_patched.graffle b/talk/vmil2012/presentation/figures/bridge_patched.graffle new file mode 100644 --- /dev/null +++ b/talk/vmil2012/presentation/figures/bridge_patched.graffle @@ -0,0 +1,1511 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGrafflePro + 139.16.0.171715 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {1118, 783}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2012-07-24 10:50:56 +0000 + Creator + David Schneider + DisplayScale + 1.000 cm = 1.000 cm + GraphDocumentVersion + 8 + GraphicsList + + + Class + LineGraphic + Head + + ID + 30 + Info + 2 + + ID + 64 + Points + + {188, 205} + {255, 147.5} + {427, 113} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 24 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 16 + Info + 1 + + ID + 63 + Points + + {427, 250} + {328, 162} + {188, 113} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 36 + + + + Class + LineGraphic + Head + + ID + 16 + Info + 1 + + ID + 62 + Points + + {188, 250} + {206, 184} + {188, 113} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 27 + + + + Class + LineGraphic + Head + + ID + 42 + + ID + 61 + Points + + {83, 205} + {42, 264.875} + {83, 334.75} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 2 + TailArrow + 0 + + + Tail + + ID + 24 + + + + Class + Group + Graphics + + + Bounds + {{232.00001379686913, 294.74999999999989}, {150.99998620313085, 93.5}} + Class + ShapedGraphic + ID + 59 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 read backend map\ +decode resume data\ +retrieve stack and register values\ +...\ +return to interpreter} + + + + Bounds + {{232, 261.25}, {151, 33.5}} + Class + ShapedGraphic + ID + 60 + Magnets + + {0, 1} + {0, -1} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 compensation code} + + + + ID + 58 + + + Class + LineGraphic + Head + + ID + 40 + + ID + 56 + Points + + {531, 333.75} + {555, 351} + {580.89735689328165, 373.74999618530273} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 44 + + + + Class + LineGraphic + Head + + ID + 41 + + ID + 55 + Points + + {531, 301.25} + {580, 278} + {580.415709839653, 277.88418648722006} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 43 + + + + Class + LineGraphic + Head + + ID + 39 + + ID + 54 + Points + + {82.536736108577472, 339.10023442863826} + {52, 351.5} + {34.428503435249759, 361.50264298468693} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 42 + Info + 2 + + + + Class + LineGraphic + Head + + ID + 38 + + ID + 53 + Points + + {83, 301.25} + {60, 286} + {33.993974985969523, 268.75} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 37 + + + + Class + LineGraphic + Head + + ID + 44 + + ID + 52 + Points + + {532, 205} + {566, 277} + {531, 333.75} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 34 + + + + Class + LineGraphic + Head + + ID + 43 + + ID + 51 + Points + + {532, 159} + {569, 211} + {531, 301.25} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 32 + + + + Class + LineGraphic + Head + + ID + 59 + + ID + 50 + Points + + {428, 301.25} + {404, 330} + {383, 341.49999999999989} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail From noreply at buildbot.pypy.org Fri Oct 12 17:27:51 2012 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 12 Oct 2012 17:27:51 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: some low-level notes Message-ID: <20121012152751.2B9961C1C5A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4851:26dc9d26e27c Date: 2012-10-12 12:25 -0300 http://bitbucket.org/pypy/extradoc/changeset/26dc9d26e27c/ Log: some low-level notes diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -179,6 +179,16 @@ \begin{frame} \frametitle{Emitting Guards} + Guards are compiled as + \begin{itemize} + \item Quick Check if the condition holds + \item and a mapping of machine locations to JIT-variables % indirection using the fail-boxes + \end{itemize} + In case of failure + \begin{itemize} + \item execution jumps to compensation code, decodes and stores mapping + \item returns to interpreter that rebuilds state + \end{itemize} \end{frame} \begin{frame} From noreply at buildbot.pypy.org Fri Oct 12 17:27:52 2012 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 12 Oct 2012 17:27:52 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: merge heads Message-ID: <20121012152752.54BE31C1C5A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4852:3d51b9884b17 Date: 2012-10-12 12:27 -0300 http://bitbucket.org/pypy/extradoc/changeset/3d51b9884b17/ Log: merge heads diff --git a/talk/dls2012/presentation/talk.tex b/talk/dls2012/presentation/talk.tex new file mode 100644 --- /dev/null +++ b/talk/dls2012/presentation/talk.tex @@ -0,0 +1,144 @@ +\documentclass[utf8x]{beamer} + +% This file is a solution template for: + +% - Talk at a conference/colloquium. +% - Talk length is about 20min. +% - Style is ornate. + +\mode +{ + \usetheme{Warsaw} + % or ... + + %\setbeamercovered{transparent} + % or whatever (possibly just delete it) +} + + +\usepackage[english]{babel} +\usepackage{listings} +\usepackage{ulem} +\usepackage{color} +\usepackage{alltt} + +\usepackage[utf8x]{inputenc} + + +\newcommand\redsout[1]{{\color{red}\sout{\hbox{\color{black}{#1}}}}} + +% or whatever + +% Or whatever. Note that the encoding and the font should match. If T1 +% does not look nice, try deleting the line with the fontenc. + + +\title{Loop-Aware Optimizations in PyPy’s Tracing JIT} + +\author[Ardö, Bolz, Fijałkowski]{Håkan Ardö$^1$ \and \emph{Carl Friedrich Bolz}$^2$ \and Maciej Fijałkowski} +% - Give the names in the same order as the appear in the paper. +% - Use the \inst{?} command only if the authors have different +% affiliation. + +\institute[Lund, Düsseldorf]{ +$^1$Centre for Mathematical Sciences, Lund University \and +$^2$Heinrich-Heine-Universität Düsseldorf, STUPS Group, Germany +} + +\date{2012 DLS, 22nd of October, 2012} +% - Either use conference name or its abbreviation. +% - Not really informative to the audience, more for people (including +% yourself) who are reading the slides online + + +% If you have a file called "university-logo-filename.xxx", where xxx +% is a graphic format that can be processed by latex or pdflatex, +% resp., then you can add a logo as follows: + + + + +% Delete this, if you do not want the table of contents to pop up at +% the beginning of each subsection: +%\AtBeginSubsection[] +%{ +% \begin{frame} +% \frametitle{Outline} +% \tableofcontents[currentsection,currentsubsection] +% \end{frame} +%} + + +% If you wish to uncover everything in a step-wise fashion, uncomment +% the following command: + +%\beamerdefaultoverlayspecification{<+->} + + +\begin{document} + +\begin{frame} + \titlepage +\end{frame} + +\begin{frame} + \frametitle{Why do tracing JITs work?} + \begin{itemize} + \item They are good at selecting interesting and common code paths + \item both through user program and through the runtime + \item the latter is particularly important for dynamic languages + \pause + \item traces are trivial to optimize + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Optimizing traces} + \begin{itemize} + \item Traces trivial to optimize, because there's no control flow + \item most optimizations are one forward pass + \item optimizers are often like symbolic executors + \item can do optimizations that are untractable with full control flow + \item XXX example + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Problems with this approach} + \begin{itemize} + \item most traces actually are loops + \item naive foward passes ignore this bit of control flow optimization available + \item how to fix that without sacrifing simplicity? + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Idea for solution} + \begin{itemize} + \item idea first proposed and implemented in LuaJIT by Mike Pall + \item this talk presents the implementation of the same approach in RPython's tracing JIT + \end{itemize} + \pause + \begin{block}{Approach} + \begin{itemize} + \item do a pre-processing step on the traces + \item apply the unchanged forward-pass optimizations + \item do some post-processing + \item pre-processing is done in such a way that the normal optimizations become loop-aware + \item intuition: give the optimizations a second iteration of context to work with + \end{itemize} + \end{block} +\end{frame} + +\begin{frame} + \frametitle{Pre-processing the loops} + \begin{itemize} + \item pre-processing does loop unrolling + \item peels off one iteration of the loop, duplicating the trace + \item the optimizations optimize both iterations together + \item this yields loop-invariant code motion and related optimizations + \end{itemize} +\end{frame} + + +\end{document} From noreply at buildbot.pypy.org Fri Oct 12 17:34:28 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 12 Oct 2012 17:34:28 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Add module summaries Message-ID: <20121012153428.4CD6B1C1C5A@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58067:4a7b9de49e17 Date: 2012-10-12 16:33 +0100 http://bitbucket.org/pypy/pypy/changeset/4a7b9de49e17/ Log: Add module summaries diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -1,3 +1,7 @@ +"""Implements the core parts of flow graph creation, in tandem +with pypy.objspace.flow.objspace. +""" + import sys import collections diff --git a/pypy/objspace/flow/generator.py b/pypy/objspace/flow/generator.py --- a/pypy/objspace/flow/generator.py +++ b/pypy/objspace/flow/generator.py @@ -1,3 +1,5 @@ +"""Flow graph building for generators""" + from pypy.objspace.flow.model import Block, Link, SpaceOperation, checkgraph from pypy.objspace.flow.model import Variable, Constant from pypy.translator.unsimplify import insert_empty_startblock diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -1,4 +1,7 @@ -# ______________________________________________________________________ +"""Implements the core parts of flow graph creation, in tandem +with pypy.objspace.flow.flowcontext. +""" + import __builtin__ import sys import types From noreply at buildbot.pypy.org Fri Oct 12 17:42:19 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 17:42:19 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: (fijal, arigo) Kill kill kill. Message-ID: <20121012154219.C71271C1C5A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: result-in-resops Changeset: r58068:b83240c8204f Date: 2012-10-12 17:41 +0200 http://bitbucket.org/pypy/pypy/changeset/b83240c8204f/ Log: (fijal, arigo) Kill kill kill. diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -2,16 +2,12 @@ """ This files describes the model used in pyjitpl. Note that all of the following are IMMUTABLE. That means that we cannot just randomly change parameters, instead we need to create a new version and setup the correct -forwarding. Optimizeopt uses optimize_value extra parameter for setting -up the forwarding of resops. Public interface: +forwarding. Public interface: * create_resop, create_resop_0, create_resop_1, create_resop_2, create_resop_3 create resops of various amount of arguments -* BoxInt, BoxFloat, BoxPtr - various types of Boxes. Boxes are inputargs to - the loop. - * ConstInt, ConstFloat, ConstPtr - constant versions of boxes """ @@ -240,10 +236,6 @@ def is_constant(self): return False - @specialize.arg(1) - def get_extra(self, key): - raise KeyError - def get_key_op(self, optimizer): return self @@ -288,175 +280,6 @@ except AttributeError: return box.value -class Box(AbstractValue): - __slots__ = () - _counter = 0 - _extended_display = True - - def nonconstbox(self): - return self - - def _get_hash_(self): - return compute_identity_hash(self) - - def __repr__(self): - result = str(self) - if self._extended_display: - result += '(%s)' % self._getrepr_() - return result - - def __str__(self): - if not hasattr(self, '_str'): - try: - if self.type == INT: - t = 'i' - elif self.type == FLOAT: - t = 'f' - else: - t = 'p' - except AttributeError: - t = 'b' - self._str = '%s%d' % (t, Box._counter) - Box._counter += 1 - return self._str - - def _get_str(self): # for debugging only - return self.constbox()._get_str() - - def forget_value(self): - raise NotImplementedError - - def is_constant(self): - return False - - @specialize.arg(1) - def get_extra(self, key): - if key == 'llgraph_var2index': - return self.llgraph_var2index - if key == 'optimize_value': - try: - return self._optimize_value - except AttributeError: - raise KeyError - raise KeyError - - @specialize.arg(1) - def set_extra(self, key, value): - if key == 'llgraph_var2index': - self.llgraph_var2index = value - return - if key == 'optimize_value': - self._optimize_value = value - return - raise KeyError - - @specialize.arg(1) - def del_extra(self, key): - if key == 'optimize_value': - if hasattr(self, '_optimize_value'): - del self._optimize_value - -class BoxInt(Box): - type = INT - _attrs_ = ('value',) - - def __init__(self, value=0): - if not we_are_translated(): - if is_valid_int(value): - value = int(value) # bool -> int - else: - assert isinstance(value, Symbolic) - self.value = value - - def forget_value(self): - self.value = 0 - - def constbox(self): - return ConstInt(self.value) - - def getint(self): - return self.value - - def getaddr(self): - return heaptracker.int2adr(self.value) - - def nonnull(self): - return self.value != 0 - - def _getrepr_(self): - return self.value - - def repr_rpython(self): - return repr_rpython(self, 'bi') - - def eq_value(self, other): - return self.value == other.getint() - -class BoxFloat(Box): - type = FLOAT - _attrs_ = ('value',) - - def __init__(self, valuestorage=longlong.ZEROF): - assert lltype.typeOf(valuestorage) is longlong.FLOATSTORAGE - self.value = valuestorage - - def forget_value(self): - self.value = longlong.ZEROF - - def constbox(self): - return ConstFloat(self.value) - - def getfloatstorage(self): - return self.value - - def nonnull(self): - return self.value != longlong.ZEROF - - def _getrepr_(self): - return self.getfloat() - - def repr_rpython(self): - return repr_rpython(self, 'bf') - - def eq_value(self, other): - return self.value == other.getfloatstorage() - -class BoxPtr(Box): - type = REF - _attrs_ = ('value',) - - def __init__(self, value=lltype.nullptr(llmemory.GCREF.TO)): - assert lltype.typeOf(value) == llmemory.GCREF - self.value = value - - def forget_value(self): - self.value = lltype.nullptr(llmemory.GCREF.TO) - - def constbox(self): - return ConstPtr(self.value) - - def getref_base(self): - return self.value - - def getref(self, PTR): - return lltype.cast_opaque_ptr(PTR, self.getref_base()) - getref._annspecialcase_ = 'specialize:arg(1)' - - def getaddr(self): - return llmemory.cast_ptr_to_adr(self.value) - - def nonnull(self): - return bool(self.value) - - def repr_rpython(self): - return repr_rpython(self, 'bp') - - def eq_value(self, other): - return self.value == other.getref_base() - - _getrepr_ = repr_pointer - -NULLBOX = BoxPtr() class Const(AbstractValue): __slots__ = () @@ -654,46 +477,6 @@ _hash = 0 opnum = 0 - DOCUMENTED_KEYS = { - 'failargs': 'arguments for guard ops that are alive. ' - 'valid from optimizations (store_final_args) until ' - 'the backend', - 'llgraph_var2index': 'llgraph internal attribute', - 'optimize_value': 'value replacement for the optimizer. only valid for' - ' the length of optimization pass', - 'optimize_replace': 'replacement for the op by another op, can be ' - 'chained', - } - - extras = None - # ResOps are immutable, however someone can store a temporary - # extra mutable stuff here, in the extras field. Other fields (including - # descr) should be deeply immutable. This replaces various dictionaries - # that has been previously used. - - @specialize.arg(1) - def get_extra(self, key): - if key not in self.DOCUMENTED_KEYS: - raise Exception("Please document '%s' extra parameter and it's lifetime" % key) - if not hasattr(self, key): - raise KeyError - return getattr(self, key) - - @specialize.arg(1) - def has_extra(self, key): - return hasattr(self, key) - - @specialize.arg(1) - def set_extra(self, key, value): - if key not in self.DOCUMENTED_KEYS: - raise Exception("Please document '%s' extra parameter and it's lifetime" % key) - setattr(self, key, value) - - @specialize.arg(1) - def del_extra(self, key): - if hasattr(self, key): - delattr(self, key) - @classmethod def getopnum(cls): return cls.opnum @@ -1394,6 +1177,7 @@ '_FINAL_LAST', 'LABEL/*d/N', + 'INPUT/0/*', '_GUARD_FIRST', '_GUARD_FOLDABLE_FIRST', diff --git a/pypy/jit/metainterp/test/test_resoperation.py b/pypy/jit/metainterp/test/test_resoperation.py --- a/pypy/jit/metainterp/test/test_resoperation.py +++ b/pypy/jit/metainterp/test/test_resoperation.py @@ -17,15 +17,18 @@ def __ne__(self, other): return not self == other - def __hash__(self): - return hash(self.v) - def __str__(self): return self.v def is_constant(self): return False + def _get_hash_(self): + return 75 + self.v + + def eq(self, other): + return self.v == other.v + class FakeDescr(AbstractDescr): def __repr__(self): return 'descr' @@ -109,37 +112,6 @@ return FakeBox('rrr') return None -def test_copy_if_modified_by_optimization(): - mydescr = FakeDescr() - op = rop.create_resop_0(rop.rop.GUARD_NO_EXCEPTION, None) - op.setdescr(mydescr) - assert op.copy_if_modified_by_optimization(MockOpt({})) is op - op = rop.create_resop_1(rop.rop.INT_IS_ZERO, 1, FakeBox('a')) - assert op.copy_if_modified_by_optimization(MockOpt({})) is op - op2 = op.copy_if_modified_by_optimization(MockOpt(set([FakeBox('a')]))) - assert op2 is not op - assert op2.getarg(0) == FakeBox('rrr') - op = rop.create_resop_2(rop.rop.INT_ADD, 3, FakeBox("a"), FakeBox("b")) - op2 = op.copy_if_modified_by_optimization(MockOpt(set([FakeBox('c')]))) - assert op2 is op - op2 = op.copy_if_modified_by_optimization(MockOpt(set([FakeBox('b')]))) - assert op2 is not op - assert op2._arg0 is op._arg0 - assert op2._arg1 != op._arg1 - assert op2.getint() == op.getint() - op = rop.create_resop_3(rop.rop.STRSETITEM, None, FakeBox('a'), - FakeBox('b'), FakeBox('c')) - op2 = op.copy_if_modified_by_optimization(MockOpt(set([FakeBox('b')]))) - assert op2 is not op - op = rop.create_resop(rop.rop.CALL_i, 13, [FakeBox('a'), FakeBox('b'), - FakeBox('c')], descr=mydescr) - op2 = op.copy_if_modified_by_optimization(MockOpt(set([FakeBox('aa')]))) - assert op2 is op - op2 = op.copy_if_modified_by_optimization(MockOpt(set([FakeBox('b')]))) - assert op2 is not op - assert op2.getarglist() == [FakeBox("a"), FakeBox("rrr"), FakeBox("c")] - assert op2.getdescr() == mydescr - def test_copy_and_change(): op = rop.create_resop_1(rop.rop.INT_IS_ZERO, 1, FakeBox('a')) op2 = op.copy_and_change(rop.rop.INT_IS_TRUE) @@ -169,13 +141,9 @@ op2 = op.copy_and_change(rop.rop.CALL_i, [FakeBox('a')]) assert op2.getarglist() == ['a'] -def test_get_set_extra(): - op = rop.create_resop_2(rop.rop.INT_ADD, 3, FakeBox("a"), FakeBox("b")) - op.set_extra("failargs", 2) - assert op.get_extra("failargs") == 2 - def test_hashes_eq(): - arg1 = rop.create_resop_1(rop.rop.FLOAT_NEG, 12.5, rop.BoxFloat(3.5)) + arg1 = rop.create_resop_1(rop.rop.FLOAT_NEG, 12.5, + rop.create_resop_0(rop.rop.INPUT_f, 3.5)) op = rop.create_resop_2(rop.rop.FLOAT_ADD, 13.5, rop.ConstFloat(3.0), arg1) ope = rop.create_resop_2(rop.rop.FLOAT_ADD, 13.5, rop.ConstFloat(3.0), @@ -204,39 +172,35 @@ s = lltype.malloc(S) nonnull_ref = lltype.cast_opaque_ptr(llmemory.GCREF, s) nullref = lltype.nullptr(llmemory.GCREF.TO) - op = rop.create_resop_1(rop.rop.NEWSTR, nullref, rop.BoxInt(5)) - op1 = rop.create_resop_1(rop.rop.NEWSTR, nonnull_ref, rop.BoxInt(5)) + op = rop.create_resop_1(rop.rop.NEWSTR, nullref, FakeBox(5)) + op1 = rop.create_resop_1(rop.rop.NEWSTR, nonnull_ref, FakeBox(5)) assert op._get_hash_() != op1._get_hash_() assert not op.eq(op1) - op = rop.create_resop_1(rop.rop.NEWSTR, nullref, rop.BoxInt(5)) - op1 = rop.create_resop_1(rop.rop.NEWSTR, nullref, rop.BoxInt(15)) + op = rop.create_resop_1(rop.rop.NEWSTR, nullref, FakeBox(5)) + op1 = rop.create_resop_1(rop.rop.NEWSTR, nullref, FakeBox(5)) + assert op._get_hash_() == op1._get_hash_() + assert op.eq(op1) + op = rop.create_resop_1(rop.rop.NEWSTR, nullref, FakeBox(5)) + op1 = rop.create_resop_1(rop.rop.NEWSTR, nullref, FakeBox(15)) assert op._get_hash_() != op1._get_hash_() assert not op.eq(op1) descr = FakeDescr() descr2 = FakeDescr() - op = rop.create_resop(rop.rop.CALL_i, 12, [rop.BoxInt(0), rop.BoxFloat(2.0), - rop.BoxPtr(nullref)], descr) - op1 = rop.create_resop(rop.rop.CALL_i, 12, [rop.BoxInt(0), - rop.BoxFloat(2.0), - rop.BoxPtr(nullref)], descr2) - op2 = rop.create_resop(rop.rop.CALL_i, 12, [rop.BoxInt(0), - rop.BoxFloat(2.5), - rop.BoxPtr(nullref)], descr) - op3 = rop.create_resop(rop.rop.CALL_i, 15, [rop.BoxInt(0), - rop.BoxFloat(2.0), - rop.BoxPtr(nullref)], descr) - op4 = rop.create_resop(rop.rop.CALL_i, 12, [rop.BoxInt(0), - rop.BoxFloat(2.0), - rop.BoxPtr(nonnull_ref)], descr) + op = rop.create_resop(rop.rop.CALL_i, 12, [FakeBox(0), FakeBox(2), + FakeBox(4)], descr) + op1 = rop.create_resop(rop.rop.CALL_i, 12, [FakeBox(0), FakeBox(2), + FakeBox(4)], descr2) + op2 = rop.create_resop(rop.rop.CALL_i, 12, [FakeBox(0), FakeBox(3), + FakeBox(4)], descr) + op3 = rop.create_resop(rop.rop.CALL_i, 15, [FakeBox(0), FakeBox(2), + FakeBox(4)], descr) assert op1._get_hash_() != op._get_hash_() assert op2._get_hash_() != op._get_hash_() assert op3._get_hash_() != op._get_hash_() - assert op4._get_hash_() != op._get_hash_() assert not op.eq(op1) assert not op.eq(op2) assert not op.eq(op3) - assert not op.eq(op4) # class StrangeDescr(AbstractDescr): # def _get_hash_(self): From noreply at buildbot.pypy.org Fri Oct 12 18:18:37 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 18:18:37 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: kill a bit more stuff Message-ID: <20121012161837.A671F1C0FE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: result-in-resops Changeset: r58069:3a4f00542c79 Date: 2012-10-12 18:18 +0200 http://bitbucket.org/pypy/pypy/changeset/3a4f00542c79/ Log: kill a bit more stuff diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -803,7 +803,7 @@ return 0 # for tests return compute_identity_hash(self._descr) -class GuardResOp(ResOpWithDescr): +class GuardResOp(PlainResOp): # gathered during tracing _rd_snapshot = None @@ -872,9 +872,6 @@ res.set_rd_snapshot(self.get_rd_snapshot()) return res - def copy_if_modified_by_optimization(self, opt): - return self - def get_key_op(self, opt): return self @@ -906,18 +903,6 @@ def foreach_arg(self, func, arg): func(arg, self.getopnum(), 0, self._arg0) - @specialize.argtype(1) - def copy_if_modified_by_optimization(self, opt): - new_arg = opt.get_value_replacement(self._arg0) - if new_arg is None: - return self - res = create_resop_1(self.opnum, self.getresult(), new_arg, - self.getdescr()) - if self.is_guard(): - res.set_rd_frame_info_list(self.get_rd_frame_info_list()) - res.set_rd_snapshot(self.get_rd_snapshot()) - return res - def get_key_op(self, opt): new_arg = opt.getvalue(self._arg0).get_key_box() if new_arg is self._arg0: @@ -971,21 +956,6 @@ func(arg, self.getopnum(), 1, self._arg1) @specialize.argtype(1) - def copy_if_modified_by_optimization(self, opt): - new_arg0 = opt.get_value_replacement(self._arg0) - new_arg1 = opt.get_value_replacement(self._arg1) - if new_arg0 is None and new_arg1 is None: - return self - res = create_resop_2(self.opnum, self.getresult(), - new_arg0 or self._arg0, - new_arg1 or self._arg1, - self.getdescr()) - if self.is_guard(): - res.set_rd_frame_info_list(self.get_rd_frame_info_list()) - res.set_rd_snapshot(self.get_rd_snapshot()) - return res - - @specialize.argtype(1) def get_key_op(self, opt): new_arg0 = opt.getvalue(self._arg0).get_key_box() new_arg1 = opt.getvalue(self._arg1).get_key_box() @@ -1045,20 +1015,6 @@ func(arg, self.getopnum(), 2, self._arg2) @specialize.argtype(1) - def copy_if_modified_by_optimization(self, opt): - assert not self.is_guard() - new_arg0 = opt.get_value_replacement(self._arg0) - new_arg1 = opt.get_value_replacement(self._arg1) - new_arg2 = opt.get_value_replacement(self._arg2) - if new_arg0 is None and new_arg1 is None and new_arg2 is None: - return self - return create_resop_3(self.opnum, self.getresult(), - new_arg0 or self._arg0, - new_arg1 or self._arg1, - new_arg2 or self._arg2, - self.getdescr()) - - @specialize.argtype(1) def get_key_op(self, opt): new_arg0 = opt.getvalue(self._arg0).get_key_box() new_arg1 = opt.getvalue(self._arg1).get_key_box() @@ -1111,24 +1067,6 @@ func(func_arg, self.getopnum(), i, arg) @specialize.argtype(1) - def copy_if_modified_by_optimization(self, opt): - newargs = None - for i, arg in enumerate(self._args): - new_arg = opt.get_value_replacement(arg) - if new_arg is not None: - if newargs is None: - newargs = newlist_hint(len(self._args)) - for k in range(i): - newargs.append(self._args[k]) - newargs.append(new_arg) - elif newargs is not None: - newargs.append(arg) - if newargs is None: - return self - return create_resop(self.opnum, self.getresult(), - newargs, self.getdescr()) - - @specialize.argtype(1) def get_key_op(self, opt): newargs = None for i, arg in enumerate(self._args): @@ -1181,20 +1119,20 @@ '_GUARD_FIRST', '_GUARD_FOLDABLE_FIRST', - 'GUARD_TRUE/1d/N', - 'GUARD_FALSE/1d/N', - 'GUARD_VALUE/2d/N', - 'GUARD_CLASS/2d/N', - 'GUARD_NONNULL/1d/N', - 'GUARD_ISNULL/1d/N', - 'GUARD_NONNULL_CLASS/2d/N', + 'GUARD_TRUE/1/N', + 'GUARD_FALSE/1/N', + 'GUARD_VALUE/2/N', + 'GUARD_CLASS/2/N', + 'GUARD_NONNULL/1/N', + 'GUARD_ISNULL/1/N', + 'GUARD_NONNULL_CLASS/2/N', '_GUARD_FOLDABLE_LAST', - 'GUARD_NO_EXCEPTION/0d/N', # may be called with an exception currently set - 'GUARD_EXCEPTION/1d/r', # may be called with an exception currently set - 'GUARD_NO_OVERFLOW/0d/N', - 'GUARD_OVERFLOW/0d/N', - 'GUARD_NOT_FORCED/0d/N', # may be called with an exception currently set - 'GUARD_NOT_INVALIDATED/0d/N', + 'GUARD_NO_EXCEPTION/0/N', # may be called with an exception currently set + 'GUARD_EXCEPTION/1/r', # may be called with an exception currently set + 'GUARD_NO_OVERFLOW/0/N', + 'GUARD_OVERFLOW/0/N', + 'GUARD_NOT_FORCED/0/N', # may be called with an exception currently set + 'GUARD_NOT_INVALIDATED/0/N', '_GUARD_LAST', # ----- end of guard operations ----- '_NOSIDEEFFECT_FIRST', # ----- start of no_side_effect operations ----- From noreply at buildbot.pypy.org Fri Oct 12 18:22:27 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 18:22:27 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Ah ah, we can get 'Aborted (core dumped)' too. General fix. Message-ID: <20121012162227.CE6D91C0FE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58070:077647c293a7 Date: 2012-10-12 18:22 +0200 http://bitbucket.org/pypy/pypy/changeset/077647c293a7/ Log: Ah ah, we can get 'Aborted (core dumped)' too. General fix. diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -138,10 +138,8 @@ print '--------------' stderr, prevline, lastline, empty = stderr.rsplit('\n', 3) assert empty == '' - if lastline == 'Aborted': - lastline = prevline - assert lastline == ('Fatal RPython error: ' + - expected_exception_name) + expected = 'Fatal RPython error: ' + expected_exception_name + assert lastline == expected or prevline == expected return None output(stdout) From noreply at buildbot.pypy.org Fri Oct 12 18:27:47 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 18:27:47 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: bah Message-ID: <20121012162747.DE2711C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58071:afe76c7cb0cd Date: 2012-10-12 18:24 +0200 http://bitbucket.org/pypy/pypy/changeset/afe76c7cb0cd/ Log: bah 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 @@ -535,7 +535,8 @@ @unwrap_spec(offset=int) def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None, offset=0, w_strides=None, w_order=None): - if (offset != 0 or space.is_none(w_strides) or not space.is_none(w_order) or + if (offset != 0 or not space.is_none(w_strides) or + not space.is_none(w_order) or not space.is_none(w_buffer)): raise OperationError(space.w_NotImplementedError, space.wrap("unsupported param")) From noreply at buildbot.pypy.org Fri Oct 12 18:27:49 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 18:27:49 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge Message-ID: <20121012162749.0DB531C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58072:da5f9d700d45 Date: 2012-10-12 18:27 +0200 http://bitbucket.org/pypy/pypy/changeset/da5f9d700d45/ Log: merge diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -138,10 +138,8 @@ print '--------------' stderr, prevline, lastline, empty = stderr.rsplit('\n', 3) assert empty == '' - if lastline == 'Aborted': - lastline = prevline - assert lastline == ('Fatal RPython error: ' + - expected_exception_name) + expected = 'Fatal RPython error: ' + expected_exception_name + assert lastline == expected or prevline == expected return None output(stdout) From noreply at buildbot.pypy.org Fri Oct 12 18:53:06 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 18:53:06 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Change the default to make crashes a little bit less obscure Message-ID: <20121012165306.0FAA91C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58073:119b9df1047e Date: 2012-10-12 18:33 +0200 http://bitbucket.org/pypy/pypy/changeset/119b9df1047e/ Log: Change the default to make crashes a little bit less obscure (OpErrFmt asserts that w_type is not None) diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -58,8 +58,8 @@ # the following exceptions should not show up # during flow graph construction - w_NameError = None - w_UnboundLocalError = None + w_NameError = 'NameError' + w_UnboundLocalError = 'UnboundLocalError' specialcases = SPECIAL_CASES # objects which should keep their SomeObjectness From noreply at buildbot.pypy.org Fri Oct 12 18:53:07 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 18:53:07 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Fix properly, with a test, the escaping. Argh. Message-ID: <20121012165307.515F01C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58074:9b93e53bec31 Date: 2012-10-12 18:52 +0200 http://bitbucket.org/pypy/pypy/changeset/9b93e53bec31/ Log: Fix properly, with a test, the escaping. Argh. diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py --- a/pypy/translator/c/test/test_genc.py +++ b/pypy/translator/c/test/test_genc.py @@ -26,7 +26,10 @@ elif isinstance(v, float): return repr(v) # extra precision than str(v) elif isinstance(v, str): - return v + '.' + if v.isalnum(): + return v + else: # escape the string + return '/' + ','.join([str(ord(c)) for c in v]) return str(v) @specialize.argtype(0) @@ -83,7 +86,13 @@ else: args += (float(a),) else: - args += (a[:-1],) + if a.startswith('/'): # escaped string + if len(a) == 1: + a = '' + else: + l = a[1:].split(',') + a = ''.join([chr(int(x)) for x in l]) + args += (a,) res = fn(*args) print "THE RESULT IS:", llrepr_out(res), ";" return 0 @@ -196,6 +205,20 @@ py.test.raises(Exception, f1, "world") # check that it's really typed +def test_string_arg(): + def f(s): + total = 0 + for c in s: + total += ord(c) + return total + len(s) + + f1 = compile(f, [str]) + + for check in ['x', '', '\x00', '\x01', '\n', '\x7f', '\xff', + '\x00\x00', '\x00\x01']: + assert f1(check) == len(check) + sum(map(ord, check)) + + def test_dont_write_source_files(): def f(x): return x*2 From noreply at buildbot.pypy.org Fri Oct 12 18:53:08 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 18:53:08 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: merge heads Message-ID: <20121012165308.7D5BB1C1C59@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58075:d2ffb5175e87 Date: 2012-10-12 18:52 +0200 http://bitbucket.org/pypy/pypy/changeset/d2ffb5175e87/ Log: merge heads 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 @@ -535,7 +535,8 @@ @unwrap_spec(offset=int) def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None, offset=0, w_strides=None, w_order=None): - if (offset != 0 or space.is_none(w_strides) or not space.is_none(w_order) or + if (offset != 0 or not space.is_none(w_strides) or + not space.is_none(w_order) or not space.is_none(w_buffer)): raise OperationError(space.w_NotImplementedError, space.wrap("unsupported param")) From noreply at buildbot.pypy.org Fri Oct 12 19:01:35 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 19:01:35 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: Add optmodel Message-ID: <20121012170135.06B041C1C5A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58076:c2a22f88e26a Date: 2012-10-12 19:01 +0200 http://bitbucket.org/pypy/pypy/changeset/c2a22f88e26a/ Log: Add optmodel diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py new file mode 100644 --- /dev/null +++ b/pypy/jit/metainterp/optmodel.py @@ -0,0 +1,18 @@ + +""" Mutable subclasses for each of ResOperation. +""" + +from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable + +def create_mutable_subclasses(): + for i, cls in enumerate(opclasses): + if cls is None: + Mutable = None + else: + class Mutable(cls): + is_mutable = True + Mutable.__name__ = cls.__name__ + '_mutable' + assert len(opclasses_mutable) == i + opclasses_mutable.append(Mutable) + +create_mutable_subclasses() diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -43,11 +43,18 @@ else: return create_resop(opnum, result, args, descr) - at specialize.arg(0) -def create_resop(opnum, result, args, descr=None): + at specialize.memo() +def _getcls(opnum, mutable): + if mutable: + return opclasses_mutable[opnum] + else: + return opclasses[opnum] + + at specialize.arg(0, 4) +def create_resop(opnum, result, args, descr=None, mutable=False): """ Create an N-args resop with given opnum and args """ - cls = opclasses[opnum] + cls = _getcls(opnum, mutable) assert cls.NUMARGS == -1 if cls.is_always_pure(): for arg in args: @@ -68,11 +75,11 @@ op.setdescr(descr) return op - at specialize.arg(0) -def create_resop_0(opnum, result, descr=None): + at specialize.arg(0, 3) +def create_resop_0(opnum, result, descr=None, mutable=False): """ Create an 0-arg resop with given opnum and args """ - cls = opclasses[opnum] + cls = _getcls(opnum, mutable) assert cls.NUMARGS == 0 if result is None: op = cls() @@ -84,11 +91,11 @@ op.setdescr(descr) return op - at specialize.arg(0) -def create_resop_1(opnum, result, arg0, descr=None): + at specialize.arg(0, 4) +def create_resop_1(opnum, result, arg0, descr=None, mutable=False): """ Create a 1-arg resop with given opnum and args """ - cls = opclasses[opnum] + cls = _getcls(opnum, mutable) assert cls.NUMARGS == 1 if (cls.is_always_pure() and opnum not in (rop.SAME_AS_i, rop.SAME_AS_f, rop.SAME_AS_r)): @@ -106,11 +113,11 @@ op.setdescr(descr) return op - at specialize.arg(0) -def create_resop_2(opnum, result, arg0, arg1, descr=None): + at specialize.arg(0, 5) +def create_resop_2(opnum, result, arg0, arg1, descr=None, mutable=False): """ Create a 2-arg resop with given opnum and args """ - cls = opclasses[opnum] + cls = _getcls(opnum, mutable) assert cls.NUMARGS == 2 if cls.is_always_pure(): if arg0.is_constant() and arg1.is_constant(): @@ -129,11 +136,11 @@ op.setdescr(descr) return op - at specialize.arg(0) -def create_resop_3(opnum, result, arg0, arg1, arg2, descr=None): + at specialize.arg(0, 6) +def create_resop_3(opnum, result, arg0, arg1, arg2, descr=None, mutable=False): """ Create a 3-arg resop with given opnum and args """ - cls = opclasses[opnum] + cls = _getcls(opnum, mutable) assert cls.NUMARGS == 3 if cls.is_always_pure(): if arg0.is_constant() and arg1.is_constant() and arg2.is_constant(): @@ -474,9 +481,13 @@ # debug name = "" pc = 0 + _hash = 0 opnum = 0 + is_mutable = False + _forwarded = None + @classmethod def getopnum(cls): return cls.opnum @@ -862,11 +873,11 @@ pass @specialize.arg(1) - def copy_and_change(self, newopnum=-1, descr=None): + def mutable_copy(self, newopnum=-1, descr=None): if newopnum == -1: newopnum = self.getopnum() res = create_resop_0(newopnum, self.getresult(), - descr or self.getdescr()) + descr or self.getdescr(), mutable=True) if self.is_guard(): res.set_rd_frame_info_list(self.get_rd_frame_info_list()) res.set_rd_snapshot(self.get_rd_snapshot()) @@ -912,11 +923,11 @@ return res @specialize.arg(1) - def copy_and_change(self, newopnum=-1, arg0=None, descr=None): + def mutable_copy(self, newopnum=-1, arg0=None, descr=None): if newopnum == -1: newopnum = self.getopnum() res = create_resop_1(newopnum, self.getresult(), arg0 or self._arg0, - descr or self.getdescr()) + descr or self.getdescr(), mutable=True) if self.is_guard(): res.set_rd_frame_info_list(self.get_rd_frame_info_list()) res.set_rd_snapshot(self.get_rd_snapshot()) @@ -965,12 +976,13 @@ new_arg0, new_arg1, self.getdescr()) @specialize.arg(1) - def copy_and_change(self, newopnum=-1, arg0=None, arg1=None, descr=None): + def mutable_copy(self, newopnum=-1, arg0=None, arg1=None, descr=None): if newopnum == -1: newopnum = self.getopnum() res = create_resop_2(newopnum, self.getresult(), arg0 or self._arg0, arg1 or self._arg1, - descr or self.getdescr()) + descr or self.getdescr(), + mutable=True) if self.is_guard(): res.set_rd_frame_info_list(self.get_rd_frame_info_list()) res.set_rd_snapshot(self.get_rd_snapshot()) @@ -1026,13 +1038,13 @@ new_arg0, new_arg1, new_arg2, self.getdescr()) @specialize.arg(1) - def copy_and_change(self, newopnum=-1, arg0=None, arg1=None, arg2=None, - descr=None): + def mutable_copy(self, newopnum=-1, arg0=None, arg1=None, arg2=None, + descr=None): if newopnum == -1: newopnum = self.getopnum() r = create_resop_3(newopnum, self.getresult(), arg0 or self._arg0, arg1 or self._arg1, arg2 or self._arg2, - descr or self.getdescr()) + descr or self.getdescr(), mutable=True) assert not r.is_guard() return r @@ -1085,12 +1097,12 @@ newargs, self.getdescr()) @specialize.arg(1) - def copy_and_change(self, newopnum=-1, newargs=None, descr=None): + def mutable_copy(self, newopnum=-1, newargs=None, descr=None): if newopnum == -1: newopnum = self.getopnum() r = create_resop(newopnum, self.getresult(), newargs or self.getarglist(), - descr or self.getdescr()) + descr or self.getdescr(), mutable=True) assert not r.is_guard() return r @@ -1284,6 +1296,8 @@ pass # for convinience opclasses = [] # mapping numbers to the concrete ResOp class + # mapping numbers to the concrete ResOp, mutable version +opclasses_mutable = [] opname = {} # mapping numbers to the original names, for debugging oparity = [] # mapping numbers to the arity of the operation or -1 opwithdescr = [] # mapping numbers to a flag "takes a descr" @@ -1366,7 +1380,7 @@ is_guard = name.startswith('GUARD') if is_guard: - assert withdescr + assert not withdescr baseclass = GuardResOp elif withdescr: baseclass = ResOpWithDescr diff --git a/pypy/jit/metainterp/test/test_optmodel.py b/pypy/jit/metainterp/test/test_optmodel.py new file mode 100644 --- /dev/null +++ b/pypy/jit/metainterp/test/test_optmodel.py @@ -0,0 +1,38 @@ + +""" Direct tests of optmodel.py +""" + +from pypy.jit.metainterp.test.test_resoperation import FakeBox, FakeDescr +from pypy.jit.metainterp import resoperation as rop +from pypy.jit.metainterp import optmodel + +def test_mutable_copy(): + op = rop.create_resop_1(rop.rop.INT_IS_ZERO, 1, FakeBox('a')) + assert not op.is_mutable + op2 = op.mutable_copy(rop.rop.INT_IS_TRUE) + assert op2.opnum == rop.rop.INT_IS_TRUE + assert op2.getarg(0) == FakeBox('a') + op2 = op.mutable_copy(rop.rop.INT_IS_TRUE, FakeBox('b')) + assert op2.is_mutable + assert op2.opnum == rop.rop.INT_IS_TRUE + assert op2.getarg(0) == FakeBox('b') + assert op2 is not op + op = rop.create_resop_2(rop.rop.INT_ADD, 3, FakeBox("a"), FakeBox("b")) + op2 = op.mutable_copy(rop.rop.INT_SUB) + assert op2.opnum == rop.rop.INT_SUB + assert op2.getarglist() == [FakeBox("a"), FakeBox("b")] + op2 = op.mutable_copy(rop.rop.INT_SUB, None, FakeBox("c")) + assert op2.opnum == rop.rop.INT_SUB + assert op2.getarglist() == [FakeBox("a"), FakeBox("c")] + op = rop.create_resop_3(rop.rop.STRSETITEM, None, FakeBox('a'), + FakeBox('b'), FakeBox('c')) + op2 = op.mutable_copy(rop.rop.UNICODESETITEM, None, FakeBox("c")) + assert op2.opnum == rop.rop.UNICODESETITEM + assert op2.getarglist() == [FakeBox("a"), FakeBox("c"), FakeBox("c")] + mydescr = FakeDescr() + op = rop.create_resop(rop.rop.CALL_PURE_i, 13, [FakeBox('a'), FakeBox('b'), + FakeBox('c')], descr=mydescr) + op2 = op.mutable_copy(rop.rop.CALL_i) + assert op2.getarglist() == ['a', 'b', 'c'] + op2 = op.mutable_copy(rop.rop.CALL_i, [FakeBox('a')]) + assert op2.getarglist() == ['a'] diff --git a/pypy/jit/metainterp/test/test_resoperation.py b/pypy/jit/metainterp/test/test_resoperation.py --- a/pypy/jit/metainterp/test/test_resoperation.py +++ b/pypy/jit/metainterp/test/test_resoperation.py @@ -95,10 +95,8 @@ FakeBox('b')).can_malloc() def test_repr(): - mydescr = FakeDescr() op = rop.create_resop_0(rop.rop.GUARD_NO_EXCEPTION, None) - op.setdescr(mydescr) - assert repr(op) == 'guard_no_exception(, descr=descr)' + assert repr(op) == 'guard_no_exception()' op = rop.create_resop_2(rop.rop.INT_ADD, 3, FakeBox("a"), FakeBox("b")) assert repr(op) == '3 = int_add(a, b)' # XXX more tests once we decide what we actually want to print @@ -112,35 +110,6 @@ return FakeBox('rrr') return None -def test_copy_and_change(): - op = rop.create_resop_1(rop.rop.INT_IS_ZERO, 1, FakeBox('a')) - op2 = op.copy_and_change(rop.rop.INT_IS_TRUE) - assert op2.opnum == rop.rop.INT_IS_TRUE - assert op2.getarg(0) == FakeBox('a') - op2 = op.copy_and_change(rop.rop.INT_IS_TRUE, FakeBox('b')) - assert op2.opnum == rop.rop.INT_IS_TRUE - assert op2.getarg(0) == FakeBox('b') - assert op2 is not op - op = rop.create_resop_2(rop.rop.INT_ADD, 3, FakeBox("a"), FakeBox("b")) - op2 = op.copy_and_change(rop.rop.INT_SUB) - assert op2.opnum == rop.rop.INT_SUB - assert op2.getarglist() == [FakeBox("a"), FakeBox("b")] - op2 = op.copy_and_change(rop.rop.INT_SUB, None, FakeBox("c")) - assert op2.opnum == rop.rop.INT_SUB - assert op2.getarglist() == [FakeBox("a"), FakeBox("c")] - op = rop.create_resop_3(rop.rop.STRSETITEM, None, FakeBox('a'), - FakeBox('b'), FakeBox('c')) - op2 = op.copy_and_change(rop.rop.UNICODESETITEM, None, FakeBox("c")) - assert op2.opnum == rop.rop.UNICODESETITEM - assert op2.getarglist() == [FakeBox("a"), FakeBox("c"), FakeBox("c")] - mydescr = FakeDescr() - op = rop.create_resop(rop.rop.CALL_PURE_i, 13, [FakeBox('a'), FakeBox('b'), - FakeBox('c')], descr=mydescr) - op2 = op.copy_and_change(rop.rop.CALL_i) - assert op2.getarglist() == ['a', 'b', 'c'] - op2 = op.copy_and_change(rop.rop.CALL_i, [FakeBox('a')]) - assert op2.getarglist() == ['a'] - def test_hashes_eq(): arg1 = rop.create_resop_1(rop.rop.FLOAT_NEG, 12.5, rop.create_resop_0(rop.rop.INPUT_f, 3.5)) From noreply at buildbot.pypy.org Fri Oct 12 19:03:12 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 12 Oct 2012 19:03:12 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: Kill this complicated logic that crashes in Message-ID: <20121012170312.0F26B1C1C5A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-someobject Changeset: r58077:e5b2826ed555 Date: 2012-10-12 19:02 +0200 http://bitbucket.org/pypy/pypy/changeset/e5b2826ed555/ Log: Kill this complicated logic that crashes in module.unicodedata.test.test_unicodedata because it's wrong when generalizing. diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -39,13 +39,7 @@ def type(obj, *moreargs): if moreargs: raise Exception, 'type() called with more than one argument' - if obj.is_constant(): - if isinstance(obj, SomeInstance): - r = SomePBC([obj.classdef.classdesc]) - else: - r = immutablevalue(obj.knowntype) - else: - r = SomeType() + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator From noreply at buildbot.pypy.org Fri Oct 12 19:47:47 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 19:47:47 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: move stuff around Message-ID: <20121012174747.D57441C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58078:93c02fed9531 Date: 2012-10-12 19:47 +0200 http://bitbucket.org/pypy/pypy/changeset/93c02fed9531/ Log: move stuff around diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -481,12 +481,13 @@ # debug name = "" pc = 0 + _counter = 0 _hash = 0 opnum = 0 is_mutable = False - _forwarded = None + _forwarded = None @classmethod def getopnum(cls): @@ -566,11 +567,25 @@ except NotImplementedError: return object.__repr__(self) + def __str__(self): + if not hasattr(self, '_str'): + if self.type == INT: + t = 'i' + elif self.type == FLOAT: + t = 'f' + else: + t = 'p' + self._str = '%s%d' % (t, AbstractResOp._counter) + AbstractResOp._counter += 1 + return self._str + def repr(self, graytext=False): # RPython-friendly version + args = self.getarglist() + argsrepr = ', '.join([str(a) for a in args]) resultrepr = self.getresultrepr() if resultrepr is not None: - sres = '%s = ' % (resultrepr,) + sres = '%s = ' % (str(self),) else: sres = '' if self.name: @@ -579,14 +594,12 @@ prefix = "\f%s\f" % prefix else: prefix = "" - args = self.getarglist() descr = self.getdescr() if descr is None or we_are_translated(): - return '%s%s%s(%s)' % (prefix, sres, self.getopname(), - ', '.join([str(a) for a in args])) + return '%s%s%s(%s)' % (prefix, sres, self.getopname(), argsrepr) else: return '%s%s%s(%s, descr=%r)' % (prefix, sres, self.getopname(), - ', '.join([str(a) for a in args]), descr) + argsrepr, descr) @classmethod def getopname(cls): @@ -685,7 +698,7 @@ class ResOpInt(object): _mixin_ = True type = INT - + def __init__(self, intval): assert isinstance(intval, int) self.intval = intval @@ -713,7 +726,7 @@ class ResOpFloat(object): _mixin_ = True type = FLOAT - + def __init__(self, floatval): #assert isinstance(floatval, float) # XXX not sure between float or float storage @@ -742,7 +755,7 @@ class ResOpPointer(object): _mixin_ = True type = REF - + def __init__(self, pval): assert lltype.typeOf(pval) == llmemory.GCREF self.pval = pval diff --git a/pypy/jit/metainterp/test/test_resoperation.py b/pypy/jit/metainterp/test/test_resoperation.py --- a/pypy/jit/metainterp/test/test_resoperation.py +++ b/pypy/jit/metainterp/test/test_resoperation.py @@ -97,9 +97,11 @@ def test_repr(): op = rop.create_resop_0(rop.rop.GUARD_NO_EXCEPTION, None) assert repr(op) == 'guard_no_exception()' - op = rop.create_resop_2(rop.rop.INT_ADD, 3, FakeBox("a"), FakeBox("b")) - assert repr(op) == '3 = int_add(a, b)' - # XXX more tests once we decide what we actually want to print + c = op._counter + i0 = rop.create_resop_0(rop.rop.INPUT_i, 3) + op = rop.create_resop_2(rop.rop.INT_ADD, 3, i0, i0) + assert repr(op) == 'i%d = int_add(i%d, i%d)' % (c+1, c, c) + assert str(op) == 'i%d' % (c + 1,) class MockOpt(object): def __init__(self, replacements): diff --git a/pypy/jit/metainterp/typesystem.py b/pypy/jit/metainterp/typesystem.py --- a/pypy/jit/metainterp/typesystem.py +++ b/pypy/jit/metainterp/typesystem.py @@ -43,7 +43,6 @@ nullptr = staticmethod(lltype.nullptr) cast_instance_to_base_ref = staticmethod(cast_instance_to_base_ptr) BASETYPE = llmemory.GCREF - BoxRef = resoperation.BoxPtr ConstRef = resoperation.ConstPtr loops_done_with_this_frame_ref = None # patched by compile.py NULLREF = resoperation.ConstPtr.value @@ -86,9 +85,6 @@ def get_exception_box(self, etype): return resoperation.ConstInt(etype) - def get_exc_value_box(self, evalue): - return resoperation.BoxPtr(evalue) - def get_exception_obj(self, evaluebox): # only works when translated obj = evaluebox.getref(lltype.Ptr(rclass.OBJECT)) @@ -152,7 +148,6 @@ nullptr = staticmethod(ootype.null) cast_instance_to_base_ref = staticmethod(cast_instance_to_base_obj) BASETYPE = ootype.Object - #BoxRef = resoperation.BoxObj #ConstRef = resoperation.ConstObj loops_done_with_this_frame_ref = None # patched by compile.py #$NULLREF = resoperation.ConstObj.value @@ -193,9 +188,6 @@ def get_exception_box(self, etype): return resoperation.ConstObj(etype) - def get_exc_value_box(self, evalue): - return resoperation.BoxObj(evalue) - def get_exception_obj(self, evaluebox): # only works when translated obj = evaluebox.getref(ootype.ROOT) diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -7,7 +7,7 @@ from pypy.jit.metainterp.resoperation import rop, opclasses, rop_lowercase,\ ResOpWithDescr, N_aryOp, UnaryOp, PlainResOp, create_resop_dispatch,\ - ResOpNone + ResOpNone, create_resop_0, example_for_opnum from pypy.rpython.lltypesystem import lltype, llmemory class ParseError(Exception): @@ -67,25 +67,23 @@ use_mock_model = False - def __init__(self, input, cpu, namespace, type_system, boxkinds, - invent_fail_descr=True, - nonstrict=False, results=None, process_guard=None): + def __init__(self, input, cpu, namespace, type_system, + invent_fail_descr=True, results=None, + guards_with_failargs=False): self.input = input self.vars = {} self.cpu = cpu self._consts = namespace self.type_system = type_system - self.boxkinds = boxkinds or {} + self.guards_with_failargs = guards_with_failargs if namespace is not None: self._cache = namespace.setdefault('_CACHE_', {}) else: self._cache = {} self.invent_fail_descr = invent_fail_descr - self.nonstrict = nonstrict self.model = get_model(self.use_mock_model) self.original_jitcell_token = self.model.JitCellToken() self.results = results - self.process_guard = process_guard def get_const(self, name, typ): if self._consts is None: @@ -123,25 +121,15 @@ return self._cache[self.type_system, elem] except KeyError: pass - if elem.startswith('i'): - # integer - box = self.model.BoxInt() - _box_counter_more_than(self.model, elem[1:]) - elif elem.startswith('f'): - box = self.model.BoxFloat() - _box_counter_more_than(self.model, elem[1:]) - elif elem.startswith('p'): - # pointer - ts = getattr(self.cpu, 'ts', self.model.llhelper) - box = ts.BoxRef() - _box_counter_more_than(self.model, elem[1:]) + if elem[0] in 'ifp': + if elem[0] == 'p': + p = 'r' + else: + p = elem[0] + opnum = getattr(rop, 'INPUT_' + p) + box = create_resop_0(opnum, example_for_opnum(opnum)) else: - for prefix, boxclass in self.boxkinds.iteritems(): - if elem.startswith(prefix): - box = boxclass() - break - else: - raise ParseError("Unknown variable type: %s" % elem) + raise ParseError("Unknown variable type: %s" % elem) self._cache[self.type_system, elem] = box box._str = elem return box @@ -196,8 +184,8 @@ elif arg.startswith('ConstPtr('): name = arg[len('ConstPtr('):-1] return self.get_const(name, 'ptr') - if arg not in self.vars and self.nonstrict: - self.newvar(arg) + if arg not in self.vars: + raise Exception("unexpected var %s" % (arg,)) return self.vars[arg] def _example_for(self, opnum): @@ -253,10 +241,12 @@ i = line.find('[', endnum) + 1 j = line.find(']', i) if i <= 0 or j <= 0: - if not self.nonstrict: + if self.guards_with_failargs: raise ParseError("missing fail_args for guard operation") fail_args = None else: + if not self.guards_with_failargs: + raise ParseError("fail_args should be NULL") fail_args = [] if i < j: for arg in line[i:j].split(','): @@ -303,18 +293,14 @@ opres = self.create_op(opnum, result, args, descr) self.vars[res] = opres if fail_args is not None: - opres.set_extra("failargs", fail_args) - if self.process_guard and opres.is_guard(): - self.process_guard(opres, self) + explode return opres def parse_op_no_result(self, line): opnum, args, descr, fail_args = self.parse_op(line) res = self.create_op(opnum, None, args, descr) if fail_args is not None: - res.set_extra("failargs", fail_args) - if self.process_guard and res.is_guard(): - self.process_guard(res, self) + explode return res def parse_next_op(self, line, num): @@ -396,8 +382,8 @@ line = lines[0] base_indent = len(line) - len(line.lstrip(' ')) line = line.strip() - if not line.startswith('[') and self.nonstrict: - return base_indent, [], lines + if not line.startswith('['): + raise ParseError("error parsing %s as inputargs" % (line,)) lines = lines[1:] if line == '[]': return base_indent, [], lines @@ -406,21 +392,16 @@ inpargs = self.parse_header_line(line[1:-1]) return base_indent, inpargs, lines -def parse(input, cpu=None, namespace=None, type_system='lltype', - boxkinds=None, invent_fail_descr=True, - no_namespace=False, nonstrict=False, OpParser=OpParser, - results=None, process_guard=None): - if namespace is None and not no_namespace: +DEFAULT = object() + +def parse(input, cpu=None, namespace=DEFAULT, type_system='lltype', + invent_fail_descr=True, OpParser=OpParser, + results=None, guards_with_failargs=False): + if namespace is DEFAULT: namespace = {} - return OpParser(input, cpu, namespace, type_system, boxkinds, - invent_fail_descr, nonstrict, results, - process_guard).parse() + return OpParser(input, cpu, namespace, type_system, + invent_fail_descr, results, guards_with_failargs).parse() def pure_parse(*args, **kwds): kwds['invent_fail_descr'] = False return parse(*args, **kwds) - - -def _box_counter_more_than(model, s): - if s.isdigit(): - model.Box._counter = max(model.Box._counter, int(s)+1) diff --git a/pypy/jit/tool/oparser_model.py b/pypy/jit/tool/oparser_model.py --- a/pypy/jit/tool/oparser_model.py +++ b/pypy/jit/tool/oparser_model.py @@ -4,7 +4,6 @@ def get_real_model(): class LoopModel(object): from pypy.jit.metainterp.history import TreeLoop, JitCellToken - from pypy.jit.metainterp.resoperation import Box, BoxInt, BoxFloat from pypy.jit.metainterp.resoperation import ConstInt,\ ConstPtr, ConstFloat from pypy.jit.metainterp.history import BasicFailDescr, TargetToken @@ -50,36 +49,6 @@ class BasicFailDescr(object): I_am_a_descr = True - class Box(object): - _counter = 0 - type = 'b' - - def __init__(self, value=0): - self.value = value - - def __repr__(self): - result = str(self) - result += '(%s)' % self.value - return result - - def __str__(self): - if not hasattr(self, '_str'): - self._str = '%s%d' % (self.type, Box._counter) - Box._counter += 1 - return self._str - - def is_constant(self): - return False - - class BoxInt(Box): - type = 'i' - - class BoxFloat(Box): - type = 'f' - - class BoxRef(Box): - type = 'p' - class Const(object): def __init__(self, value=None): self.value = value @@ -118,8 +87,6 @@ class llhelper(object): pass - MockLoopModel.llhelper.BoxRef = MockLoopModel.BoxRef - return MockLoopModel @@ -129,26 +96,5 @@ else: model = get_real_model() - #class ExtendedTreeLoop(model.TreeLoop): - - # def getboxes(self): - # def allboxes(): - # for box in self.inputargs: - # yield box - # for op in self.operations: - # yield op - - # boxes = Boxes() - # for box in allboxes(): - # if isinstance(box, model.Box): - # name = str(box) - # setattr(boxes, name, box) - # return boxes - - # def setvalues(self, **kwds): - # boxes = self.getboxes() - # for name, value in kwds.iteritems(): - # getattr(boxes, name).value = value - model.ExtendedTreeLoop = model.TreeLoop return model diff --git a/pypy/jit/tool/test/test_oparser.py b/pypy/jit/tool/test/test_oparser.py --- a/pypy/jit/tool/test/test_oparser.py +++ b/pypy/jit/tool/test/test_oparser.py @@ -3,7 +3,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.jit.tool.oparser import parse, OpParser -from pypy.jit.metainterp.resoperation import rop, BoxInt +from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp.history import AbstractDescr, JitCellToken,\ TargetToken @@ -31,19 +31,6 @@ #assert loop.operations[-1].getdescr() # descr is invented by optimizations - def test_const_ptr_subops(self): - x = """ - [p0] - guard_class(p0, ConstClass(vtable)) [] - """ - S = lltype.Struct('S') - vtable = lltype.nullptr(S) - loop = self.parse(x, None, locals()) - assert len(loop.operations) == 1 - #assert loop.operations[0].getdescr() - # descr is invented by optimizations - assert loop.operations[0].get_extra("failargs") == [] - def test_descr(self): class Xyz(AbstractDescr): I_am_a_descr = True # for the mock case @@ -59,7 +46,7 @@ def test_after_fail(self): x = """ [i0] - guard_value(i0, 3) [] + guard_value(i0, 3) i1 = int_add(1, 2) """ loop = self.parse(x, None, {}) @@ -122,18 +109,16 @@ ''' loop = self.parse(x) box = loop.operations[0].getarg(0) - # we cannot use isinstance, because in case of mock the class will be - # constructed on the fly - assert box.__class__.__name__ == 'BoxFloat' + assert box.type == 'f' def test_debug_merge_point(self): - x = ''' + x = """ [] debug_merge_point(0, 0, "info") debug_merge_point(0, 0, 'info') debug_merge_point(1, 1, ' info') debug_merge_point(0, 0, '(stuff) #1') - ''' + """ loop = self.parse(x) assert loop.operations[0].getarg(2)._get_str() == 'info' assert loop.operations[0].getarg(1).value == 0 @@ -162,11 +147,9 @@ jump(i6, i4, descr=) """ - def test_parse_no_namespace(self): - loop = self.parse(self.example_loop_log, no_namespace=True) - def test_attach_comment_to_loop(self): - loop = self.parse(self.example_loop_log, no_namespace=True) + py.test.skip("failargs") + loop = self.parse(self.example_loop_log, guards_with_failargs=True) assert loop.comment == ' # bridge out of Guard12, 6 ops' def test_parse_new_with_comma(self): @@ -178,25 +161,6 @@ loop = self.parse(x) assert loop.operations[0].getopname() == 'new' - def test_no_fail_args(self): - x = ''' - [i0] - guard_true(i0, descr=) - ''' - loop = self.parse(x, nonstrict=True) - assert not loop.operations[0].has_extra("failargs") - - def test_fail_args_invent_snapshot(self): - def f(op, oparser): - op.set_rd_snapshot(['foo']) - - x = ''' - [i0] - guard_true(i0, descr=) [i0] - ''' - loop = self.parse(x, process_guard=f) - assert loop.operations[0].get_rd_snapshot() == ['foo'] - def test_results(self): x = ''' [i0] @@ -207,14 +171,6 @@ assert loop.operations[0].getint() == 13 assert loop.operations[1].getint() == 12 - def test_no_inputargs(self): - x = ''' - i2 = int_add(i0, i1) - ''' - loop = self.parse(x, nonstrict=True) - assert loop.inputargs == [] - assert loop.operations[0].getopname() == 'int_add' - def test_offsets(self): x = """ [i0, i1] @@ -242,15 +198,6 @@ OpParser = OpParser - def test_boxkind(self): - py.test.skip("what's that?") - x = """ - [sum0] - """ - loop = self.parse(x, None, {}, boxkinds={'sum': BoxInt}) - b = loop.getboxes() - assert isinstance(b.sum0, BoxInt) - def test_label(self): x = """ [i0] From noreply at buildbot.pypy.org Fri Oct 12 20:02:04 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 20:02:04 +0200 (CEST) Subject: [pypy-commit] pypy default: (arigo, fijal) merge kill-someobject branch Message-ID: <20121012180204.8E8431C0FE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58079:a1737e5c43ff Date: 2012-10-12 20:01 +0200 http://bitbucket.org/pypy/pypy/changeset/a1737e5c43ff/ Log: (arigo, fijal) merge kill-someobject branch This branch provides a few cleanups: * kill the someobject annotation policy * replace wrapping of default args with WrappedDefault in unwrap_spec * _freeze_ now always returns True, use _cleanup_ for cleanups * kill multiple variants of compile(), use one from c/test_genc.py everywhere * cleanup translator/interactive.py * kill the CExtModuleBuilder * kill pyobj code diff too long, truncating to 2000 out of 16516 lines diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -1,9 +1,8 @@ -import sys import types -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception +from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - format_someobject_error, AnnotatorError) + AnnotatorError, gather_error, ErrorWrapper) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -38,22 +37,9 @@ self.links_followed = {} # set of links that have ever been followed self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + self.blocked_blocks = {} # set of {blocked_block: (graph, index)} + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +63,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +164,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +181,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +192,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +242,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +265,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +283,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +333,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -414,7 +340,7 @@ self.flowin(graph, block) except BlockedInference, e: self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, e.opindex) except Exception, e: # hack for debug tools only if not hasattr(e, '__annotator_block'): @@ -433,25 +359,24 @@ self.pendingblocks[block] = graph assert block in self.annotated self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -471,14 +396,11 @@ for i in range(len(block.operations)): try: self.bookkeeper.enter((graph, block, i)) - self.consider_op(block.operations[i]) + self.consider_op(block, i) finally: self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +484,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +494,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +530,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell @@ -653,7 +572,8 @@ #___ creating the annotations based on operations ______ - def consider_op(self, op): + def consider_op(self, block, opindex): + op = block.operations[opindex] argcells = [self.binding(a) for a in op.args] consider_meth = getattr(self,'consider_op_'+op.opname, None) @@ -668,16 +588,18 @@ # boom -- in the assert of setbinding() for arg in argcells: if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op) + raise BlockedInference(self, op, opindex) try: resultcell = consider_meth(*argcells) - except Exception: + except Exception, e: graph = self.bookkeeper.position_key[0] - raise_nicer_exception(op, str(graph)) + e.args = e.args + ( + ErrorWrapper(gather_error(self, graph, block, opindex)),) + raise if resultcell is None: resultcell = self.noreturnvalue(op) elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op) # the operation cannot succeed + raise BlockedInference(self, op, opindex) # the operation cannot succeed assert isinstance(resultcell, annmodel.SomeObject) assert isinstance(op.result, Variable) self.setbinding(op.result, resultcell) # bind resultcell to op.result @@ -728,13 +650,14 @@ """This exception signals the type inference engine that the situation is currently blocked, and that it should try to progress elsewhere.""" - def __init__(self, annotator, op): + def __init__(self, annotator, op, opindex): self.annotator = annotator try: self.break_at = annotator.bookkeeper.position_key except AttributeError: self.break_at = None self.op = op + self.opindex = opindex def __repr__(self): if not self.break_at: diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,15 +29,6 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', 'truediv', 'floordiv', 'divmod', 'pow', @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -238,7 +201,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -564,14 +550,30 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - return SomeObject() + raise UnionError("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): return SomeTuple(items = tup1.items + tup2.items) + def eq(tup1tup2): + tup1tup2.union() + return s_Bool + ne = eq + + def lt((tup1, tup2)): + raise Exception("unsupported: (...) < (...)") + def le((tup1, tup2)): + raise Exception("unsupported: (...) <= (...)") + def gt((tup1, tup2)): + raise Exception("unsupported: (...) > (...)") + def ge((tup1, tup2)): + raise Exception("unsupported: (...) >= (...)") + class __extend__(pairtype(SomeDict, SomeDict)): @@ -723,8 +725,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -764,7 +765,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -778,7 +779,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -806,7 +807,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,7 +10,7 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef @@ -148,7 +148,6 @@ self.descs = {} # map Python objects to their XxxDesc wrappers self.methoddescs = {} # map (funcdesc, classdef) to the MethodDesc self.classdefs = [] # list of all ClassDefs - self.pbctypes = {} self.seen_mutable = {} self.listdefs = {} # map position_keys to ListDefs self.dictdefs = {} # map position_keys to DictDefs @@ -167,9 +166,6 @@ self.stats = Stats(self) - # used in SomeObject.__new__ for keeping debugging info - self._isomeobject_coming_from = identity_dict() - delayed_imports() def count(self, category, *args): @@ -275,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() @@ -325,8 +320,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -445,6 +438,12 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if (x is type(None) or # add cases here if needed + x.__module__ == 'pypy.rpython.lltypesystem.lltype'): + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) 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 @@ -455,20 +454,13 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) - elif hasattr(x, '_freeze_') and x._freeze_(): + result = SomePBC([self.getdesc(x)]) + elif hasattr(x, '_freeze_'): + assert x._freeze_() is True # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method # returns True, the instance is considered immutable and becomes @@ -476,16 +468,18 @@ result = SomePBC([self.getdesc(x)]) elif hasattr(x, '__class__') \ and x.__class__.__module__ != '__builtin__': + if hasattr(x, '_cleanup_'): + x._cleanup_() self.see_mutable(x) result = SomeInstance(self.getuniqueclassdef(x.__class__)) elif x is None: return s_None else: - result = SomeObject() + raise Exception("Don't know how to represent %r" % (x,)) if need_const: result.const = x return result - + def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: @@ -509,8 +503,10 @@ elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) - elif (hasattr(pyobj.im_self, '_freeze_') and - pyobj.im_self._freeze_()): # method of frozen + if hasattr(pyobj.im_self, '_cleanup_'): + pyobj.im_self._cleanup_() + if hasattr(pyobj.im_self, '_freeze_'): # method of frozen + assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc(self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc @@ -529,9 +525,9 @@ name) else: # must be a frozen pre-built constant, but let's check - try: - assert pyobj._freeze_() - except AttributeError: + if hasattr(pyobj, '_freeze_'): + assert pyobj._freeze_() is True + else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: @@ -551,11 +547,7 @@ return False def getfrozen(self, pyobj): - result = description.FrozenDesc(self, pyobj) - cls = result.knowntype - if cls not in self.pbctypes: - self.pbctypes[cls] = True - return result + return description.FrozenDesc(self, pyobj) def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, flags={}): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -150,7 +150,7 @@ def builtin_isinstance(s_obj, s_type, variables=None): - r = SomeBool() + r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,8 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + + if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -247,13 +247,16 @@ defs_s = [] if graph is None: signature = self.signature - defaults = self.defaults + defaults = self.defaults else: signature = graph.signature - defaults = graph.defaults + defaults = graph.defaults if defaults: for x in defaults: - defs_s.append(self.bookkeeper.immutablevalue(x)) + if x is NODEFAULT: + defs_s.append(None) + else: + defs_s.append(self.bookkeeper.immutablevalue(x)) try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,8 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype + immutable = False knowntype = object - immutable = False + + def __init__(self): + assert type(self) is not SomeObject def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -105,60 +106,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: - self = new(cls, *args, **kw) - if DEBUG: - try: - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - position_key = bookkeeper.position_key - except AttributeError: - pass - else: - bookkeeper._isomeobject_coming_from[self] = position_key, None + def can_be_none(self): + return True + + def nonnoneify(self): return self - def origin(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] - origin = property(origin) - def caused_by_merge(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] - def set_caused_by_merge(self, nvalue): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return - bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue - caused_by_merge = property(caused_by_merge, set_caused_by_merge) - del set_caused_by_merge +class SomeType(SomeObject): + "Stands for a type. We might not be sure which one it is." + knowntype = type + immutable = True def can_be_none(self): - return True - - def nonnoneify(self): - return self + return False class SomeFloat(SomeObject): "Stands for a float or an integer." @@ -517,6 +486,7 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) @@ -710,14 +680,8 @@ # this is just a performance shortcut if s1 != s2: s1 = pair(s1, s2).union() - if DEBUG: - if s1.caused_by_merge is None and len(somevalues) > 1: - s1.caused_by_merge = somevalues return s1 -def isdegenerated(s_value): - return s_value.__class__ is SomeObject and s_value.knowntype is not type - # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -10,7 +10,6 @@ class BasicAnnotatorPolicy(object): - allow_someobjects = True def event(pol, bookkeeper, what, *args): pass @@ -80,6 +79,3 @@ def specialize__ll_and_arg(pol, *args): from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args) - -class StrictAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -3,9 +3,9 @@ from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF -from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF + unionof, SomeUnicodeString, SomeType +from pypy.annotation.listdef import ListDef +from pypy.annotation.dictdef import DictDef _annotation_cache = {} @@ -78,24 +78,18 @@ return SomeString() elif t is unicode: return SomeUnicodeString() - elif t is list: - return SomeList(MOST_GENERAL_LISTDEF) - elif t is dict: - return SomeDict(MOST_GENERAL_DICTDEF) - # can't do tuple elif t is types.NoneType: return s_None elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) - elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes: + elif t is type: + return SomeType() + elif bookkeeper and not hasattr(t, '_freeze_'): classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) else: - o = SomeObject() - if t != object: - o.knowntype = t - return o + raise AssertionError("annotationoftype(%r)" % (t,)) class Sig(object): diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -24,7 +24,7 @@ assert isinstance(s_list, annmodel.SomeList) return s_list.listdef.listitem.s_value -def somelist(s_type=annmodel.SomeObject()): +def somelist(s_type): return annmodel.SomeList(ListDef(None, s_type)) def dictkey(s_dict): @@ -35,7 +35,7 @@ assert isinstance(s_dict, annmodel.SomeDict) return s_dict.dictdef.dictvalue.s_value -def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()): +def somedict(s_key, s_value): return annmodel.SomeDict(DictDef(None, s_key, s_value)) @@ -205,15 +205,6 @@ annmodel.SomeInteger() ]) - def test_inheritance2(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet._inheritance_nonrunnable, []) - # result should be exactly: - assert s == annmodel.SomeTuple([ - annmodel.SomeInteger(), - annmodel.SomeObject() - ]) - def test_poor_man_range(self): a = self.RPythonAnnotator() s = a.build_types(snippet.poor_man_range, [int]) @@ -336,9 +327,13 @@ def test_flow_type_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_type_info, [object]) + s = a.build_types(snippet.flow_type_info, [int]) a.simplify() - #a.translator.view() + assert s.knowntype == int + + a = self.RPythonAnnotator() + s = a.build_types(snippet.flow_type_info, [str]) + a.simplify() assert s.knowntype == int def test_flow_type_info_2(self): @@ -351,7 +346,7 @@ def test_flow_usertype_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_usertype_info, [object]) + s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit]) #a.translator.view() assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit) @@ -363,13 +358,6 @@ assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit) - def test_flow_identity_info(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_identity_info, [object, object]) - a.simplify() - #a.translator.view() - assert s == a.bookkeeper.immutablevalue((None, None)) - def test_mergefunctions(self): a = self.RPythonAnnotator() s = a.build_types(snippet.mergefunctions, [int]) @@ -431,11 +419,11 @@ # the annotator (it doesn't check that they operate property, though) for example, methname, s_example in [ ('', 'join', annmodel.SomeString()), - ([], 'append', somelist()), - ([], 'extend', somelist()), - ([], 'reverse', somelist()), - ([], 'insert', somelist()), - ([], 'pop', somelist()), + ([], 'append', somelist(annmodel.s_Int)), + ([], 'extend', somelist(annmodel.s_Int)), + ([], 'reverse', somelist(annmodel.s_Int)), + ([], 'insert', somelist(annmodel.s_Int)), + ([], 'pop', somelist(annmodel.s_Int)), ]: constmeth = getattr(example, methname) s_constmeth = iv(constmeth) @@ -497,12 +485,12 @@ def test_simple_slicing(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_slice, [list]) + s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeList) def test_simple_iter_list(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_iter, [list]) + s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeIterator) def test_simple_iter_next(self): @@ -542,11 +530,6 @@ assert isinstance(dictkey(s), annmodel.SomeInteger) assert isinstance(dictvalue(s), annmodel.SomeInteger) - a = self.RPythonAnnotator() - s = a.build_types(snippet.dict_update, [str]) - assert not isinstance(dictkey(s), annmodel.SomeString) - assert not isinstance(dictvalue(s), annmodel.SomeString) - def test_dict_update_2(self): a = self.RPythonAnnotator() def g(n): @@ -568,7 +551,7 @@ def test_dict_keys2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_keys2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_values(self): a = self.RPythonAnnotator() @@ -578,7 +561,7 @@ def test_dict_values2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_items(self): a = self.RPythonAnnotator() @@ -643,25 +626,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_bltin_code_frame_confusion(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_confusion,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - # annotator confused by original bltin code/frame setup, we just get SomeObject here - assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - - def test_bltin_code_frame_reorg(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_reorg,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - assert isinstance(a.binding(f_flowgraph.getreturnvar()), - annmodel.SomeInteger) - assert isinstance(a.binding(g_flowgraph.getreturnvar()), - annmodel.SomeString) - def test_propagation_of_fresh_instances_through_attrs(self): a = self.RPythonAnnotator() s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int]) @@ -748,14 +712,15 @@ assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc) def test_type_is(self): - class C(object): + class B(object): + pass + class C(B): pass def f(x): - if type(x) is C: - return x - raise Exception - a = self.RPythonAnnotator() - s = a.build_types(f, [object]) + assert type(x) is C + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) def test_ann_assert(self): @@ -793,24 +758,30 @@ return None a = self.RPythonAnnotator() - s = a.build_types(f, [list]) + s = a.build_types(f, [somelist(annmodel.s_Int)]) assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list def test_freeze_protocol(self): class Stuff: - def __init__(self, flag): + def __init__(self): self.called = False - self.flag = flag def _freeze_(self): self.called = True - return self.flag - myobj = Stuff(True) + return True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - myobj = Stuff(False) + + def test_cleanup_protocol(self): + class Stuff: + def __init__(self): + self.called = False + def _cleanup_(self): + self.called = True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called @@ -854,7 +825,7 @@ def f(a,b): return bool(a) or bool(b) a = self.RPythonAnnotator() - s = a.build_types(f, [int,list]) + s = a.build_types(f, [int, somelist(annmodel.s_Int)]) assert s.knowntype == bool def test_float(self): @@ -1299,22 +1270,6 @@ assert isinstance(s_item, annmodel.SomeInstance) assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - def test_assert_type_is_list_doesnt_lose_info(self): - class T(object): - pass - def g(l): - assert type(l) is list - return l - def f(): - l = [T()] - return g(l) - a = self.RPythonAnnotator() - s = a.build_types(f, []) - s_item = listitem(s) - assert isinstance(s_item, annmodel.SomeInstance) - assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - - def test_int_str_mul(self): def f(x,a,b): return a*x+x*b @@ -1395,11 +1350,10 @@ except KeyError: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.const = KeyError t.is_type_of = [ev] assert a.binding(et) == t @@ -1412,11 +1366,10 @@ except: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t @@ -1448,11 +1401,10 @@ finally: h() a = self.RPythonAnnotator() - a.build_types(f, [int, list]) + a.build_types(f, [int, somelist(annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) @@ -1474,24 +1426,11 @@ a.build_types(f, []) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_sys_attrs(self): - def f(): - return sys.argv[0] - a = self.RPythonAnnotator() - try: - oldvalue = sys.argv - sys.argv = [] - s = a.build_types(f, []) - finally: - sys.argv = oldvalue - assert s is not None - def test_pow(self): def f(n): n **= 2 @@ -1523,7 +1462,6 @@ a = self.RPythonAnnotator() 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)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] def test_is_true_coalesce2(self): def f(a,b,a1,b1,c,d,e): @@ -1532,9 +1470,12 @@ return d,c return e,c a = self.RPythonAnnotator() - s = a.build_types(f, [int, str, float, list, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) - assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] + s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int), + 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_coalesce_sanity(self): def f(a): @@ -1954,16 +1895,7 @@ t = type(x) return issubclass(t, A) - def f(): - x = g(1) - y = g(0) - return x or y - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert s.knowntype == bool - assert not s.is_constant() - a = self.RPythonAnnotator() - # sanity check + a = self.RPythonAnnotator() x = annmodel.SomeInteger() x.const = 1 s = a.build_types(g, [x]) @@ -2383,8 +2315,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int]) - assert s.__class__ == annmodel.SomeObject - assert s.knowntype == type + assert isinstance(s, annmodel.SomeType) def test_annotate_iter_empty_container(self): def f(): @@ -3075,7 +3006,6 @@ v = -maxint return intmask(v * 10) P = policy.AnnotatorPolicy() - P.allow_someobjects = False a = self.RPythonAnnotator(policy=P) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) @@ -3866,6 +3796,24 @@ s = a.build_types(fn, [annmodel.SomeChar()]) assert s == annmodel.SomeChar() + def test_isinstance_double_const(self): + class X(object): + def _freeze_(self): + return True + + x = X() + + def f(i): + if i: + x1 = x + else: + x1 = None + print "hello" # this is to force the merge of blocks + return isinstance(x1, X) + + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeBool) def g(n): return [0,1,2,n] diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -2,20 +2,20 @@ import autopath import py from pypy.annotation.model import * -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF +from pypy.annotation.listdef import ListDef from pypy.rpython.ootypesystem.ootype import ROOT listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) -s1 = SomeObject() +s1 = SomeType() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s1,s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s1, s2, s3, s4, s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -42,7 +42,7 @@ def test_equality(): assert s1 != s2 != s3 != s4 != s5 != s6 - assert s1 == SomeObject() + assert s1 == SomeType() assert s2 == SomeInteger(nonneg=True) assert s3 == SomeInteger(nonneg=False) assert s4 == SomeList(listdef1) @@ -51,19 +51,11 @@ def test_contains(): assert ([(s,t) for s in slist for t in slist if s.contains(t)] == - [(s1,s1), (s1,s2), (s1,s3), (s1,s4), (s1,s6), - (s2,s2), (s2,s6), - (s3,s2), (s3,s3), (s3,s6), - (s4,s4), (s4,s6), - (s6,s6)]) - -def test_union(): - assert ([unionof(s,t) for s in slist for t in slist] == - [s1, s1, s1, s1, s1, - s1, s2, s3, s1, s2, - s1, s3, s3, s1, s3, - s1, s1, s1, s4, s4, - s1, s2, s3, s4, s6]) + [(s1, s1), (s1, s6), + (s2, s2), (s2, s6), + (s3, s2), (s3, s3), (s3, s6), + (s4, s4), (s4, s6), + (s6, s6)]) def test_commonbase_simple(): class A0: @@ -100,9 +92,10 @@ def test_list_contains(): listdef1 = ListDef(None, SomeInteger(nonneg=True)) s1 = SomeList(listdef1) - s2 = SomeList(MOST_GENERAL_LISTDEF) + listdef2 = ListDef(None, SomeInteger(nonneg=False)) + s2 = SomeList(listdef2) assert s1 != s2 - assert s2.contains(s1) + assert not s2.contains(s1) assert s1 != s2 assert not s1.contains(s2) assert s1 != s2 diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -7,7 +7,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -39,14 +39,7 @@ def type(obj, *moreargs): if moreargs: raise Exception, 'type() called with more than one argument' - if obj.is_constant(): - if isinstance(obj, SomeInstance): - r = SomePBC([obj.classdef.classdesc]) - else: - r = immutablevalue(obj.knowntype) - else: - r = SomeObject() - r.knowntype = type + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator @@ -133,9 +126,6 @@ def float(obj): return SomeFloat() - def long(obj): - return SomeObject() # XXX - def delattr(obj, s_attr): if obj.__class__ != SomeObject or obj.knowntype != object: getbookkeeper().warning( @@ -154,18 +144,17 @@ def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - s_method = obj.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)) - else: - getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' % - (obj, s_attr)) - return SomeObject() + 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)) + attr = s_attr.const + s_method = obj.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)) getattr.can_only_throw = [] def bind_callables_under(obj, classdef, name): diff --git a/pypy/bin/translatorshell.py b/pypy/bin/translatorshell.py --- a/pypy/bin/translatorshell.py +++ b/pypy/bin/translatorshell.py @@ -8,10 +8,10 @@ Example: - t = Translation(func) + t = Translation(func, [int]) # pass the list of args types t.view() # control flow graph - t.annotate([int]) # pass the list of args types + t.annotate() t.view() # graph + annotations under the mouse t.rtype() # use low level operations diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py --- a/pypy/config/test/test_config.py +++ b/pypy/config/test/test_config.py @@ -111,8 +111,8 @@ else: return 'foo' - t = Translation(f) - t.rtype([int]) + t = Translation(f, [int]) + t.rtype() block = t.context.graphs[0].startblock assert len(block.exits[0].target.operations) == 0 diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -129,8 +129,6 @@ # misc BoolOption("verbose", "Print extra information", default=False), - BoolOption("debug", "Record extra annotation information", - cmdline="-d --debug", default=True), BoolOption("insist", "Try hard to go on RTyping", default=False, cmdline="--insist"), StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -101,15 +101,7 @@ def maketestobjspace(config=None): if config is None: config = make_config(option) - try: - space = make_objspace(config) - except OperationError, e: - check_keyboard_interrupt(e) - if option.verbose: - import traceback - traceback.print_exc() - py.test.fail("fatal: cannot initialize objspace: %r" % - (config.objspace.name,)) + space = make_objspace(config) space.startup() # Initialize all builtin modules space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), appsupport.build_pytest_assertion(space)) diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -9,7 +9,7 @@ `import` statements:: from pypy.interpreter.baseobjspace import Wrappable - from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -27,7 +27,7 @@ ``pypy/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: - >>> t = Translation(snippet.is_perfect_number) + >>> t = Translation(snippet.is_perfect_number, [int]) >>> t.view() After that, the graph viewer pops up, that lets you interactively inspect the @@ -40,7 +40,7 @@ We have a type annotator that can completely infer types for functions like ``is_perfect_number`` (as well as for much larger examples):: - >>> t.annotate([int]) + >>> t.annotate() >>> t.view() Move the mouse over variable names (in red) to see their inferred types. @@ -74,8 +74,8 @@ >>> def myfunc(a, b): return a+b ... - >>> t = Translation(myfunc) - >>> t.annotate([int, int]) + >>> t = Translation(myfunc, [int, int]) + >>> t.annotate() >>> f = t.compile_cli() # or compile_jvm() >>> f(4, 5) 9 diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -719,8 +719,15 @@ # done by a method call on w_two (and not on w_one, because of the # expected programming style where we say "if x is None" or # "if x is object"). + assert w_two is not None return w_two.is_w(self, w_one) + def is_none(self, w_obj): + """ mostly for checking inputargs that have unwrap_spec and + can accept both w_None and None + """ + return w_obj is None or self.is_w(w_obj, self.w_None) + def id(self, w_obj): w_result = w_obj.immutable_unique_id(self) if w_result is None: @@ -804,7 +811,7 @@ interpreter class (a subclass of Wrappable). """ assert RequiredClass is not None - if can_be_None and self.is_w(w_obj, self.w_None): + if can_be_None and self.is_none(w_obj): return None obj = self.interpclass_w(w_obj) if not isinstance(obj, RequiredClass): # or obj is None diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -205,11 +205,11 @@ code = space.interp_w(Code, w_code) if not space.is_true(space.isinstance(w_globals, space.w_dict)): raise OperationError(space.w_TypeError, space.wrap("expected dict")) - if not space.is_w(w_name, space.w_None): + if not space.is_none(w_name): name = space.str_w(w_name) else: name = None - if not space.is_w(w_argdefs, space.w_None): + if not space.is_none(w_argdefs): defs_w = space.fixedview(w_argdefs) else: defs_w = [] @@ -217,7 +217,7 @@ from pypy.interpreter.pycode import PyCode if isinstance(code, PyCode): nfreevars = len(code.co_freevars) - if space.is_w(w_closure, space.w_None) and nfreevars == 0: + if space.is_none(w_closure) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) @@ -244,7 +244,7 @@ # delicate _all = {'': None} - def _freeze_(self): + def _cleanup_(self): from pypy.interpreter.gateway import BuiltinCode if isinstance(self.code, BuiltinCode): # we have been seen by other means so rtyping should not choke @@ -343,7 +343,7 @@ def fget_func_defaults(self, space): values_w = self.defs_w # the `None in values_w` check here is to ensure that interp-level - # functions with a default of NoneNotWrapped do not get their defaults + # functions with a default of None do not get their defaults # exposed at applevel if not values_w or None in values_w: return space.w_None @@ -424,11 +424,12 @@ w_res = space.w_None return w_res + def descr_function_get(space, w_function, w_obj, w_cls=None): """functionobject.__get__(obj[, type]) -> method""" # this is not defined as a method on Function because it's generally # useful logic: w_function can be any callable. It is used by Method too. - asking_for_bound = (space.is_w(w_cls, space.w_None) or + asking_for_bound = (space.is_none(w_cls) or not space.is_w(w_obj, space.w_None) or space.is_w(w_cls, space.type(space.w_None))) if asking_for_bound: @@ -445,12 +446,15 @@ self.space = space self.w_function = w_function self.w_instance = w_instance # or None + if w_class is None: + w_class = space.w_None self.w_class = w_class # possibly space.w_None - def descr_method__new__(space, w_subtype, w_function, w_instance, w_class=None): + def descr_method__new__(space, w_subtype, w_function, w_instance, + w_class=None): if space.is_w(w_instance, space.w_None): w_instance = None - if w_instance is None and space.is_w(w_class, space.w_None): + if w_instance is None and space.is_none(w_class): raise OperationError(space.w_TypeError, space.wrap("unbound methods must have class")) method = space.allocate_instance(Method, w_subtype) @@ -610,7 +614,7 @@ self.w_function = w_function def descr_classmethod_get(self, space, w_obj, w_klass=None): - if space.is_w(w_klass, space.w_None): + if space.is_none(w_klass): w_klass = space.type(w_obj) return space.wrap(Method(space, self.w_function, w_klass, space.w_None)) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -7,31 +7,29 @@ """ -import types, sys, os -from pypy.tool.compat import md5 +import sys +import os +import types -NoneNotWrapped = object() +import py -from pypy.tool.sourcetools import func_with_new_name +from pypy.interpreter.eval import Code +from pypy.interpreter.argument import Arguments, Signature +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, + SpaceCache, DescrMismatch) from pypy.interpreter.error import OperationError -from pypy.interpreter import eval -from pypy.interpreter.function import Function, Method, ClassMethod -from pypy.interpreter.function import FunctionWithFixedCode -from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable -from pypy.interpreter.baseobjspace import Wrappable, SpaceCache, DescrMismatch -from pypy.interpreter.argument import Arguments, Signature -from pypy.tool.sourcetools import NiceCompile, compile2 -from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from pypy.rlib import rstackovf from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.tool.sourcetools import func_with_new_name, compile2 + # internal non-translatable parts: -import py - class SignatureBuilder(object): "NOT_RPYTHON" def __init__(self, func=None, argnames=None, varargname=None, - kwargname=None, name = None): + kwargname=None, name=None): self.func = func if func is not None: self.name = func.__name__ @@ -60,10 +58,12 @@ if isinstance(el, str): getattr(self, "visit_%s" % (el,))(el, *args) elif isinstance(el, tuple): - if el[0] == 'self': + if el[0] == 'INTERNAL:self': self.visit_self(el[1], *args) else: - self.visit_function(el, *args) + assert False, "not supported any more, use WrappedDefault" + elif isinstance(el, WrappedDefault): + self.visit__W_Root(W_Root, *args) elif isinstance(el, type): for typ in self.bases_order: if issubclass(el, typ): @@ -81,8 +81,8 @@ for el in unwrap_spec: dispatch(el, *extra) + class UnwrapSpecEmit(UnwrapSpecRecipe): - def __init__(self): self.n = 0 self.miniglobals = {} @@ -97,10 +97,11 @@ self.miniglobals[name] = obj return name + #________________________________________________________________ + class UnwrapSpec_Check(UnwrapSpecRecipe): - # checks for checking interp2app func argument names wrt unwrap_spec # and synthetizing an app-level signature @@ -108,9 +109,6 @@ self.func = original_sig.func self.orig_arg = iter(original_sig.argnames).next - def visit_function(self, (func, cls), app_sig): - self.dispatch(cls, app_sig) - def visit_self(self, cls, app_sig): self.visit__Wrappable(cls, app_sig) @@ -168,8 +166,8 @@ app_sig.append(argname[2:]) def visit__Arguments(self, el, app_sig): - argname = self.orig_arg() - assert app_sig.varargname is None,( + self.orig_arg() + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = 'args' app_sig.kwargname = 'keywords' @@ -179,7 +177,7 @@ assert argname.endswith('_w'), ( "rest arguments arg %s of built-in function %r should end in '_w'" % (argname, self.func)) - assert app_sig.varargname is None,( + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = argname[:-2] @@ -188,7 +186,7 @@ assert argname.startswith('w_'), ( "rest arguments arg %s of built-in function %r should start 'w_'" % (argname, self.func)) - assert app_sig.varargname is None,( + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = argname[2:] @@ -208,10 +206,6 @@ def scopenext(self): return "scope_w[%d]" % self.succ() - def visit_function(self, (func, cls)): - self.run_args.append("%s(%s)" % (self.use(func), - self.scopenext())) - def visit_self(self, typ): self.run_args.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.scopenext())) @@ -284,6 +278,8 @@ if isinstance(el, tuple): parts.append(''.join([getattr(subel, '__name__', subel) for subel in el])) + elif isinstance(el, WrappedDefault): + parts.append('W_Root') else: parts.append(getattr(el, '__name__', el)) label = '_'.join(parts) @@ -320,15 +316,16 @@ def _run(self, space, scope_w): """Subclasses with behavior specific for an unwrap spec are generated""" - raise TypeError, "abstract" + raise TypeError("abstract") #________________________________________________________________ + class FastFuncNotSupported(Exception): pass + class UnwrapSpec_FastFunc_Unwrap(UnwrapSpecEmit): - def __init__(self): UnwrapSpecEmit.__init__(self) self.args = [] @@ -346,9 +343,6 @@ self.args.append(arg) return arg - def visit_function(self, (func, cls)): - raise FastFuncNotSupported - def visit_self(self, typ): self.unwrap.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.nextarg())) @@ -439,6 +433,7 @@ return narg, fastfunc make_fastfunc = staticmethod(make_fastfunc) + def int_unwrapping_space_method(typ): assert typ in (int, str, float, unicode, r_longlong, r_uint, r_ulonglong, bool) if typ is r_int is r_longlong: @@ -455,6 +450,7 @@ - positional arguments must be as many as the function parameters - keywords arguments allow to change only some parameter specs """ + assert spec or kwargs def decorator(func): if kwargs: if spec: @@ -466,6 +462,14 @@ return func return decorator +class WrappedDefault(object): + """ Can be used inside unwrap_spec as WrappedDefault(3) which means + it'll be treated as W_Root, but fed with default which will be a wrapped + argument to constructor. + """ + def __init__(self, default_value): + self.default_value = default_value + def build_unwrap_spec(func, argnames, self_type=None): """build the list of parameter unwrap spec for the function. """ @@ -505,7 +509,8 @@ return unwrap_spec -class BuiltinCode(eval.Code): + +class BuiltinCode(Code): "The code object implementing a built-in (interpreter-level) hook." _immutable_ = True hidden_applevel = True @@ -515,14 +520,11 @@ # When a BuiltinCode is stored in a Function object, # you get the functionality of CPython's built-in function type. - NOT_RPYTHON_ATTRIBUTES = ['_bltin', '_unwrap_spec'] - From noreply at buildbot.pypy.org Fri Oct 12 20:04:55 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 20:04:55 +0200 (CEST) Subject: [pypy-commit] pypy kill-someobject: close merged branch Message-ID: <20121012180455.2544C1C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: kill-someobject Changeset: r58080:3db9f211d201 Date: 2012-10-12 20:03 +0200 http://bitbucket.org/pypy/pypy/changeset/3db9f211d201/ Log: close merged branch From noreply at buildbot.pypy.org Fri Oct 12 20:04:56 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 12 Oct 2012 20:04:56 +0200 (CEST) Subject: [pypy-commit] pypy default: fix whatsnew Message-ID: <20121012180456.882931C1C59@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58081:0c8cf6db2041 Date: 2012-10-12 20:04 +0200 http://bitbucket.org/pypy/pypy/changeset/0c8cf6db2041/ Log: fix whatsnew diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -38,7 +38,8 @@ .. branch: numpypy-complex2 Complex dtype support for numpy - +.. branch: kill-someobject +major cleanups including killing some object support .. "uninteresting" branches that we should just ignore for the whatsnew: From noreply at buildbot.pypy.org Fri Oct 12 23:07:04 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 12 Oct 2012 23:07:04 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Revert previous change: ll_thread.py also compiles thread.c, without genc.py and generated header files. Message-ID: <20121012210704.315C31C1C5D@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r58082:73b8484483b1 Date: 2012-10-03 22:12 +0200 http://bitbucket.org/pypy/pypy/changeset/73b8484483b1/ Log: Revert previous change: ll_thread.py also compiles thread.c, without genc.py and generated header files. diff --git a/pypy/translator/c/src/thread.c b/pypy/translator/c/src/thread.c --- a/pypy/translator/c/src/thread.c +++ b/pypy/translator/c/src/thread.c @@ -1,12 +1,6 @@ /* Thread implementation */ #include "src/thread.h" -/* The following include is required by the Boehm GC, which apparently - * crashes where pthread_create() is not redefined to call a Boehm - * wrapper function instead. Ugly. - */ -#include "common_header.h" - #ifdef _WIN32 #include "src/thread_nt.c" #else From noreply at buildbot.pypy.org Fri Oct 12 23:07:05 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 12 Oct 2012 23:07:05 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: It's certainly a good idea to put thread functions apart, Message-ID: <20121012210705.69AD61C1C5D@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r58083:5e1a89eeafe4 Date: 2012-10-03 22:32 +0200 http://bitbucket.org/pypy/pypy/changeset/5e1a89eeafe4/ Log: It's certainly a good idea to put thread functions apart, and only compile TLS storage with other genc sources. diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py --- a/pypy/translator/c/genc.py +++ b/pypy/translator/c/genc.py @@ -918,7 +918,7 @@ srcdir / 'debug_print.c', srcdir / 'debug_traceback.c', # ifdef HAVE_RTYPER srcdir / 'stack.c', - srcdir / 'thread.c', + srcdir / 'threadlocal.c', srcdir / 'asm.c', srcdir / 'instrument.c', srcdir / 'int.c', diff --git a/pypy/translator/c/src/g_prerequisite.h b/pypy/translator/c/src/g_prerequisite.h --- a/pypy/translator/c/src/g_prerequisite.h +++ b/pypy/translator/c/src/g_prerequisite.h @@ -11,9 +11,6 @@ # include /* needed, otherwise _lseeki64 truncates to 32-bits (??) */ #endif -#include "thread.h" /* needs to be included early to define the - struct RPyOpaque_ThreadLock */ - #include diff --git a/pypy/translator/c/src/obmalloc.c b/pypy/translator/c/src/obmalloc.c --- a/pypy/translator/c/src/obmalloc.c +++ b/pypy/translator/c/src/obmalloc.c @@ -2,6 +2,7 @@ #ifdef WITH_PYMALLOC #include +#include /* An object allocator for Python. diff --git a/pypy/translator/c/src/stack.h b/pypy/translator/c/src/stack.h --- a/pypy/translator/c/src/stack.h +++ b/pypy/translator/c/src/stack.h @@ -9,7 +9,7 @@ /* This include must be done in any case to initialise * the header dependencies early (winsock2, before windows.h). * It is needed to have RPyThreadStaticTLS, too. */ -#include "thread.h" +#include "threadlocal.h" extern char *_LLstacktoobig_stack_end; extern long _LLstacktoobig_stack_length; diff --git a/pypy/translator/c/src/thread.h b/pypy/translator/c/src/thread.h --- a/pypy/translator/c/src/thread.h +++ b/pypy/translator/c/src/thread.h @@ -1,6 +1,3 @@ - -/* #ifdef logic from CPython */ - #ifndef __PYPY_THREAD_H #define __PYPY_THREAD_H #include @@ -19,25 +16,6 @@ #endif /* !_WIN32 */ -#ifdef USE___THREAD - -#define RPyThreadStaticTLS __thread void * -#define RPyThreadStaticTLS_Create(tls) NULL -#define RPyThreadStaticTLS_Get(tls) tls -#define RPyThreadStaticTLS_Set(tls, value) tls = value - -#endif - -#ifndef RPyThreadStaticTLS - -#define RPyThreadStaticTLS RPyThreadTLS -#define RPyThreadStaticTLS_Create(key) RPyThreadTLS_Create(key) -#define RPyThreadStaticTLS_Get(key) RPyThreadTLS_Get(key) -#define RPyThreadStaticTLS_Set(key, value) RPyThreadTLS_Set(key, value) -char *RPyThreadTLS_Create(RPyThreadTLS *result); - -#endif - long RPyGilAllocate(void); long RPyGilYieldThread(void); void RPyGilRelease(void); diff --git a/pypy/translator/c/src/thread_nt.c b/pypy/translator/c/src/thread_nt.c --- a/pypy/translator/c/src/thread_nt.c +++ b/pypy/translator/c/src/thread_nt.c @@ -181,17 +181,6 @@ } /************************************************************/ - -char *RPyThreadTLS_Create(RPyThreadTLS *result) -{ - *result = TlsAlloc(); - if (*result == TLS_OUT_OF_INDEXES) - return "out of thread-local storage indexes"; - else - return NULL; -} - -/************************************************************/ /* GIL code */ /************************************************************/ diff --git a/pypy/translator/c/src/thread_nt.h b/pypy/translator/c/src/thread_nt.h --- a/pypy/translator/c/src/thread_nt.h +++ b/pypy/translator/c/src/thread_nt.h @@ -21,8 +21,3 @@ long RPyThreadGetStackSize(void); long RPyThreadSetStackSize(long); -/* Thread-local storage */ -#define __thread __declspec(thread) -typedef DWORD RPyThreadTLS; -#define RPyThreadTLS_Get(key) TlsGetValue(key) -#define RPyThreadTLS_Set(key, value) TlsSetValue(key, value) diff --git a/pypy/translator/c/src/thread_pthread.c b/pypy/translator/c/src/thread_pthread.c --- a/pypy/translator/c/src/thread_pthread.c +++ b/pypy/translator/c/src/thread_pthread.c @@ -377,17 +377,6 @@ /************************************************************/ -/* Thread-local storage */ - -char *RPyThreadTLS_Create(RPyThreadTLS *result) -{ - if (pthread_key_create(result, NULL) != 0) - return "out of thread-local storage keys"; - else - return NULL; -} - - /************************************************************/ /* GIL code */ /************************************************************/ diff --git a/pypy/translator/c/src/thread_pthread.h b/pypy/translator/c/src/thread_pthread.h --- a/pypy/translator/c/src/thread_pthread.h +++ b/pypy/translator/c/src/thread_pthread.h @@ -75,11 +75,3 @@ long RPyThreadGetStackSize(void); long RPyThreadSetStackSize(long); void RPyThreadAfterFork(void); - - -/* implementations */ - -/* Thread-local storage */ -typedef pthread_key_t RPyThreadTLS; -#define RPyThreadTLS_Get(key) pthread_getspecific(key) -#define RPyThreadTLS_Set(key, value) pthread_setspecific(key, value) diff --git a/pypy/translator/c/src/threadlocal.c b/pypy/translator/c/src/threadlocal.c new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/threadlocal.c @@ -0,0 +1,24 @@ +#include "src/threadlocal.h" + +#ifdef _WIN32 + +char *RPyThreadTLS_Create(RPyThreadTLS *result) +{ + *result = TlsAlloc(); + if (*result == TLS_OUT_OF_INDEXES) + return "out of thread-local storage indexes"; + else + return NULL; +} + +#else + +char *RPyThreadTLS_Create(RPyThreadTLS *result) +{ + if (pthread_key_create(result, NULL) != 0) + return "out of thread-local storage keys"; + else + return NULL; +} + +#endif diff --git a/pypy/translator/c/src/threadlocal.h b/pypy/translator/c/src/threadlocal.h new file mode 100644 --- /dev/null +++ b/pypy/translator/c/src/threadlocal.h @@ -0,0 +1,39 @@ +/* Thread-local storage */ + +#ifdef _WIN32 + +#include +#define __thread __declspec(thread) +typedef DWORD RPyThreadTLS; +#define RPyThreadTLS_Get(key) TlsGetValue(key) +#define RPyThreadTLS_Set(key, value) TlsSetValue(key, value) + +#else + +#include +typedef pthread_key_t RPyThreadTLS; +#define RPyThreadTLS_Get(key) pthread_getspecific(key) +#define RPyThreadTLS_Set(key, value) pthread_setspecific(key, value) + +#endif + + +#ifdef USE___THREAD + +#define RPyThreadStaticTLS __thread void * +#define RPyThreadStaticTLS_Create(tls) NULL +#define RPyThreadStaticTLS_Get(tls) tls +#define RPyThreadStaticTLS_Set(tls, value) tls = value + +#endif + +#ifndef RPyThreadStaticTLS + +#define RPyThreadStaticTLS RPyThreadTLS +#define RPyThreadStaticTLS_Create(key) RPyThreadTLS_Create(key) +#define RPyThreadStaticTLS_Get(key) RPyThreadTLS_Get(key) +#define RPyThreadStaticTLS_Set(key, value) RPyThreadTLS_Set(key, value) +char *RPyThreadTLS_Create(RPyThreadTLS *result); + +#endif + From noreply at buildbot.pypy.org Fri Oct 12 23:07:09 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 12 Oct 2012 23:07:09 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: hg merge default. Message-ID: <20121012210709.A76691C1C5D@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r58084:a9fe088c69b1 Date: 2012-10-12 23:06 +0200 http://bitbucket.org/pypy/pypy/changeset/a9fe088c69b1/ Log: hg merge default. Some conflicts in translator/c/src. diff too long, truncating to 2000 out of 29054 lines diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,11 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - libpath = ctypes.util.find_library('db-4.5') - if not libpath: + for c in '56789': + libpath = ctypes.util.find_library('db-4.%s' % c) + if libpath: + break + else: raise ImportError("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' diff --git a/py/_io/capture.py b/py/_io/capture.py --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -176,7 +176,7 @@ class StdCaptureFD(Capture): - """ This class allows to capture writes to FD1 and FD2 + """ This class allows capturing writes to FD1 and FD2 and may connect a NULL file to FD0 (and prevent reads from sys.stdin). If any of the 0,1,2 file descriptors is invalid it will not be captured. @@ -267,8 +267,8 @@ return l class StdCapture(Capture): - """ This class allows to capture writes to sys.stdout|stderr "in-memory" - and will raise errors on tries to read from sys.stdin. It only + """ This class allows capturing writes to sys.stdout|stderr "in-memory" + and will raise errors on read attempts from sys.stdin. It only modifies sys.stdout|stderr|stdin attributes and does not touch underlying File Descriptors (use StdCaptureFD for that). """ diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -1,9 +1,8 @@ -import sys import types -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception +from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - format_someobject_error, AnnotatorError) + AnnotatorError, gather_error, ErrorWrapper) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -38,22 +37,9 @@ self.links_followed = {} # set of links that have ever been followed self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + self.blocked_blocks = {} # set of {blocked_block: (graph, index)} + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +63,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +164,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +181,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +192,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +242,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +265,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +283,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +333,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -414,7 +340,7 @@ self.flowin(graph, block) except BlockedInference, e: self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, e.opindex) except Exception, e: # hack for debug tools only if not hasattr(e, '__annotator_block'): @@ -433,25 +359,24 @@ self.pendingblocks[block] = graph assert block in self.annotated self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -471,14 +396,11 @@ for i in range(len(block.operations)): try: self.bookkeeper.enter((graph, block, i)) - self.consider_op(block.operations[i]) + self.consider_op(block, i) finally: self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +484,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +494,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +530,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell @@ -653,7 +572,8 @@ #___ creating the annotations based on operations ______ - def consider_op(self, op): + def consider_op(self, block, opindex): + op = block.operations[opindex] argcells = [self.binding(a) for a in op.args] consider_meth = getattr(self,'consider_op_'+op.opname, None) @@ -668,16 +588,18 @@ # boom -- in the assert of setbinding() for arg in argcells: if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op) + raise BlockedInference(self, op, opindex) try: resultcell = consider_meth(*argcells) - except Exception: + except Exception, e: graph = self.bookkeeper.position_key[0] - raise_nicer_exception(op, str(graph)) + e.args = e.args + ( + ErrorWrapper(gather_error(self, graph, block, opindex)),) + raise if resultcell is None: resultcell = self.noreturnvalue(op) elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op) # the operation cannot succeed + raise BlockedInference(self, op, opindex) # the operation cannot succeed assert isinstance(resultcell, annmodel.SomeObject) assert isinstance(op.result, Variable) self.setbinding(op.result, resultcell) # bind resultcell to op.result @@ -728,13 +650,14 @@ """This exception signals the type inference engine that the situation is currently blocked, and that it should try to progress elsewhere.""" - def __init__(self, annotator, op): + def __init__(self, annotator, op, opindex): self.annotator = annotator try: self.break_at = annotator.bookkeeper.position_key except AttributeError: self.break_at = None self.op = op + self.opindex = opindex def __repr__(self): if not self.break_at: diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,15 +29,6 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', 'truediv', 'floordiv', 'divmod', 'pow', @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -238,7 +201,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -564,14 +550,30 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - return SomeObject() + raise UnionError("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): return SomeTuple(items = tup1.items + tup2.items) + def eq(tup1tup2): + tup1tup2.union() + return s_Bool + ne = eq + + def lt((tup1, tup2)): + raise Exception("unsupported: (...) < (...)") + def le((tup1, tup2)): + raise Exception("unsupported: (...) <= (...)") + def gt((tup1, tup2)): + raise Exception("unsupported: (...) > (...)") + def ge((tup1, tup2)): + raise Exception("unsupported: (...) >= (...)") + class __extend__(pairtype(SomeDict, SomeDict)): @@ -723,8 +725,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -764,7 +765,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -778,7 +779,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -806,7 +807,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,7 +10,7 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef @@ -148,7 +148,6 @@ self.descs = {} # map Python objects to their XxxDesc wrappers self.methoddescs = {} # map (funcdesc, classdef) to the MethodDesc self.classdefs = [] # list of all ClassDefs - self.pbctypes = {} self.seen_mutable = {} self.listdefs = {} # map position_keys to ListDefs self.dictdefs = {} # map position_keys to DictDefs @@ -167,9 +166,6 @@ self.stats = Stats(self) - # used in SomeObject.__new__ for keeping debugging info - self._isomeobject_coming_from = identity_dict() - delayed_imports() def count(self, category, *args): @@ -275,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() @@ -325,8 +320,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -445,6 +438,12 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if (x is type(None) or # add cases here if needed + x.__module__ == 'pypy.rpython.lltypesystem.lltype'): + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) 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 @@ -455,20 +454,13 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) - elif hasattr(x, '_freeze_') and x._freeze_(): + result = SomePBC([self.getdesc(x)]) + elif hasattr(x, '_freeze_'): + assert x._freeze_() is True # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method # returns True, the instance is considered immutable and becomes @@ -476,16 +468,18 @@ result = SomePBC([self.getdesc(x)]) elif hasattr(x, '__class__') \ and x.__class__.__module__ != '__builtin__': + if hasattr(x, '_cleanup_'): + x._cleanup_() self.see_mutable(x) result = SomeInstance(self.getuniqueclassdef(x.__class__)) elif x is None: return s_None else: - result = SomeObject() + raise Exception("Don't know how to represent %r" % (x,)) if need_const: result.const = x return result - + def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: @@ -509,8 +503,10 @@ elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) - elif (hasattr(pyobj.im_self, '_freeze_') and - pyobj.im_self._freeze_()): # method of frozen + if hasattr(pyobj.im_self, '_cleanup_'): + pyobj.im_self._cleanup_() + if hasattr(pyobj.im_self, '_freeze_'): # method of frozen + assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc(self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc @@ -529,9 +525,9 @@ name) else: # must be a frozen pre-built constant, but let's check - try: - assert pyobj._freeze_() - except AttributeError: + if hasattr(pyobj, '_freeze_'): + assert pyobj._freeze_() is True + else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: @@ -551,11 +547,7 @@ return False def getfrozen(self, pyobj): - result = description.FrozenDesc(self, pyobj) - cls = result.knowntype - if cls not in self.pbctypes: - self.pbctypes[cls] = True - return result + return description.FrozenDesc(self, pyobj) def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, flags={}): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -150,7 +150,7 @@ def builtin_isinstance(s_obj, s_type, variables=None): - r = SomeBool() + r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,8 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + + if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -247,13 +247,16 @@ defs_s = [] if graph is None: signature = self.signature - defaults = self.defaults + defaults = self.defaults else: signature = graph.signature - defaults = graph.defaults + defaults = graph.defaults if defaults: for x in defaults: - defs_s.append(self.bookkeeper.immutablevalue(x)) + if x is NODEFAULT: + defs_s.append(None) + else: + defs_s.append(self.bookkeeper.immutablevalue(x)) try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,8 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype + immutable = False knowntype = object - immutable = False + + def __init__(self): + assert type(self) is not SomeObject def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -105,60 +106,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: - self = new(cls, *args, **kw) - if DEBUG: - try: - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - position_key = bookkeeper.position_key - except AttributeError: - pass - else: - bookkeeper._isomeobject_coming_from[self] = position_key, None + def can_be_none(self): + return True + + def nonnoneify(self): return self - def origin(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] - origin = property(origin) - def caused_by_merge(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] - def set_caused_by_merge(self, nvalue): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return - bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue - caused_by_merge = property(caused_by_merge, set_caused_by_merge) - del set_caused_by_merge +class SomeType(SomeObject): + "Stands for a type. We might not be sure which one it is." + knowntype = type + immutable = True def can_be_none(self): - return True - - def nonnoneify(self): - return self + return False class SomeFloat(SomeObject): "Stands for a float or an integer." @@ -517,6 +486,7 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) @@ -710,14 +680,8 @@ # this is just a performance shortcut if s1 != s2: s1 = pair(s1, s2).union() - if DEBUG: - if s1.caused_by_merge is None and len(somevalues) > 1: - s1.caused_by_merge = somevalues return s1 -def isdegenerated(s_value): - return s_value.__class__ is SomeObject and s_value.knowntype is not type - # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -10,7 +10,6 @@ class BasicAnnotatorPolicy(object): - allow_someobjects = True def event(pol, bookkeeper, what, *args): pass @@ -80,6 +79,3 @@ def specialize__ll_and_arg(pol, *args): from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args) - -class StrictAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -3,9 +3,9 @@ from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF -from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF + unionof, SomeUnicodeString, SomeType +from pypy.annotation.listdef import ListDef +from pypy.annotation.dictdef import DictDef _annotation_cache = {} @@ -78,24 +78,18 @@ return SomeString() elif t is unicode: return SomeUnicodeString() - elif t is list: - return SomeList(MOST_GENERAL_LISTDEF) - elif t is dict: - return SomeDict(MOST_GENERAL_DICTDEF) - # can't do tuple elif t is types.NoneType: return s_None elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) - elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes: + elif t is type: + return SomeType() + elif bookkeeper and not hasattr(t, '_freeze_'): classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) else: - o = SomeObject() - if t != object: - o.knowntype = t - return o + raise AssertionError("annotationoftype(%r)" % (t,)) class Sig(object): diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -24,7 +24,7 @@ assert isinstance(s_list, annmodel.SomeList) return s_list.listdef.listitem.s_value -def somelist(s_type=annmodel.SomeObject()): +def somelist(s_type): return annmodel.SomeList(ListDef(None, s_type)) def dictkey(s_dict): @@ -35,7 +35,7 @@ assert isinstance(s_dict, annmodel.SomeDict) return s_dict.dictdef.dictvalue.s_value -def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()): +def somedict(s_key, s_value): return annmodel.SomeDict(DictDef(None, s_key, s_value)) @@ -205,15 +205,6 @@ annmodel.SomeInteger() ]) - def test_inheritance2(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet._inheritance_nonrunnable, []) - # result should be exactly: - assert s == annmodel.SomeTuple([ - annmodel.SomeInteger(), - annmodel.SomeObject() - ]) - def test_poor_man_range(self): a = self.RPythonAnnotator() s = a.build_types(snippet.poor_man_range, [int]) @@ -336,9 +327,13 @@ def test_flow_type_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_type_info, [object]) + s = a.build_types(snippet.flow_type_info, [int]) a.simplify() - #a.translator.view() + assert s.knowntype == int + + a = self.RPythonAnnotator() + s = a.build_types(snippet.flow_type_info, [str]) + a.simplify() assert s.knowntype == int def test_flow_type_info_2(self): @@ -351,7 +346,7 @@ def test_flow_usertype_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_usertype_info, [object]) + s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit]) #a.translator.view() assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit) @@ -363,13 +358,6 @@ assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit) - def test_flow_identity_info(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_identity_info, [object, object]) - a.simplify() - #a.translator.view() - assert s == a.bookkeeper.immutablevalue((None, None)) - def test_mergefunctions(self): a = self.RPythonAnnotator() s = a.build_types(snippet.mergefunctions, [int]) @@ -431,11 +419,11 @@ # the annotator (it doesn't check that they operate property, though) for example, methname, s_example in [ ('', 'join', annmodel.SomeString()), - ([], 'append', somelist()), - ([], 'extend', somelist()), - ([], 'reverse', somelist()), - ([], 'insert', somelist()), - ([], 'pop', somelist()), + ([], 'append', somelist(annmodel.s_Int)), + ([], 'extend', somelist(annmodel.s_Int)), + ([], 'reverse', somelist(annmodel.s_Int)), + ([], 'insert', somelist(annmodel.s_Int)), + ([], 'pop', somelist(annmodel.s_Int)), ]: constmeth = getattr(example, methname) s_constmeth = iv(constmeth) @@ -497,12 +485,12 @@ def test_simple_slicing(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_slice, [list]) + s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeList) def test_simple_iter_list(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_iter, [list]) + s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeIterator) def test_simple_iter_next(self): @@ -542,11 +530,6 @@ assert isinstance(dictkey(s), annmodel.SomeInteger) assert isinstance(dictvalue(s), annmodel.SomeInteger) - a = self.RPythonAnnotator() - s = a.build_types(snippet.dict_update, [str]) - assert not isinstance(dictkey(s), annmodel.SomeString) - assert not isinstance(dictvalue(s), annmodel.SomeString) - def test_dict_update_2(self): a = self.RPythonAnnotator() def g(n): @@ -568,7 +551,7 @@ def test_dict_keys2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_keys2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_values(self): a = self.RPythonAnnotator() @@ -578,7 +561,7 @@ def test_dict_values2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_items(self): a = self.RPythonAnnotator() @@ -643,25 +626,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_bltin_code_frame_confusion(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_confusion,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - # annotator confused by original bltin code/frame setup, we just get SomeObject here - assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - - def test_bltin_code_frame_reorg(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_reorg,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - assert isinstance(a.binding(f_flowgraph.getreturnvar()), - annmodel.SomeInteger) - assert isinstance(a.binding(g_flowgraph.getreturnvar()), - annmodel.SomeString) - def test_propagation_of_fresh_instances_through_attrs(self): a = self.RPythonAnnotator() s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int]) @@ -748,14 +712,15 @@ assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc) def test_type_is(self): - class C(object): + class B(object): + pass + class C(B): pass def f(x): - if type(x) is C: - return x - raise Exception - a = self.RPythonAnnotator() - s = a.build_types(f, [object]) + assert type(x) is C + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) def test_ann_assert(self): @@ -793,24 +758,30 @@ return None a = self.RPythonAnnotator() - s = a.build_types(f, [list]) + s = a.build_types(f, [somelist(annmodel.s_Int)]) assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list def test_freeze_protocol(self): class Stuff: - def __init__(self, flag): + def __init__(self): self.called = False - self.flag = flag def _freeze_(self): self.called = True - return self.flag - myobj = Stuff(True) + return True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - myobj = Stuff(False) + + def test_cleanup_protocol(self): + class Stuff: + def __init__(self): + self.called = False + def _cleanup_(self): + self.called = True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called @@ -854,7 +825,7 @@ def f(a,b): return bool(a) or bool(b) a = self.RPythonAnnotator() - s = a.build_types(f, [int,list]) + s = a.build_types(f, [int, somelist(annmodel.s_Int)]) assert s.knowntype == bool def test_float(self): @@ -1299,22 +1270,6 @@ assert isinstance(s_item, annmodel.SomeInstance) assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - def test_assert_type_is_list_doesnt_lose_info(self): - class T(object): - pass - def g(l): - assert type(l) is list - return l - def f(): - l = [T()] - return g(l) - a = self.RPythonAnnotator() - s = a.build_types(f, []) - s_item = listitem(s) - assert isinstance(s_item, annmodel.SomeInstance) - assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - - def test_int_str_mul(self): def f(x,a,b): return a*x+x*b @@ -1395,11 +1350,10 @@ except KeyError: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.const = KeyError t.is_type_of = [ev] assert a.binding(et) == t @@ -1412,11 +1366,10 @@ except: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t @@ -1448,11 +1401,10 @@ finally: h() a = self.RPythonAnnotator() - a.build_types(f, [int, list]) + a.build_types(f, [int, somelist(annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) @@ -1474,24 +1426,11 @@ a.build_types(f, []) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_sys_attrs(self): - def f(): - return sys.argv[0] - a = self.RPythonAnnotator() - try: - oldvalue = sys.argv - sys.argv = [] - s = a.build_types(f, []) - finally: - sys.argv = oldvalue - assert s is not None - def test_pow(self): def f(n): n **= 2 @@ -1523,7 +1462,6 @@ a = self.RPythonAnnotator() 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)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] def test_is_true_coalesce2(self): def f(a,b,a1,b1,c,d,e): @@ -1532,9 +1470,12 @@ return d,c return e,c a = self.RPythonAnnotator() - s = a.build_types(f, [int, str, float, list, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) - assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] + s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int), + 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_coalesce_sanity(self): def f(a): @@ -1954,16 +1895,7 @@ t = type(x) return issubclass(t, A) - def f(): - x = g(1) - y = g(0) - return x or y - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert s.knowntype == bool - assert not s.is_constant() - a = self.RPythonAnnotator() - # sanity check + a = self.RPythonAnnotator() x = annmodel.SomeInteger() x.const = 1 s = a.build_types(g, [x]) @@ -2383,8 +2315,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int]) - assert s.__class__ == annmodel.SomeObject - assert s.knowntype == type + assert isinstance(s, annmodel.SomeType) def test_annotate_iter_empty_container(self): def f(): @@ -3075,7 +3006,6 @@ v = -maxint return intmask(v * 10) P = policy.AnnotatorPolicy() - P.allow_someobjects = False a = self.RPythonAnnotator(policy=P) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) @@ -3859,6 +3789,32 @@ a = self.RPythonAnnotator() py.test.raises(Exception, a.build_types, fn, []) + def test_lower_char(self): + def fn(c): + return c.lower() + a = self.RPythonAnnotator() + s = a.build_types(fn, [annmodel.SomeChar()]) + assert s == annmodel.SomeChar() + + def test_isinstance_double_const(self): + class X(object): + def _freeze_(self): + return True + + x = X() + + def f(i): + if i: + x1 = x + else: + x1 = None + print "hello" # this is to force the merge of blocks + return isinstance(x1, X) + + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeBool) + def g(n): return [0,1,2,n] diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -2,20 +2,20 @@ import autopath import py from pypy.annotation.model import * -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF +from pypy.annotation.listdef import ListDef from pypy.rpython.ootypesystem.ootype import ROOT listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) -s1 = SomeObject() +s1 = SomeType() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s1,s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s1, s2, s3, s4, s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -42,7 +42,7 @@ def test_equality(): assert s1 != s2 != s3 != s4 != s5 != s6 - assert s1 == SomeObject() + assert s1 == SomeType() assert s2 == SomeInteger(nonneg=True) assert s3 == SomeInteger(nonneg=False) assert s4 == SomeList(listdef1) @@ -51,19 +51,11 @@ def test_contains(): assert ([(s,t) for s in slist for t in slist if s.contains(t)] == - [(s1,s1), (s1,s2), (s1,s3), (s1,s4), (s1,s6), - (s2,s2), (s2,s6), - (s3,s2), (s3,s3), (s3,s6), - (s4,s4), (s4,s6), - (s6,s6)]) - -def test_union(): - assert ([unionof(s,t) for s in slist for t in slist] == - [s1, s1, s1, s1, s1, - s1, s2, s3, s1, s2, - s1, s3, s3, s1, s3, - s1, s1, s1, s4, s4, - s1, s2, s3, s4, s6]) + [(s1, s1), (s1, s6), + (s2, s2), (s2, s6), + (s3, s2), (s3, s3), (s3, s6), + (s4, s4), (s4, s6), + (s6, s6)]) def test_commonbase_simple(): class A0: @@ -100,9 +92,10 @@ def test_list_contains(): listdef1 = ListDef(None, SomeInteger(nonneg=True)) s1 = SomeList(listdef1) - s2 = SomeList(MOST_GENERAL_LISTDEF) + listdef2 = ListDef(None, SomeInteger(nonneg=False)) + s2 = SomeList(listdef2) assert s1 != s2 - assert s2.contains(s1) + assert not s2.contains(s1) assert s1 != s2 assert not s1.contains(s2) assert s1 != s2 diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -7,7 +7,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -39,14 +39,7 @@ def type(obj, *moreargs): if moreargs: raise Exception, 'type() called with more than one argument' - if obj.is_constant(): - if isinstance(obj, SomeInstance): - r = SomePBC([obj.classdef.classdesc]) - else: - r = immutablevalue(obj.knowntype) - else: - r = SomeObject() - r.knowntype = type + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator @@ -133,9 +126,6 @@ def float(obj): return SomeFloat() - def long(obj): - return SomeObject() # XXX - def delattr(obj, s_attr): if obj.__class__ != SomeObject or obj.knowntype != object: getbookkeeper().warning( @@ -154,18 +144,17 @@ def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - s_method = obj.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)) - else: - getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' % - (obj, s_attr)) - return SomeObject() + 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)) + attr = s_attr.const + s_method = obj.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)) getattr.can_only_throw = [] def bind_callables_under(obj, classdef, name): @@ -586,6 +575,12 @@ def method_isupper(chr): return s_Bool + def method_lower(chr): + return chr + + def method_upper(chr): + return chr + class __extend__(SomeIterator): def iter(itr): diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -2,9 +2,9 @@ """ Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME -Print a report for the static data informations contained in FILENAME +Print a report for the static data information contained in FILENAME -The static data informations are saved in the file staticdata.info when +The static data information is saved in the file staticdata.info when passing --dump_static_data_info to translate.py. Options: diff --git a/pypy/bin/translatorshell.py b/pypy/bin/translatorshell.py --- a/pypy/bin/translatorshell.py +++ b/pypy/bin/translatorshell.py @@ -8,10 +8,10 @@ Example: - t = Translation(func) + t = Translation(func, [int]) # pass the list of args types t.view() # control flow graph - t.annotate([int]) # pass the list of args types + t.annotate() t.view() # graph + annotations under the mouse t.rtype() # use low level operations diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py --- a/pypy/config/test/test_config.py +++ b/pypy/config/test/test_config.py @@ -111,8 +111,8 @@ else: return 'foo' - t = Translation(f) - t.rtype([int]) + t = Translation(f, [int]) + t.rtype() block = t.context.graphs[0].startblock assert len(block.exits[0].target.operations) == 0 diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -129,8 +129,6 @@ # misc BoolOption("verbose", "Print extra information", default=False), - BoolOption("debug", "Record extra annotation information", - cmdline="-d --debug", default=True), BoolOption("insist", "Try hard to go on RTyping", default=False, cmdline="--insist"), StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -101,15 +101,7 @@ def maketestobjspace(config=None): if config is None: config = make_config(option) - try: - space = make_objspace(config) - except OperationError, e: - check_keyboard_interrupt(e) - if option.verbose: - import traceback - traceback.print_exc() - py.test.fail("fatal: cannot initialize objspace: %r" % - (config.objspace.name,)) + space = make_objspace(config) space.startup() # Initialize all builtin modules space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), appsupport.build_pytest_assertion(space)) diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -238,7 +238,7 @@ interpreter`_. .. _`documentation index`: index.html#project-documentation -.. _`getting-started`: getting-started.html +.. _`getting-started`: getting-started-dev.html .. _`PyPy's approach to virtual machine construction`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dls2006/pypy-vm-construction.pdf .. _`the translation document`: translation.html .. _`RPython toolchain`: translation.html diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -9,7 +9,7 @@ `import` statements:: from pypy.interpreter.baseobjspace import Wrappable - from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w @@ -41,9 +41,6 @@ llexternal functions. For a typical usage, see `pypy.rlib.rsocket.RSocket.getsockopt_int`. -- Support context managers and the `with` statement. This could be a workaround - before the previous point is available. - Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -27,7 +27,7 @@ ``pypy/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: - >>> t = Translation(snippet.is_perfect_number) + >>> t = Translation(snippet.is_perfect_number, [int]) >>> t.view() After that, the graph viewer pops up, that lets you interactively inspect the @@ -40,7 +40,7 @@ We have a type annotator that can completely infer types for functions like ``is_perfect_number`` (as well as for much larger examples):: - >>> t.annotate([int]) + >>> t.annotate() >>> t.view() Move the mouse over variable names (in red) to see their inferred types. @@ -74,8 +74,8 @@ >>> def myfunc(a, b): return a+b ... - >>> t = Translation(myfunc) - >>> t.annotate([int, int]) + >>> t = Translation(myfunc, [int, int]) + >>> t.annotate() >>> f = t.compile_cli() # or compile_jvm() >>> f(4, 5) 9 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 @@ -36,6 +36,11 @@ .. branch: stdlib-2.7.3 The stdlib was updated to version 2.7.3 +.. branch: numpypy-complex2 +Complex dtype support for numpy +.. branch: kill-someobject +major cleanups including killing some object support + .. "uninteresting" branches that we should just ignore for the whatsnew: .. branch: slightly-shorter-c diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -719,8 +719,15 @@ # done by a method call on w_two (and not on w_one, because of the # expected programming style where we say "if x is None" or # "if x is object"). + assert w_two is not None return w_two.is_w(self, w_one) + def is_none(self, w_obj): + """ mostly for checking inputargs that have unwrap_spec and + can accept both w_None and None + """ + return w_obj is None or self.is_w(w_obj, self.w_None) + def id(self, w_obj): w_result = w_obj.immutable_unique_id(self) if w_result is None: @@ -804,7 +811,7 @@ interpreter class (a subclass of Wrappable). """ assert RequiredClass is not None - if can_be_None and self.is_w(w_obj, self.w_None): + if can_be_None and self.is_none(w_obj): return None obj = self.interpclass_w(w_obj) if not isinstance(obj, RequiredClass): # or obj is None diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -205,11 +205,11 @@ code = space.interp_w(Code, w_code) if not space.is_true(space.isinstance(w_globals, space.w_dict)): raise OperationError(space.w_TypeError, space.wrap("expected dict")) - if not space.is_w(w_name, space.w_None): + if not space.is_none(w_name): name = space.str_w(w_name) else: name = None - if not space.is_w(w_argdefs, space.w_None): + if not space.is_none(w_argdefs): defs_w = space.fixedview(w_argdefs) else: defs_w = [] @@ -217,7 +217,7 @@ from pypy.interpreter.pycode import PyCode if isinstance(code, PyCode): nfreevars = len(code.co_freevars) - if space.is_w(w_closure, space.w_None) and nfreevars == 0: + if space.is_none(w_closure) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) @@ -244,7 +244,7 @@ # delicate _all = {'': None} - def _freeze_(self): + def _cleanup_(self): from pypy.interpreter.gateway import BuiltinCode if isinstance(self.code, BuiltinCode): # we have been seen by other means so rtyping should not choke @@ -343,7 +343,7 @@ def fget_func_defaults(self, space): values_w = self.defs_w # the `None in values_w` check here is to ensure that interp-level - # functions with a default of NoneNotWrapped do not get their defaults + # functions with a default of None do not get their defaults # exposed at applevel if not values_w or None in values_w: return space.w_None @@ -424,11 +424,12 @@ w_res = space.w_None return w_res + def descr_function_get(space, w_function, w_obj, w_cls=None): """functionobject.__get__(obj[, type]) -> method""" # this is not defined as a method on Function because it's generally # useful logic: w_function can be any callable. It is used by Method too. - asking_for_bound = (space.is_w(w_cls, space.w_None) or + asking_for_bound = (space.is_none(w_cls) or not space.is_w(w_obj, space.w_None) or space.is_w(w_cls, space.type(space.w_None))) if asking_for_bound: @@ -445,12 +446,15 @@ self.space = space self.w_function = w_function self.w_instance = w_instance # or None + if w_class is None: + w_class = space.w_None self.w_class = w_class # possibly space.w_None - def descr_method__new__(space, w_subtype, w_function, w_instance, w_class=None): + def descr_method__new__(space, w_subtype, w_function, w_instance, + w_class=None): if space.is_w(w_instance, space.w_None): w_instance = None - if w_instance is None and space.is_w(w_class, space.w_None): + if w_instance is None and space.is_none(w_class): raise OperationError(space.w_TypeError, space.wrap("unbound methods must have class")) method = space.allocate_instance(Method, w_subtype) @@ -610,7 +614,7 @@ self.w_function = w_function def descr_classmethod_get(self, space, w_obj, w_klass=None): - if space.is_w(w_klass, space.w_None): + if space.is_none(w_klass): w_klass = space.type(w_obj) return space.wrap(Method(space, self.w_function, w_klass, space.w_None)) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -7,31 +7,29 @@ """ -import types, sys, os -from pypy.tool.compat import md5 +import sys +import os +import types -NoneNotWrapped = object() +import py -from pypy.tool.sourcetools import func_with_new_name +from pypy.interpreter.eval import Code +from pypy.interpreter.argument import Arguments, Signature +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, + SpaceCache, DescrMismatch) from pypy.interpreter.error import OperationError -from pypy.interpreter import eval -from pypy.interpreter.function import Function, Method, ClassMethod -from pypy.interpreter.function import FunctionWithFixedCode -from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable -from pypy.interpreter.baseobjspace import Wrappable, SpaceCache, DescrMismatch -from pypy.interpreter.argument import Arguments, Signature -from pypy.tool.sourcetools import NiceCompile, compile2 -from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from pypy.rlib import rstackovf from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.tool.sourcetools import func_with_new_name, compile2 + # internal non-translatable parts: -import py - class SignatureBuilder(object): "NOT_RPYTHON" def __init__(self, func=None, argnames=None, varargname=None, - kwargname=None, name = None): + kwargname=None, name=None): self.func = func if func is not None: self.name = func.__name__ @@ -60,10 +58,12 @@ if isinstance(el, str): getattr(self, "visit_%s" % (el,))(el, *args) elif isinstance(el, tuple): - if el[0] == 'self': + if el[0] == 'INTERNAL:self': self.visit_self(el[1], *args) else: - self.visit_function(el, *args) + assert False, "not supported any more, use WrappedDefault" + elif isinstance(el, WrappedDefault): + self.visit__W_Root(W_Root, *args) elif isinstance(el, type): for typ in self.bases_order: if issubclass(el, typ): @@ -81,8 +81,8 @@ for el in unwrap_spec: dispatch(el, *extra) + class UnwrapSpecEmit(UnwrapSpecRecipe): - def __init__(self): self.n = 0 self.miniglobals = {} @@ -97,10 +97,11 @@ self.miniglobals[name] = obj return name + #________________________________________________________________ + class UnwrapSpec_Check(UnwrapSpecRecipe): - # checks for checking interp2app func argument names wrt unwrap_spec # and synthetizing an app-level signature @@ -108,9 +109,6 @@ self.func = original_sig.func self.orig_arg = iter(original_sig.argnames).next - def visit_function(self, (func, cls), app_sig): - self.dispatch(cls, app_sig) - def visit_self(self, cls, app_sig): self.visit__Wrappable(cls, app_sig) @@ -168,8 +166,8 @@ app_sig.append(argname[2:]) def visit__Arguments(self, el, app_sig): - argname = self.orig_arg() - assert app_sig.varargname is None,( + self.orig_arg() + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = 'args' app_sig.kwargname = 'keywords' @@ -179,7 +177,7 @@ From noreply at buildbot.pypy.org Sat Oct 13 00:13:41 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 13 Oct 2012 00:13:41 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: failargs support Message-ID: <20121012221341.7830C1C1C5D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58085:aea0991bf56e Date: 2012-10-12 20:12 +0200 http://bitbucket.org/pypy/pypy/changeset/aea0991bf56e/ Log: failargs support diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -2,17 +2,30 @@ """ Mutable subclasses for each of ResOperation. """ +from pypy.tool.sourcetools import func_with_new_name from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable def create_mutable_subclasses(): + def addattr(cls, attr, default_value=None): + def getter(self): + return getattr(self, '_' + attr) + def setter(self, value): + setattr(self, '_' + attr, value) + setattr(cls, '_' + attr, default_value) + setattr(cls, 'get_' + attr, func_with_new_name(getter, 'get_' + attr)) + setattr(cls, 'set_' + attr, func_with_new_name(setter, 'set_' + attr)) + for i, cls in enumerate(opclasses): if cls is None: Mutable = None else: class Mutable(cls): is_mutable = True + if cls.is_guard(): + addattr(Mutable, 'failargs') Mutable.__name__ = cls.__name__ + '_mutable' assert len(opclasses_mutable) == i opclasses_mutable.append(Mutable) + assert len(opclasses) == len(opclasses_mutable) create_mutable_subclasses() diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -28,20 +28,22 @@ VOID = 'v' HOLE = '_' -def create_resop_dispatch(opnum, result, args, descr=None): +def create_resop_dispatch(opnum, result, args, descr=None, mutable=False): """ NOT_RPYTHON this is for tests only! """ cls = opclasses[opnum] if cls.NUMARGS == 0: - return create_resop_0(opnum, result, descr) + return create_resop_0(opnum, result, descr, mutable=mutable) elif cls.NUMARGS == 1: - return create_resop_1(opnum, result, args[0], descr) + return create_resop_1(opnum, result, args[0], descr, mutable=mutable) elif cls.NUMARGS == 2: - return create_resop_2(opnum, result, args[0], args[1], descr) + return create_resop_2(opnum, result, args[0], args[1], descr, + mutable=mutable) elif cls.NUMARGS == 3: - return create_resop_3(opnum, result, args[0], args[1], args[2], descr) + return create_resop_3(opnum, result, args[0], args[1], args[2], descr, + mutable=mutable) else: - return create_resop(opnum, result, args, descr) + return create_resop(opnum, result, args, descr, mutable=mutable) @specialize.memo() def _getcls(opnum, mutable): diff --git a/pypy/jit/metainterp/test/test_optmodel.py b/pypy/jit/metainterp/test/test_optmodel.py --- a/pypy/jit/metainterp/test/test_optmodel.py +++ b/pypy/jit/metainterp/test/test_optmodel.py @@ -36,3 +36,10 @@ assert op2.getarglist() == ['a', 'b', 'c'] op2 = op.mutable_copy(rop.rop.CALL_i, [FakeBox('a')]) assert op2.getarglist() == ['a'] + +def test_failargs(): + op = rop.create_resop_0(rop.rop.GUARD_NO_OVERFLOW, None) + assert not hasattr(op, 'set_failargs') + op2 = op.mutable_copy() + op2.set_failargs([1, 2, 3]) + assert op2.get_failargs() == [1, 2, 3] diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -8,6 +8,7 @@ from pypy.jit.metainterp.resoperation import rop, opclasses, rop_lowercase,\ ResOpWithDescr, N_aryOp, UnaryOp, PlainResOp, create_resop_dispatch,\ ResOpNone, create_resop_0, example_for_opnum +from pypy.jit.metainterp import optmodel from pypy.rpython.lltypesystem import lltype, llmemory class ParseError(Exception): @@ -274,7 +275,8 @@ if opnum == FORCE_SPILL.OPNUM: return FORCE_SPILL(opnum, args, result, descr) else: - r = create_resop_dispatch(opnum, result, args) + r = create_resop_dispatch(opnum, result, args, + mutable=self.guards_with_failargs) if descr is not None: r.setdescr(descr) return r @@ -293,14 +295,14 @@ opres = self.create_op(opnum, result, args, descr) self.vars[res] = opres if fail_args is not None: - explode + opres.set_failargs(fail_args) return opres def parse_op_no_result(self, line): opnum, args, descr, fail_args = self.parse_op(line) res = self.create_op(opnum, None, args, descr) if fail_args is not None: - explode + res.set_failargs(fail_args) return res def parse_next_op(self, line, num): diff --git a/pypy/jit/tool/test/test_oparser.py b/pypy/jit/tool/test/test_oparser.py --- a/pypy/jit/tool/test/test_oparser.py +++ b/pypy/jit/tool/test/test_oparser.py @@ -148,9 +148,9 @@ """ def test_attach_comment_to_loop(self): - py.test.skip("failargs") loop = self.parse(self.example_loop_log, guards_with_failargs=True) assert loop.comment == ' # bridge out of Guard12, 6 ops' + assert loop.operations[-3].get_failargs() def test_parse_new_with_comma(self): # this is generated by PYPYJITLOG, check that we can handle it From noreply at buildbot.pypy.org Sat Oct 13 00:13:43 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 13 Oct 2012 00:13:43 +0200 (CEST) Subject: [pypy-commit] pypy default: removed absolutely pointless copy of pybench Message-ID: <20121012221343.0571D1C1C5D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58086:7f44b55de98e Date: 2012-10-13 00:13 +0200 http://bitbucket.org/pypy/pypy/changeset/7f44b55de98e/ Log: removed absolutely pointless copy of pybench diff too long, truncating to 2000 out of 12111 lines diff --git a/pypy/translator/microbench/microbench.py b/pypy/translator/microbench/microbench.py deleted file mode 100755 --- a/pypy/translator/microbench/microbench.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python - -"""This script computes the relative performance between python -implementations on a set of microbenchmarks. The script usually is started -with "./microbench.py python ./pypy" where pypy is a symlink to your pypy executable.""" - -import os, time, sys - -try: - import gc -except ImportError: - if sys.platform.startswith('java'): - import java.lang - gccollect = java.lang.System.gc - else: - gccollect = lambda: None -else: - gccollect = gc.collect - -try: - this_dir = os.path.dirname(__file__) -except NameError: - this_dir = os.path.dirname(sys.argv[0]) - -microbenches = [] -for fname in os.listdir(this_dir): - if not fname.startswith('test_') or not fname.endswith('.py'): - continue - microbench = fname[:-3] - microbenches.append(microbench) - -def run(test_cases, fmt): - MINIMUM_MICROBENCH_TIME = 1.0 - - for microbench in microbenches: - testmoddict = {} - execfile(os.path.join(this_dir, microbench + '.py'), testmoddict) - for k in [s for s in testmoddict if s.startswith('test_')] : - if test_cases: - for tc in test_cases: - if k.startswith(tc) or microbench.startswith(tc): - break - else: - continue - testcase_name = microbench + '.' + k + '()' - testcase = testmoddict[k] - gccollect() - start = time.clock() - n = 0 - duration = 0.0 - while duration < MINIMUM_MICROBENCH_TIME: - testcase() - n += 1 - duration = time.clock() - start - print ('%s took ' + fmt +' seconds') % (testcase_name, duration / float(n)) - -if __name__ == '__main__': - args = sys.argv[1:] - if args[0].startswith('-F'): - fmt = "%" + args[0][2:] - args.pop(0) - inner = True - else: - fmt = "%.2f" - inner = False - - if '-k' in args: - i = args.index('-k') - executables = args[:i] - test_cases = args[i+1:] - limit = '-k ' + ' '.join(test_cases) - else: - executables = args - test_cases = [] - limit = '' - - for n, exe in enumerate(executables): - print 'exe:', exe - data = [s for s in os.popen('%s %s -Fr %s 2>&1' % - (exe, os.path.join(this_dir, 'microbench.py'), limit)).readlines() - if not s.startswith('debug:')] - benchdata = {} - for d in data: - try: - testcase, took, duration, seconds = d.split() - except ValueError: - print >> sys.stderr, 'Unexpected output:\n%s' % d - sys.exit(1) - benchdata[testcase] = float(duration) - if n == 0: - benchdata_ref = benchdata - else: - result = [] - for k, v in benchdata.iteritems(): - result.append( (v / benchdata_ref[k], k) ) - result.sort() - for slowdown, testcase in result: - print '%5.2fx slower on %s' % (slowdown, testcase) - if not inner and n == 0: - result = [] - for k, v in benchdata.iteritems(): - result.append((v, k)) - result.sort() - for v, testcase in result: - print 'took %5.5fs for %s' % (v, testcase) - - if not executables: - run(test_cases, fmt) - diff --git a/pypy/translator/microbench/pybench/Arithmetic.py b/pypy/translator/microbench/pybench/Arithmetic.py deleted file mode 100644 --- a/pypy/translator/microbench/pybench/Arithmetic.py +++ /dev/null @@ -1,778 +0,0 @@ -from pybench import Test - -class SimpleIntegerArithmetic(Test): - - version = 0.3 - operations = 5 * (3 + 5 + 5 + 3 + 3 + 3) - rounds = 120000 - - def test(self): - - for i in xrange(self.rounds): - - a = 2 - b = 3 - c = 3 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 - b = 3 - c = 3 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 - b = 3 - c = 3 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 - b = 3 - c = 3 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 - b = 3 - c = 3 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - def calibrate(self): - - for i in xrange(self.rounds): - pass - -class SimpleFloatArithmetic(Test): - - version = 0.3 - operations = 5 * (3 + 5 + 5 + 3 + 3 + 3) - rounds = 100000 - - def test(self): - - for i in xrange(self.rounds): - - a = 2.1 - b = 3.3332 - c = 3.14159 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2.1 - b = 3.3332 - c = 3.14159 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2.1 - b = 3.3332 - c = 3.14159 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2.1 - b = 3.3332 - c = 3.14159 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2.1 - b = 3.3332 - c = 3.14159 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - def calibrate(self): - - for i in xrange(self.rounds): - pass - -class SimpleIntFloatArithmetic(Test): - - version = 0.3 - operations = 5 * (3 + 5 + 5 + 3 + 3 + 3) - rounds = 120000 - - def test(self): - - for i in xrange(self.rounds): - - a = 2 - b = 3 - c = 3.14159 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 - b = 3 - c = 3.14159 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 - b = 3 - c = 3.14159 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 - b = 3 - c = 3.14159 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 - b = 3 - c = 3.14159 - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - def calibrate(self): - - for i in xrange(self.rounds): - pass - - -class SimpleLongArithmetic(Test): - - version = 0.3 - operations = 5 * (3 + 5 + 5 + 3 + 3 + 3) - rounds = 30000 - - def test(self): - - for i in xrange(self.rounds): - - a = 2220001L - b = 100001L - c = 30005L - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2220001L - b = 100001L - c = 30005L - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2220001L - b = 100001L - c = 30005L - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2220001L - b = 100001L - c = 30005L - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2220001L - b = 100001L - c = 30005L - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - def calibrate(self): - - for i in xrange(self.rounds): - pass - -class SimpleComplexArithmetic(Test): - - version = 0.3 - operations = 5 * (3 + 5 + 5 + 3 + 3 + 3) - rounds = 40000 - - def test(self): - - for i in xrange(self.rounds): - - a = 2 + 3j - b = 2.5 + 4.5j - c = 1.2 + 6.2j - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 + 3j - b = 2.5 + 4.5j - c = 1.2 + 6.2j - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 + 3j - b = 2.5 + 4.5j - c = 1.2 + 6.2j - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 + 3j - b = 2.5 + 4.5j - c = 1.2 + 6.2j - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - a = 2 + 3j - b = 2.5 + 4.5j - c = 1.2 + 6.2j - - c = a + b - c = b + c - c = c + a - c = a + b - c = b + c - - c = c - a - c = a - b - c = b - c - c = c - a - c = b - c - - c = a / b - c = b / a - c = c / b - - c = a * b - c = b * a - c = c * b - - c = a / b - c = b / a - c = c / b - - def calibrate(self): - - for i in xrange(self.rounds): - pass - diff --git a/pypy/translator/microbench/pybench/Calls.py b/pypy/translator/microbench/pybench/Calls.py deleted file mode 100644 --- a/pypy/translator/microbench/pybench/Calls.py +++ /dev/null @@ -1,410 +0,0 @@ -from pybench import Test - -class PythonFunctionCalls(Test): - - version = 0.3 - operations = 5*(1+4+4+2) - rounds = 60000 - - def test(self): - - global f,f1,g,h - - # define functions - def f(): - pass - - def f1(x): - pass - - def g(a,b,c): - return a,b,c - - def h(a,b,c,d=1,e=2,f=3): - return d,e,f - - # do calls - for i in xrange(self.rounds): - - f() - f1(i) - f1(i) - f1(i) - f1(i) - g(i,i,i) - g(i,i,i) - g(i,i,i) - g(i,i,i) - h(i,i,3,i,i) - h(i,i,i,2,i,3) - - f() - f1(i) - f1(i) - f1(i) - f1(i) - g(i,i,i) - g(i,i,i) - g(i,i,i) - g(i,i,i) - h(i,i,3,i,i) - h(i,i,i,2,i,3) - - f() - f1(i) - f1(i) - f1(i) - f1(i) - g(i,i,i) - g(i,i,i) - g(i,i,i) - g(i,i,i) - h(i,i,3,i,i) - h(i,i,i,2,i,3) - - f() - f1(i) - f1(i) - f1(i) - f1(i) - g(i,i,i) - g(i,i,i) - g(i,i,i) - g(i,i,i) - h(i,i,3,i,i) - h(i,i,i,2,i,3) - - f() - f1(i) - f1(i) - f1(i) - f1(i) - g(i,i,i) - g(i,i,i) - g(i,i,i) - g(i,i,i) - h(i,i,3,i,i) - h(i,i,i,2,i,3) - - def calibrate(self): - - global f,f1,g,h - - # define functions - def f(): - pass - - def f1(x): - pass - - def g(a,b,c): - return a,b,c - - def h(a,b,c,d=1,e=2,f=3): - return d,e,f - - # do calls - for i in xrange(self.rounds): - pass - -### - -class BuiltinFunctionCalls(Test): - - version = 0.4 - operations = 5*(2+5+5+5) - rounds = 30000 - - def test(self): - - # localize functions - f0 = globals - f1 = hash - f2 = cmp - f3 = range - - # do calls - for i in xrange(self.rounds): - - f0() - f0() - f1(i) - f1(i) - f1(i) - f1(i) - f1(i) - f2(1,2) - f2(1,2) - f2(1,2) - f2(1,2) - f2(1,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - - f0() - f0() - f1(i) - f1(i) - f1(i) - f1(i) - f1(i) - f2(1,2) - f2(1,2) - f2(1,2) - f2(1,2) - f2(1,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - - f0() - f0() - f1(i) - f1(i) - f1(i) - f1(i) - f1(i) - f2(1,2) - f2(1,2) - f2(1,2) - f2(1,2) - f2(1,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - - f0() - f0() - f1(i) - f1(i) - f1(i) - f1(i) - f1(i) - f2(1,2) - f2(1,2) - f2(1,2) - f2(1,2) - f2(1,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - - f0() - f0() - f1(i) - f1(i) - f1(i) - f1(i) - f1(i) - f2(1,2) - f2(1,2) - f2(1,2) - f2(1,2) - f2(1,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - f3(1,3,2) - - def calibrate(self): - - # localize functions - f0 = dir - f1 = hash - f2 = range - f3 = range - - # do calls - for i in xrange(self.rounds): - pass - -### - -class PythonMethodCalls(Test): - - version = 0.3 - operations = 5*(6 + 5 + 4) - rounds = 20000 - - def test(self): - - class c: - - x = 2 - s = 'string' - - def f(self): - - return self.x - - def j(self,a,b): - - self.y = a - self.t = b - return self.y - - def k(self,a,b,c=3): - - self.y = a - self.s = b - self.t = c - - o = c() - - for i in xrange(self.rounds): - - o.f() - o.f() - o.f() - o.f() - o.f() - o.f() - o.j(i,i) - o.j(i,i) - o.j(i,2) - o.j(i,2) - o.j(2,2) - o.k(i,i) - o.k(i,2) - o.k(i,2,3) - o.k(i,i,c=4) - - o.f() - o.f() - o.f() - o.f() - o.f() - o.f() - o.j(i,i) - o.j(i,i) - o.j(i,2) - o.j(i,2) - o.j(2,2) - o.k(i,i) - o.k(i,2) - o.k(i,2,3) - o.k(i,i,c=4) - - o.f() - o.f() - o.f() - o.f() - o.f() - o.f() - o.j(i,i) - o.j(i,i) - o.j(i,2) - o.j(i,2) - o.j(2,2) - o.k(i,i) - o.k(i,2) - o.k(i,2,3) - o.k(i,i,c=4) - - o.f() - o.f() - o.f() - o.f() - o.f() - o.f() - o.j(i,i) - o.j(i,i) - o.j(i,2) - o.j(i,2) - o.j(2,2) - o.k(i,i) - o.k(i,2) - o.k(i,2,3) - o.k(i,i,c=4) - - o.f() - o.f() - o.f() - o.f() - o.f() - o.f() - o.j(i,i) - o.j(i,i) - o.j(i,2) - o.j(i,2) - o.j(2,2) - o.k(i,i) - o.k(i,2) - o.k(i,2,3) - o.k(i,i,c=4) - - def calibrate(self): - - class c: - - x = 2 - s = 'string' - - def f(self): - - return self.x - - def j(self,a,b): - - self.y = a - self.t = b - - def k(self,a,b,c=3): - - self.y = a - self.s = b - self.t = c - - o = c - - for i in xrange(self.rounds): - pass - -### - -class Recursion(Test): - - version = 0.3 - operations = 5 - rounds = 50000 - - def test(self): - - global f - - def f(x): - - if x > 1: - return f(x-1) - return 1 - - for i in xrange(self.rounds): - f(10) - f(10) - f(10) - f(10) - f(10) - - def calibrate(self): - - global f - - def f(x): - - if x > 0: - return f(x-1) - return 1 - - for i in xrange(self.rounds): - pass - diff --git a/pypy/translator/microbench/pybench/CommandLine.py b/pypy/translator/microbench/pybench/CommandLine.py deleted file mode 100644 --- a/pypy/translator/microbench/pybench/CommandLine.py +++ /dev/null @@ -1,573 +0,0 @@ -""" CommandLine - Get and parse command line options - - NOTE: This still is very much work in progress !!! - - Different version are likely to be incompatible. - - TODO: - - - Incorporate the changes made by (see Inbox) - - Add number range option using srange() - - Copyright (c) 1997-2001, Marc-Andre Lemburg; mailto:mal at lemburg.com - Copyright (c) 2000-2001, eGenix.com Software GmbH; mailto:info at egenix.com - See the documentation for further information on copyrights, - or contact the author. All Rights Reserved. -""" - -__version__ = '1.0' - -import sys,getopt,string,glob,os,traceback,re - -### Helpers - -def _getopt_flags(options): - - """ Convert the option list to a getopt flag string and long opt - list - - """ - s = [] - l = [] - for o in options: - if o.prefix == '-': - # short option - s.append(o.name) - if o.takes_argument: - s.append(':') - else: - # long option - if o.takes_argument: - l.append(o.name+'=') - else: - l.append(o.name) - return string.join(s,''),l - -def invisible_input(prompt='>>> '): - - """ Get raw input from a terminal without echoing the characters to - the terminal, e.g. for password queries. - - """ - import getpass - entry = getpass.getpass(prompt) - if entry is None: - raise KeyboardInterrupt - return entry - -def option_dict(options): - - """ Return a dictionary mapping option names to Option instances. - """ - d = {} - for option in options: - d[option.name] = option - return d - -# Alias -getpasswd = invisible_input - -_integerRE = re.compile('\s*(-?\d+)\s*$') -_integerRangeRE = re.compile('\s*(-?\d+)\s*-\s*(-?\d+)\s*$') - -def srange(s, - - split=string.split,integer=_integerRE, - integerRange=_integerRangeRE): - - """ Converts a textual representation of integer numbers and ranges - to a Python list. - - Supported formats: 2,3,4,2-10,-1 - -3, 5 - -2 - - Values are appended to the created list in the order specified - in the string. - - """ - l = [] - append = l.append - for entry in split(s,','): - m = integer.match(entry) - if m: - append(int(m.groups()[0])) - continue - m = integerRange.match(entry) - if m: - start,end = map(int,m.groups()) - l[len(l):] = range(start,end+1) - return l - -### Option classes - -class Option: - - """ Option base class. Takes no argument. - - """ - default = None - helptext = '' - prefix = '-' - takes_argument = 0 - has_default = 0 - tab = 15 - - def __init__(self,name,help=None): - - if not name[:1] == '-': - raise TypeError('option names must start with "-"') - if name[1:2] == '-': - self.prefix = '--' - self.name = name[2:] - else: - self.name = name[1:] - if help: - self.help = help - - def __str__(self): - - o = self - name = o.prefix + o.name - if o.takes_argument: - name = name + ' arg' - if len(name) > self.tab: - name = name + '\n' + ' ' * (self.tab + 1 + len(o.prefix)) - else: - name = '%-*s ' % (self.tab, name) - description = o.help - if o.has_default: - description = description + ' (%s)' % o.default - return '%s %s' % (name, description) - -class ArgumentOption(Option): - - """ Option that takes an argument. - - An optional default argument can be given. - - """ - def __init__(self,name,help=None,default=None): - - # Basemethod - Option.__init__(self,name,help) - - if default is not None: - self.default = default - self.has_default = 1 - self.takes_argument = 1 - -class SwitchOption(Option): - - """ Options that can be on or off. Has an optional default value. - - """ - def __init__(self,name,help=None,default=None): - - # Basemethod - Option.__init__(self,name,help) - - if default is not None: - self.default = default - self.has_default = 1 - -### Application baseclass - -class Application: - - """ Command line application interface with builtin argument - parsing. - - """ - # Options the program accepts (Option instances) - options = [] - - # Standard settings; these are appended to options in __init__ - preset_options = [SwitchOption('-v','generate verbose output'), - SwitchOption('-h','show this help text'), - SwitchOption('--help','show this help text'), - SwitchOption('--debug','enable debugging'), - SwitchOption('--copyright','show copyright'), - SwitchOption('--examples','show examples of usage')] - - # The help layout looks like this: - # [header] - defaults to '' - # - # [synopsis] - formatted as ' %s' % self.synopsis - # - # options: - # [options] - formatted from self.options - # - # [version] - formatted as 'Version:\n %s' % self.version, if given - # - # [about] - defaults to '' - # - # Note: all fields that do not behave as template are formatted - # using the instances dictionary as substitution namespace, - # e.g. %(name)s will be replaced by the applications name. - # - - # Header (default to program name) - header = '' - - # Name (defaults to program name) - name = '' - - # Synopsis (%(name)s is replaced by the program name) - synopsis = '%(name)s [option] files...' - - # Version (optional) - version = '' - - # General information printed after the possible options (optional) - about = '' - - # Examples of usage to show when the --examples option is given (optional) - examples = '' - - # Copyright to show - copyright = ( - 'Copyright (c) 1997-2001, Marc-Andre Lemburg; mailto:mal at lemburg.com\n' - 'Copyright (c) 2000-2001, eGenix.com Software GmbH; mailto:info at egenix.com\n' - 'See the documentation for further information on copyrights,\n' - 'or contact the author. All Rights Reserved.\n' - '*** UNAUTHORIZED COPYING, USAGE or DISTRIBUTION PROHIBITED. ***' - ) - - # Apply file globbing ? - globbing = 1 - - # Generate debug output ? - debug = 0 - - # Generate verbose output ? - verbose = 0 - - # Instance variables: - values = None # Dictionary of passed options (or default values) - # indexed by the options name, e.g. '-h' - files = None # List of passed filenames - - def __init__(self,argv=None): - - # Setup application specs - if argv is None: - argv = sys.argv - self.filename = os.path.split(argv[0])[1] - if not self.name: - self.name = os.path.split(self.filename)[1] - else: - self.name = self.name - if not self.header: - self.header = self.name - else: - self.header = self.header - - # Init .arguments list - self.arguments = argv[1:] - - # Setup Option mapping - self.option_map = option_dict(self.options) - - # Append preset options - for option in self.preset_options: - if not self.option_map.has_key(option.name): - self.add_option(option) - - # Init .files list - self.files = [] - - # Start Application - try: - # Process startup - rc = self.startup() - if rc is not None: - raise SystemExit(rc) - - # Parse command line - rc = self.parse() - if rc is not None: - raise SystemExit(rc) - - # Start application - rc = self.main() - if rc is None: - rc = 0 - - except SystemExit,rc: - pass - - except KeyboardInterrupt: - print - print '* User Break' - rc = 1 - - except: - print - print '* Internal Error' - if self.debug: - print - traceback.print_exc(20) - rc = 1 - - raise SystemExit(rc) - - def add_option(self, option): - - """ Add a new Option instance to the Application dynamically. - - Note that this has to be done *before* .parse() is being - executed. - - """ - self.options.append(option) - self.option_map[option.name] = option - - def startup(self): - - """ Set user defined instance variables. - - If this method returns anything other than None, the - process is terminated with the return value as exit code. - - """ - return None - - def exit(self, rc=0): - - """ Exit the program. - - rc is used as exit code and passed back to the calling - program. It defaults to 0 which usually means: OK. - - """ - raise SystemExit(rc) - - def parse(self): - - """ Parse the command line and fill in self.values and self.files. - - After having parsed the options, the remaining command line - arguments are interpreted as files and passed to .handle_files() - for processing. - - As final step the option handlers are called in the order - of the options given on the command line. - - """ - # Parse arguments - self.values = values = {} - for o in self.options: - if o.has_default: - values[o.prefix+o.name] = o.default - else: - values[o.prefix+o.name] = 0 - flags,lflags = _getopt_flags(self.options) - try: - optlist,files = getopt.getopt(self.arguments,flags,lflags) - if self.globbing: - l = [] - for f in files: - gf = glob.glob(f) - if not gf: - l.append(f) - else: - l[len(l):] = gf - files = l - self.optionlist = optlist - self.files = files + self.files - except getopt.error,why: - self.help(why) - sys.exit(1) - - # Call file handler - rc = self.handle_files(self.files) - if rc is not None: - sys.exit(rc) - - # Call option handlers - for optionname, value in optlist: - - # Try to convert value to integer - try: - value = string.atoi(value) - except ValueError: - pass - - # Find handler and call it (or count the number of option - # instances on the command line) - handlername = 'handle' + string.replace(optionname, '-', '_') - try: - handler = getattr(self, handlername) - except AttributeError: - if value == '': - # count the number of occurances - if values.has_key(optionname): - values[optionname] = values[optionname] + 1 - else: - values[optionname] = 1 - else: - values[optionname] = value - else: - rc = handler(value) - if rc is not None: - raise SystemExit(rc) - - # Apply final file check (for backward compatibility) - rc = self.check_files(self.files) - if rc is not None: - sys.exit(rc) - - def check_files(self,filelist): - - """ Apply some user defined checks on the files given in filelist. - - This may modify filelist in place. A typical application - is checking that at least n files are given. - - If this method returns anything other than None, the - process is terminated with the return value as exit code. - - """ - return None - - def help(self,note=''): - - self.print_header() - if self.synopsis: - print 'Synopsis:' - # To remain backward compatible: - try: - synopsis = self.synopsis % self.name - except (NameError, KeyError, TypeError): - synopsis = self.synopsis % self.__dict__ - print ' ' + synopsis - print - self.print_options() - if self.version: - print 'Version:' - print ' %s' % self.version - print - if self.about: - print string.strip(self.about % self.__dict__) - print - if note: - print '-'*72 - print 'Note:',note - print - - def notice(self,note): - - print '-'*72 - print 'Note:',note - print '-'*72 - print - - def print_header(self): - - print '-'*72 - print self.header % self.__dict__ - print '-'*72 - print - - def print_options(self): - - options = self.options - print 'Options and default settings:' - if not options: - print ' None' - return - long = filter(lambda x: x.prefix == '--', options) - short = filter(lambda x: x.prefix == '-', options) - items = short + long - for o in options: - print ' ',o - print - - # - # Example handlers: - # - # If a handler returns anything other than None, processing stops - # and the return value is passed to sys.exit() as argument. - # - - # File handler - def handle_files(self,files): - - """ This may process the files list in place. - """ - return None - - # Short option handler - def handle_h(self,arg): - - self.help() - return 0 - - def handle_v(self, value): - - """ Turn on verbose output. - """ - self.verbose = 1 - - # Handlers for long options have two underscores in their name - def handle__help(self,arg): - - self.help() - return 0 - - def handle__debug(self,arg): - - self.debug = 1 - - def handle__copyright(self,arg): - - self.print_header() - print string.strip(self.copyright % self.__dict__) - print - return 0 - - def handle__examples(self,arg): - - self.print_header() - if self.examples: - print 'Examples:' - print - print string.strip(self.examples % self.__dict__) - print - else: - print 'No examples available.' - print - return 0 - - def main(self): - - """ Override this method as program entry point. - - The return value is passed to sys.exit() as argument. If - it is None, 0 is assumed (meaning OK). Unhandled - exceptions are reported with exit status code 1 (see - __init__ for further details). - - """ - return None - -# Alias -CommandLine = Application - -def _test(): - - class MyApplication(Application): - header = 'Test Application' - version = __version__ - options = [Option('-v','verbose')] - - def handle_v(self,arg): - print 'VERBOSE, Yeah !' - - cmd = MyApplication() - if not cmd.values['-h']: - cmd.help() - print 'files:',cmd.files - print 'Bye...' - -if __name__ == '__main__': - _test() diff --git a/pypy/translator/microbench/pybench/Constructs.py b/pypy/translator/microbench/pybench/Constructs.py deleted file mode 100644 --- a/pypy/translator/microbench/pybench/Constructs.py +++ /dev/null @@ -1,565 +0,0 @@ -from pybench import Test - -class IfThenElse(Test): - - version = 0.31 - operations = 30*3 # hard to say... - rounds = 150000 - - def test(self): - - a,b,c = 1,2,3 - for i in xrange(self.rounds): - - if a == 1: - if b == 2: - if c != 3: - c = 3 - b = 3 - else: - c = 2 - elif b == 3: - b = 2 - a = 2 - elif a == 2: - a = 3 - else: - a = 1 - - if a == 1: - if b == 2: - if c != 3: - c = 3 - b = 3 - else: - c = 2 - elif b == 3: - b = 2 - a = 2 - elif a == 2: - a = 3 - else: - a = 1 - - if a == 1: - if b == 2: - if c != 3: - c = 3 - b = 3 - else: - c = 2 - elif b == 3: - b = 2 - a = 2 - elif a == 2: - a = 3 - else: - a = 1 - - if a == 1: - if b == 2: - if c != 3: - c = 3 - b = 3 - else: - c = 2 - elif b == 3: - b = 2 - a = 2 - elif a == 2: - a = 3 - else: - a = 1 - - if a == 1: - if b == 2: - if c != 3: - c = 3 - b = 3 - else: - c = 2 - elif b == 3: - b = 2 - a = 2 - elif a == 2: - a = 3 - else: - a = 1 - - if a == 1: - if b == 2: - if c != 3: - c = 3 - b = 3 - else: - c = 2 - elif b == 3: - b = 2 - a = 2 - elif a == 2: - a = 3 - else: - a = 1 - - if a == 1: - if b == 2: From noreply at buildbot.pypy.org Sat Oct 13 00:16:48 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 13 Oct 2012 00:16:48 +0200 (CEST) Subject: [pypy-commit] pypy default: more of spring cleaning Message-ID: <20121012221648.494F31C1C5D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58087:963843fdfe13 Date: 2012-10-13 00:16 +0200 http://bitbucket.org/pypy/pypy/changeset/963843fdfe13/ Log: more of spring cleaning diff --git a/pypy/rpython/microbench/__init__.py b/pypy/rpython/microbench/__init__.py deleted file mode 100644 diff --git a/pypy/rpython/microbench/autopath.py b/pypy/rpython/microbench/autopath.py deleted file mode 100644 --- a/pypy/rpython/microbench/autopath.py +++ /dev/null @@ -1,131 +0,0 @@ -""" -self cloning, automatic path configuration - -copy this into any subdirectory of pypy from which scripts need -to be run, typically all of the test subdirs. -The idea is that any such script simply issues - - import autopath - -and this will make sure that the parent directory containing "pypy" -is in sys.path. - -If you modify the master "autopath.py" version (in pypy/tool/autopath.py) -you can directly run it which will copy itself on all autopath.py files -it finds under the pypy root directory. - -This module always provides these attributes: - - pypydir pypy root directory path - this_dir directory where this autopath.py resides - -""" - -def __dirinfo(part): - """ return (partdir, this_dir) and insert parent of partdir - into sys.path. If the parent directories don't have the part - an EnvironmentError is raised.""" - - import sys, os - try: - head = this_dir = os.path.realpath(os.path.dirname(__file__)) - except NameError: - head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0])) - - error = None - while head: - partdir = head - head, tail = os.path.split(head) - if tail == part: - checkfile = os.path.join(partdir, os.pardir, 'pypy', '__init__.py') - if not os.path.exists(checkfile): - error = "Cannot find %r" % (os.path.normpath(checkfile),) - break - else: - error = "Cannot find the parent directory %r of the path %r" % ( - partdir, this_dir) - if not error: - # check for bogus end-of-line style (e.g. files checked out on - # Windows and moved to Unix) - f = open(__file__.replace('.pyc', '.py'), 'r') - data = f.read() - f.close() - if data.endswith('\r\n') or data.endswith('\r'): - error = ("Bad end-of-line style in the .py files. Typically " - "caused by a zip file or a checkout done on Windows and " - "moved to Unix or vice-versa.") - if error: - raise EnvironmentError("Invalid source tree - bogus checkout! " + - error) - - pypy_root = os.path.join(head, '') - try: - sys.path.remove(head) - except ValueError: - pass - sys.path.insert(0, head) - - munged = {} - for name, mod in sys.modules.items(): - if '.' in name: - continue - fn = getattr(mod, '__file__', None) - if not isinstance(fn, str): - continue - newname = os.path.splitext(os.path.basename(fn))[0] - if not newname.startswith(part + '.'): - continue - path = os.path.join(os.path.dirname(os.path.realpath(fn)), '') - if path.startswith(pypy_root) and newname != part: - modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep) - if newname != '__init__': - modpaths.append(newname) - modpath = '.'.join(modpaths) - if modpath not in sys.modules: - munged[modpath] = mod - - for name, mod in munged.iteritems(): - if name not in sys.modules: - sys.modules[name] = mod - if '.' in name: - prename = name[:name.rfind('.')] - postname = name[len(prename)+1:] - if prename not in sys.modules: - __import__(prename) - if not hasattr(sys.modules[prename], postname): - setattr(sys.modules[prename], postname, mod) - - return partdir, this_dir - -def __clone(): - """ clone master version of autopath.py into all subdirs """ - from os.path import join, walk - if not this_dir.endswith(join('pypy','tool')): - raise EnvironmentError("can only clone master version " - "'%s'" % join(pypydir, 'tool',_myname)) - - - def sync_walker(arg, dirname, fnames): - if _myname in fnames: - fn = join(dirname, _myname) - f = open(fn, 'rwb+') - try: - if f.read() == arg: - print "checkok", fn - else: - print "syncing", fn - f = open(fn, 'w') - f.write(arg) - finally: - f.close() - s = open(join(pypydir, 'tool', _myname), 'rb').read() - walk(pypydir, sync_walker, s) - -_myname = 'autopath.py' - -# set guaranteed attributes - -pypydir, this_dir = __dirinfo('pypy') - -if __name__ == '__main__': - __clone() diff --git a/pypy/rpython/microbench/dict.py b/pypy/rpython/microbench/dict.py deleted file mode 100644 --- a/pypy/rpython/microbench/dict.py +++ /dev/null @@ -1,65 +0,0 @@ -from pypy.rpython.microbench.microbench import MetaBench - -class str_dict__set_item: - __metaclass__ = MetaBench - - def init(): - return {} - args = ['obj', 'i'] - def loop(obj, i): - obj['foo'] = i - obj['bar'] = i - -class str_dict__get_item: - __metaclass__ = MetaBench - - def init(): - return {'foo': 0, 'bar': 1} - args = ['obj', 'i'] - def loop(obj, i): - return obj['foo'] + obj['bar'] - -class int_dict__set_item: - __metaclass__ = MetaBench - - def init(): - return {} - args = ['obj', 'i'] - def loop(obj, i): - obj[42] = i - obj[43] = i - -class int_dict__get_item: - __metaclass__ = MetaBench - - def init(): - return {42: 0, 43: 1} - args = ['obj', 'i'] - def loop(obj, i): - return obj[42] + obj[43] - - -class Foo: - pass - -obj1 = Foo() -obj2 = Foo() - -class obj_dict__set_item: - __metaclass__ = MetaBench - - def init(): - return {} - args = ['obj', 'i'] - def loop(obj, i): - obj[obj1] = i - obj[obj2] = i - -class obj_dict__get_item: - __metaclass__ = MetaBench - - def init(): - return {obj1: 0, obj2: 1} - args = ['obj', 'i'] - def loop(obj, i): - return obj[obj1] + obj[obj2] diff --git a/pypy/rpython/microbench/indirect.py b/pypy/rpython/microbench/indirect.py deleted file mode 100644 --- a/pypy/rpython/microbench/indirect.py +++ /dev/null @@ -1,24 +0,0 @@ -from pypy.rpython.microbench.microbench import MetaBench - -def f1(x): - return x - -def f2(x): - return x+1 - -def f3(x): - return x+2 - -def f4(x): - return x+3 - -FUNCS = [f1, f2, f3, f4] - -class indirect__call: - __metaclass__ = MetaBench - - def init(): - return FUNCS - args = ['obj', 'i'] - def loop(obj, i): - return obj[i%4](i) diff --git a/pypy/rpython/microbench/list.py b/pypy/rpython/microbench/list.py deleted file mode 100644 --- a/pypy/rpython/microbench/list.py +++ /dev/null @@ -1,79 +0,0 @@ -from pypy.rpython.microbench.microbench import MetaBench - -class list__append: - __metaclass__ = MetaBench - def init(): - return [] - args = ['obj', 'i'] - def loop(obj, i): - obj.append(i) - -class list__get_item: - __metaclass__ = MetaBench - LOOPS = 100000000 - def init(): - obj = [] - for i in xrange(1000): - obj.append(i) - return obj - args = ['obj', 'i'] - def loop(obj, i): - return obj[i%1000] - -class list__set_item: - __metaclass__ = MetaBench - LOOPS = 100000000 - def init(): - obj = [] - for i in xrange(1000): - obj.append(i) - return obj - args = ['obj', 'i'] - def loop(obj, i): - obj[i%1000] = i - -class fixed_list__get_item: - __metaclass__ = MetaBench - LOOPS = 100000000 - def init(): - return [0] * 1000 - args = ['obj', 'i'] - def loop(obj, i): - return obj[i%1000] - -class fixed_list__set_item: - __metaclass__ = MetaBench - LOOPS = 100000000 - def init(): - return [0] * 1000 - args = ['obj', 'i'] - def loop(obj, i): - obj[i%1000] = i - -class list__iteration__int: - __metaclass__ = MetaBench - LOOPS = 100000 - def init(): - obj = [0]*1000 - obj[0] = 42 - return obj - args = ['obj'] - def loop(obj): - tot = 0 - for item in obj: - tot += item - return tot - -class list__iteration__string: - __metaclass__ = MetaBench - LOOPS = 100000 - def init(): - obj = ['foo']*1000 - obj[0] = 'bar' - return obj - args = ['obj'] - def loop(obj): - tot = 0 - for item in obj: - tot += len(item) - return tot diff --git a/pypy/rpython/microbench/microbench.py b/pypy/rpython/microbench/microbench.py deleted file mode 100644 --- a/pypy/rpython/microbench/microbench.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python - -import sys -import autopath -from time import clock -import subprocess -from pypy.translator.interactive import Translation - -LOOPS = 10000000 - -class MetaBench(type): - def __new__(self, cls_name, bases, cls_dict): - loop = cls_dict['loop'] - loop._dont_inline_ = True - myglob = { - 'init': cls_dict['init'], - 'loop': loop, - 'LOOPS': cls_dict.get('LOOPS', LOOPS), - 'clock': clock, - } - args = ', '.join(cls_dict['args']) - source = """ -def %(cls_name)s(): - obj = init() - start = clock() - for i in xrange(LOOPS): - loop(%(args)s) - return clock() - start -""" % locals() - exec source in myglob - func = myglob[cls_name] - func.benchmark = True - return func - - -def run_benchmark(exe): - from pypy.translator.cli.test.runtest import CliFunctionWrapper - from pypy.translator.jvm.test.runtest import JvmGeneratedSourceWrapper - - if exe.__class__ in [CliFunctionWrapper,JvmGeneratedSourceWrapper]: - stdout, stderr, retval = exe.run() - else: - assert isinstance(exe, str) - bench = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = bench.communicate() - retval = bench.wait() - - if retval != 0: - print 'Running benchmark failed' - print 'Standard Output:' - print stdout - print '-' * 40 - print 'Standard Error:' - print stderr - raise SystemExit(-1) - - mydict = {} - for line in stdout.splitlines(): - name, res = line.split(':') - mydict[name.strip()] = float(res) - return mydict - -def import_benchmarks(): - modules = sys.argv[1:] - if len(modules) == 0: - # import all the microbenchs - from glob import glob - for module in glob('*.py'): - if module not in ('__init__.py', 'autopath.py', 'microbench.py'): - modules.append(module) - - for module in modules: - module = module.rstrip('.py') - exec 'from %s import *' % module in globals() - -def main(): - import_benchmarks() - benchmarks = [] - for name, thing in globals().iteritems(): - if getattr(thing, 'benchmark', False): - benchmarks.append((name, thing)) - benchmarks.sort() - - def entry_point(argv): - for name, func in benchmarks: - print name, ':', func() - return 0 - - t = Translation(entry_point, standalone=True, backend='c') - c_exe = t.compile() - t = Translation(entry_point, standalone=True, backend='cli') - cli_exe = t.compile() - t = Translation(entry_point, standalone=True, backend='jvm') - jvm_exe = t.compile() - - c_res = run_benchmark(c_exe) - cli_res = run_benchmark(cli_exe) - jvm_res = run_benchmark(jvm_exe) - - print 'benchmark genc gencli cli_ratio genjvm jvm_ratio' - print - for name, _ in benchmarks: - c_time = c_res[name] - cli_time = cli_res[name] - jvm_time = jvm_res[name] - if c_time == 0: - cli_ratio = '%10s' % '---' - else: - cli_ratio = '%10.2f' % (cli_time/c_time) - if c_time == 0: - jvm_ratio = '%10s' % '---' - else: - jvm_ratio = '%10.2f' % (jvm_time/c_time) - print '%-32s %10.2f %10.2f %s %10.2f %s' % (name, c_time, cli_time, cli_ratio, jvm_time, jvm_ratio) - -if __name__ == '__main__': - main() diff --git a/pypy/rpython/microbench/rdict.py b/pypy/rpython/microbench/rdict.py deleted file mode 100644 --- a/pypy/rpython/microbench/rdict.py +++ /dev/null @@ -1,70 +0,0 @@ -from pypy.rlib.objectmodel import r_dict -from pypy.rpython.microbench.microbench import MetaBench - -class Obj: - def __init__(self, x): - self.x = x - -def myhash(obj): - return obj.x - -def mycmp(obj1, obj2): - return obj1.x == obj2.x - -class Space: - def myhash(self, obj): - return obj.x - - def mycmp(self, obj1, obj2): - return obj1.x == obj2.x - - def _freeze_(self): - return True - -space = Space() -obj1 = Obj(1) -obj2 = Obj(2) - -class r_dict__set_item: - __metaclass__ = MetaBench - - def init(): - return r_dict(mycmp, myhash) - args = ['obj', 'i'] - def loop(obj, i): - obj[obj1] = i - obj[obj2] = i - -class r_dict__get_item: - __metaclass__ = MetaBench - - def init(): - res = r_dict(mycmp, myhash) - res[obj1] = 42 - res[obj2] = 43 - return res - args = ['obj', 'i'] - def loop(obj, i): - return obj[obj1] + obj[obj2] - -class r_dict__frozen_pbc__set_item: - __metaclass__ = MetaBench - - def init(): - return r_dict(space.mycmp, space.myhash) - args = ['obj', 'i'] - def loop(obj, i): - obj[obj1] = i - obj[obj2] = i - -class r_dict__frozen_pbc__get_item: - __metaclass__ = MetaBench - - def init(): - res = r_dict(space.mycmp, space.myhash) - res[obj1] = 42 - res[obj2] = 43 - return res - args = ['obj', 'i'] - def loop(obj, i): - return obj[obj1] + obj[obj2] From noreply at buildbot.pypy.org Sat Oct 13 00:19:19 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 13 Oct 2012 00:19:19 +0200 (CEST) Subject: [pypy-commit] pypy default: more cleaning Message-ID: <20121012221919.165481C1C5E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58088:64820bd14b80 Date: 2012-10-13 00:19 +0200 http://bitbucket.org/pypy/pypy/changeset/64820bd14b80/ Log: more cleaning diff --git a/pypy/translator/goal/bench-cronjob.py b/pypy/translator/goal/bench-cronjob.py deleted file mode 100755 --- a/pypy/translator/goal/bench-cronjob.py +++ /dev/null @@ -1,141 +0,0 @@ -#! /usr/bin/env python - -import os -homedir = os.getenv('HOME') -os.environ['PATH'] += ':'+homedir+'/bin' - -import autopath -import py -import time, os, sys, stat - -os.umask(022) # allow everyone to read/execute the produced pypy-c's - - -tmpdir = py.std.tempfile.gettempdir() + '/usession-' + os.environ['USER'] + '/' -cflags = "-O3" -lflags = "-lgc -lm -lpthread" - -dry_run = False - -def run(cmd): - print 'RUN:', cmd - sys.stdout.flush() - result = 0 #OK - if not dry_run: - result = os.system(cmd) #note: result is system dependent but works on Linux the way we want - return result - -def update_pypy(): - os.chdir(homedir + '/projects/pypy-trunk') - run('/usr/local/bin/svn up 2>&1') - -def compile(backend): - try: - backend, features = backend.split('--', 1) - featureoptions = ''.join([" --" + f for f in features.split('--') if f[0] != '_']) - targetoptions = ''.join([" --" + f[1:] for f in features.split('--') if f[0] == '_']) - except: - features = '' - featureoptions = '' - targetoptions = '' - - translateoptions = '' - - def normalize(f): - if f.startswith('_'): - f = f[1:] - if f.startswith('profopt'): - f = 'prof' - return f - features = '--'.join([normalize(f) for f in features.split('--')]) - - os.chdir(homedir + '/projects/pypy-trunk/pypy/translator/goal') - run('/usr/local/bin/python translate.py --backend=%(backend)s%(featureoptions)s%(translateoptions)s --batch targetpypystandalone.py %(targetoptions)s 2>&1' % locals()) - - os.chdir(homedir + '/projects/pypy-trunk') - try: - revision = '%d' % (py.path.svnwc('.').info().rev,) - except: - revision = 'unknown' - basename = homedir + '/projects/pypy-trunk/pypy/translator/goal/' + 'pypy-' + backend - realname = basename + '-' + revision - if features: - realname += "-" + features - - if os.path.exists(basename): #copy executable - run("mv %s %s" % (basename, realname)) - if backend == 'cli': - basename_dir = basename + '-data' - realname_dir = realname + '-data' - run("mv %s %s" % (basename_dir, realname_dir)) - elif backend == 'jvm': - basename_jar = basename + '.jar' - realname_jar = realname + '.jar' - run("mv %s %s" % (basename_jar, realname_jar)) - #pypy = open(basename, 'rb').read() - #if len(pypy) > 0: - # open(realname, 'wb').write(pypy) - #os.chmod(realname, stat.S_IRWXU) - #os.unlink(basename) - -def get_load(): - g = os.popen('uptime', 'r') - buf = g.read().strip() - g.close() - return buf - -def benchmark(): - os.chdir(homedir + '/projects/pypy-trunk/pypy/translator/goal') - uname = os.popen('uname -a', 'r').read() - startload = get_load() -# result = run('/usr/local/bin/withlock /tmp/cpu_cycles_lock /usr/local/bin/python bench-unix.py 2>&1 | tee benchmark.txt' % locals()) - result = run('/usr/local/bin/python bench-unix.py 2>&1 | tee benchmark.txt' % locals()) - endload = get_load() - if not dry_run and result == 0: - f = open('benchmark.html', 'w') - print >> f, "" - print >> f, "
"
-        print >> f, "uname -a:", uname
-        print >> f, "Benchmark started:", startload
-        print >> f, "            ended:", endload
-        print >> f
-        f.write(open('benchmark.txt').read())
-        print >> f, "
" - print >> f, "" - f.close() - -def main(backends=[]): - if backends == []: #_ prefix means target specific option, # prefix to outcomment - backends = [backend.strip() for backend in """ - c--opt=0--_no-allworkingmodules - c--stackless--gc=boehm--opt=3--_no-allworkingmodules - c--gc=boehm--opt=3 - c--thread--gc=hybrid--opt=3--_no-allworkingmodules - c--gc=semispace--opt=3--_no-allworkingmodules - c--gc=generation--opt=3--_no-allworkingmodules - c--gc=hybrid--opt=3--_no-allworkingmodules - cli--opt=3--_no-allworkingmodules - jvm--opt=3--_no-allworkingmodules - jvm--inline-threshold=0--opt=3--_no-allworkingmodules - """.split('\n') if backend.strip() and not backend.strip().startswith('#')] - print time.ctime() - update_pypy() - for backend in backends: - try: - compile(backend) - except: - raise - pass - benchmark() - print time.ctime() - print 80*'-' - -if __name__ == '__main__': - args = sys.argv[1:] - if args and args[0] == '--benchmark-only': - benchmark() - else: - if args and args[0] == '--dry-run': - del args[0] - dry_run = True - main(args) diff --git a/pypy/translator/goal/bench-unix.py b/pypy/translator/goal/bench-unix.py deleted file mode 100644 --- a/pypy/translator/goal/bench-unix.py +++ /dev/null @@ -1,171 +0,0 @@ -# benchmarks on a unix machine. -# to be executed in the goal folder, -# where a couple of pypy-* files is expected. - -import os, sys, time, pickle - -PYSTONE_CMD = 'from test import pystone;pystone.main(%s)' -PYSTONE_PATTERN = 'This machine benchmarks at' -PYSTONE_ASCENDING_GOOD = True - -RICHARDS_CMD = 'from richards import *;main(iterations=%d)' -RICHARDS_PATTERN = 'Average time per iteration:' -RICHARDS_ASCENDING_GOOD = False - -class BenchmarkResult(object): - - def __init__(self, filename, max_results=10): - self.filename = filename - self.max_results = max_results - if os.path.exists(filename): - f = open(filename, 'r') - self.n_results = pickle.load(f) - self.best_result = pickle.load(f) - f.close() - # any exception while loading the file is best reported - # as a crash, instead of as a silent loss of all the - # data :-/ - else: - self.n_results = {} - self.best_result = {} - - def is_stable(self, name): - try: - return self.n_results[name] >= self.max_results - except: - return False - - def update(self, name, result, ascending_good): - try: - if ascending_good: - self.best_result[name] = max(self.best_result[name], result) - else: - self.best_result[name] = min(self.best_result[name], result) - except KeyError: - self.n_results[name] = 0 - self.best_result[name] = result - self.n_results[name] += 1 - - f = open(self.filename, 'w') - pickle.dump(self.n_results , f) - pickle.dump(self.best_result, f) - f.close() - - def get_best_result(self, name): - return self.best_result[name] - - -def get_result(txt, pattern): - for line in txt.split('\n'): - if line.startswith(pattern): - break - else: - print 'warning: this is no valid output' - return 99999.0 - return float(line.split()[len(pattern.split())]) - -def run_cmd(cmd): - #print "running", cmd - pipe = os.popen(cmd + ' 2>&1') - return pipe.read() - -def run_pystone(executable='/usr/local/bin/python', n=0): - argstr = PYSTONE_CMD % (str(n) and n or '') - txt = run_cmd('"%s" -c "%s"' % (executable, argstr)) - return get_result(txt, PYSTONE_PATTERN) - -def run_richards(executable='/usr/local/bin/python', n=5): - argstr = RICHARDS_CMD % n - txt = run_cmd('"%s" -c "%s"' % (executable, argstr)) - return get_result(txt, RICHARDS_PATTERN) - -def get_executables(): #sorted by revision number (highest first) - exes = [] - for exe in [os.path.join('.', name) for name in os.listdir('.') if name.startswith('pypy-')]: - if os.path.isdir(exe) or exe.endswith('.jar'): - continue - try: - exes.append( (exe.split('-')[2], exe) ) - except: - pass #skip filenames without version number - exes.sort() - exes.reverse() - exes = [s[1] for s in exes] - return exes - -def main(): - benchmark_result = BenchmarkResult('bench-unix.benchmark_result') - - print 'date size codesize executable richards pystone' - sys.stdout.flush() - - ref_rich, ref_stone = None, None - -# for exe in '/usr/local/bin/python2.5 python2.4 python2.3'.split(): - for exe in 'python2.4 python2.3'.split(): - v = os.popen(exe + ' -c "import sys;print sys.version.split()[0]"').read().strip() - if not v: - continue - r = v + '_richards' - if not benchmark_result.is_stable(r): - benchmark_result.update(r, run_richards(exe), RICHARDS_ASCENDING_GOOD) - rich = benchmark_result.get_best_result(r) - if not ref_rich: - ref_rich = rich - - p = v + '_pystone' - if not benchmark_result.is_stable(p): - benchmark_result.update(p, run_pystone(exe), PYSTONE_ASCENDING_GOOD) - stone = benchmark_result.get_best_result(p) - if not ref_stone: - ref_stone = stone - - fmt = '%-26s %8s %8s %-60s %6dms (%6.1fx) %6d (%6.1fx)' - print fmt % (time.ctime(), '-', '-', 'python', 'CPython ' + v, rich, rich / ref_rich, stone, stone / ref_stone) - sys.stdout.flush() - - for exe in get_executables(): - exename = os.path.splitext(exe)[0].lstrip('./') - ctime = time.ctime( os.path.getmtime(exename) ) - - #compute microbenchmark results (only once) - f = '../microbench/archive/%s.txt' % exe - if not os.path.exists(f) or os.stat(f).st_size < 100: - os.chdir('../microbench') - run_cmd('python2.4 ./microbench.py python2.4 "../goal/%s" > "archive/%s.txt"' % (exe, exe)) - os.chdir('../goal') - - r = exe + '_richards' - if not benchmark_result.is_stable(r): - #continue with our regular benchmarks - benchmark_result.update(r, run_richards(exe, 1), RICHARDS_ASCENDING_GOOD) - rich = benchmark_result.get_best_result(r) - - p = exe + '_pystone' - if not benchmark_result.is_stable(p): - benchmark_result.update(p, run_pystone(exe), PYSTONE_ASCENDING_GOOD) - stone = benchmark_result.get_best_result(p) - - if 'pypy-cli' in exename: - dirname = exename + '-data' - codesize = 'N/A' - try: - exesize = os.path.getsize(os.path.join(dirname, 'main.exe')) - except OSError: - exesize = 'XXX' - elif 'pypy-jvm' in exename: - jarname = exename + '.jar' - codesize = 'N/A' - try: - exesize = os.path.getsize(jarname) - except OSError: - exesize = 'XXX' - else: - codesize = os.popen('size "%s" | tail -n1 | cut -f1'%(exename,)).read().strip() - exesize = os.path.getsize(exe) - - print fmt % (ctime, exesize, codesize, exename, exename, rich, rich / ref_rich, stone, ref_stone / stone) - sys.stdout.flush() - -if __name__ == '__main__': - main() diff --git a/pypy/translator/goal/bench-windows.py b/pypy/translator/goal/bench-windows.py deleted file mode 100644 --- a/pypy/translator/goal/bench-windows.py +++ /dev/null @@ -1,186 +0,0 @@ -# benchmarks on a windows machine. -# to be executed in the goal folder, -# where a couple of .exe files is expected. - -USE_HIGH_PRIORITY = True -# usage with high priority: -# the program will try to import subprocess. -# you can have this with python older than 2.4: copy -# subprocess into lib and change line 392 to use win32 - -current_result = """ -executable richards pystone size (MB) -pypy-c-17439 37413 47.7x 678.4 60.7x 5.65 -pypy-c-17600-lo 26352 33.6x 906.2 45.4x 6.43 -pypy-c-17634-lo 20108 25.7x 1023.5 40.2x 6.42 -pypy-c-17649-lo 22612 28.9x 1042.0 39.5x 6.41 -pypy-c-17674-lo 19248 24.6x 1358.8 30.3x 6.40 -pypy-c-17674 12402 15.8x 1941.4 21.2x 7.37 -pypy-c-17439-lo 29638 37.8x 971.4 42.4x 6.49 -pypy-c-17707 14095 18.0x 2092.7 19.7x 7.37 -pypy-c-17707-lo 19102 24.4x 1354.7 30.4x 6.40 -pypy-c-17707-lo-range 18786 24.0x 2800.8 14.7x 6.40 -pypy-c-17707-range 13980 17.8x 2899.9 14.2x 7.38 -pypy-c-17743 13944 17.8x 2800.3 14.7x 7.30 -pypy-c-17761-samuele 13243 16.9x 2983.3 13.8x 7.69 -pypy-c-17794-ref-crash 41088 52.4x 1084.5 37.9x 14.62 -pypy-c-17950 12888 16.4x 3203.0 12.8x 5.49 -pypy-c-18236 9263 11.8x 3702.8 11.1x 5.12 -python 2.4.1 783 1.0x 41150.3 1.0x 0.96 - -Defaults are: --gc=boehm -'lo' indicates --lowmem -STarting with rev. 18236, gc_pypy.dll is used -""" - -import os, sys, pickle, md5 -try: - from subprocess import * -except ImportError: - Popen = None - -PYSTONE_CMD = 'from test import pystone;pystone.main(%s)' -PYSTONE_PATTERN = 'This machine benchmarks at' -RICHARDS_CMD = 'from richards import *;main(iterations=%d)' -RICHARDS_PATTERN = 'Average time per iteration:' - -def get_result(txt, pattern): - for line in txt.split('\n'): - if line.startswith(pattern): - break - else: - raise ValueError, 'this is no valid output: %r' % txt - return float(line.split()[len(pattern.split())]) - -def run_cmd(cmd): - print "running", cmd - pipe = os.popen(cmd + ' 2>&1') - result = pipe.read() - print "done" - return result - -def run_cmd_subprocess(cmd): - print "running", cmd - result = Popen(cmd, stdout=PIPE, creationflags=CREATIONFLAGS - ).communicate()[0] - print "done" - return result - -CREATIONFLAGS = 0 -if Popen: - run_cmd = run_cmd_subprocess - try: - import win32con, win32api - except ImportError: - pass - else: - if USE_HIGH_PRIORITY: - CREATIONFLAGS = win32con.HIGH_PRIORITY_CLASS - print "configured to run under high priority" - -BENCH_EXECONFIG = '_bench_windows_exe.txt' -bench_exe = None - -def reference(progname): - global bench_exe - if not bench_exe: - if os.path.exists(BENCH_EXECONFIG): - progname = file(BENCH_EXECONFIG).read().strip() - print "using %s instead of the system default" % progname - bench_exe = progname - return bench_exe - -def run_version_size(executable=reference('python'), *args): - ver, size, dll = run_cmd('%s -c "import sys, os; print sys.version.split()[0], ' - 'os.path.getsize(sys.executable), sys.dllhandle"' - % executable).split() - size = int(size) - try: - import win32api - except ImportError: - pass - else: - size += os.path.getsize(win32api.GetModuleFileName(int(dll))) - return ver, size - -def run_pystone(executable=reference('python'), n=0, rpy=False): - if rpy: - txt = run_cmd('%s pystone' % executable) - else: - argstr = PYSTONE_CMD % (str(n) and n or '') - txt = run_cmd('%s -c "%s"' % (executable, argstr)) - res = get_result(txt, PYSTONE_PATTERN) - print res - return res - -def run_richards(executable=reference('python'), n=20, rpy=False): - if rpy: - txt = run_cmd('%s richards' % executable) - else: - argstr = RICHARDS_CMD % n - txt = run_cmd('%s -c "%s"' % (executable, argstr)) - res = get_result(txt, RICHARDS_PATTERN) - print res - return res - -def get_executables(): - exes = [name for name in os.listdir('.') if name.endswith('.exe')] - exes.sort() - return exes - -STAT_FILE = '_bench_windows.dump' -def load_stats(statfile=STAT_FILE): - try: - dic = pickle.load(file(statfile, 'rb')) - except IOError: - dic = {} - return dic - -def save_stats(dic, statfile=STAT_FILE): - pickle.dump(dic, file(statfile, 'wb')) - -HEADLINE = '''\ -executable richards pystone size (MB)''' -FMT = '''\ -%-27s''' + '%5d %5.1fx' + ' %9.1f %5.1fx %5.3f' -FMT2 = '''\ -%-27s''' + '%5.3f %5.1f/' + ' %9.1f %5.1f/ %5.3f' - -def main(): - print 'getting the richards reference' - ref_rich = run_richards() - print 'getting the pystone reference' - ref_stone = run_pystone() - resdic = {} - prior = load_stats() - for exe in get_executables(): - exename = os.path.splitext(exe)[0] - mtime = os.path.getmtime(exe) - size = os.path.getsize(exe) - rpy = size < 500000 - key = md5.new(file(exe,'rb').read()).digest() - if key in prior: - print 'skipped', exename - resdic[key] = prior[key][:2] + (exename, mtime, size) - else: - resdic[key] = (run_richards(exe, 2,rpy), run_pystone(exe, 20000, rpy), - exename, mtime, size) - prior[key] = resdic[key] # save result, temporarily - save_stats(prior) - save_stats(resdic) # save cleaned result - res = [ (stone / rich, exe, size, rich, stone) - for rich, stone, exe, mtime, size in resdic.values()] - version, size = run_version_size() - res.append( (ref_stone/ref_rich, 'python %s' % version, size, ref_rich, ref_stone) ) - res.sort() - print HEADLINE - for speed2, exe, size, rich, stone in res: - if speed2 <= ref_stone/ref_rich: - print FMT % (exe, rich, rich / ref_rich, stone, ref_stone / stone, - size / float(1024 * 1024)) - else: - print FMT2 % (exe, rich, ref_rich / rich, stone, stone / ref_stone, - size / float(1024 * 1024)) - -if __name__ == '__main__': - main() From noreply at buildbot.pypy.org Sat Oct 13 01:55:17 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 13 Oct 2012 01:55:17 +0200 (CEST) Subject: [pypy-commit] pypy default: kill Message-ID: <20121012235517.4C2B81C1C59@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r58089:1d01c6911981 Date: 2012-10-12 16:55 -0700 http://bitbucket.org/pypy/pypy/changeset/1d01c6911981/ Log: kill diff --git a/pypy/module/oracle/interp_cursor.py b/pypy/module/oracle/interp_cursor.py --- a/pypy/module/oracle/interp_cursor.py +++ b/pypy/module/oracle/interp_cursor.py @@ -1,5 +1,4 @@ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, unwrap_spec From noreply at buildbot.pypy.org Sat Oct 13 02:09:53 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 13 Oct 2012 02:09:53 +0200 (CEST) Subject: [pypy-commit] pypy default: cleanup Message-ID: <20121013000953.2608B1C1C5A@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r58090:9a2f93998995 Date: 2012-10-12 17:05 -0700 http://bitbucket.org/pypy/pypy/changeset/9a2f93998995/ Log: cleanup diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -1,7 +1,6 @@ -import sys -from pypy.interpreter import gateway from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import interp2app from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, SMM @@ -163,9 +162,9 @@ bytearray(sequence) -> bytearray initialized from sequence\'s items If the argument is a bytearray, the return value is the same object.''', - __new__ = gateway.interp2app(descr__new__), + __new__ = interp2app(descr__new__), __hash__ = None, - __reduce__ = gateway.interp2app(descr_bytearray__reduce__), - fromhex = gateway.interp2app(descr_fromhex, as_classmethod=True) + __reduce__ = interp2app(descr_bytearray__reduce__), + fromhex = interp2app(descr_fromhex, as_classmethod=True) ) bytearray_typedef.registermethods(globals()) From noreply at buildbot.pypy.org Sat Oct 13 02:09:56 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 13 Oct 2012 02:09:56 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20121013000956.6B3531C1C5A@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58091:4bf82358629c Date: 2012-10-12 17:04 -0700 http://bitbucket.org/pypy/pypy/changeset/4bf82358629c/ Log: merge default diff too long, truncating to 2000 out of 29662 lines diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -1,9 +1,8 @@ -import sys import types -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception +from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - format_someobject_error, AnnotatorError) + AnnotatorError, gather_error, ErrorWrapper) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -38,22 +37,9 @@ self.links_followed = {} # set of links that have ever been followed self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + self.blocked_blocks = {} # set of {blocked_block: (graph, index)} + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +63,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +164,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +181,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +192,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +242,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +265,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +283,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +333,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -414,7 +340,7 @@ self.flowin(graph, block) except BlockedInference, e: self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, e.opindex) except Exception, e: # hack for debug tools only if not hasattr(e, '__annotator_block'): @@ -433,25 +359,24 @@ self.pendingblocks[block] = graph assert block in self.annotated self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -471,14 +396,11 @@ for i in range(len(block.operations)): try: self.bookkeeper.enter((graph, block, i)) - self.consider_op(block.operations[i]) + self.consider_op(block, i) finally: self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +484,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +494,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +530,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell @@ -653,7 +572,8 @@ #___ creating the annotations based on operations ______ - def consider_op(self, op): + def consider_op(self, block, opindex): + op = block.operations[opindex] argcells = [self.binding(a) for a in op.args] consider_meth = getattr(self,'consider_op_'+op.opname, None) @@ -668,16 +588,18 @@ # boom -- in the assert of setbinding() for arg in argcells: if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op) + raise BlockedInference(self, op, opindex) try: resultcell = consider_meth(*argcells) - except Exception: + except Exception, e: graph = self.bookkeeper.position_key[0] - raise_nicer_exception(op, str(graph)) + e.args = e.args + ( + ErrorWrapper(gather_error(self, graph, block, opindex)),) + raise if resultcell is None: resultcell = self.noreturnvalue(op) elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op) # the operation cannot succeed + raise BlockedInference(self, op, opindex) # the operation cannot succeed assert isinstance(resultcell, annmodel.SomeObject) assert isinstance(op.result, Variable) self.setbinding(op.result, resultcell) # bind resultcell to op.result @@ -728,13 +650,14 @@ """This exception signals the type inference engine that the situation is currently blocked, and that it should try to progress elsewhere.""" - def __init__(self, annotator, op): + def __init__(self, annotator, op, opindex): self.annotator = annotator try: self.break_at = annotator.bookkeeper.position_key except AttributeError: self.break_at = None self.op = op + self.opindex = opindex def __repr__(self): if not self.break_at: diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,15 +29,6 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', 'truediv', 'floordiv', 'divmod', 'pow', @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -238,7 +201,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -565,14 +551,30 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - return SomeObject() + raise UnionError("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): return SomeTuple(items = tup1.items + tup2.items) + def eq(tup1tup2): + tup1tup2.union() + return s_Bool + ne = eq + + def lt((tup1, tup2)): + raise Exception("unsupported: (...) < (...)") + def le((tup1, tup2)): + raise Exception("unsupported: (...) <= (...)") + def gt((tup1, tup2)): + raise Exception("unsupported: (...) > (...)") + def ge((tup1, tup2)): + raise Exception("unsupported: (...) >= (...)") + class __extend__(pairtype(SomeDict, SomeDict)): @@ -724,8 +726,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -765,7 +766,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -779,7 +780,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -807,7 +808,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,7 +10,7 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef @@ -148,7 +148,6 @@ self.descs = {} # map Python objects to their XxxDesc wrappers self.methoddescs = {} # map (funcdesc, classdef) to the MethodDesc self.classdefs = [] # list of all ClassDefs - self.pbctypes = {} self.seen_mutable = {} self.listdefs = {} # map position_keys to ListDefs self.dictdefs = {} # map position_keys to DictDefs @@ -167,9 +166,6 @@ self.stats = Stats(self) - # used in SomeObject.__new__ for keeping debugging info - self._isomeobject_coming_from = identity_dict() - delayed_imports() def count(self, category, *args): @@ -275,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() @@ -325,8 +320,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -445,6 +438,12 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if (x is type(None) or # add cases here if needed + x.__module__ == 'pypy.rpython.lltypesystem.lltype'): + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) 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 @@ -455,20 +454,13 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) - elif hasattr(x, '_freeze_') and x._freeze_(): + result = SomePBC([self.getdesc(x)]) + elif hasattr(x, '_freeze_'): + assert x._freeze_() is True # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method # returns True, the instance is considered immutable and becomes @@ -476,16 +468,18 @@ result = SomePBC([self.getdesc(x)]) elif hasattr(x, '__class__') \ and x.__class__.__module__ != '__builtin__': + if hasattr(x, '_cleanup_'): + x._cleanup_() self.see_mutable(x) result = SomeInstance(self.getuniqueclassdef(x.__class__)) elif x is None: return s_None else: - result = SomeObject() + raise Exception("Don't know how to represent %r" % (x,)) if need_const: result.const = x return result - + def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: @@ -509,8 +503,10 @@ elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) - elif (hasattr(pyobj.im_self, '_freeze_') and - pyobj.im_self._freeze_()): # method of frozen + if hasattr(pyobj.im_self, '_cleanup_'): + pyobj.im_self._cleanup_() + if hasattr(pyobj.im_self, '_freeze_'): # method of frozen + assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc(self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc @@ -529,9 +525,9 @@ name) else: # must be a frozen pre-built constant, but let's check - try: - assert pyobj._freeze_() - except AttributeError: + if hasattr(pyobj, '_freeze_'): + assert pyobj._freeze_() is True + else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: @@ -551,11 +547,7 @@ return False def getfrozen(self, pyobj): - result = description.FrozenDesc(self, pyobj) - cls = result.knowntype - if cls not in self.pbctypes: - self.pbctypes[cls] = True - return result + return description.FrozenDesc(self, pyobj) def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, flags={}): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -150,7 +150,7 @@ def builtin_isinstance(s_obj, s_type, variables=None): - r = SomeBool() + r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,8 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + + if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -247,13 +247,16 @@ defs_s = [] if graph is None: signature = self.signature - defaults = self.defaults + defaults = self.defaults else: signature = graph.signature - defaults = graph.defaults + defaults = graph.defaults if defaults: for x in defaults: - defs_s.append(self.bookkeeper.immutablevalue(x)) + if x is NODEFAULT: + defs_s.append(None) + else: + defs_s.append(self.bookkeeper.immutablevalue(x)) try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,8 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype + immutable = False knowntype = object - immutable = False + + def __init__(self): + assert type(self) is not SomeObject def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -105,60 +106,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: - self = new(cls, *args, **kw) - if DEBUG: - try: - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - position_key = bookkeeper.position_key - except AttributeError: - pass - else: - bookkeeper._isomeobject_coming_from[self] = position_key, None + def can_be_none(self): + return True + + def nonnoneify(self): return self - def origin(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] - origin = property(origin) - def caused_by_merge(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] - def set_caused_by_merge(self, nvalue): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return - bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue - caused_by_merge = property(caused_by_merge, set_caused_by_merge) - del set_caused_by_merge +class SomeType(SomeObject): + "Stands for a type. We might not be sure which one it is." + knowntype = type + immutable = True def can_be_none(self): - return True - - def nonnoneify(self): - return self + return False class SomeFloat(SomeObject): "Stands for a float or an integer." @@ -517,6 +486,7 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) @@ -710,14 +680,8 @@ # this is just a performance shortcut if s1 != s2: s1 = pair(s1, s2).union() - if DEBUG: - if s1.caused_by_merge is None and len(somevalues) > 1: - s1.caused_by_merge = somevalues return s1 -def isdegenerated(s_value): - return s_value.__class__ is SomeObject and s_value.knowntype is not type - # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -10,7 +10,6 @@ class BasicAnnotatorPolicy(object): - allow_someobjects = True def event(pol, bookkeeper, what, *args): pass @@ -80,6 +79,3 @@ def specialize__ll_and_arg(pol, *args): from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args) - -class StrictAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -3,9 +3,9 @@ from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF -from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF + unionof, SomeUnicodeString, SomeType +from pypy.annotation.listdef import ListDef +from pypy.annotation.dictdef import DictDef _annotation_cache = {} @@ -78,24 +78,18 @@ return SomeString() elif t is unicode: return SomeUnicodeString() - elif t is list: - return SomeList(MOST_GENERAL_LISTDEF) - elif t is dict: - return SomeDict(MOST_GENERAL_DICTDEF) - # can't do tuple elif t is types.NoneType: return s_None elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) - elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes: + elif t is type: + return SomeType() + elif bookkeeper and not hasattr(t, '_freeze_'): classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) else: - o = SomeObject() - if t != object: - o.knowntype = t - return o + raise AssertionError("annotationoftype(%r)" % (t,)) class Sig(object): diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -24,7 +24,7 @@ assert isinstance(s_list, annmodel.SomeList) return s_list.listdef.listitem.s_value -def somelist(s_type=annmodel.SomeObject()): +def somelist(s_type): return annmodel.SomeList(ListDef(None, s_type)) def dictkey(s_dict): @@ -35,7 +35,7 @@ assert isinstance(s_dict, annmodel.SomeDict) return s_dict.dictdef.dictvalue.s_value -def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()): +def somedict(s_key, s_value): return annmodel.SomeDict(DictDef(None, s_key, s_value)) @@ -205,15 +205,6 @@ annmodel.SomeInteger() ]) - def test_inheritance2(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet._inheritance_nonrunnable, []) - # result should be exactly: - assert s == annmodel.SomeTuple([ - annmodel.SomeInteger(), - annmodel.SomeObject() - ]) - def test_poor_man_range(self): a = self.RPythonAnnotator() s = a.build_types(snippet.poor_man_range, [int]) @@ -336,9 +327,13 @@ def test_flow_type_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_type_info, [object]) + s = a.build_types(snippet.flow_type_info, [int]) a.simplify() - #a.translator.view() + assert s.knowntype == int + + a = self.RPythonAnnotator() + s = a.build_types(snippet.flow_type_info, [str]) + a.simplify() assert s.knowntype == int def test_flow_type_info_2(self): @@ -351,7 +346,7 @@ def test_flow_usertype_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_usertype_info, [object]) + s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit]) #a.translator.view() assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit) @@ -363,13 +358,6 @@ assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit) - def test_flow_identity_info(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_identity_info, [object, object]) - a.simplify() - #a.translator.view() - assert s == a.bookkeeper.immutablevalue((None, None)) - def test_mergefunctions(self): a = self.RPythonAnnotator() s = a.build_types(snippet.mergefunctions, [int]) @@ -431,11 +419,11 @@ # the annotator (it doesn't check that they operate property, though) for example, methname, s_example in [ ('', 'join', annmodel.SomeString()), - ([], 'append', somelist()), - ([], 'extend', somelist()), - ([], 'reverse', somelist()), - ([], 'insert', somelist()), - ([], 'pop', somelist()), + ([], 'append', somelist(annmodel.s_Int)), + ([], 'extend', somelist(annmodel.s_Int)), + ([], 'reverse', somelist(annmodel.s_Int)), + ([], 'insert', somelist(annmodel.s_Int)), + ([], 'pop', somelist(annmodel.s_Int)), ]: constmeth = getattr(example, methname) s_constmeth = iv(constmeth) @@ -497,12 +485,12 @@ def test_simple_slicing(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_slice, [list]) + s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeList) def test_simple_iter_list(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_iter, [list]) + s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeIterator) def test_simple_iter_next(self): @@ -542,11 +530,6 @@ assert isinstance(dictkey(s), annmodel.SomeInteger) assert isinstance(dictvalue(s), annmodel.SomeInteger) - a = self.RPythonAnnotator() - s = a.build_types(snippet.dict_update, [str]) - assert not isinstance(dictkey(s), annmodel.SomeString) - assert not isinstance(dictvalue(s), annmodel.SomeString) - def test_dict_update_2(self): a = self.RPythonAnnotator() def g(n): @@ -568,7 +551,7 @@ def test_dict_keys2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_keys2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_values(self): a = self.RPythonAnnotator() @@ -578,7 +561,7 @@ def test_dict_values2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_items(self): a = self.RPythonAnnotator() @@ -643,25 +626,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_bltin_code_frame_confusion(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_confusion,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - # annotator confused by original bltin code/frame setup, we just get SomeObject here - assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - - def test_bltin_code_frame_reorg(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_reorg,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - assert isinstance(a.binding(f_flowgraph.getreturnvar()), - annmodel.SomeInteger) - assert isinstance(a.binding(g_flowgraph.getreturnvar()), - annmodel.SomeString) - def test_propagation_of_fresh_instances_through_attrs(self): a = self.RPythonAnnotator() s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int]) @@ -748,14 +712,15 @@ assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc) def test_type_is(self): - class C(object): + class B(object): + pass + class C(B): pass def f(x): - if type(x) is C: - return x - raise Exception - a = self.RPythonAnnotator() - s = a.build_types(f, [object]) + assert type(x) is C + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) def test_ann_assert(self): @@ -793,24 +758,30 @@ return None a = self.RPythonAnnotator() - s = a.build_types(f, [list]) + s = a.build_types(f, [somelist(annmodel.s_Int)]) assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list def test_freeze_protocol(self): class Stuff: - def __init__(self, flag): + def __init__(self): self.called = False - self.flag = flag def _freeze_(self): self.called = True - return self.flag - myobj = Stuff(True) + return True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - myobj = Stuff(False) + + def test_cleanup_protocol(self): + class Stuff: + def __init__(self): + self.called = False + def _cleanup_(self): + self.called = True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called @@ -854,7 +825,7 @@ def f(a,b): return bool(a) or bool(b) a = self.RPythonAnnotator() - s = a.build_types(f, [int,list]) + s = a.build_types(f, [int, somelist(annmodel.s_Int)]) assert s.knowntype == bool def test_float(self): @@ -1299,22 +1270,6 @@ assert isinstance(s_item, annmodel.SomeInstance) assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - def test_assert_type_is_list_doesnt_lose_info(self): - class T(object): - pass - def g(l): - assert type(l) is list - return l - def f(): - l = [T()] - return g(l) - a = self.RPythonAnnotator() - s = a.build_types(f, []) - s_item = listitem(s) - assert isinstance(s_item, annmodel.SomeInstance) - assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - - def test_int_str_mul(self): def f(x,a,b): return a*x+x*b @@ -1395,11 +1350,10 @@ except KeyError: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.const = KeyError t.is_type_of = [ev] assert a.binding(et) == t @@ -1412,11 +1366,10 @@ except: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t @@ -1448,11 +1401,10 @@ finally: h() a = self.RPythonAnnotator() - a.build_types(f, [int, list]) + a.build_types(f, [int, somelist(annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) @@ -1474,24 +1426,11 @@ a.build_types(f, []) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_sys_attrs(self): - def f(): - return sys.argv[0] - a = self.RPythonAnnotator() - try: - oldvalue = sys.argv - sys.argv = [] - s = a.build_types(f, []) - finally: - sys.argv = oldvalue - assert s is not None - def test_pow(self): def f(n): n **= 2 @@ -1523,7 +1462,6 @@ a = self.RPythonAnnotator() 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)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] def test_is_true_coalesce2(self): def f(a,b,a1,b1,c,d,e): @@ -1532,9 +1470,12 @@ return d,c return e,c a = self.RPythonAnnotator() - s = a.build_types(f, [int, str, float, list, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) - assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] + s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int), + 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_coalesce_sanity(self): def f(a): @@ -1954,16 +1895,7 @@ t = type(x) return issubclass(t, A) - def f(): - x = g(1) - y = g(0) - return x or y - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert s.knowntype == bool - assert not s.is_constant() - a = self.RPythonAnnotator() - # sanity check + a = self.RPythonAnnotator() x = annmodel.SomeInteger() x.const = 1 s = a.build_types(g, [x]) @@ -2383,8 +2315,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int]) - assert s.__class__ == annmodel.SomeObject - assert s.knowntype == type + assert isinstance(s, annmodel.SomeType) def test_annotate_iter_empty_container(self): def f(): @@ -3075,7 +3006,6 @@ v = -maxint return intmask(v * 10) P = policy.AnnotatorPolicy() - P.allow_someobjects = False a = self.RPythonAnnotator(policy=P) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) @@ -3866,6 +3796,24 @@ s = a.build_types(fn, [annmodel.SomeChar()]) assert s == annmodel.SomeChar() + def test_isinstance_double_const(self): + class X(object): + def _freeze_(self): + return True + + x = X() + + def f(i): + if i: + x1 = x + else: + x1 = None + print "hello" # this is to force the merge of blocks + return isinstance(x1, X) + + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeBool) def g(n): return [0,1,2,n] diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -2,20 +2,20 @@ import autopath import py from pypy.annotation.model import * -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF +from pypy.annotation.listdef import ListDef from pypy.rpython.ootypesystem.ootype import ROOT listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) -s1 = SomeObject() +s1 = SomeType() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s1,s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s1, s2, s3, s4, s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -42,7 +42,7 @@ def test_equality(): assert s1 != s2 != s3 != s4 != s5 != s6 - assert s1 == SomeObject() + assert s1 == SomeType() assert s2 == SomeInteger(nonneg=True) assert s3 == SomeInteger(nonneg=False) assert s4 == SomeList(listdef1) @@ -51,19 +51,11 @@ def test_contains(): assert ([(s,t) for s in slist for t in slist if s.contains(t)] == - [(s1,s1), (s1,s2), (s1,s3), (s1,s4), (s1,s6), - (s2,s2), (s2,s6), - (s3,s2), (s3,s3), (s3,s6), - (s4,s4), (s4,s6), - (s6,s6)]) - -def test_union(): - assert ([unionof(s,t) for s in slist for t in slist] == - [s1, s1, s1, s1, s1, - s1, s2, s3, s1, s2, - s1, s3, s3, s1, s3, - s1, s1, s1, s4, s4, - s1, s2, s3, s4, s6]) + [(s1, s1), (s1, s6), + (s2, s2), (s2, s6), + (s3, s2), (s3, s3), (s3, s6), + (s4, s4), (s4, s6), + (s6, s6)]) def test_commonbase_simple(): class A0: @@ -100,9 +92,10 @@ def test_list_contains(): listdef1 = ListDef(None, SomeInteger(nonneg=True)) s1 = SomeList(listdef1) - s2 = SomeList(MOST_GENERAL_LISTDEF) + listdef2 = ListDef(None, SomeInteger(nonneg=False)) + s2 = SomeList(listdef2) assert s1 != s2 - assert s2.contains(s1) + assert not s2.contains(s1) assert s1 != s2 assert not s1.contains(s2) assert s1 != s2 diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -7,7 +7,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -39,14 +39,7 @@ def type(obj, *moreargs): if moreargs: raise Exception, 'type() called with more than one argument' - if obj.is_constant(): - if isinstance(obj, SomeInstance): - r = SomePBC([obj.classdef.classdesc]) - else: - r = immutablevalue(obj.knowntype) - else: - r = SomeObject() - r.knowntype = type + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator @@ -133,9 +126,6 @@ def float(obj): return SomeFloat() - def long(obj): - return SomeObject() # XXX - def delattr(obj, s_attr): if obj.__class__ != SomeObject or obj.knowntype != object: getbookkeeper().warning( @@ -154,18 +144,17 @@ def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - s_method = obj.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)) - else: - getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' % - (obj, s_attr)) - return SomeObject() + 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)) + attr = s_attr.const + s_method = obj.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)) getattr.can_only_throw = [] def bind_callables_under(obj, classdef, name): diff --git a/pypy/bin/translatorshell.py b/pypy/bin/translatorshell.py --- a/pypy/bin/translatorshell.py +++ b/pypy/bin/translatorshell.py @@ -8,10 +8,10 @@ Example: - t = Translation(func) + t = Translation(func, [int]) # pass the list of args types t.view() # control flow graph - t.annotate([int]) # pass the list of args types + t.annotate() t.view() # graph + annotations under the mouse t.rtype() # use low level operations diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py --- a/pypy/config/test/test_config.py +++ b/pypy/config/test/test_config.py @@ -111,8 +111,8 @@ else: return 'foo' - t = Translation(f) - t.rtype([int]) + t = Translation(f, [int]) + t.rtype() block = t.context.graphs[0].startblock assert len(block.exits[0].target.operations) == 0 diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -129,8 +129,6 @@ # misc BoolOption("verbose", "Print extra information", default=False), - BoolOption("debug", "Record extra annotation information", - cmdline="-d --debug", default=True), BoolOption("insist", "Try hard to go on RTyping", default=False, cmdline="--insist"), StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -111,15 +111,7 @@ def maketestobjspace(config=None): if config is None: config = make_config(option) - try: - space = make_objspace(config) - except OperationError, e: - check_keyboard_interrupt(e) - if option.verbose: - import traceback - traceback.print_exc() - py.test.fail("fatal: cannot initialize objspace: %r" % - (config.objspace.name,)) + space = make_objspace(config) space.startup() # Initialize all builtin modules space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), appsupport.build_pytest_assertion(space)) diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -9,7 +9,7 @@ `import` statements:: from pypy.interpreter.baseobjspace import Wrappable - from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -27,7 +27,7 @@ ``pypy/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: - >>> t = Translation(snippet.is_perfect_number) + >>> t = Translation(snippet.is_perfect_number, [int]) >>> t.view() After that, the graph viewer pops up, that lets you interactively inspect the @@ -40,7 +40,7 @@ We have a type annotator that can completely infer types for functions like ``is_perfect_number`` (as well as for much larger examples):: - >>> t.annotate([int]) + >>> t.annotate() >>> t.view() Move the mouse over variable names (in red) to see their inferred types. @@ -74,8 +74,8 @@ >>> def myfunc(a, b): return a+b ... - >>> t = Translation(myfunc) - >>> t.annotate([int, int]) + >>> t = Translation(myfunc, [int, int]) + >>> t.annotate() >>> f = t.compile_cli() # or compile_jvm() >>> f(4, 5) 9 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 @@ -38,7 +38,8 @@ .. branch: numpypy-complex2 Complex dtype support for numpy - +.. branch: kill-someobject +major cleanups including killing some object support .. "uninteresting" branches that we should just ignore for the whatsnew: diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -730,8 +730,15 @@ # done by a method call on w_two (and not on w_one, because of the # expected programming style where we say "if x is None" or # "if x is object"). + assert w_two is not None return w_two.is_w(self, w_one) + def is_none(self, w_obj): + """ mostly for checking inputargs that have unwrap_spec and + can accept both w_None and None + """ + return w_obj is None or self.is_w(w_obj, self.w_None) + def id(self, w_obj): w_result = w_obj.immutable_unique_id(self) if w_result is None: @@ -815,7 +822,7 @@ interpreter class (a subclass of Wrappable). """ assert RequiredClass is not None - if can_be_None and self.is_w(w_obj, self.w_None): + if can_be_None and self.is_none(w_obj): return None obj = self.interpclass_w(w_obj) if not isinstance(obj, RequiredClass): # or obj is None diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -207,11 +207,11 @@ code = space.interp_w(Code, w_code) if not space.is_true(space.isinstance(w_globals, space.w_dict)): raise OperationError(space.w_TypeError, space.wrap("expected dict")) - if not space.is_w(w_name, space.w_None): + if not space.is_none(w_name): name = space.str_w(w_name) else: name = None - if not space.is_w(w_argdefs, space.w_None): + if not space.is_none(w_argdefs): defs_w = space.fixedview(w_argdefs) else: defs_w = [] @@ -219,7 +219,7 @@ from pypy.interpreter.pycode import PyCode if isinstance(code, PyCode): nfreevars = len(code.co_freevars) - if space.is_w(w_closure, space.w_None) and nfreevars == 0: + if space.is_none(w_closure) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) @@ -247,7 +247,7 @@ # delicate _all = {'': None} - def _freeze_(self): + def _cleanup_(self): from pypy.interpreter.gateway import BuiltinCode if isinstance(self.code, BuiltinCode): # we have been seen by other means so rtyping should not choke @@ -346,7 +346,7 @@ def fget_func_defaults(self, space): values_w = self.defs_w # the `None in values_w` check here is to ensure that interp-level - # functions with a default of NoneNotWrapped do not get their defaults + # functions with a default of None do not get their defaults # exposed at applevel if not values_w or None in values_w: return space.w_None @@ -459,6 +459,7 @@ def fdel_func_annotations(self, space): self.w_ann = None + def descr_function_get(space, w_function, w_obj, w_cls=None): """functionobject.__get__(obj[, type]) -> method""" # this is not defined as a method on Function because it's generally @@ -476,7 +477,7 @@ def __init__(self, space, w_function, w_instance): self.space = space self.w_function = w_function - self.w_instance = w_instance + self.w_instance = w_instance # or None def descr_method__new__(space, w_subtype, w_function, w_instance): if space.is_w(w_instance, space.w_None): @@ -577,7 +578,7 @@ self.w_function = w_function def descr_classmethod_get(self, space, w_obj, w_klass=None): - if space.is_w(w_klass, space.w_None): + if space.is_none(w_klass): w_klass = space.type(w_obj) return space.wrap(Method(space, self.w_function, w_klass)) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -7,31 +7,29 @@ """ -import types, sys, os -from pypy.tool.compat import md5 +import sys +import os +import types -NoneNotWrapped = object() +import py -from pypy.tool.sourcetools import func_with_new_name +from pypy.interpreter.eval import Code +from pypy.interpreter.argument import Arguments, Signature +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, + SpaceCache, DescrMismatch) from pypy.interpreter.error import OperationError -from pypy.interpreter import eval -from pypy.interpreter.function import Function, Method, ClassMethod -from pypy.interpreter.function import FunctionWithFixedCode -from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable -from pypy.interpreter.baseobjspace import Wrappable, SpaceCache, DescrMismatch -from pypy.interpreter.argument import Arguments, Signature -from pypy.tool.sourcetools import NiceCompile, compile2 -from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from pypy.rlib import rstackovf from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.tool.sourcetools import func_with_new_name, compile2 + # internal non-translatable parts: -import py - class SignatureBuilder(object): "NOT_RPYTHON" def __init__(self, func=None, argnames=None, varargname=None, - kwargname=None, name = None): + kwargname=None, name=None): self.func = func if func is not None: self.name = func.__name__ @@ -60,10 +58,12 @@ if isinstance(el, str): getattr(self, "visit_%s" % (el,))(el, *args) elif isinstance(el, tuple): - if el[0] == 'self': + if el[0] == 'INTERNAL:self': self.visit_self(el[1], *args) else: - self.visit_function(el, *args) + assert False, "not supported any more, use WrappedDefault" + elif isinstance(el, WrappedDefault): + self.visit__W_Root(W_Root, *args) elif isinstance(el, type): for typ in self.bases_order: if issubclass(el, typ): @@ -81,8 +81,8 @@ for el in unwrap_spec: dispatch(el, *extra) + class UnwrapSpecEmit(UnwrapSpecRecipe): - def __init__(self): self.n = 0 self.miniglobals = {} @@ -97,10 +97,11 @@ self.miniglobals[name] = obj return name + #________________________________________________________________ + class UnwrapSpec_Check(UnwrapSpecRecipe): - # checks for checking interp2app func argument names wrt unwrap_spec # and synthetizing an app-level signature @@ -108,9 +109,6 @@ self.func = original_sig.func self.orig_arg = iter(original_sig.argnames).next - def visit_function(self, (func, cls), app_sig): - self.dispatch(cls, app_sig) - def visit_self(self, cls, app_sig): self.visit__Wrappable(cls, app_sig) @@ -168,8 +166,8 @@ app_sig.append(argname[2:]) def visit__Arguments(self, el, app_sig): - argname = self.orig_arg() - assert app_sig.varargname is None,( + self.orig_arg() + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = 'args' app_sig.kwargname = 'keywords' @@ -179,7 +177,7 @@ assert argname.endswith('_w'), ( "rest arguments arg %s of built-in function %r should end in '_w'" % (argname, self.func)) - assert app_sig.varargname is None,( + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = argname[:-2] @@ -188,7 +186,7 @@ assert argname.startswith('w_'), ( "rest arguments arg %s of built-in function %r should start 'w_'" % (argname, self.func)) - assert app_sig.varargname is None,( + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = argname[2:] @@ -208,10 +206,6 @@ def scopenext(self): return "scope_w[%d]" % self.succ() - def visit_function(self, (func, cls)): - self.run_args.append("%s(%s)" % (self.use(func), - self.scopenext())) - def visit_self(self, typ): self.run_args.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.scopenext())) @@ -284,6 +278,8 @@ if isinstance(el, tuple): parts.append(''.join([getattr(subel, '__name__', subel) for subel in el])) + elif isinstance(el, WrappedDefault): + parts.append('W_Root') else: parts.append(getattr(el, '__name__', el)) label = '_'.join(parts) @@ -320,15 +316,16 @@ def _run(self, space, scope_w): """Subclasses with behavior specific for an unwrap spec are generated""" - raise TypeError, "abstract" + raise TypeError("abstract") #________________________________________________________________ + class FastFuncNotSupported(Exception): pass + class UnwrapSpec_FastFunc_Unwrap(UnwrapSpecEmit): - def __init__(self): UnwrapSpecEmit.__init__(self) self.args = [] @@ -346,9 +343,6 @@ self.args.append(arg) return arg - def visit_function(self, (func, cls)): - raise FastFuncNotSupported - def visit_self(self, typ): self.unwrap.append("space.descr_self_interp_w(%s, %s)" % (self.use(typ), self.nextarg())) @@ -439,6 +433,7 @@ return narg, fastfunc make_fastfunc = staticmethod(make_fastfunc) + def int_unwrapping_space_method(typ): assert typ in (int, str, float, unicode, r_longlong, r_uint, r_ulonglong, bool) if typ is r_int is r_longlong: @@ -455,6 +450,7 @@ - positional arguments must be as many as the function parameters - keywords arguments allow to change only some parameter specs """ + assert spec or kwargs def decorator(func): if kwargs: if spec: @@ -466,6 +462,14 @@ return func return decorator +class WrappedDefault(object): + """ Can be used inside unwrap_spec as WrappedDefault(3) which means + it'll be treated as W_Root, but fed with default which will be a wrapped + argument to constructor. + """ + def __init__(self, default_value): + self.default_value = default_value + def build_unwrap_spec(func, argnames, self_type=None): """build the list of parameter unwrap spec for the function. """ @@ -505,7 +509,8 @@ return unwrap_spec -class BuiltinCode(eval.Code): + +class BuiltinCode(Code): "The code object implementing a built-in (interpreter-level) hook." _immutable_ = True hidden_applevel = True @@ -515,14 +520,11 @@ # When a BuiltinCode is stored in a Function object, # you get the functionality of CPython's built-in function type. - NOT_RPYTHON_ATTRIBUTES = ['_bltin', '_unwrap_spec'] - - def __init__(self, func, unwrap_spec = None, self_type = None, - descrmismatch=None): From noreply at buildbot.pypy.org Sat Oct 13 02:09:57 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 13 Oct 2012 02:09:57 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20121013000957.B700A1C1C5A@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58092:448892c68233 Date: 2012-10-12 17:09 -0700 http://bitbucket.org/pypy/pypy/changeset/448892c68233/ Log: merge default diff --git a/pypy/module/oracle/interp_cursor.py b/pypy/module/oracle/interp_cursor.py --- a/pypy/module/oracle/interp_cursor.py +++ b/pypy/module/oracle/interp_cursor.py @@ -1,5 +1,4 @@ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, unwrap_spec diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -1,7 +1,6 @@ -import sys -from pypy.interpreter import gateway from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, SMM @@ -62,9 +61,8 @@ def descr__new__(space, w_bytearraytype, __args__): return new_bytearray(space,w_bytearraytype, []) - at gateway.unwrap_spec(encoding='str_or_None', errors='str_or_None') -def descr__init__(space, w_self, w_source=gateway.NoneNotWrapped, - encoding=None, errors=None): + at unwrap_spec(encoding='str_or_None', errors='str_or_None') +def descr__init__(space, w_self, w_source=None, encoding=None, errors=None): from pypy.objspace.std.bytearrayobject import W_BytearrayObject assert isinstance(w_self, W_BytearrayObject) data = makebytesdata_w(space, w_source, encoding, errors) @@ -141,10 +139,10 @@ bytearray(sequence) -> bytearray initialized from sequence\'s items If the argument is a bytearray, the return value is the same object.''', - __new__ = gateway.interp2app(descr__new__), - __init__ = gateway.interp2app(descr__init__), + __new__ = interp2app(descr__new__), + __init__ = interp2app(descr__init__), __hash__ = None, - __reduce__ = gateway.interp2app(descr_bytearray__reduce__), - fromhex = gateway.interp2app(descr_fromhex, as_classmethod=True) + __reduce__ = interp2app(descr_bytearray__reduce__), + fromhex = interp2app(descr_fromhex, as_classmethod=True) ) bytearray_typedef.registermethods(globals()) From noreply at buildbot.pypy.org Sat Oct 13 11:25:09 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 13 Oct 2012 11:25:09 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: hg merge default Message-ID: <20121013092509.F321B1C015F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58093:7465a76a9d28 Date: 2012-10-13 11:01 +0200 http://bitbucket.org/pypy/pypy/changeset/7465a76a9d28/ Log: hg merge default diff too long, truncating to 2000 out of 49446 lines diff --git a/lib-python/2.7/test/test_csv.py b/lib-python/2.7/test/test_csv.py --- a/lib-python/2.7/test/test_csv.py +++ b/lib-python/2.7/test/test_csv.py @@ -20,7 +20,8 @@ """ def _test_arg_valid(self, ctor, arg): self.assertRaises(TypeError, ctor) - self.assertRaises(TypeError, ctor, None) + # PyPy gets an AttributeError instead of a TypeError + self.assertRaises((TypeError, AttributeError), ctor, None) self.assertRaises(TypeError, ctor, arg, bad_attr = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 'XX') @@ -59,7 +60,8 @@ self.assertRaises((TypeError, AttributeError), setattr, obj.dialect, 'delimiter', ':') self.assertRaises(AttributeError, delattr, obj.dialect, 'quoting') - self.assertRaises(AttributeError, setattr, obj.dialect, + # PyPy gets a TypeError instead of an AttributeError + self.assertRaises((AttributeError, TypeError), setattr, obj.dialect, 'quoting', None) def test_reader_attrs(self): @@ -133,7 +135,8 @@ os.unlink(name) def test_write_arg_valid(self): - self.assertRaises(csv.Error, self._write_test, None, '') + # PyPy gets a TypeError instead of a csv.Error for "not a sequence" + self.assertRaises((csv.Error, TypeError), self._write_test, None, '') self._write_test((), '') self._write_test([None], '""') self.assertRaises(csv.Error, self._write_test, diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -183,7 +183,7 @@ RegrTest('test_cpickle.py', core=True), RegrTest('test_cprofile.py'), RegrTest('test_crypt.py', usemodules='crypt', skip=skip_win32), - RegrTest('test_csv.py'), + RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_curses.py', skip="unsupported extension module"), RegrTest('test_datetime.py'), diff --git a/lib_pypy/_csv.py b/lib_pypy/_csv.py --- a/lib_pypy/_csv.py +++ b/lib_pypy/_csv.py @@ -363,9 +363,7 @@ (self.dialect.delimiter, self.dialect.quotechar)) elif self.state == self.EAT_CRNL: - if c in '\r\n': - pass - else: + if c not in '\r\n': raise Error("new-line character seen in unquoted field - " "do you need to open the file " "in universal-newline mode?") diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py --- a/lib_pypy/_ctypes/pointer.py +++ b/lib_pypy/_ctypes/pointer.py @@ -81,7 +81,9 @@ addr = self._buffer[0] if addr == 0: raise ValueError("NULL pointer access") - return self._type_.from_address(addr) + instance = self._type_.from_address(addr) + instance.__dict__['_base'] = self + return instance def setcontents(self, value): if not isinstance(value, self._type_): diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,11 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - libpath = ctypes.util.find_library('db-4.5') - if not libpath: + for c in '56789': + libpath = ctypes.util.find_library('db-4.%s' % c) + if libpath: + break + else: raise ImportError("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' diff --git a/py/_io/capture.py b/py/_io/capture.py --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -176,7 +176,7 @@ class StdCaptureFD(Capture): - """ This class allows to capture writes to FD1 and FD2 + """ This class allows capturing writes to FD1 and FD2 and may connect a NULL file to FD0 (and prevent reads from sys.stdin). If any of the 0,1,2 file descriptors is invalid it will not be captured. @@ -267,8 +267,8 @@ return l class StdCapture(Capture): - """ This class allows to capture writes to sys.stdout|stderr "in-memory" - and will raise errors on tries to read from sys.stdin. It only + """ This class allows capturing writes to sys.stdout|stderr "in-memory" + and will raise errors on read attempts from sys.stdin. It only modifies sys.stdout|stderr|stdin attributes and does not touch underlying File Descriptors (use StdCaptureFD for that). """ diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -1,9 +1,8 @@ -import sys import types -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception +from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - format_someobject_error, AnnotatorError) + AnnotatorError, gather_error, ErrorWrapper) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -38,22 +37,9 @@ self.links_followed = {} # set of links that have ever been followed self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + self.blocked_blocks = {} # set of {blocked_block: (graph, index)} + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +63,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +164,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +181,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +192,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +242,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +265,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +283,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +333,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -414,7 +340,7 @@ self.flowin(graph, block) except BlockedInference, e: self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, e.opindex) except Exception, e: # hack for debug tools only if not hasattr(e, '__annotator_block'): @@ -433,25 +359,24 @@ self.pendingblocks[block] = graph assert block in self.annotated self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -471,14 +396,11 @@ for i in range(len(block.operations)): try: self.bookkeeper.enter((graph, block, i)) - self.consider_op(block.operations[i]) + self.consider_op(block, i) finally: self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +484,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +494,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +530,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell @@ -653,7 +572,8 @@ #___ creating the annotations based on operations ______ - def consider_op(self, op): + def consider_op(self, block, opindex): + op = block.operations[opindex] argcells = [self.binding(a) for a in op.args] consider_meth = getattr(self,'consider_op_'+op.opname, None) @@ -668,16 +588,18 @@ # boom -- in the assert of setbinding() for arg in argcells: if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op) + raise BlockedInference(self, op, opindex) try: resultcell = consider_meth(*argcells) - except Exception: + except Exception, e: graph = self.bookkeeper.position_key[0] - raise_nicer_exception(op, str(graph)) + e.args = e.args + ( + ErrorWrapper(gather_error(self, graph, block, opindex)),) + raise if resultcell is None: resultcell = self.noreturnvalue(op) elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op) # the operation cannot succeed + raise BlockedInference(self, op, opindex) # the operation cannot succeed assert isinstance(resultcell, annmodel.SomeObject) assert isinstance(op.result, Variable) self.setbinding(op.result, resultcell) # bind resultcell to op.result @@ -728,13 +650,14 @@ """This exception signals the type inference engine that the situation is currently blocked, and that it should try to progress elsewhere.""" - def __init__(self, annotator, op): + def __init__(self, annotator, op, opindex): self.annotator = annotator try: self.break_at = annotator.bookkeeper.position_key except AttributeError: self.break_at = None self.op = op + self.opindex = opindex def __repr__(self): if not self.break_at: diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,15 +29,6 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', 'truediv', 'floordiv', 'divmod', 'pow', @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -238,7 +201,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -564,14 +550,30 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - return SomeObject() + raise UnionError("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): return SomeTuple(items = tup1.items + tup2.items) + def eq(tup1tup2): + tup1tup2.union() + return s_Bool + ne = eq + + def lt((tup1, tup2)): + raise Exception("unsupported: (...) < (...)") + def le((tup1, tup2)): + raise Exception("unsupported: (...) <= (...)") + def gt((tup1, tup2)): + raise Exception("unsupported: (...) > (...)") + def ge((tup1, tup2)): + raise Exception("unsupported: (...) >= (...)") + class __extend__(pairtype(SomeDict, SomeDict)): @@ -723,8 +725,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -764,7 +765,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -778,7 +779,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -806,7 +807,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,7 +10,7 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef @@ -148,7 +148,6 @@ self.descs = {} # map Python objects to their XxxDesc wrappers self.methoddescs = {} # map (funcdesc, classdef) to the MethodDesc self.classdefs = [] # list of all ClassDefs - self.pbctypes = {} self.seen_mutable = {} self.listdefs = {} # map position_keys to ListDefs self.dictdefs = {} # map position_keys to DictDefs @@ -167,9 +166,6 @@ self.stats = Stats(self) - # used in SomeObject.__new__ for keeping debugging info - self._isomeobject_coming_from = identity_dict() - delayed_imports() def count(self, category, *args): @@ -275,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() @@ -325,8 +320,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -445,6 +438,12 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if (x is type(None) or # add cases here if needed + x.__module__ == 'pypy.rpython.lltypesystem.lltype'): + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) 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 @@ -455,20 +454,13 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) - elif hasattr(x, '_freeze_') and x._freeze_(): + result = SomePBC([self.getdesc(x)]) + elif hasattr(x, '_freeze_'): + assert x._freeze_() is True # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method # returns True, the instance is considered immutable and becomes @@ -476,16 +468,18 @@ result = SomePBC([self.getdesc(x)]) elif hasattr(x, '__class__') \ and x.__class__.__module__ != '__builtin__': + if hasattr(x, '_cleanup_'): + x._cleanup_() self.see_mutable(x) result = SomeInstance(self.getuniqueclassdef(x.__class__)) elif x is None: return s_None else: - result = SomeObject() + raise Exception("Don't know how to represent %r" % (x,)) if need_const: result.const = x return result - + def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: @@ -509,8 +503,10 @@ elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) - elif (hasattr(pyobj.im_self, '_freeze_') and - pyobj.im_self._freeze_()): # method of frozen + if hasattr(pyobj.im_self, '_cleanup_'): + pyobj.im_self._cleanup_() + if hasattr(pyobj.im_self, '_freeze_'): # method of frozen + assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc(self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc @@ -529,9 +525,9 @@ name) else: # must be a frozen pre-built constant, but let's check - try: - assert pyobj._freeze_() - except AttributeError: + if hasattr(pyobj, '_freeze_'): + assert pyobj._freeze_() is True + else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: @@ -551,11 +547,7 @@ return False def getfrozen(self, pyobj): - result = description.FrozenDesc(self, pyobj) - cls = result.knowntype - if cls not in self.pbctypes: - self.pbctypes[cls] = True - return result + return description.FrozenDesc(self, pyobj) def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, flags={}): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -150,7 +150,7 @@ def builtin_isinstance(s_obj, s_type, variables=None): - r = SomeBool() + r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,8 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + + if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -247,13 +247,16 @@ defs_s = [] if graph is None: signature = self.signature - defaults = self.defaults + defaults = self.defaults else: signature = graph.signature - defaults = graph.defaults + defaults = graph.defaults if defaults: for x in defaults: - defs_s.append(self.bookkeeper.immutablevalue(x)) + if x is NODEFAULT: + defs_s.append(None) + else: + defs_s.append(self.bookkeeper.immutablevalue(x)) try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,8 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype + immutable = False knowntype = object - immutable = False + + def __init__(self): + assert type(self) is not SomeObject def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -105,60 +106,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: - self = new(cls, *args, **kw) - if DEBUG: - try: - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - position_key = bookkeeper.position_key - except AttributeError: - pass - else: - bookkeeper._isomeobject_coming_from[self] = position_key, None + def can_be_none(self): + return True + + def nonnoneify(self): return self - def origin(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] - origin = property(origin) - def caused_by_merge(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] - def set_caused_by_merge(self, nvalue): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return - bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue - caused_by_merge = property(caused_by_merge, set_caused_by_merge) - del set_caused_by_merge +class SomeType(SomeObject): + "Stands for a type. We might not be sure which one it is." + knowntype = type + immutable = True def can_be_none(self): - return True - - def nonnoneify(self): - return self + return False class SomeFloat(SomeObject): "Stands for a float or an integer." @@ -517,6 +486,7 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) @@ -710,14 +680,8 @@ # this is just a performance shortcut if s1 != s2: s1 = pair(s1, s2).union() - if DEBUG: - if s1.caused_by_merge is None and len(somevalues) > 1: - s1.caused_by_merge = somevalues return s1 -def isdegenerated(s_value): - return s_value.__class__ is SomeObject and s_value.knowntype is not type - # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -10,7 +10,6 @@ class BasicAnnotatorPolicy(object): - allow_someobjects = True def event(pol, bookkeeper, what, *args): pass @@ -80,6 +79,3 @@ def specialize__ll_and_arg(pol, *args): from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args) - -class StrictAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -3,9 +3,9 @@ from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF -from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF + unionof, SomeUnicodeString, SomeType +from pypy.annotation.listdef import ListDef +from pypy.annotation.dictdef import DictDef _annotation_cache = {} @@ -78,24 +78,18 @@ return SomeString() elif t is unicode: return SomeUnicodeString() - elif t is list: - return SomeList(MOST_GENERAL_LISTDEF) - elif t is dict: - return SomeDict(MOST_GENERAL_DICTDEF) - # can't do tuple elif t is types.NoneType: return s_None elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) - elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes: + elif t is type: + return SomeType() + elif bookkeeper and not hasattr(t, '_freeze_'): classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) else: - o = SomeObject() - if t != object: - o.knowntype = t - return o + raise AssertionError("annotationoftype(%r)" % (t,)) class Sig(object): diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -24,7 +24,7 @@ assert isinstance(s_list, annmodel.SomeList) return s_list.listdef.listitem.s_value -def somelist(s_type=annmodel.SomeObject()): +def somelist(s_type): return annmodel.SomeList(ListDef(None, s_type)) def dictkey(s_dict): @@ -35,7 +35,7 @@ assert isinstance(s_dict, annmodel.SomeDict) return s_dict.dictdef.dictvalue.s_value -def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()): +def somedict(s_key, s_value): return annmodel.SomeDict(DictDef(None, s_key, s_value)) @@ -205,15 +205,6 @@ annmodel.SomeInteger() ]) - def test_inheritance2(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet._inheritance_nonrunnable, []) - # result should be exactly: - assert s == annmodel.SomeTuple([ - annmodel.SomeInteger(), - annmodel.SomeObject() - ]) - def test_poor_man_range(self): a = self.RPythonAnnotator() s = a.build_types(snippet.poor_man_range, [int]) @@ -336,9 +327,13 @@ def test_flow_type_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_type_info, [object]) + s = a.build_types(snippet.flow_type_info, [int]) a.simplify() - #a.translator.view() + assert s.knowntype == int + + a = self.RPythonAnnotator() + s = a.build_types(snippet.flow_type_info, [str]) + a.simplify() assert s.knowntype == int def test_flow_type_info_2(self): @@ -351,7 +346,7 @@ def test_flow_usertype_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_usertype_info, [object]) + s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit]) #a.translator.view() assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit) @@ -363,13 +358,6 @@ assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit) - def test_flow_identity_info(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_identity_info, [object, object]) - a.simplify() - #a.translator.view() - assert s == a.bookkeeper.immutablevalue((None, None)) - def test_mergefunctions(self): a = self.RPythonAnnotator() s = a.build_types(snippet.mergefunctions, [int]) @@ -431,11 +419,11 @@ # the annotator (it doesn't check that they operate property, though) for example, methname, s_example in [ ('', 'join', annmodel.SomeString()), - ([], 'append', somelist()), - ([], 'extend', somelist()), - ([], 'reverse', somelist()), - ([], 'insert', somelist()), - ([], 'pop', somelist()), + ([], 'append', somelist(annmodel.s_Int)), + ([], 'extend', somelist(annmodel.s_Int)), + ([], 'reverse', somelist(annmodel.s_Int)), + ([], 'insert', somelist(annmodel.s_Int)), + ([], 'pop', somelist(annmodel.s_Int)), ]: constmeth = getattr(example, methname) s_constmeth = iv(constmeth) @@ -497,12 +485,12 @@ def test_simple_slicing(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_slice, [list]) + s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeList) def test_simple_iter_list(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_iter, [list]) + s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeIterator) def test_simple_iter_next(self): @@ -542,11 +530,6 @@ assert isinstance(dictkey(s), annmodel.SomeInteger) assert isinstance(dictvalue(s), annmodel.SomeInteger) - a = self.RPythonAnnotator() - s = a.build_types(snippet.dict_update, [str]) - assert not isinstance(dictkey(s), annmodel.SomeString) - assert not isinstance(dictvalue(s), annmodel.SomeString) - def test_dict_update_2(self): a = self.RPythonAnnotator() def g(n): @@ -568,7 +551,7 @@ def test_dict_keys2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_keys2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_values(self): a = self.RPythonAnnotator() @@ -578,7 +561,7 @@ def test_dict_values2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_items(self): a = self.RPythonAnnotator() @@ -643,25 +626,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_bltin_code_frame_confusion(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_confusion,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - # annotator confused by original bltin code/frame setup, we just get SomeObject here - assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - - def test_bltin_code_frame_reorg(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_reorg,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - assert isinstance(a.binding(f_flowgraph.getreturnvar()), - annmodel.SomeInteger) - assert isinstance(a.binding(g_flowgraph.getreturnvar()), - annmodel.SomeString) - def test_propagation_of_fresh_instances_through_attrs(self): a = self.RPythonAnnotator() s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int]) @@ -748,14 +712,15 @@ assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc) def test_type_is(self): - class C(object): + class B(object): + pass + class C(B): pass def f(x): - if type(x) is C: - return x - raise Exception - a = self.RPythonAnnotator() - s = a.build_types(f, [object]) + assert type(x) is C + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) def test_ann_assert(self): @@ -793,24 +758,30 @@ return None a = self.RPythonAnnotator() - s = a.build_types(f, [list]) + s = a.build_types(f, [somelist(annmodel.s_Int)]) assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list def test_freeze_protocol(self): class Stuff: - def __init__(self, flag): + def __init__(self): self.called = False - self.flag = flag def _freeze_(self): self.called = True - return self.flag - myobj = Stuff(True) + return True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - myobj = Stuff(False) + + def test_cleanup_protocol(self): + class Stuff: + def __init__(self): + self.called = False + def _cleanup_(self): + self.called = True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called @@ -854,7 +825,7 @@ def f(a,b): return bool(a) or bool(b) a = self.RPythonAnnotator() - s = a.build_types(f, [int,list]) + s = a.build_types(f, [int, somelist(annmodel.s_Int)]) assert s.knowntype == bool def test_float(self): @@ -1299,22 +1270,6 @@ assert isinstance(s_item, annmodel.SomeInstance) assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - def test_assert_type_is_list_doesnt_lose_info(self): - class T(object): - pass - def g(l): - assert type(l) is list - return l - def f(): - l = [T()] - return g(l) - a = self.RPythonAnnotator() - s = a.build_types(f, []) - s_item = listitem(s) - assert isinstance(s_item, annmodel.SomeInstance) - assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - - def test_int_str_mul(self): def f(x,a,b): return a*x+x*b @@ -1395,11 +1350,10 @@ except KeyError: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.const = KeyError t.is_type_of = [ev] assert a.binding(et) == t @@ -1412,11 +1366,10 @@ except: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t @@ -1448,11 +1401,10 @@ finally: h() a = self.RPythonAnnotator() - a.build_types(f, [int, list]) + a.build_types(f, [int, somelist(annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) @@ -1474,24 +1426,11 @@ a.build_types(f, []) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_sys_attrs(self): - def f(): - return sys.argv[0] - a = self.RPythonAnnotator() - try: - oldvalue = sys.argv - sys.argv = [] - s = a.build_types(f, []) - finally: - sys.argv = oldvalue - assert s is not None - def test_pow(self): def f(n): n **= 2 @@ -1523,7 +1462,6 @@ a = self.RPythonAnnotator() 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)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] def test_is_true_coalesce2(self): def f(a,b,a1,b1,c,d,e): @@ -1532,9 +1470,12 @@ return d,c return e,c a = self.RPythonAnnotator() - s = a.build_types(f, [int, str, float, list, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) - assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] + s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int), + 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_coalesce_sanity(self): def f(a): @@ -1954,16 +1895,7 @@ t = type(x) return issubclass(t, A) - def f(): - x = g(1) - y = g(0) - return x or y - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert s.knowntype == bool - assert not s.is_constant() - a = self.RPythonAnnotator() - # sanity check + a = self.RPythonAnnotator() x = annmodel.SomeInteger() x.const = 1 s = a.build_types(g, [x]) @@ -2383,8 +2315,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int]) - assert s.__class__ == annmodel.SomeObject - assert s.knowntype == type + assert isinstance(s, annmodel.SomeType) def test_annotate_iter_empty_container(self): def f(): @@ -3075,7 +3006,6 @@ v = -maxint return intmask(v * 10) P = policy.AnnotatorPolicy() - P.allow_someobjects = False a = self.RPythonAnnotator(policy=P) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) @@ -3859,6 +3789,32 @@ a = self.RPythonAnnotator() py.test.raises(Exception, a.build_types, fn, []) + def test_lower_char(self): + def fn(c): + return c.lower() + a = self.RPythonAnnotator() + s = a.build_types(fn, [annmodel.SomeChar()]) + assert s == annmodel.SomeChar() + + def test_isinstance_double_const(self): + class X(object): + def _freeze_(self): + return True + + x = X() + + def f(i): + if i: + x1 = x + else: + x1 = None + print "hello" # this is to force the merge of blocks + return isinstance(x1, X) + + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeBool) + def g(n): return [0,1,2,n] diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -2,20 +2,20 @@ import autopath import py from pypy.annotation.model import * -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF +from pypy.annotation.listdef import ListDef from pypy.rpython.ootypesystem.ootype import ROOT listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) -s1 = SomeObject() +s1 = SomeType() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s1,s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s1, s2, s3, s4, s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -42,7 +42,7 @@ def test_equality(): assert s1 != s2 != s3 != s4 != s5 != s6 - assert s1 == SomeObject() + assert s1 == SomeType() assert s2 == SomeInteger(nonneg=True) assert s3 == SomeInteger(nonneg=False) assert s4 == SomeList(listdef1) @@ -51,19 +51,11 @@ def test_contains(): assert ([(s,t) for s in slist for t in slist if s.contains(t)] == - [(s1,s1), (s1,s2), (s1,s3), (s1,s4), (s1,s6), - (s2,s2), (s2,s6), - (s3,s2), (s3,s3), (s3,s6), - (s4,s4), (s4,s6), - (s6,s6)]) - -def test_union(): - assert ([unionof(s,t) for s in slist for t in slist] == - [s1, s1, s1, s1, s1, - s1, s2, s3, s1, s2, - s1, s3, s3, s1, s3, - s1, s1, s1, s4, s4, - s1, s2, s3, s4, s6]) + [(s1, s1), (s1, s6), + (s2, s2), (s2, s6), + (s3, s2), (s3, s3), (s3, s6), + (s4, s4), (s4, s6), + (s6, s6)]) def test_commonbase_simple(): class A0: @@ -100,9 +92,10 @@ def test_list_contains(): listdef1 = ListDef(None, SomeInteger(nonneg=True)) s1 = SomeList(listdef1) - s2 = SomeList(MOST_GENERAL_LISTDEF) + listdef2 = ListDef(None, SomeInteger(nonneg=False)) + s2 = SomeList(listdef2) assert s1 != s2 - assert s2.contains(s1) + assert not s2.contains(s1) assert s1 != s2 assert not s1.contains(s2) assert s1 != s2 diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -7,7 +7,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -39,14 +39,7 @@ def type(obj, *moreargs): if moreargs: raise Exception, 'type() called with more than one argument' - if obj.is_constant(): - if isinstance(obj, SomeInstance): - r = SomePBC([obj.classdef.classdesc]) - else: - r = immutablevalue(obj.knowntype) - else: - r = SomeObject() - r.knowntype = type + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator @@ -133,9 +126,6 @@ def float(obj): return SomeFloat() - def long(obj): - return SomeObject() # XXX - def delattr(obj, s_attr): if obj.__class__ != SomeObject or obj.knowntype != object: getbookkeeper().warning( @@ -154,18 +144,17 @@ def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - s_method = obj.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)) - else: - getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' % - (obj, s_attr)) - return SomeObject() + 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)) + attr = s_attr.const + s_method = obj.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)) getattr.can_only_throw = [] def bind_callables_under(obj, classdef, name): @@ -586,6 +575,12 @@ def method_isupper(chr): return s_Bool + def method_lower(chr): + return chr + + def method_upper(chr): + return chr + class __extend__(SomeIterator): def iter(itr): diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -2,9 +2,9 @@ """ Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME -Print a report for the static data informations contained in FILENAME +Print a report for the static data information contained in FILENAME -The static data informations are saved in the file staticdata.info when +The static data information is saved in the file staticdata.info when passing --dump_static_data_info to translate.py. Options: diff --git a/pypy/bin/translatorshell.py b/pypy/bin/translatorshell.py --- a/pypy/bin/translatorshell.py +++ b/pypy/bin/translatorshell.py @@ -8,10 +8,10 @@ Example: - t = Translation(func) + t = Translation(func, [int]) # pass the list of args types t.view() # control flow graph - t.annotate([int]) # pass the list of args types + t.annotate() t.view() # graph + annotations under the mouse t.rtype() # use low level operations diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -34,7 +34,7 @@ "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array", "_bisect", "binascii", "_multiprocessing", '_warnings', "_collections", "_multibytecodec", "micronumpy", "_ffi", - "_continuation", "_cffi_backend"] + "_continuation", "_cffi_backend", "_csv"] )) translation_modules = default_modules.copy() diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py --- a/pypy/config/test/test_config.py +++ b/pypy/config/test/test_config.py @@ -111,8 +111,8 @@ else: return 'foo' - t = Translation(f) - t.rtype([int]) + t = Translation(f, [int]) + t.rtype() block = t.context.graphs[0].startblock assert len(block.exits[0].target.operations) == 0 diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -129,8 +129,6 @@ # misc BoolOption("verbose", "Print extra information", default=False), - BoolOption("debug", "Record extra annotation information", - cmdline="-d --debug", default=True), BoolOption("insist", "Try hard to go on RTyping", default=False, cmdline="--insist"), StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -101,15 +101,7 @@ def maketestobjspace(config=None): if config is None: config = make_config(option) - try: - space = make_objspace(config) - except OperationError, e: - check_keyboard_interrupt(e) - if option.verbose: - import traceback - traceback.print_exc() - py.test.fail("fatal: cannot initialize objspace: %r" % - (config.objspace.name,)) + space = make_objspace(config) space.startup() # Initialize all builtin modules space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), appsupport.build_pytest_assertion(space)) diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -238,7 +238,7 @@ interpreter`_. .. _`documentation index`: index.html#project-documentation -.. _`getting-started`: getting-started.html +.. _`getting-started`: getting-started-dev.html .. _`PyPy's approach to virtual machine construction`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dls2006/pypy-vm-construction.pdf .. _`the translation document`: translation.html .. _`RPython toolchain`: translation.html diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -23,7 +23,7 @@ The tools required to cross translate from a Linux based host to an ARM based Linux target are: -- A checkout of PyPy's arm-backend-2 branch. +- A checkout of PyPy (default branch). - The GCC ARM cross compiler (on Ubuntu it is the ``gcc-arm-linux-gnueabi package``) but other toolchains should also work. - Scratchbox 2, a cross-compilation engine (``scratchbox2`` Ubuntu package). - A 32-bit PyPy or Python. @@ -147,4 +147,4 @@ return 0 def target(*args): - return main, None \ No newline at end of file + return main, None diff --git a/pypy/doc/config/objspace.usemodules._csv.txt b/pypy/doc/config/objspace.usemodules._csv.txt new file mode 100644 --- /dev/null +++ b/pypy/doc/config/objspace.usemodules._csv.txt @@ -0,0 +1,2 @@ +Implementation in RPython for the core of the 'csv' module + diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -9,7 +9,7 @@ `import` statements:: from pypy.interpreter.baseobjspace import Wrappable - from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w @@ -41,9 +41,6 @@ llexternal functions. For a typical usage, see `pypy.rlib.rsocket.RSocket.getsockopt_int`. -- Support context managers and the `with` statement. This could be a workaround - before the previous point is available. - Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -27,7 +27,7 @@ ``pypy/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: - >>> t = Translation(snippet.is_perfect_number) + >>> t = Translation(snippet.is_perfect_number, [int]) >>> t.view() After that, the graph viewer pops up, that lets you interactively inspect the @@ -40,7 +40,7 @@ We have a type annotator that can completely infer types for functions like ``is_perfect_number`` (as well as for much larger examples):: - >>> t.annotate([int]) + >>> t.annotate() >>> t.view() Move the mouse over variable names (in red) to see their inferred types. @@ -74,8 +74,8 @@ >>> def myfunc(a, b): return a+b ... - >>> t = Translation(myfunc) - >>> t.annotate([int, int]) + >>> t = Translation(myfunc, [int, int]) + >>> t.annotate() >>> f = t.compile_cli() # or compile_jvm() >>> f(4, 5) 9 diff --git a/pypy/doc/jit/pyjitpl5.rst b/pypy/doc/jit/pyjitpl5.rst --- a/pypy/doc/jit/pyjitpl5.rst +++ b/pypy/doc/jit/pyjitpl5.rst @@ -149,7 +149,7 @@ A *virtual* value is an array, struct, or RPython level instance that is created during the loop and does not escape from it via calls or longevity past the -loop. Since it is only used by the JIT, it be "optimized out"; the value +loop. Since it is only used by the JIT, it can be "optimized out"; the value doesn't have to be allocated at all and its fields can be stored as first class values instead of deferencing them in memory. Virtuals allow temporary objects in the interpreter to be unwrapped. For example, a W_IntObject in the PyPy can diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -21,7 +21,7 @@ ------------------------- PyPy's implementation of the Python ``long`` type is slower than CPython's. -Find out why and optimize them. +Find out why and optimize them. **UPDATE:** this was done (thanks stian). Make bytearray type fast ------------------------ @@ -103,13 +103,35 @@ * A concurrent garbage collector (a lot of work) -STM, a.k.a. "remove the GIL" ----------------------------- +STM (Software Transactional Memory) +----------------------------------- -Removing the GIL --- or more precisely, a GIL-less thread-less solution --- -is `now work in progress.`__ Contributions welcome. +This is work in progress. Besides the main development path, whose goal is +to make a (relatively fast) version of pypy which includes STM, there are +independent topics that can already be experimented with on the existing, +JIT-less pypy-stm version: + +* What kind of conflicts do we get in real use cases? And, sometimes, + which data structures would be more appropriate? For example, a dict + implemented as a hash table will suffer "stm collisions" in all threads + whenever one thread writes anything to it; but there could be other + implementations. Maybe alternate strategies can be implemented at the + level of the Python interpreter (see list/dict strategies, + ``pypy/objspace/std/{list,dict}object.py``). -.. __: http://pypy.org/tmdonate.html +* More generally, there is the idea that we would need some kind of + "debugger"-like tool to "debug" things that are not bugs, but stm + conflicts. How would this tool look like to the end Python + programmers? Like a profiler? Or like a debugger with breakpoints + on aborted transactions? It would probably be all app-level, with + a few hooks e.g. for transaction conflicts. + +* Find good ways to have libraries using internally threads and atomics, + but not exposing threads to the user. Right now there is a rough draft + in ``lib_pypy/transaction.py``, but much better is possible. For example + we could probably have an iterator-like concept that allows each loop + iteration to run in parallel. + Introduce new benchmarks ------------------------ 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 @@ -18,6 +18,9 @@ .. branch: numpypy_count_nonzero .. branch: numpy-refactor Remove numpy lazy evaluation and simplify everything +.. branch: numpy-reintroduce-jit-drivers +.. branch: numpy-fancy-indexing +Support for array[array-of-ints] in numpy .. branch: even-more-jit-hooks Implement better JIT hooks .. branch: virtual-arguments @@ -33,6 +36,11 @@ .. branch: stdlib-2.7.3 The stdlib was updated to version 2.7.3 +.. branch: numpypy-complex2 +Complex dtype support for numpy +.. branch: kill-someobject +major cleanups including killing some object support + .. "uninteresting" branches that we should just ignore for the whatsnew: .. branch: slightly-shorter-c diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py --- a/pypy/interpreter/astcompiler/assemble.py +++ b/pypy/interpreter/astcompiler/assemble.py @@ -65,24 +65,44 @@ self.marked = False self.have_return = False - def _post_order(self, blocks): - if self.marked: - return - self.marked = True - if self.next_block is not None: - self.next_block._post_order(blocks) - for instr in self.instructions: - if instr.has_jump: - instr.jump[0]._post_order(blocks) - blocks.append(self) - self.marked = True + def _post_order_see(self, stack, nextblock): + if nextblock.marked == 0: + nextblock.marked = 1 + stack.append(nextblock) def post_order(self): - """Return this block and its children in post order.""" - blocks = [] - self._post_order(blocks) - blocks.reverse() - return blocks + """Return this block and its children in post order. + This means that the graph of blocks is first cleaned up to + ignore back-edges, thus turning it into a DAG. Then the DAG + is linearized. For example: + + A --> B -\ => [A, D, B, C] From noreply at buildbot.pypy.org Sat Oct 13 11:25:11 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 13 Oct 2012 11:25:11 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (fijal, arigo) Message-ID: <20121013092511.556DA1C015F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58094:a1337ae1db6d Date: 2012-10-13 11:24 +0200 http://bitbucket.org/pypy/pypy/changeset/a1337ae1db6d/ Log: (fijal, arigo) Simplify things by storing jit_frame as a GCREF. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -287,41 +287,34 @@ assert 0 # jit_frame = self._execute_token(loop_token) - jit_frame = lltype.cast_opaque_ptr(JITFRAMEPTR, jit_frame) return jit_frame # return execute_token def get_latest_descr(self, jitframe): - assert lltype.typeOf(jitframe) == JITFRAMEPTR - opaqueframe = lltype.cast_opaque_ptr(llmemory.GCREF, jitframe) - fail_index = llimpl.frame_descr_index(opaqueframe) + assert lltype.typeOf(jitframe) == llmemory.GCREF + fail_index = llimpl.frame_descr_index(jitframe) return self.get_fail_descr_from_number(fail_index) def get_latest_value_int(self, jitframe, index): - assert lltype.typeOf(jitframe) == JITFRAMEPTR - opaqueframe = lltype.cast_opaque_ptr(llmemory.GCREF, jitframe) - return llimpl.frame_int_getvalue(opaqueframe, index) + assert lltype.typeOf(jitframe) == llmemory.GCREF + return llimpl.frame_int_getvalue(jitframe, index) def get_latest_value_ref(self, jitframe, index): - assert lltype.typeOf(jitframe) == JITFRAMEPTR - opaqueframe = lltype.cast_opaque_ptr(llmemory.GCREF, jitframe) - return llimpl.frame_ptr_getvalue(opaqueframe, index) + assert lltype.typeOf(jitframe) == llmemory.GCREF + return llimpl.frame_ptr_getvalue(jitframe, index) def get_latest_value_float(self, jitframe, index): - assert lltype.typeOf(jitframe) == JITFRAMEPTR - opaqueframe = lltype.cast_opaque_ptr(llmemory.GCREF, jitframe) - return llimpl.frame_float_getvalue(opaqueframe, index) + assert lltype.typeOf(jitframe) == llmemory.GCREF + return llimpl.frame_float_getvalue(jitframe, index) def get_latest_value_count(self, jitframe): - assert lltype.typeOf(jitframe) == JITFRAMEPTR - opaqueframe = lltype.cast_opaque_ptr(llmemory.GCREF, jitframe) - return llimpl.frame_get_value_count(opaqueframe) + assert lltype.typeOf(jitframe) == llmemory.GCREF + return llimpl.frame_get_value_count(jitframe) def grab_exc_value(self, jitframe): - assert lltype.typeOf(jitframe) == JITFRAMEPTR - opaqueframe = lltype.cast_opaque_ptr(llmemory.GCREF, jitframe) - return llimpl.grab_exc_value(opaqueframe) + assert lltype.typeOf(jitframe) == llmemory.GCREF + return llimpl.grab_exc_value(jitframe) def redirect_call_assembler(self, oldlooptoken, newlooptoken): if we_are_translated(): @@ -600,9 +593,8 @@ return lltype.malloc(LOOP_RUN_CONTAINER, 0) def force(self, jitframe): - assert lltype.typeOf(jitframe) == JITFRAMEPTR - opaqueframe = lltype.cast_opaque_ptr(llmemory.GCREF, jitframe) - fail_index = llimpl.force(opaqueframe) + assert lltype.typeOf(jitframe) == llmemory.GCREF + fail_index = llimpl.force(jitframe) return self.get_fail_descr_from_number(fail_index) diff --git a/pypy/jit/metainterp/jitframe.py b/pypy/jit/metainterp/jitframe.py --- a/pypy/jit/metainterp/jitframe.py +++ b/pypy/jit/metainterp/jitframe.py @@ -1,6 +1,5 @@ from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.annlowlevel import llhelper -from pypy.rpython.lltypesystem.rvirtualizable2 import JITFRAMEPTR _LONGLONGARRAY = lltype.GcArray(lltype.SignedLongLong) @@ -10,7 +9,7 @@ ('jf_excvalue', llmemory.GCREF), ('jf_nongcvalues', lltype.Ptr(_LONGLONGARRAY)), ('jf_gcvalues', lltype.Array(llmemory.GCREF))) -JITFRAMEPTR.TO.become(JITFRAME) +JITFRAMEPTR = lltype.Ptr(JITFRAME) # Constants used for the 'jit_frame' field of virtualizables/virtualrefs: # @@ -27,5 +26,8 @@ # to the actual CPU frame allocated by the generated assembler, # as fetched with the 'JIT_FRAME' resoperation. # -TOKEN_NONE = lltype.nullptr(JITFRAME) -TOKEN_TRACING_RESCALL = lltype.malloc(JITFRAME, 0, immortal=True, zero=True) +TOKEN_NONE = lltype.nullptr(llmemory.GCREF.TO) + +_JITFRAME_TRACING = lltype.GcStruct('JITFRAME_TRACING') +TOKEN_TRACING_RESCALL = lltype.cast_opaque_ptr( + llmemory.GCREF, lltype.malloc(_JITFRAME_TRACING, immortal=True)) diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py --- a/pypy/jit/metainterp/test/test_virtualizable.py +++ b/pypy/jit/metainterp/test/test_virtualizable.py @@ -42,7 +42,7 @@ XY = lltype.GcStruct( 'XY', ('parent', rclass.OBJECT), - ('jit_frame', JITFRAMEPTR), + ('jit_frame', llmemory.GCREF), ('inst_x', lltype.Signed), ('inst_node', lltype.Ptr(LLtypeMixin.NODE)), hints = {'virtualizable2_accessor': FieldListAccessor()}) @@ -57,7 +57,7 @@ def setup(self): xy = lltype.malloc(self.XY) - xy.jit_frame = lltype.nullptr(JITFRAMEPTR.TO) + xy.jit_frame = lltype.nullptr(llmemory.GCREF.TO) xy.parent.typeptr = self.xy_vtable return xy @@ -207,7 +207,7 @@ XY2 = lltype.GcStruct( 'XY2', ('parent', rclass.OBJECT), - ('jit_frame', JITFRAMEPTR), + ('jit_frame', llmemory.GCREF), ('inst_x', lltype.Signed), ('inst_l1', lltype.Ptr(lltype.GcArray(lltype.Signed))), ('inst_l2', lltype.Ptr(lltype.GcArray(lltype.Signed))), @@ -221,7 +221,7 @@ def setup2(self): xy2 = lltype.malloc(self.XY2) - xy2.jit_frame = lltype.nullptr(JITFRAMEPTR.TO) + xy2.jit_frame = lltype.nullptr(llmemory.GCREF.TO) xy2.parent.typeptr = self.xy2_vtable return xy2 @@ -394,7 +394,7 @@ def setup2sub(self): xy2 = lltype.malloc(self.XY2SUB) - xy2.parent.jit_frame = lltype.nullptr(JITFRAMEPTR.TO) + xy2.parent.jit_frame = lltype.nullptr(llmemory.GCREF.TO) xy2.parent.parent.typeptr = self.xy2_vtable return xy2 diff --git a/pypy/jit/metainterp/virtualizable.py b/pypy/jit/metainterp/virtualizable.py --- a/pypy/jit/metainterp/virtualizable.py +++ b/pypy/jit/metainterp/virtualizable.py @@ -221,20 +221,20 @@ def clear_jit_frame(virtualizable): virtualizable = cast_gcref_to_vtype(virtualizable) - if virtualizable.jit_frame: + if virtualizable.jit_frame != jitframe.TOKEN_NONE: force_now(virtualizable) - assert not virtualizable.jit_frame + assert virtualizable.jit_frame == jitframe.TOKEN_NONE self.clear_jit_frame = clear_jit_frame def tracing_before_residual_call(virtualizable): virtualizable = cast_gcref_to_vtype(virtualizable) - assert not virtualizable.jit_frame + assert virtualizable.jit_frame == jitframe.TOKEN_NONE virtualizable.jit_frame = jitframe.TOKEN_TRACING_RESCALL self.tracing_before_residual_call = tracing_before_residual_call def tracing_after_residual_call(virtualizable): virtualizable = cast_gcref_to_vtype(virtualizable) - if virtualizable.jit_frame: + if virtualizable.jit_frame != jitframe.TOKEN_NONE: # not modified by the residual call; assert that it is still # set to TOKEN_TRACING_RESCALL and clear it. assert virtualizable.jit_frame == jitframe.TOKEN_TRACING_RESCALL @@ -262,7 +262,7 @@ def is_token_nonnull_gcref(virtualizable): virtualizable = cast_gcref_to_vtype(virtualizable) - return bool(virtualizable.jit_frame) + return virtualizable.jit_frame != jitframe.TOKEN_NONE self.is_token_nonnull_gcref = is_token_nonnull_gcref def reset_token_gcref(virtualizable): @@ -276,7 +276,7 @@ def finish(self): # def force_virtualizable_if_necessary(virtualizable): - if virtualizable.jit_frame: + if virtualizable.jit_frame != jitframe.TOKEN_NONE: self.force_now(virtualizable) force_virtualizable_if_necessary._always_inline_ = True # diff --git a/pypy/rpython/lltypesystem/rvirtualizable2.py b/pypy/rpython/lltypesystem/rvirtualizable2.py --- a/pypy/rpython/lltypesystem/rvirtualizable2.py +++ b/pypy/rpython/lltypesystem/rvirtualizable2.py @@ -1,10 +1,9 @@ -from pypy.rpython.rmodel import inputconst -from pypy.rpython.lltypesystem import lltype, llmemory -from pypy.rpython.lltypesystem.rclass import InstanceRepr, OBJECTPTR +from pypy.rpython.lltypesystem import llmemory +from pypy.rpython.lltypesystem.rclass import InstanceRepr from pypy.rpython.rvirtualizable2 import AbstractVirtualizable2InstanceRepr -JITFRAMEPTR = lltype.Ptr(lltype.GcForwardReference()) +JITFRAMEPTR = llmemory.GCREF class Virtualizable2InstanceRepr(AbstractVirtualizable2InstanceRepr, InstanceRepr): @@ -14,14 +13,3 @@ if self.top_of_virtualizable_hierarchy: llfields.append(('jit_frame', JITFRAMEPTR)) return llfields - - #def set_vable(self, llops, vinst, force_cast=False): - # if self.top_of_virtualizable_hierarchy: - # if force_cast: - # vinst = llops.genop('cast_pointer', [vinst], resulttype=self) - # cname = inputconst(lltype.Void, 'vable_token') - # cvalue = inputconst(llmemory.GCREF, - # lltype.nullptr(llmemory.GCREF.TO)) - # llops.genop('setfield', [vinst, cname, cvalue]) - # else: - # self.rbase.set_vable(llops, vinst, force_cast=True) From noreply at buildbot.pypy.org Sat Oct 13 11:41:17 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 13 Oct 2012 11:41:17 +0200 (CEST) Subject: [pypy-commit] pypy numpy-reintroduce-zjit-tests: merge default\ Message-ID: <20121013094117.5D8B21C015F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: numpy-reintroduce-zjit-tests Changeset: r58095:aed59d1c47fb Date: 2012-10-13 11:27 +0200 http://bitbucket.org/pypy/pypy/changeset/aed59d1c47fb/ Log: merge default\ diff too long, truncating to 2000 out of 41943 lines diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,11 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - libpath = ctypes.util.find_library('db-4.5') - if not libpath: + for c in '56789': + libpath = ctypes.util.find_library('db-4.%s' % c) + if libpath: + break + else: raise ImportError("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' diff --git a/py/_io/capture.py b/py/_io/capture.py --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -176,7 +176,7 @@ class StdCaptureFD(Capture): - """ This class allows to capture writes to FD1 and FD2 + """ This class allows capturing writes to FD1 and FD2 and may connect a NULL file to FD0 (and prevent reads from sys.stdin). If any of the 0,1,2 file descriptors is invalid it will not be captured. @@ -267,8 +267,8 @@ return l class StdCapture(Capture): - """ This class allows to capture writes to sys.stdout|stderr "in-memory" - and will raise errors on tries to read from sys.stdin. It only + """ This class allows capturing writes to sys.stdout|stderr "in-memory" + and will raise errors on read attempts from sys.stdin. It only modifies sys.stdout|stderr|stdin attributes and does not touch underlying File Descriptors (use StdCaptureFD for that). """ diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -1,9 +1,8 @@ -import sys import types -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception +from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - format_someobject_error, AnnotatorError) + AnnotatorError, gather_error, ErrorWrapper) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -38,22 +37,9 @@ self.links_followed = {} # set of links that have ever been followed self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + self.blocked_blocks = {} # set of {blocked_block: (graph, index)} + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +63,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +164,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +181,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +192,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +242,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +265,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +283,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +333,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -414,7 +340,7 @@ self.flowin(graph, block) except BlockedInference, e: self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, e.opindex) except Exception, e: # hack for debug tools only if not hasattr(e, '__annotator_block'): @@ -433,25 +359,24 @@ self.pendingblocks[block] = graph assert block in self.annotated self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -471,14 +396,11 @@ for i in range(len(block.operations)): try: self.bookkeeper.enter((graph, block, i)) - self.consider_op(block.operations[i]) + self.consider_op(block, i) finally: self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +484,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +494,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +530,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell @@ -653,7 +572,8 @@ #___ creating the annotations based on operations ______ - def consider_op(self, op): + def consider_op(self, block, opindex): + op = block.operations[opindex] argcells = [self.binding(a) for a in op.args] consider_meth = getattr(self,'consider_op_'+op.opname, None) @@ -668,16 +588,18 @@ # boom -- in the assert of setbinding() for arg in argcells: if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op) + raise BlockedInference(self, op, opindex) try: resultcell = consider_meth(*argcells) - except Exception: + except Exception, e: graph = self.bookkeeper.position_key[0] - raise_nicer_exception(op, str(graph)) + e.args = e.args + ( + ErrorWrapper(gather_error(self, graph, block, opindex)),) + raise if resultcell is None: resultcell = self.noreturnvalue(op) elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op) # the operation cannot succeed + raise BlockedInference(self, op, opindex) # the operation cannot succeed assert isinstance(resultcell, annmodel.SomeObject) assert isinstance(op.result, Variable) self.setbinding(op.result, resultcell) # bind resultcell to op.result @@ -728,13 +650,14 @@ """This exception signals the type inference engine that the situation is currently blocked, and that it should try to progress elsewhere.""" - def __init__(self, annotator, op): + def __init__(self, annotator, op, opindex): self.annotator = annotator try: self.break_at = annotator.bookkeeper.position_key except AttributeError: self.break_at = None self.op = op + self.opindex = opindex def __repr__(self): if not self.break_at: diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,15 +29,6 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', 'truediv', 'floordiv', 'divmod', 'pow', @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -238,7 +201,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -564,14 +550,30 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - return SomeObject() + raise UnionError("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): return SomeTuple(items = tup1.items + tup2.items) + def eq(tup1tup2): + tup1tup2.union() + return s_Bool + ne = eq + + def lt((tup1, tup2)): + raise Exception("unsupported: (...) < (...)") + def le((tup1, tup2)): + raise Exception("unsupported: (...) <= (...)") + def gt((tup1, tup2)): + raise Exception("unsupported: (...) > (...)") + def ge((tup1, tup2)): + raise Exception("unsupported: (...) >= (...)") + class __extend__(pairtype(SomeDict, SomeDict)): @@ -723,8 +725,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -764,7 +765,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -778,7 +779,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -806,7 +807,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,7 +10,7 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef @@ -148,7 +148,6 @@ self.descs = {} # map Python objects to their XxxDesc wrappers self.methoddescs = {} # map (funcdesc, classdef) to the MethodDesc self.classdefs = [] # list of all ClassDefs - self.pbctypes = {} self.seen_mutable = {} self.listdefs = {} # map position_keys to ListDefs self.dictdefs = {} # map position_keys to DictDefs @@ -167,9 +166,6 @@ self.stats = Stats(self) - # used in SomeObject.__new__ for keeping debugging info - self._isomeobject_coming_from = identity_dict() - delayed_imports() def count(self, category, *args): @@ -275,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() @@ -325,8 +320,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -445,6 +438,12 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if (x is type(None) or # add cases here if needed + x.__module__ == 'pypy.rpython.lltypesystem.lltype'): + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) 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 @@ -455,20 +454,13 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) - elif hasattr(x, '_freeze_') and x._freeze_(): + result = SomePBC([self.getdesc(x)]) + elif hasattr(x, '_freeze_'): + assert x._freeze_() is True # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method # returns True, the instance is considered immutable and becomes @@ -476,16 +468,18 @@ result = SomePBC([self.getdesc(x)]) elif hasattr(x, '__class__') \ and x.__class__.__module__ != '__builtin__': + if hasattr(x, '_cleanup_'): + x._cleanup_() self.see_mutable(x) result = SomeInstance(self.getuniqueclassdef(x.__class__)) elif x is None: return s_None else: - result = SomeObject() + raise Exception("Don't know how to represent %r" % (x,)) if need_const: result.const = x return result - + def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: @@ -509,8 +503,10 @@ elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) - elif (hasattr(pyobj.im_self, '_freeze_') and - pyobj.im_self._freeze_()): # method of frozen + if hasattr(pyobj.im_self, '_cleanup_'): + pyobj.im_self._cleanup_() + if hasattr(pyobj.im_self, '_freeze_'): # method of frozen + assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc(self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc @@ -529,9 +525,9 @@ name) else: # must be a frozen pre-built constant, but let's check - try: - assert pyobj._freeze_() - except AttributeError: + if hasattr(pyobj, '_freeze_'): + assert pyobj._freeze_() is True + else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: @@ -551,11 +547,7 @@ return False def getfrozen(self, pyobj): - result = description.FrozenDesc(self, pyobj) - cls = result.knowntype - if cls not in self.pbctypes: - self.pbctypes[cls] = True - return result + return description.FrozenDesc(self, pyobj) def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, flags={}): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -150,7 +150,7 @@ def builtin_isinstance(s_obj, s_type, variables=None): - r = SomeBool() + r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,8 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + + if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -247,13 +247,16 @@ defs_s = [] if graph is None: signature = self.signature - defaults = self.defaults + defaults = self.defaults else: signature = graph.signature - defaults = graph.defaults + defaults = graph.defaults if defaults: for x in defaults: - defs_s.append(self.bookkeeper.immutablevalue(x)) + if x is NODEFAULT: + defs_s.append(None) + else: + defs_s.append(self.bookkeeper.immutablevalue(x)) try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,8 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype + immutable = False knowntype = object - immutable = False + + def __init__(self): + assert type(self) is not SomeObject def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -105,60 +106,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: - self = new(cls, *args, **kw) - if DEBUG: - try: - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - position_key = bookkeeper.position_key - except AttributeError: - pass - else: - bookkeeper._isomeobject_coming_from[self] = position_key, None + def can_be_none(self): + return True + + def nonnoneify(self): return self - def origin(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] - origin = property(origin) - def caused_by_merge(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] - def set_caused_by_merge(self, nvalue): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return - bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue - caused_by_merge = property(caused_by_merge, set_caused_by_merge) - del set_caused_by_merge +class SomeType(SomeObject): + "Stands for a type. We might not be sure which one it is." + knowntype = type + immutable = True def can_be_none(self): - return True - - def nonnoneify(self): - return self + return False class SomeFloat(SomeObject): "Stands for a float or an integer." @@ -517,6 +486,7 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) @@ -710,14 +680,8 @@ # this is just a performance shortcut if s1 != s2: s1 = pair(s1, s2).union() - if DEBUG: - if s1.caused_by_merge is None and len(somevalues) > 1: - s1.caused_by_merge = somevalues return s1 -def isdegenerated(s_value): - return s_value.__class__ is SomeObject and s_value.knowntype is not type - # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -10,7 +10,6 @@ class BasicAnnotatorPolicy(object): - allow_someobjects = True def event(pol, bookkeeper, what, *args): pass @@ -80,6 +79,3 @@ def specialize__ll_and_arg(pol, *args): from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args) - -class StrictAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -3,9 +3,9 @@ from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF -from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF + unionof, SomeUnicodeString, SomeType +from pypy.annotation.listdef import ListDef +from pypy.annotation.dictdef import DictDef _annotation_cache = {} @@ -78,24 +78,18 @@ return SomeString() elif t is unicode: return SomeUnicodeString() - elif t is list: - return SomeList(MOST_GENERAL_LISTDEF) - elif t is dict: - return SomeDict(MOST_GENERAL_DICTDEF) - # can't do tuple elif t is types.NoneType: return s_None elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) - elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes: + elif t is type: + return SomeType() + elif bookkeeper and not hasattr(t, '_freeze_'): classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) else: - o = SomeObject() - if t != object: - o.knowntype = t - return o + raise AssertionError("annotationoftype(%r)" % (t,)) class Sig(object): diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -24,7 +24,7 @@ assert isinstance(s_list, annmodel.SomeList) return s_list.listdef.listitem.s_value -def somelist(s_type=annmodel.SomeObject()): +def somelist(s_type): return annmodel.SomeList(ListDef(None, s_type)) def dictkey(s_dict): @@ -35,7 +35,7 @@ assert isinstance(s_dict, annmodel.SomeDict) return s_dict.dictdef.dictvalue.s_value -def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()): +def somedict(s_key, s_value): return annmodel.SomeDict(DictDef(None, s_key, s_value)) @@ -205,15 +205,6 @@ annmodel.SomeInteger() ]) - def test_inheritance2(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet._inheritance_nonrunnable, []) - # result should be exactly: - assert s == annmodel.SomeTuple([ - annmodel.SomeInteger(), - annmodel.SomeObject() - ]) - def test_poor_man_range(self): a = self.RPythonAnnotator() s = a.build_types(snippet.poor_man_range, [int]) @@ -336,9 +327,13 @@ def test_flow_type_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_type_info, [object]) + s = a.build_types(snippet.flow_type_info, [int]) a.simplify() - #a.translator.view() + assert s.knowntype == int + + a = self.RPythonAnnotator() + s = a.build_types(snippet.flow_type_info, [str]) + a.simplify() assert s.knowntype == int def test_flow_type_info_2(self): @@ -351,7 +346,7 @@ def test_flow_usertype_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_usertype_info, [object]) + s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit]) #a.translator.view() assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit) @@ -363,13 +358,6 @@ assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit) - def test_flow_identity_info(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_identity_info, [object, object]) - a.simplify() - #a.translator.view() - assert s == a.bookkeeper.immutablevalue((None, None)) - def test_mergefunctions(self): a = self.RPythonAnnotator() s = a.build_types(snippet.mergefunctions, [int]) @@ -431,11 +419,11 @@ # the annotator (it doesn't check that they operate property, though) for example, methname, s_example in [ ('', 'join', annmodel.SomeString()), - ([], 'append', somelist()), - ([], 'extend', somelist()), - ([], 'reverse', somelist()), - ([], 'insert', somelist()), - ([], 'pop', somelist()), + ([], 'append', somelist(annmodel.s_Int)), + ([], 'extend', somelist(annmodel.s_Int)), + ([], 'reverse', somelist(annmodel.s_Int)), + ([], 'insert', somelist(annmodel.s_Int)), + ([], 'pop', somelist(annmodel.s_Int)), ]: constmeth = getattr(example, methname) s_constmeth = iv(constmeth) @@ -497,12 +485,12 @@ def test_simple_slicing(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_slice, [list]) + s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeList) def test_simple_iter_list(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_iter, [list]) + s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeIterator) def test_simple_iter_next(self): @@ -542,11 +530,6 @@ assert isinstance(dictkey(s), annmodel.SomeInteger) assert isinstance(dictvalue(s), annmodel.SomeInteger) - a = self.RPythonAnnotator() - s = a.build_types(snippet.dict_update, [str]) - assert not isinstance(dictkey(s), annmodel.SomeString) - assert not isinstance(dictvalue(s), annmodel.SomeString) - def test_dict_update_2(self): a = self.RPythonAnnotator() def g(n): @@ -568,7 +551,7 @@ def test_dict_keys2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_keys2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_values(self): a = self.RPythonAnnotator() @@ -578,7 +561,7 @@ def test_dict_values2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_items(self): a = self.RPythonAnnotator() @@ -643,25 +626,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_bltin_code_frame_confusion(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_confusion,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - # annotator confused by original bltin code/frame setup, we just get SomeObject here - assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - - def test_bltin_code_frame_reorg(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_reorg,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - assert isinstance(a.binding(f_flowgraph.getreturnvar()), - annmodel.SomeInteger) - assert isinstance(a.binding(g_flowgraph.getreturnvar()), - annmodel.SomeString) - def test_propagation_of_fresh_instances_through_attrs(self): a = self.RPythonAnnotator() s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int]) @@ -748,14 +712,15 @@ assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc) def test_type_is(self): - class C(object): + class B(object): + pass + class C(B): pass def f(x): - if type(x) is C: - return x - raise Exception - a = self.RPythonAnnotator() - s = a.build_types(f, [object]) + assert type(x) is C + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) def test_ann_assert(self): @@ -793,24 +758,30 @@ return None a = self.RPythonAnnotator() - s = a.build_types(f, [list]) + s = a.build_types(f, [somelist(annmodel.s_Int)]) assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list def test_freeze_protocol(self): class Stuff: - def __init__(self, flag): + def __init__(self): self.called = False - self.flag = flag def _freeze_(self): self.called = True - return self.flag - myobj = Stuff(True) + return True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - myobj = Stuff(False) + + def test_cleanup_protocol(self): + class Stuff: + def __init__(self): + self.called = False + def _cleanup_(self): + self.called = True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called @@ -854,7 +825,7 @@ def f(a,b): return bool(a) or bool(b) a = self.RPythonAnnotator() - s = a.build_types(f, [int,list]) + s = a.build_types(f, [int, somelist(annmodel.s_Int)]) assert s.knowntype == bool def test_float(self): @@ -1299,22 +1270,6 @@ assert isinstance(s_item, annmodel.SomeInstance) assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - def test_assert_type_is_list_doesnt_lose_info(self): - class T(object): - pass - def g(l): - assert type(l) is list - return l - def f(): - l = [T()] - return g(l) - a = self.RPythonAnnotator() - s = a.build_types(f, []) - s_item = listitem(s) - assert isinstance(s_item, annmodel.SomeInstance) - assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - - def test_int_str_mul(self): def f(x,a,b): return a*x+x*b @@ -1395,11 +1350,10 @@ except KeyError: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.const = KeyError t.is_type_of = [ev] assert a.binding(et) == t @@ -1412,11 +1366,10 @@ except: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t @@ -1448,11 +1401,10 @@ finally: h() a = self.RPythonAnnotator() - a.build_types(f, [int, list]) + a.build_types(f, [int, somelist(annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) @@ -1474,24 +1426,11 @@ a.build_types(f, []) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_sys_attrs(self): - def f(): - return sys.argv[0] - a = self.RPythonAnnotator() - try: - oldvalue = sys.argv - sys.argv = [] - s = a.build_types(f, []) - finally: - sys.argv = oldvalue - assert s is not None - def test_pow(self): def f(n): n **= 2 @@ -1523,7 +1462,6 @@ a = self.RPythonAnnotator() 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)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] def test_is_true_coalesce2(self): def f(a,b,a1,b1,c,d,e): @@ -1532,9 +1470,12 @@ return d,c return e,c a = self.RPythonAnnotator() - s = a.build_types(f, [int, str, float, list, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) - assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] + s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int), + 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_coalesce_sanity(self): def f(a): @@ -1954,16 +1895,7 @@ t = type(x) return issubclass(t, A) - def f(): - x = g(1) - y = g(0) - return x or y - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert s.knowntype == bool - assert not s.is_constant() - a = self.RPythonAnnotator() - # sanity check + a = self.RPythonAnnotator() x = annmodel.SomeInteger() x.const = 1 s = a.build_types(g, [x]) @@ -2383,8 +2315,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int]) - assert s.__class__ == annmodel.SomeObject - assert s.knowntype == type + assert isinstance(s, annmodel.SomeType) def test_annotate_iter_empty_container(self): def f(): @@ -3105,7 +3036,6 @@ v = -maxint return intmask(v * 10) P = policy.AnnotatorPolicy() - P.allow_someobjects = False a = self.RPythonAnnotator(policy=P) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) @@ -3896,6 +3826,24 @@ s = a.build_types(fn, [annmodel.SomeChar()]) assert s == annmodel.SomeChar() + def test_isinstance_double_const(self): + class X(object): + def _freeze_(self): + return True + + x = X() + + def f(i): + if i: + x1 = x + else: + x1 = None + print "hello" # this is to force the merge of blocks + return isinstance(x1, X) + + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeBool) def g(n): return [0,1,2,n] diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -2,20 +2,20 @@ import autopath import py from pypy.annotation.model import * -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF +from pypy.annotation.listdef import ListDef from pypy.rpython.ootypesystem.ootype import ROOT listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) -s1 = SomeObject() +s1 = SomeType() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s1,s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s1, s2, s3, s4, s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -42,7 +42,7 @@ def test_equality(): assert s1 != s2 != s3 != s4 != s5 != s6 - assert s1 == SomeObject() + assert s1 == SomeType() assert s2 == SomeInteger(nonneg=True) assert s3 == SomeInteger(nonneg=False) assert s4 == SomeList(listdef1) @@ -51,19 +51,11 @@ def test_contains(): assert ([(s,t) for s in slist for t in slist if s.contains(t)] == - [(s1,s1), (s1,s2), (s1,s3), (s1,s4), (s1,s6), - (s2,s2), (s2,s6), - (s3,s2), (s3,s3), (s3,s6), - (s4,s4), (s4,s6), - (s6,s6)]) - -def test_union(): - assert ([unionof(s,t) for s in slist for t in slist] == - [s1, s1, s1, s1, s1, - s1, s2, s3, s1, s2, - s1, s3, s3, s1, s3, - s1, s1, s1, s4, s4, - s1, s2, s3, s4, s6]) + [(s1, s1), (s1, s6), + (s2, s2), (s2, s6), + (s3, s2), (s3, s3), (s3, s6), + (s4, s4), (s4, s6), + (s6, s6)]) def test_commonbase_simple(): class A0: @@ -100,9 +92,10 @@ def test_list_contains(): listdef1 = ListDef(None, SomeInteger(nonneg=True)) s1 = SomeList(listdef1) - s2 = SomeList(MOST_GENERAL_LISTDEF) + listdef2 = ListDef(None, SomeInteger(nonneg=False)) + s2 = SomeList(listdef2) assert s1 != s2 - assert s2.contains(s1) + assert not s2.contains(s1) assert s1 != s2 assert not s1.contains(s2) assert s1 != s2 diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -7,7 +7,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -39,14 +39,7 @@ def type(obj, *moreargs): if moreargs: raise Exception, 'type() called with more than one argument' - if obj.is_constant(): - if isinstance(obj, SomeInstance): - r = SomePBC([obj.classdef.classdesc]) - else: - r = immutablevalue(obj.knowntype) - else: - r = SomeObject() - r.knowntype = type + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator @@ -133,9 +126,6 @@ def float(obj): return SomeFloat() - def long(obj): - return SomeObject() # XXX - def delattr(obj, s_attr): if obj.__class__ != SomeObject or obj.knowntype != object: getbookkeeper().warning( @@ -154,18 +144,17 @@ def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - s_method = obj.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)) - else: - getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' % - (obj, s_attr)) - return SomeObject() + 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)) + attr = s_attr.const + s_method = obj.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)) getattr.can_only_throw = [] def bind_callables_under(obj, classdef, name): diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -2,9 +2,9 @@ """ Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME -Print a report for the static data informations contained in FILENAME +Print a report for the static data information contained in FILENAME -The static data informations are saved in the file staticdata.info when +The static data information is saved in the file staticdata.info when passing --dump_static_data_info to translate.py. Options: diff --git a/pypy/bin/translatorshell.py b/pypy/bin/translatorshell.py --- a/pypy/bin/translatorshell.py +++ b/pypy/bin/translatorshell.py @@ -8,10 +8,10 @@ Example: - t = Translation(func) + t = Translation(func, [int]) # pass the list of args types t.view() # control flow graph - t.annotate([int]) # pass the list of args types + t.annotate() t.view() # graph + annotations under the mouse t.rtype() # use low level operations diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py --- a/pypy/config/test/test_config.py +++ b/pypy/config/test/test_config.py @@ -111,8 +111,8 @@ else: return 'foo' - t = Translation(f) - t.rtype([int]) + t = Translation(f, [int]) + t.rtype() block = t.context.graphs[0].startblock assert len(block.exits[0].target.operations) == 0 diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -129,8 +129,6 @@ # misc BoolOption("verbose", "Print extra information", default=False), - BoolOption("debug", "Record extra annotation information", - cmdline="-d --debug", default=True), BoolOption("insist", "Try hard to go on RTyping", default=False, cmdline="--insist"), StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -101,15 +101,7 @@ def maketestobjspace(config=None): if config is None: config = make_config(option) - try: - space = make_objspace(config) - except OperationError, e: - check_keyboard_interrupt(e) - if option.verbose: - import traceback - traceback.print_exc() - py.test.fail("fatal: cannot initialize objspace: %r" % - (config.objspace.name,)) + space = make_objspace(config) space.startup() # Initialize all builtin modules space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), appsupport.build_pytest_assertion(space)) diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -238,7 +238,7 @@ interpreter`_. .. _`documentation index`: index.html#project-documentation -.. _`getting-started`: getting-started.html +.. _`getting-started`: getting-started-dev.html .. _`PyPy's approach to virtual machine construction`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dls2006/pypy-vm-construction.pdf .. _`the translation document`: translation.html .. _`RPython toolchain`: translation.html diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -9,7 +9,7 @@ `import` statements:: from pypy.interpreter.baseobjspace import Wrappable - from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w @@ -41,9 +41,6 @@ llexternal functions. For a typical usage, see `pypy.rlib.rsocket.RSocket.getsockopt_int`. -- Support context managers and the `with` statement. This could be a workaround - before the previous point is available. - Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -27,7 +27,7 @@ ``pypy/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: - >>> t = Translation(snippet.is_perfect_number) + >>> t = Translation(snippet.is_perfect_number, [int]) >>> t.view() After that, the graph viewer pops up, that lets you interactively inspect the @@ -40,7 +40,7 @@ We have a type annotator that can completely infer types for functions like ``is_perfect_number`` (as well as for much larger examples):: - >>> t.annotate([int]) + >>> t.annotate() >>> t.view() Move the mouse over variable names (in red) to see their inferred types. @@ -74,8 +74,8 @@ >>> def myfunc(a, b): return a+b ... - >>> t = Translation(myfunc) - >>> t.annotate([int, int]) + >>> t = Translation(myfunc, [int, int]) + >>> t.annotate() >>> f = t.compile_cli() # or compile_jvm() >>> f(4, 5) 9 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 @@ -36,6 +36,11 @@ .. branch: stdlib-2.7.3 The stdlib was updated to version 2.7.3 +.. branch: numpypy-complex2 +Complex dtype support for numpy +.. branch: kill-someobject +major cleanups including killing some object support + .. "uninteresting" branches that we should just ignore for the whatsnew: .. branch: slightly-shorter-c diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -719,8 +719,15 @@ # done by a method call on w_two (and not on w_one, because of the # expected programming style where we say "if x is None" or # "if x is object"). + assert w_two is not None return w_two.is_w(self, w_one) + def is_none(self, w_obj): + """ mostly for checking inputargs that have unwrap_spec and + can accept both w_None and None + """ + return w_obj is None or self.is_w(w_obj, self.w_None) + def id(self, w_obj): w_result = w_obj.immutable_unique_id(self) if w_result is None: @@ -804,7 +811,7 @@ interpreter class (a subclass of Wrappable). """ assert RequiredClass is not None - if can_be_None and self.is_w(w_obj, self.w_None): + if can_be_None and self.is_none(w_obj): return None obj = self.interpclass_w(w_obj) if not isinstance(obj, RequiredClass): # or obj is None diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -205,11 +205,11 @@ code = space.interp_w(Code, w_code) if not space.is_true(space.isinstance(w_globals, space.w_dict)): raise OperationError(space.w_TypeError, space.wrap("expected dict")) - if not space.is_w(w_name, space.w_None): + if not space.is_none(w_name): name = space.str_w(w_name) else: name = None - if not space.is_w(w_argdefs, space.w_None): + if not space.is_none(w_argdefs): defs_w = space.fixedview(w_argdefs) else: defs_w = [] @@ -217,7 +217,7 @@ from pypy.interpreter.pycode import PyCode if isinstance(code, PyCode): nfreevars = len(code.co_freevars) - if space.is_w(w_closure, space.w_None) and nfreevars == 0: + if space.is_none(w_closure) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) @@ -244,7 +244,7 @@ # delicate _all = {'': None} - def _freeze_(self): + def _cleanup_(self): from pypy.interpreter.gateway import BuiltinCode if isinstance(self.code, BuiltinCode): # we have been seen by other means so rtyping should not choke @@ -343,7 +343,7 @@ def fget_func_defaults(self, space): values_w = self.defs_w # the `None in values_w` check here is to ensure that interp-level - # functions with a default of NoneNotWrapped do not get their defaults + # functions with a default of None do not get their defaults # exposed at applevel if not values_w or None in values_w: return space.w_None @@ -424,11 +424,12 @@ w_res = space.w_None return w_res + def descr_function_get(space, w_function, w_obj, w_cls=None): """functionobject.__get__(obj[, type]) -> method""" # this is not defined as a method on Function because it's generally # useful logic: w_function can be any callable. It is used by Method too. - asking_for_bound = (space.is_w(w_cls, space.w_None) or + asking_for_bound = (space.is_none(w_cls) or not space.is_w(w_obj, space.w_None) or space.is_w(w_cls, space.type(space.w_None))) if asking_for_bound: @@ -445,12 +446,15 @@ self.space = space self.w_function = w_function self.w_instance = w_instance # or None + if w_class is None: + w_class = space.w_None self.w_class = w_class # possibly space.w_None - def descr_method__new__(space, w_subtype, w_function, w_instance, w_class=None): + def descr_method__new__(space, w_subtype, w_function, w_instance, + w_class=None): if space.is_w(w_instance, space.w_None): w_instance = None - if w_instance is None and space.is_w(w_class, space.w_None): + if w_instance is None and space.is_none(w_class): raise OperationError(space.w_TypeError, space.wrap("unbound methods must have class")) method = space.allocate_instance(Method, w_subtype) @@ -610,7 +614,7 @@ self.w_function = w_function def descr_classmethod_get(self, space, w_obj, w_klass=None): - if space.is_w(w_klass, space.w_None): + if space.is_none(w_klass): w_klass = space.type(w_obj) return space.wrap(Method(space, self.w_function, w_klass, space.w_None)) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -7,31 +7,29 @@ """ -import types, sys, os -from pypy.tool.compat import md5 +import sys +import os +import types -NoneNotWrapped = object() +import py -from pypy.tool.sourcetools import func_with_new_name +from pypy.interpreter.eval import Code +from pypy.interpreter.argument import Arguments, Signature +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, + SpaceCache, DescrMismatch) from pypy.interpreter.error import OperationError -from pypy.interpreter import eval -from pypy.interpreter.function import Function, Method, ClassMethod -from pypy.interpreter.function import FunctionWithFixedCode -from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable -from pypy.interpreter.baseobjspace import Wrappable, SpaceCache, DescrMismatch -from pypy.interpreter.argument import Arguments, Signature -from pypy.tool.sourcetools import NiceCompile, compile2 -from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from pypy.rlib import rstackovf from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.tool.sourcetools import func_with_new_name, compile2 + # internal non-translatable parts: -import py - class SignatureBuilder(object): "NOT_RPYTHON" def __init__(self, func=None, argnames=None, varargname=None, - kwargname=None, name = None): + kwargname=None, name=None): self.func = func if func is not None: self.name = func.__name__ @@ -60,10 +58,12 @@ if isinstance(el, str): getattr(self, "visit_%s" % (el,))(el, *args) elif isinstance(el, tuple): - if el[0] == 'self': + if el[0] == 'INTERNAL:self': self.visit_self(el[1], *args) else: - self.visit_function(el, *args) + assert False, "not supported any more, use WrappedDefault" + elif isinstance(el, WrappedDefault): + self.visit__W_Root(W_Root, *args) elif isinstance(el, type): for typ in self.bases_order: if issubclass(el, typ): @@ -81,8 +81,8 @@ for el in unwrap_spec: dispatch(el, *extra) + class UnwrapSpecEmit(UnwrapSpecRecipe): - def __init__(self): self.n = 0 self.miniglobals = {} @@ -97,10 +97,11 @@ self.miniglobals[name] = obj return name + #________________________________________________________________ + class UnwrapSpec_Check(UnwrapSpecRecipe): - # checks for checking interp2app func argument names wrt unwrap_spec # and synthetizing an app-level signature @@ -108,9 +109,6 @@ self.func = original_sig.func self.orig_arg = iter(original_sig.argnames).next - def visit_function(self, (func, cls), app_sig): - self.dispatch(cls, app_sig) - def visit_self(self, cls, app_sig): self.visit__Wrappable(cls, app_sig) @@ -168,8 +166,8 @@ app_sig.append(argname[2:]) def visit__Arguments(self, el, app_sig): - argname = self.orig_arg() - assert app_sig.varargname is None,( + self.orig_arg() + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = 'args' app_sig.kwargname = 'keywords' @@ -179,7 +177,7 @@ assert argname.endswith('_w'), ( "rest arguments arg %s of built-in function %r should end in '_w'" % (argname, self.func)) - assert app_sig.varargname is None,( + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = argname[:-2] @@ -188,7 +186,7 @@ assert argname.startswith('w_'), ( "rest arguments arg %s of built-in function %r should start 'w_'" % (argname, self.func)) - assert app_sig.varargname is None,( + assert app_sig.varargname is None, ( "built-in function %r has conflicting rest args specs" % self.func) app_sig.varargname = argname[2:] @@ -208,10 +206,6 @@ def scopenext(self): return "scope_w[%d]" % self.succ() From noreply at buildbot.pypy.org Sat Oct 13 11:41:18 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 13 Oct 2012 11:41:18 +0200 (CEST) Subject: [pypy-commit] pypy numpy-reintroduce-zjit-tests: (arigo, fijal) support static methods for mixins Message-ID: <20121013094118.868AC1C015F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: numpy-reintroduce-zjit-tests Changeset: r58096:d544c05cb373 Date: 2012-10-13 11:40 +0200 http://bitbucket.org/pypy/pypy/changeset/d544c05cb373/ Log: (arigo, fijal) support static methods for mixins diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -3,7 +3,7 @@ from pypy.interpreter.pycode import cpython_code_signature from pypy.interpreter.argument import rawshape from pypy.interpreter.argument import ArgErr -from pypy.tool.sourcetools import valid_identifier +from pypy.tool.sourcetools import valid_identifier, func_with_new_name from pypy.tool.pairtype import extendabletype class CallFamily(object): @@ -486,6 +486,10 @@ # is of type FunctionType. But bookkeeper.immutablevalue() # will do the right thing in s_get_value(). + if isinstance(value, staticmethod) and mixin: + value = staticmethod(func_with_new_name(value.__func__, + value.__func__.__name__)) + if type(value) in MemberDescriptorTypes: # skip __slots__, showing up in the class as 'member' objects return From noreply at buildbot.pypy.org Sat Oct 13 12:07:26 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 13 Oct 2012 12:07:26 +0200 (CEST) Subject: [pypy-commit] pypy default: an attempt to improve the fancy indexing situation untested Message-ID: <20121013100726.44B571C0253@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58097:c62c6904e304 Date: 2012-10-13 12:04 +0200 http://bitbucket.org/pypy/pypy/changeset/c62c6904e304/ Log: an attempt to improve the fancy indexing situation untested 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 @@ -424,39 +424,44 @@ self._done = True @jit.unroll_safe - def get_index(self, space): - return [space.wrap(i) for i in self.indexes] + def get_index(self, space, shapelen): + return [space.wrap(self.indexes[i]) for i in range(shapelen)] getitem_int_driver = jit.JitDriver(name = 'numpy_getitem_int', - greens = ['shapelen', 'indexlen', 'dtype'], + greens = ['shapelen', 'indexlen', + 'prefixlen', 'dtype'], reds = ['arr', 'res', 'iter', 'indexes_w', 'prefix_w']) def getitem_array_int(space, arr, res, iter_shape, indexes_w, prefix_w): shapelen = len(iter_shape) + prefixlen = len(prefix_w) indexlen = len(indexes_w) dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) + indexlen = len(indexes_w) while not iter.done(): getitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, dtype=dtype, arr=arr, res=res, iter=iter, indexes_w=indexes_w, - prefix_w=prefix_w) + prefix_w=prefix_w, + prefixlen=prefixlen) # prepare the index - index_w = [None] * len(indexes_w) - for i in range(len(indexes_w)): + index_w = [None] * indexlen + for i in range(indexlen): if iter.idx_w[i] is not None: index_w[i] = iter.idx_w[i].getitem() else: index_w[i] = indexes_w[i] - res.descr_setitem(space, space.newtuple(prefix_w + - iter.get_index(space)), + res.descr_setitem(space, space.newtuple(prefix_w[:prefixlen] + + iter.get_index(space, shapelen)), arr.descr_getitem(space, space.newtuple(index_w))) iter.next() return res setitem_int_driver = jit.JitDriver(name = 'numpy_setitem_int', - greens = ['shapelen', 'indexlen', 'dtype'], + greens = ['shapelen', 'indexlen', + 'prefixlen', 'dtype'], reds = ['arr', 'iter', 'indexes_w', 'prefix_w', 'val_arr']) @@ -464,21 +469,24 @@ prefix_w): shapelen = len(iter_shape) indexlen = len(indexes_w) + prefixlen = len(prefix_w) dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): setitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, dtype=dtype, arr=arr, iter=iter, indexes_w=indexes_w, - prefix_w=prefix_w, val_arr=val_arr) + prefix_w=prefix_w, val_arr=val_arr, + prefixlen=prefixlen) # prepare the index - index_w = [None] * len(indexes_w) - for i in range(len(indexes_w)): + index_w = [None] * indexlen + for i in range(indexlen): if iter.idx_w[i] is not None: index_w[i] = iter.idx_w[i].getitem() else: index_w[i] = indexes_w[i] - w_idx = space.newtuple(prefix_w + iter.get_index(space)) + w_idx = space.newtuple(prefix_w[:prefixlen] + iter.get_index(space, + shapelen)) arr.descr_setitem(space, space.newtuple(index_w), val_arr.descr_getitem(space, w_idx)) iter.next() From noreply at buildbot.pypy.org Sat Oct 13 12:07:27 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 13 Oct 2012 12:07:27 +0200 (CEST) Subject: [pypy-commit] pypy default: merge Message-ID: <20121013100727.751FE1C0253@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58098:53cf1bf9fc14 Date: 2012-10-13 12:07 +0200 http://bitbucket.org/pypy/pypy/changeset/53cf1bf9fc14/ Log: merge diff --git a/pypy/module/oracle/interp_cursor.py b/pypy/module/oracle/interp_cursor.py --- a/pypy/module/oracle/interp_cursor.py +++ b/pypy/module/oracle/interp_cursor.py @@ -1,5 +1,4 @@ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, unwrap_spec diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -1,7 +1,6 @@ -import sys -from pypy.interpreter import gateway from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import interp2app from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, SMM @@ -163,9 +162,9 @@ bytearray(sequence) -> bytearray initialized from sequence\'s items If the argument is a bytearray, the return value is the same object.''', - __new__ = gateway.interp2app(descr__new__), + __new__ = interp2app(descr__new__), __hash__ = None, - __reduce__ = gateway.interp2app(descr_bytearray__reduce__), - fromhex = gateway.interp2app(descr_fromhex, as_classmethod=True) + __reduce__ = interp2app(descr_bytearray__reduce__), + fromhex = interp2app(descr_fromhex, as_classmethod=True) ) bytearray_typedef.registermethods(globals()) From noreply at buildbot.pypy.org Sat Oct 13 14:46:29 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 13 Oct 2012 14:46:29 +0200 (CEST) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: Another attempt to fix the boehm/thread interaction. Message-ID: <20121013124629.ECB5F1C015F@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r58099:c470cecdd863 Date: 2012-10-13 14:46 +0200 http://bitbucket.org/pypy/pypy/changeset/c470cecdd863/ Log: Another attempt to fix the boehm/thread interaction. diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py --- a/pypy/translator/c/gc.py +++ b/pypy/translator/c/gc.py @@ -224,7 +224,9 @@ eci = eci.merge(ExternalCompilationInfo( pre_include_bits=pre_include_bits, - post_include_bits=['#define PYPY_USING_BOEHM_GC'], + # The following define is required by the thread module, + # See module/thread/test/test_ll_thread.py + compile_extra=['-DPYPY_USING_BOEHM_GC'], )) return eci diff --git a/pypy/translator/c/src/thread.c b/pypy/translator/c/src/thread.c --- a/pypy/translator/c/src/thread.c +++ b/pypy/translator/c/src/thread.c @@ -1,6 +1,14 @@ /* Thread implementation */ #include "src/thread.h" +#ifdef PYPY_USING_BOEHM_GC +/* The following include is required by the Boehm GC, which apparently + * crashes when pthread_create_thread() is not redefined to call a + * Boehm wrapper function instead. Ugly. + */ +#include "common_header.h" +#endif + #ifdef _WIN32 #include "src/thread_nt.c" #else From noreply at buildbot.pypy.org Sat Oct 13 17:16:53 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 13 Oct 2012 17:16:53 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Store FrameBlocks in an ordinary list Message-ID: <20121013151653.DE5EF1C015F@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58100:d3702e6e5c65 Date: 2012-10-12 18:38 +0100 http://bitbucket.org/pypy/pypy/changeset/d3702e6e5c65/ Log: Store FrameBlocks in an ordinary list diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -228,7 +228,7 @@ self.pycode = code self.space = space self.w_globals = Constant(func.func_globals) - self.lastblock = None + self.blockstack = [] self.init_closure(func.func_closure) self.f_lineno = code.co_firstlineno @@ -262,6 +262,22 @@ self.locals_stack_w[:len(items_w)] = items_w self.dropvaluesuntil(len(items_w)) + def append_block(self, block): + self.blockstack.append(block) + + def pop_block(self): + return self.blockstack.pop() + + def blockstack_non_empty(self): + return bool(self.blockstack) + + def get_blocklist(self): + """Returns a list containing all the blocks in the frame""" + return list(self.blockstack) + + def set_blocklist(self, lst): + self.blockstack = list(lst) + def getstate(self): # getfastscope() can return real None, for undefined locals data = self.save_locals_stack() @@ -626,16 +642,16 @@ return next_instr def SETUP_LOOP(self, offsettoend, next_instr): - block = LoopBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = LoopBlock(self, next_instr + offsettoend) + self.append_block(block) def SETUP_EXCEPT(self, offsettoend, next_instr): - block = ExceptBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = ExceptBlock(self, next_instr + offsettoend) + self.append_block(block) def SETUP_FINALLY(self, offsettoend, next_instr): - block = FinallyBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = FinallyBlock(self, next_instr + offsettoend) + self.append_block(block) def SETUP_WITH(self, offsettoend, next_instr): # A simpler version than the 'real' 2.7 one: @@ -645,8 +661,8 @@ w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__")) self.settopvalue(w_exit) w_result = self.space.call_method(w_manager, "__enter__") - block = WithBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = WithBlock(self, next_instr + offsettoend) + self.append_block(block) self.pushvalue(w_result) def WITH_CLEANUP(self, oparg, next_instr): @@ -823,10 +839,9 @@ """Abstract base class for frame blocks from the blockstack, used by the SETUP_XXX and POP_BLOCK opcodes.""" - def __init__(self, frame, handlerposition, previous): + def __init__(self, frame, handlerposition): self.handlerposition = handlerposition self.valuestackdepth = frame.valuestackdepth - self.previous = previous # this makes a linked list of blocks def __eq__(self, other): return (self.__class__ is other.__class__ and From noreply at buildbot.pypy.org Sat Oct 13 17:16:55 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 13 Oct 2012 17:16:55 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Flowspacify unrollstack() and kill .frame_finished_execution Message-ID: <20121013151655.1906A1C0188@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58101:f802420c39a7 Date: 2012-10-12 18:47 +0100 http://bitbucket.org/pypy/pypy/changeset/f802420c39a7/ Log: Flowspacify unrollstack() and kill .frame_finished_execution diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -278,6 +278,20 @@ def set_blocklist(self, lst): self.blockstack = list(lst) + def unrollstack(self, unroller_kind): + while self.blockstack_non_empty(): + block = self.pop_block() + 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): # getfastscope() can return real None, for undefined locals data = self.save_locals_stack() @@ -352,7 +366,6 @@ block = self.pendingblocks.popleft() try: self.recorder = self.recording(block) - self.frame_finished_execution = False while True: self.last_instr = self.handle_bytecode(self.last_instr) self.recorder.final_state = self.getstate() From noreply at buildbot.pypy.org Sat Oct 13 17:16:56 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 13 Oct 2012 17:16:56 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Inline blockstack manipulation functions Message-ID: <20121013151656.4442A1C0253@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58102:b32cf7228066 Date: 2012-10-12 19:48 +0100 http://bitbucket.org/pypy/pypy/changeset/b32cf7228066/ Log: Inline blockstack manipulation functions diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -262,25 +262,9 @@ self.locals_stack_w[:len(items_w)] = items_w self.dropvaluesuntil(len(items_w)) - def append_block(self, block): - self.blockstack.append(block) - - def pop_block(self): - return self.blockstack.pop() - - def blockstack_non_empty(self): - return bool(self.blockstack) - - def get_blocklist(self): - """Returns a list containing all the blocks in the frame""" - return list(self.blockstack) - - def set_blocklist(self, lst): - self.blockstack = list(lst) - def unrollstack(self, unroller_kind): - while self.blockstack_non_empty(): - block = self.pop_block() + while self.blockstack: + block = self.blockstack.pop() if (block.handling_mask & unroller_kind) != 0: return block block.cleanupstack(self) @@ -302,7 +286,7 @@ data.append(self.last_exception.w_type) data.append(self.last_exception.w_value) recursively_flatten(self.space, data) - return FrameState(data, self.get_blocklist(), self.last_instr) + return FrameState(data, self.blockstack[:], self.last_instr) def setstate(self, state): """ Reset the frame to the given state. """ @@ -315,7 +299,7 @@ else: self.last_exception = FSException(data[-2], data[-1]) self.last_instr = state.next_instr - self.set_blocklist(state.blocklist) + self.blockstack = state.blocklist[:] def recording(self, block): """ Setup recording of the block and return the recorder. """ @@ -614,7 +598,7 @@ return block.handle(self, unroller) def POP_BLOCK(self, oparg, next_instr): - block = self.pop_block() + block = self.blockstack.pop() block.cleanupstack(self) # the block knows how to clean up the value stack def JUMP_ABSOLUTE(self, jumpto, next_instr): @@ -656,15 +640,15 @@ def SETUP_LOOP(self, offsettoend, next_instr): block = LoopBlock(self, next_instr + offsettoend) - self.append_block(block) + self.blockstack.append(block) def SETUP_EXCEPT(self, offsettoend, next_instr): block = ExceptBlock(self, next_instr + offsettoend) - self.append_block(block) + self.blockstack.append(block) def SETUP_FINALLY(self, offsettoend, next_instr): block = FinallyBlock(self, next_instr + offsettoend) - self.append_block(block) + self.blockstack.append(block) def SETUP_WITH(self, offsettoend, next_instr): # A simpler version than the 'real' 2.7 one: @@ -675,7 +659,7 @@ self.settopvalue(w_exit) w_result = self.space.call_method(w_manager, "__enter__") block = WithBlock(self, next_instr + offsettoend) - self.append_block(block) + self.blockstack.append(block) self.pushvalue(w_result) def WITH_CLEANUP(self, oparg, next_instr): @@ -884,7 +868,7 @@ # 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 - frame.append_block(self) + frame.blockstack.append(self) return unroller.jump_to else: # jump to the end of the loop From noreply at buildbot.pypy.org Sat Oct 13 17:16:57 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 13 Oct 2012 17:16:57 +0200 (CEST) Subject: [pypy-commit] pypy default: merge branch 'translation-cleanup' Message-ID: <20121013151657.A18241C0FFB@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: Changeset: r58103:8ca16f85c8b7 Date: 2012-10-13 16:16 +0100 http://bitbucket.org/pypy/pypy/changeset/8ca16f85c8b7/ Log: merge branch 'translation-cleanup' diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,24 +1,22 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import (PyCode, BytecodeCorruption, cpython_magic, +from pypy.interpreter.pycode import (BytecodeCorruption, cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) from pypy.interpreter.astcompiler.consts import CO_GENERATOR -class HostCode(PyCode): +class HostCode(object): """ A wrapper around a native code object of the host interpreter """ opnames = host_bytecode_spec.method_names - def __init__(self, space, argcount, nlocals, stacksize, flags, + def __init__(self, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, - name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic=cpython_magic): + name, firstlineno, lnotab, freevars): """Initialize a new code object""" - self.space = space self.co_name = name assert nlocals >= 0 self.co_argcount = argcount @@ -26,43 +24,39 @@ self.co_stacksize = stacksize self.co_flags = flags self.co_code = code - self.co_consts_w = consts - self.co_names_w = [space.wrap(aname) for aname in names] + self.consts = consts + self.names = names self.co_varnames = varnames self.co_freevars = freevars - self.co_cellvars = cellvars self.co_filename = filename self.co_name = name self.co_firstlineno = firstlineno self.co_lnotab = lnotab - self.hidden_applevel = hidden_applevel - self.magic = magic - self._signature = cpython_code_signature(self) - self._initialize() + self.signature = cpython_code_signature(self) - def _initialize(self): - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] + @classmethod + def _from_code(cls, code): + """Initialize the code object from a real (CPython) one. + """ + return cls(code.co_argcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + list(code.co_consts), + list(code.co_names), + list(code.co_varnames), + code.co_filename, + code.co_name, + code.co_firstlineno, + code.co_lnotab, + list(code.co_freevars)) - if self.co_cellvars: - argcount = self.co_argcount - assert argcount >= 0 # annotator hint - if self.co_flags & CO_VARARGS: - argcount += 1 - if self.co_flags & CO_VARKEYWORDS: - argcount += 1 - # Cell vars could shadow already-set arguments. - # See comment in PyCode._initialize() - argvars = self.co_varnames - cellvars = self.co_cellvars - for i in range(len(cellvars)): - cellname = cellvars[i] - for j in range(argcount): - if cellname == argvars[j]: - # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad - self._args_as_cellvars[i] = j + @property + def formalargcount(self): + """Total number of arguments passed into the frame, including *vararg + and **varkwarg, if they exist.""" + return self.signature.scope_length() def read(self, pos): """ diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -1,15 +1,18 @@ +"""Implements the core parts of flow graph creation, in tandem +with pypy.objspace.flow.objspace. +""" + +import sys import collections + from pypy.tool.error import source_lines from pypy.interpreter import pyframe -from pypy.interpreter.nestedscope import Cell -from pypy.interpreter.pycode import CO_NEWLOCALS from pypy.interpreter.argument import ArgumentsForTranslation from pypy.interpreter.pyopcode import Return, BytecodeCorruption from pypy.objspace.flow.model import (Constant, Variable, Block, Link, - UnwrapException, SpaceOperation, FunctionGraph, c_last_exception) + UnwrapException, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, recursively_flatten) -from pypy.objspace.flow.bytecode import HostCode from pypy.objspace.flow.specialcase import (rpython_print_item, rpython_print_newline) @@ -67,6 +70,14 @@ self.last_exception = last_exception def fixeggblocks(graph): + varnames = graph.func.func_code.co_varnames + for block in graph.iterblocks(): + if isinstance(block, SpamBlock): + for name, w_value in zip(varnames, block.framestate.mergeable): + if isinstance(w_value, Variable): + w_value.rename(name) + del block.framestate # memory saver + # EggBlocks reuse the variables of their previous block, # which is deemed not acceptable for simplicity of the operations # that will be performed later on the flow graph. @@ -87,9 +98,6 @@ for a in block.inputargs: mapping[a] = Variable(a) block.renamevariables(mapping) - for block in graph.iterblocks(): - if isinstance(link, SpamBlock): - del link.framestate # memory saver # ____________________________________________________________ @@ -98,9 +106,6 @@ def append(self, operation): raise NotImplementedError - def bytecode_trace(self, frame): - pass - def guessbool(self, frame, w_condition, **kwds): raise AssertionError, "cannot guessbool(%s)" % (w_condition,) @@ -110,31 +115,13 @@ def __init__(self, block): self.crnt_block = block - # saved state at the join point most recently seen - self.last_join_point = None - self.enterspamblock = isinstance(block, SpamBlock) + # Final frame state after the operations in the block + # If this is set, no new space op may be recorded. + self.final_state = None def append(self, operation): self.crnt_block.operations.append(operation) - def bytecode_trace(self, frame): - if self.enterspamblock: - # If we have a SpamBlock, the first call to bytecode_trace() - # occurs as soon as frame.resume() starts, before interpretation - # really begins. - varnames = frame.pycode.getvarnames() - for name, w_value in zip(varnames, frame.getfastscope()): - if isinstance(w_value, Variable): - w_value.rename(name) - self.enterspamblock = False - else: - # At this point, we progress to the next bytecode. When this - # occurs, we no longer allow any more operations to be recorded in - # the same block. We will continue, to figure out where the next - # such operation *would* appear, and we make a join point just - # before. - self.last_join_point = frame.getstate() - def guessbool(self, frame, w_condition): block = self.crnt_block vars = block.getvariables() @@ -235,69 +222,45 @@ class FlowSpaceFrame(pyframe.CPythonFrame): - def __init__(self, space, func, constargs=None): - code = HostCode._from_code(space, func.func_code) + def __init__(self, space, graph, code): + self.graph = graph + func = graph.func self.pycode = code self.space = space self.w_globals = Constant(func.func_globals) - self.locals_stack_w = [None] * (code.co_nlocals + code.co_stacksize) - self.valuestackdepth = code.co_nlocals self.lastblock = None - if func.func_closure is not None: - cl = [c.cell_contents for c in func.func_closure] - closure = [Cell(Constant(value)) for value in cl] - else: - closure = [] - self.initialize_frame_scopes(closure, code) + self.init_closure(func.func_closure) self.f_lineno = code.co_firstlineno self.last_instr = 0 - if constargs is None: - constargs = {} - formalargcount = code.getformalargcount() - arg_list = [Variable() for i in range(formalargcount)] - for position, value in constargs.items(): - arg_list[position] = Constant(value) - self.setfastscope(arg_list) - + self.init_locals_stack(code) self.w_locals = None # XXX: only for compatibility with PyFrame self.joinpoints = {} - self._init_graph(func) - self.pendingblocks = collections.deque([self.graph.startblock]) - def initialize_frame_scopes(self, closure, code): - if not (code.co_flags & CO_NEWLOCALS): - raise ValueError("The code object for a function should have " - "the flag CO_NEWLOCALS set.") - if len(closure) != len(code.co_freevars): - raise ValueError("code object received a closure with " - "an unexpected number of free variables") - self.cells = [Cell() for _ in code.co_cellvars] + closure + def init_closure(self, closure): + if closure is None: + self.closure = [] + else: + self.closure = [self.space.wrap(c.cell_contents) for c in closure] + assert len(self.closure) == len(self.pycode.co_freevars) - def _init_graph(self, func): - # CallableFactory.pycall may add class_ to functions that are methods - name = func.func_name - class_ = getattr(func, 'class_', None) - if class_ is not None: - name = '%s.%s' % (class_.__name__, name) - for c in "<>&!": - name = name.replace(c, '_') + def init_locals_stack(self, code): + """ + Initialize the locals and the stack. - initialblock = SpamBlock(self.getstate()) - if self.pycode.is_generator: - initialblock.operations.append( - SpaceOperation('generator_mark', [], Variable())) - graph = FunctionGraph(name, initialblock) - graph.func = func - # attach a signature and defaults to the graph - # so that it becomes even more interchangeable with the function - # itself - graph.signature = self.pycode.signature() - graph.defaults = func.func_defaults or () - graph.is_generator = self.pycode.is_generator - self.graph = graph + The locals are ordered according to self.pycode.signature. + """ + self.valuestackdepth = code.co_nlocals + self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals) + + def save_locals_stack(self): + return self.locals_stack_w[:self.valuestackdepth] + + def restore_locals_stack(self, items_w): + self.locals_stack_w[:len(items_w)] = items_w + self.dropvaluesuntil(len(items_w)) def getstate(self): # getfastscope() can return real None, for undefined locals @@ -309,9 +272,7 @@ data.append(self.last_exception.w_type) data.append(self.last_exception.w_value) recursively_flatten(self.space, data) - nonmergeable = (self.get_blocklist(), - self.last_instr) # == next_instr when between bytecodes - return FrameState(data, nonmergeable) + return FrameState(data, self.get_blocklist(), self.last_instr) def setstate(self, state): """ Reset the frame to the given state. """ @@ -323,8 +284,8 @@ self.last_exception = None else: self.last_exception = FSException(data[-2], data[-1]) - blocklist, self.last_instr = state.nonmergeable - self.set_blocklist(blocklist) + self.last_instr = state.next_instr + self.set_blocklist(state.blocklist) def recording(self, block): """ Setup recording of the block and return the recorder. """ @@ -347,8 +308,8 @@ def record(self, spaceop): """Record an operation into the active block""" recorder = self.recorder - if getattr(recorder, 'last_join_point', None) is not None: - self.mergeblock(recorder.crnt_block, recorder.last_join_point) + if getattr(recorder, 'final_state', None) is not None: + self.mergeblock(recorder.crnt_block, recorder.final_state) raise StopFlowing recorder.append(spaceop) @@ -369,14 +330,16 @@ return self.recorder.guessexception(self, *exceptions) def build_flow(self): + graph = self.graph + self.pendingblocks = collections.deque([graph.startblock]) while self.pendingblocks: block = self.pendingblocks.popleft() try: self.recorder = self.recording(block) self.frame_finished_execution = False - next_instr = self.last_instr while True: - next_instr = self.handle_bytecode(next_instr) + self.last_instr = self.handle_bytecode(self.last_instr) + self.recorder.final_state = self.getstate() except ImplicitOperationError, e: if isinstance(e.w_type, Constant): @@ -386,14 +349,14 @@ msg = "implicit %s shouldn't occur" % exc_cls.__name__ w_type = Constant(AssertionError) w_value = Constant(AssertionError(msg)) - link = Link([w_type, w_value], self.graph.exceptblock) + link = Link([w_type, w_value], graph.exceptblock) self.recorder.crnt_block.closeblock(link) except FSException, e: if e.w_type is 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([e.w_type, e.w_value], graph.exceptblock) self.recorder.crnt_block.closeblock(link) except StopFlowing: @@ -402,7 +365,7 @@ except Return: w_result = self.popvalue() assert w_result is not None - link = Link([w_result], self.graph.returnblock) + link = Link([w_result], graph.returnblock) self.recorder.crnt_block.closeblock(link) del self.recorder @@ -414,37 +377,35 @@ candidates = self.joinpoints.setdefault(next_instr, []) for block in candidates: newstate = block.framestate.union(currentstate) - if newstate is not None: - # yes - finished = newstate == block.framestate + if newstate is None: + continue + elif newstate == block.framestate: + outputargs = currentstate.getoutputargs(newstate) + currentblock.closeblock(Link(outputargs, block)) + return + else: break else: - # no newstate = currentstate.copy() - finished = False block = None - if finished: - newblock = block - else: - newblock = SpamBlock(newstate) + newblock = SpamBlock(newstate) # unconditionally link the current block to the newblock outputargs = currentstate.getoutputargs(newstate) link = Link(outputargs, newblock) currentblock.closeblock(link) - # phew - if not finished: - if block is not None: - # to simplify the graph, we patch the old block to point - # directly at the new block which is its generalization - block.dead = True - block.operations = () - block.exitswitch = None - outputargs = block.framestate.getoutputargs(newstate) - block.recloseblock(Link(outputargs, newblock)) - candidates.remove(block) - candidates.insert(0, newblock) - self.pendingblocks.append(newblock) + + if block is not None: + # to simplify the graph, we patch the old block to point + # directly at the new block which is its generalization + block.dead = True + block.operations = () + block.exitswitch = None + outputargs = block.framestate.getoutputargs(newstate) + block.recloseblock(Link(outputargs, newblock)) + candidates.remove(block) + candidates.insert(0, newblock) + self.pendingblocks.append(newblock) # hack for unrolling iterables, don't use this def replace_in_stack(self, oldvalue, newvalue): @@ -460,17 +421,12 @@ break def handle_bytecode(self, next_instr): + next_instr, methodname, oparg = self.pycode.read(next_instr) try: - while True: - self.last_instr = next_instr - self.recorder.bytecode_trace(self) - next_instr, methodname, oparg = self.pycode.read(next_instr) - res = getattr(self, methodname)(oparg, next_instr) - if res is not None: - next_instr = res + res = getattr(self, methodname)(oparg, next_instr) + return res if res is not None else next_instr except FSException, operr: - next_instr = self.handle_operation_error(operr) - return next_instr + return self.handle_operation_error(operr) def handle_operation_error(self, operr): block = self.unrollstack(SApplicationException.kind) @@ -481,6 +437,18 @@ next_instr = block.handle(self, unroller) return next_instr + def getlocalvarname(self, index): + return self.pycode.co_varnames[index] + + def getconstant_w(self, index): + return self.space.wrap(self.pycode.consts[index]) + + def getname_u(self, index): + return self.pycode.names[index] + + def getname_w(self, index): + return Constant(self.pycode.names[index]) + def BAD_OPCODE(self, _, next_instr): raise FlowingError(self, "This operation is not RPython") @@ -685,19 +653,13 @@ # Note: RPython context managers receive None in lieu of tracebacks # and cannot suppress the exception. # This opcode changed a lot between CPython versions - if (self.pycode.magic >= 0xa0df2ef - # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) - or self.pycode.magic >= 0xa0df2d1): - # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) + if sys.version_info >= (2, 6): w_unroller = self.popvalue() w_exitfunc = self.popvalue() self.pushvalue(w_unroller) - elif self.pycode.magic >= 0xa0df28c: - # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) + else: w_exitfunc = self.popvalue() w_unroller = self.peekvalue(0) - else: - raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") unroller = self.space.unwrap(w_unroller) w_None = self.space.w_None @@ -710,6 +672,12 @@ else: self.space.call_function(w_exitfunc, w_None, w_None, w_None) + def LOAD_FAST(self, varindex, next_instr): + w_value = self.locals_stack_w[varindex] + if w_value is None: + raise FlowingError(self, "Local variable referenced before assignment") + self.pushvalue(w_value) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) @@ -722,6 +690,9 @@ self.pushvalue(w_value) LOOKUP_METHOD = LOAD_ATTR + def LOAD_DEREF(self, varindex, next_instr): + self.pushvalue(self.closure[varindex]) + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. @@ -729,6 +700,12 @@ self.pushvalue(self.space.newlist([])) self.pushvalue(last_val) + def MAKE_FUNCTION(self, numdefaults, next_instr): + w_codeobj = self.popvalue() + defaults = self.popvalues(numdefaults) + fn = self.space.newfunction(w_codeobj, self.w_globals, defaults) + self.pushvalue(fn) + # XXX Unimplemented 2.7 opcodes ---------------- # Set literals, set comprehensions @@ -744,6 +721,12 @@ def MAP_ADD(self, oparg, next_instr): raise NotImplementedError("MAP_ADD") + # Closures + + STORE_DEREF = BAD_OPCODE + LOAD_CLOSURE = BAD_OPCODE + MAKE_CLOSURE = BAD_OPCODE + def make_arguments(self, nargs): return ArgumentsForTranslation(self.space, self.peekvalues(nargs)) def argument_factory(self, *args): diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -2,10 +2,10 @@ from pypy.objspace.flow.model import * class FrameState: - def __init__(self, mergeable, nonmergeable): + def __init__(self, mergeable, blocklist, next_instr): self.mergeable = mergeable - self.nonmergeable = nonmergeable - self.next_instr = self.nonmergeable[1] + self.blocklist = blocklist + self.next_instr = next_instr for w1 in self.mergeable: assert isinstance(w1, (Variable, Constant)) or w1 is None, ( '%r found in frame state' % w1) @@ -17,7 +17,7 @@ if isinstance(w, Variable): w = Variable() newstate.append(w) - return FrameState(newstate, self.nonmergeable) + return FrameState(newstate, self.blocklist, self.next_instr) def getvariables(self): return [w for w in self.mergeable if isinstance(w, Variable)] @@ -29,7 +29,8 @@ # nonmergeable states assert isinstance(other, FrameState) assert len(self.mergeable) == len(other.mergeable) - assert self.nonmergeable == other.nonmergeable + assert self.blocklist == other.blocklist + assert self.next_instr == other.next_instr for w1, w2 in zip(self.mergeable, other.mergeable): if not (w1 == w2 or (isinstance(w1, Variable) and isinstance(w2, Variable))): @@ -50,7 +51,7 @@ newstate.append(union(w1, w2)) except UnionError: return None - return FrameState(newstate, self.nonmergeable) + return FrameState(newstate, self.blocklist, self.next_instr) def getoutputargs(self, targetstate): "Return the output arguments needed to link self to targetstate." diff --git a/pypy/objspace/flow/generator.py b/pypy/objspace/flow/generator.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/flow/generator.py @@ -0,0 +1,186 @@ +"""Flow graph building for generators""" + +from pypy.objspace.flow.model import Block, Link, SpaceOperation, checkgraph +from pypy.objspace.flow.model import Variable, Constant +from pypy.translator.unsimplify import insert_empty_startblock +from pypy.translator.unsimplify import split_block +from pypy.translator.simplify import eliminate_empty_blocks, simplify_graph +from pypy.tool.sourcetools import func_with_new_name +from pypy.interpreter.argument import Signature + + +class AbstractPosition(object): + _immutable_ = True + _attrs_ = () + +def bootstrap_generator(graph): + # This is the first copy of the graph. We replace it with + # a small bootstrap graph. + GeneratorIterator = make_generatoriterator_class(graph) + replace_graph_with_bootstrap(GeneratorIterator, graph) + # We attach a 'next' method to the GeneratorIterator class + # that will invoke the real function, based on a second + # copy of the graph. + attach_next_method(GeneratorIterator, graph) + return graph + +def tweak_generator_graph(graph): + # This is the second copy of the graph. Tweak it. + GeneratorIterator = graph.func._generator_next_method_of_ + tweak_generator_body_graph(GeneratorIterator.Entry, graph) + + +def make_generatoriterator_class(graph): + class GeneratorIterator(object): + class Entry(AbstractPosition): + _immutable_ = True + varnames = get_variable_names(graph.startblock.inputargs) + + def __init__(self, entry): + self.current = entry + + def __iter__(self): + return self + + return GeneratorIterator + +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)) + 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)) + graph.startblock = newblock + +def attach_next_method(GeneratorIterator, graph): + func = graph.func + func = func_with_new_name(func, '%s__next' % (func.func_name,)) + func._generator_next_method_of_ = GeneratorIterator + func._always_inline_ = True + # + def next(self): + entry = self.current + self.current = None + assert entry is not None # else, recursive generator invocation + (next_entry, return_value) = func(entry) + self.current = next_entry + return return_value + GeneratorIterator.next = next + return func # for debugging + +def get_variable_names(variables): + seen = set() + result = [] + for v in variables: + name = v._name.strip('_') + while name in seen: + name += '_' + result.append('g_' + name) + seen.add(name) + return result + +def _insert_reads(block, varnames): + 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])) + block.inputargs = [v_entry1] + +def tweak_generator_body_graph(Entry, graph): + # First, always run simplify_graph in order to reduce the number of + # variables passed around + simplify_graph(graph) + # + assert graph.startblock.operations[0].opname == 'generator_mark' + graph.startblock.operations.pop(0) + # + insert_empty_startblock(None, graph) + _insert_reads(graph.startblock, Entry.varnames) + Entry.block = graph.startblock + # + 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)) + # + for block in list(graph.iterblocks()): + for exit in block.exits: + if exit.target is graph.returnblock: + exit.args = [] + 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 + del block.operations[index] + newlink = split_block(None, block, index) + newblock = newlink.target + # + class Resume(AbstractPosition): + _immutable_ = True + block = newblock + Resume.__name__ = 'Resume%d' % len(mappings) + mappings.append(Resume) + varnames = get_variable_names(newlink.args) + # + _insert_reads(newblock, varnames) + # + v_resume = Variable('resume') + block.operations.append( + SpaceOperation('simple_call', [Constant(Resume)], + v_resume)) + 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] + 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 + link1 = Link([block.inputargs[0]], Resume.block) + link1.exitcase = True + nextblock = Block([Variable('entry')]) + link2 = Link([block.inputargs[0]], nextblock) + link2.exitcase = False + block.closeblock(link1, link2) + block = nextblock + block.closeblock(Link([Constant(AssertionError), + Constant(AssertionError("bad generator class"))], + graph.exceptblock)) + graph.startblock = regular_entry_block + graph.signature = Signature(['entry']) + graph.defaults = () + checkgraph(graph) + eliminate_empty_blocks(graph) diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -1,14 +1,23 @@ -# ______________________________________________________________________ +"""Implements the core parts of flow graph creation, in tandem +with pypy.objspace.flow.flowcontext. +""" + import __builtin__ import sys import types +from inspect import CO_NEWLOCALS + from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.argument import ArgumentsForTranslation from pypy.objspace.flow.model import (Constant, Variable, WrapException, UnwrapException, checkgraph, SpaceOperation) +from pypy.objspace.flow.bytecode import HostCode from pypy.objspace.flow import operation from pypy.objspace.flow.flowcontext import (FlowSpaceFrame, fixeggblocks, FSException, FlowingError) +from pypy.objspace.flow.generator import (tweak_generator_graph, + bootstrap_generator) +from pypy.objspace.flow.pygraph import PyGraph from pypy.objspace.flow.specialcase import SPECIAL_CASES from pypy.rlib.unroll import unrolling_iterable, _unroller from pypy.rlib import rstackovf, rarithmetic @@ -37,6 +46,17 @@ } } +def _assert_rpythonic(func): + """Raise ValueError if ``func`` is obviously not RPython""" + if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): + raise ValueError("%r is tagged as NOT_RPYTHON" % (func,)) + if func.func_code.co_cellvars: + raise ValueError("RPython functions cannot create closures") + if not (func.func_code.co_flags & CO_NEWLOCALS): + raise ValueError("The code object for a RPython function should have " + "the flag CO_NEWLOCALS set.") + + # ______________________________________________________________________ class FlowObjSpace(object): """NOT_RPYTHON. @@ -94,6 +114,17 @@ else: return self.w_False + def newfunction(self, w_code, w_globals, defaults_w): + try: + code = self.unwrap(w_code) + globals = self.unwrap(w_globals) + defaults = tuple([self.unwrap(value) for value in defaults_w]) + except UnwrapException: + raise FlowingError(self.frame, "Dynamically created function must" + " have constant default values.") + fn = types.FunctionType(code, globals, code.co_name, defaults) + return Constant(fn) + def wrap(self, obj): if isinstance(obj, (Variable, Constant)): raise TypeError("already wrapped: " + repr(obj)) @@ -232,18 +263,25 @@ w_type = w_instclass return FSException(w_type, w_value) - def build_flow(self, func, constargs={}, tweak_for_generator=True): + def build_flow(self, func): """ """ - if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): - raise Exception, "%r is tagged as NOT_RPYTHON" % (func,) - frame = self.frame = FlowSpaceFrame(self, func, constargs) + _assert_rpythonic(func) + code = HostCode._from_code(func.func_code) + if (code.is_generator and + not hasattr(func, '_generator_next_method_of_')): + graph = PyGraph(func, code) + block = graph.startblock + for name, w_value in zip(code.co_varnames, block.framestate.mergeable): + if isinstance(w_value, Variable): + w_value.rename(name) + return bootstrap_generator(graph) + graph = PyGraph(func, code) + frame = self.frame = FlowSpaceFrame(self, graph, code) frame.build_flow() - graph = frame.graph fixeggblocks(graph) checkgraph(graph) - if graph.is_generator and tweak_for_generator: - from pypy.translator.generator import tweak_generator_graph + if code.is_generator: tweak_generator_graph(graph) return graph diff --git a/pypy/objspace/flow/pygraph.py b/pypy/objspace/flow/pygraph.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/flow/pygraph.py @@ -0,0 +1,39 @@ +""" +Implements flow graphs for Python callables +""" +from pypy.objspace.flow.model import (FunctionGraph, Constant, Variable, + SpaceOperation) +from pypy.objspace.flow.framestate import FrameState + +class PyGraph(FunctionGraph): + """ + Flow graph for a Python function + """ + + def __init__(self, func, code): + from pypy.objspace.flow.flowcontext import SpamBlock + data = [None] * code.co_nlocals + for i in range(code.formalargcount): + data[i] = Variable() + state = FrameState(data + [Constant(None), Constant(None)], [], 0) + initialblock = SpamBlock(state) + if code.is_generator: + initialblock.operations.append( + SpaceOperation('generator_mark', [], Variable())) + + super(PyGraph, self).__init__(self._sanitize_funcname(func), initialblock) + self.func = func + self.signature = code.signature + self.defaults = func.func_defaults or () + + @staticmethod + def _sanitize_funcname(func): + # CallableFactory.pycall may add class_ to functions that are methods + name = func.func_name + class_ = getattr(func, 'class_', None) + if class_ is not None: + name = '%s.%s' % (class_.__name__, name) + for c in "<>&!": + name = name.replace(c, '_') + return name + diff --git a/pypy/objspace/flow/test/test_framestate.py b/pypy/objspace/flow/test/test_framestate.py --- a/pypy/objspace/flow/test/test_framestate.py +++ b/pypy/objspace/flow/test/test_framestate.py @@ -2,6 +2,8 @@ from pypy.rlib.unroll import SpecTag from pypy.objspace.flow.objspace import FlowObjSpace from pypy.objspace.flow.flowcontext import FlowSpaceFrame +from pypy.objspace.flow.bytecode import HostCode +from pypy.objspace.flow.pygraph import PyGraph class TestFrameState: def setup_class(cls): @@ -12,8 +14,11 @@ func = func.im_func except AttributeError: pass - frame = FlowSpaceFrame(self.space, func) + code = HostCode._from_code(func.func_code) + graph = PyGraph(func, code) + frame = FlowSpaceFrame(self.space, graph, code) # hack the frame + frame.setstate(graph.startblock.framestate) frame.locals_stack_w[frame.pycode.co_nlocals-1] = Constant(None) return frame diff --git a/pypy/objspace/flow/test/test_generator.py b/pypy/objspace/flow/test/test_generator.py --- a/pypy/objspace/flow/test/test_generator.py +++ b/pypy/objspace/flow/test/test_generator.py @@ -1,18 +1,127 @@ -from pypy.objspace.flow.test.test_objspace import Base +from pypy.conftest import option +from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.objspace.flow.model import Variable +from pypy.objspace.flow.generator import (make_generatoriterator_class, + replace_graph_with_bootstrap, get_variable_names, attach_next_method) +from pypy.translator.simplify import join_blocks -class TestGenerator(Base): +# ____________________________________________________________ - def test_simple_generator(self): - def f(n): +def f_gen(n): + i = 0 + while i < n: + yield i + i += 1 + +class GeneratorIterator(object): + def __init__(self, entry): + self.current = entry + def next(self): + e = self.current + self.current = None + if isinstance(e, Yield1): + n = e.n_0 + i = e.i_0 + i += 1 + else: + n = e.n_0 i = 0 - while i < n: - yield i - yield i - i += 1 - graph = self.codetest(f, tweak_for_generator=False) - ops = self.all_operations(graph) - assert ops == {'generator_mark': 1, - 'lt': 1, 'is_true': 1, - 'yield': 2, - 'inplace_add': 1} + if i < n: + e = Yield1() + e.n_0 = n + e.i_0 = i + self.current = e + return i + raise StopIteration + + def __iter__(self): + return self + +class AbstractPosition(object): + _immutable_ = True +class Entry1(AbstractPosition): + _immutable_ = True +class Yield1(AbstractPosition): + _immutable_ = True + +def f_explicit(n): + e = Entry1() + e.n_0 = n + return GeneratorIterator(e) + +def test_explicit(): + assert list(f_gen(10)) == list(f_explicit(10)) + +def test_get_variable_names(): + lst = get_variable_names([Variable('a'), Variable('b_'), Variable('a')]) + assert lst == ['g_a', 'g_b', 'g_a_'] + +# ____________________________________________________________ + + +class TestGenerator: + + def test_replace_graph_with_bootstrap(self): + def func(n, x, y, z): + yield n + yield n + # + graph = FlowObjSpace().build_flow(func) + if option.view: + graph.show() + block = graph.startblock + ops = block.operations + assert ops[0].opname == 'simple_call' # e = Entry1() + assert ops[1].opname == 'setattr' # e.g_n = n + assert ops[1].args[1].value == 'g_n' + assert ops[2].opname == 'setattr' # e.g_x = x + assert ops[2].args[1].value == 'g_x' + assert ops[3].opname == 'setattr' # e.g_y = y + assert ops[3].args[1].value == 'g_y' + assert ops[4].opname == 'setattr' # e.g_z = z + assert ops[4].args[1].value == 'g_z' + assert ops[5].opname == 'simple_call' # g = GeneratorIterator(e) + assert ops[5].args[1] == ops[0].result + assert len(ops) == 6 + assert len(block.exits) == 1 + assert block.exits[0].target is graph.returnblock + + def test_tweak_generator_graph(self): + def f(n, x, y, z): + z *= 10 + yield n + 1 + z -= 10 + # + space = FlowObjSpace() + graph = space.build_flow(f) + GeneratorIterator = make_generatoriterator_class(graph) + replace_graph_with_bootstrap(GeneratorIterator, graph) + func1 = attach_next_method(GeneratorIterator, graph) + if option.view: + graph.show() + # + assert func1._generator_next_method_of_ is GeneratorIterator + assert hasattr(GeneratorIterator, 'next') + # + graph_next = space.build_flow(GeneratorIterator.next.im_func) + join_blocks(graph_next) + if option.view: + graph_next.show() + # + graph1 = space.build_flow(func1) + if option.view: + graph1.show() + + def test_automatic(self): + def f(n, x, y, z): + z *= 10 + yield n + 1 + z -= 10 + # + graph = FlowObjSpace().build_flow(f) + if option.view: + graph.show() + block = graph.startblock + assert len(block.exits) == 1 + assert block.exits[0].target is graph.returnblock diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1054,6 +1054,80 @@ with py.test.raises(FlowingError): self.codetest(f) + @py.test.mark.xfail(reason="closures aren't supported") + def test_cellvar_store(self): + def f(): + x = 5 + return x + lambda: x # turn x into a cell variable + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + + @py.test.mark.xfail(reason="closures aren't supported") + def test_arg_as_cellvar(self): + def f(x, y, z): + a, b, c = 1, 2, 3 + z = b + return z + lambda: (a, b, x, z) # make cell variables + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + assert not graph.startblock.operations + assert graph.startblock.exits[0].args[0].value == 2 + + def test_lambda(self): + def f(): + g = lambda m, n: n*m + return g + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + g = graph.startblock.exits[0].args[0].value + assert g(4, 4) == 16 + + def test_lambda_with_defaults(self): + def f(): + g = lambda m, n=5: n*m + return g + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + g = graph.startblock.exits[0].args[0].value + assert g(4) == 20 + + def f2(x): + g = lambda m, n=x: n*m + return g + with py.test.raises(FlowingError): + self.codetest(f2) + + @py.test.mark.xfail(reason="closures aren't supported") + def test_closure(self): + def f(): + m = 5 + return lambda n: m * n + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + g = graph.startblock.exits[0].args[0].value + assert g(4) == 20 + + def test_closure_error(self): + def f(): + m = 5 + return lambda n: m * n + with py.test.raises(ValueError) as excinfo: + self.codetest(f) + assert "closure" in str(excinfo.value) + + def test_unbound_local(self): + def f(): + x += 1 + with py.test.raises(FlowingError): + self.codetest(f) + DATA = {'x': 5, 'y': 6} diff --git a/pypy/translator/generator.py b/pypy/translator/generator.py deleted file mode 100644 --- a/pypy/translator/generator.py +++ /dev/null @@ -1,184 +0,0 @@ -from pypy.objspace.flow.model import Block, Link, SpaceOperation, checkgraph -from pypy.objspace.flow.model import Variable, Constant, FunctionGraph -from pypy.translator.unsimplify import insert_empty_startblock -from pypy.translator.unsimplify import split_block -from pypy.translator.simplify import eliminate_empty_blocks, simplify_graph -from pypy.tool.sourcetools import func_with_new_name -from pypy.interpreter.argument import Signature - - -class AbstractPosition(object): - _immutable_ = True - _attrs_ = () - - -def tweak_generator_graph(graph): - if not hasattr(graph.func, '_generator_next_method_of_'): - # This is the first copy of the graph. We replace it with - # a small bootstrap graph. - GeneratorIterator = make_generatoriterator_class(graph) - replace_graph_with_bootstrap(GeneratorIterator, graph) - # We attach a 'next' method to the GeneratorIterator class - # that will invoke the real function, based on a second - # copy of the graph. - attach_next_method(GeneratorIterator, graph) - else: - # This is the second copy of the graph. Tweak it. - GeneratorIterator = graph.func._generator_next_method_of_ - tweak_generator_body_graph(GeneratorIterator.Entry, graph) - - -def make_generatoriterator_class(graph): - class GeneratorIterator(object): - class Entry(AbstractPosition): - _immutable_ = True - varnames = get_variable_names(graph.startblock.inputargs) - - def __init__(self, entry): - self.current = entry - - def __iter__(self): - return self - - return GeneratorIterator - -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)) - 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)) - graph.startblock = newblock - -def attach_next_method(GeneratorIterator, graph): - func = graph.func - func = func_with_new_name(func, '%s__next' % (func.func_name,)) - func._generator_next_method_of_ = GeneratorIterator - func._always_inline_ = True - # - def next(self): - entry = self.current - self.current = None - assert entry is not None # else, recursive generator invocation - (next_entry, return_value) = func(entry) - self.current = next_entry - return return_value - GeneratorIterator.next = next - return func # for debugging - -def get_variable_names(variables): - seen = set() - result = [] - for v in variables: - name = v._name.strip('_') - while name in seen: - name += '_' - result.append('g_' + name) - seen.add(name) - return result - -def _insert_reads(block, varnames): - 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])) - block.inputargs = [v_entry1] - -def tweak_generator_body_graph(Entry, graph): - # First, always run simplify_graph in order to reduce the number of - # variables passed around - simplify_graph(graph) - # - assert graph.startblock.operations[0].opname == 'generator_mark' - graph.startblock.operations.pop(0) - # - insert_empty_startblock(None, graph) - _insert_reads(graph.startblock, Entry.varnames) - Entry.block = graph.startblock - # - 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)) - # - for block in list(graph.iterblocks()): - for exit in block.exits: - if exit.target is graph.returnblock: - exit.args = [] - 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 - del block.operations[index] - newlink = split_block(None, block, index) - newblock = newlink.target - # - class Resume(AbstractPosition): - _immutable_ = True - block = newblock - Resume.__name__ = 'Resume%d' % len(mappings) - mappings.append(Resume) - varnames = get_variable_names(newlink.args) - # - _insert_reads(newblock, varnames) - # - v_resume = Variable('resume') - block.operations.append( - SpaceOperation('simple_call', [Constant(Resume)], - v_resume)) - 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] - 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 - link1 = Link([block.inputargs[0]], Resume.block) - link1.exitcase = True - nextblock = Block([Variable('entry')]) - link2 = Link([block.inputargs[0]], nextblock) - link2.exitcase = False - block.closeblock(link1, link2) - block = nextblock - block.closeblock(Link([Constant(AssertionError), - Constant(AssertionError("bad generator class"))], - graph.exceptblock)) - graph.startblock = regular_entry_block - graph.signature = Signature(['entry']) - graph.defaults = () - checkgraph(graph) - eliminate_empty_blocks(graph) diff --git a/pypy/translator/test/test_generator.py b/pypy/translator/test/test_generator.py deleted file mode 100644 --- a/pypy/translator/test/test_generator.py +++ /dev/null @@ -1,156 +0,0 @@ -from pypy.conftest import option -from pypy.objspace.flow.objspace import FlowObjSpace -from pypy.objspace.flow.model import Variable -from pypy.interpreter.argument import Signature -from pypy.translator.translator import TranslationContext -from pypy.translator.generator import make_generatoriterator_class -from pypy.translator.generator import replace_graph_with_bootstrap -from pypy.translator.generator import get_variable_names -from pypy.translator.generator import tweak_generator_body_graph -from pypy.translator.generator import attach_next_method -from pypy.translator.simplify import join_blocks - - -# ____________________________________________________________ - -def f_gen(n): - i = 0 - while i < n: - yield i - i += 1 - -class GeneratorIterator(object): - def __init__(self, entry): - self.current = entry - def next(self): - e = self.current - self.current = None - if isinstance(e, Yield1): - n = e.n_0 - i = e.i_0 - i += 1 - else: - n = e.n_0 - i = 0 - if i < n: - e = Yield1() - e.n_0 = n - e.i_0 = i - self.current = e - return i - raise StopIteration - - def __iter__(self): - return self - -class AbstractPosition(object): - _immutable_ = True -class Entry1(AbstractPosition): - _immutable_ = True -class Yield1(AbstractPosition): - _immutable_ = True - -def f_explicit(n): - e = Entry1() - e.n_0 = n - return GeneratorIterator(e) - -def test_explicit(): - assert list(f_gen(10)) == list(f_explicit(10)) - -def test_get_variable_names(): - lst = get_variable_names([Variable('a'), Variable('b_'), Variable('a')]) - assert lst == ['g_a', 'g_b', 'g_a_'] - -# ____________________________________________________________ - - -class TestGenerator: - - def test_replace_graph_with_bootstrap(self): - def func(n, x, y, z): - yield n - yield n - # - space = FlowObjSpace() - graph = space.build_flow(func, tweak_for_generator=False) - assert graph.startblock.operations[0].opname == 'generator_mark' - GeneratorIterator = make_generatoriterator_class(graph) - replace_graph_with_bootstrap(GeneratorIterator, graph) - if option.view: - graph.show() - block = graph.startblock - ops = block.operations - assert ops[0].opname == 'simple_call' # e = Entry1() - assert ops[1].opname == 'setattr' # e.g_n = n - assert ops[1].args[1].value == 'g_n' - assert ops[2].opname == 'setattr' # e.g_x = x - assert ops[2].args[1].value == 'g_x' - assert ops[3].opname == 'setattr' # e.g_y = y - assert ops[3].args[1].value == 'g_y' - assert ops[4].opname == 'setattr' # e.g_z = z - assert ops[4].args[1].value == 'g_z' - assert ops[5].opname == 'simple_call' # g = GeneratorIterator(e) - assert ops[5].args[1] == ops[0].result - assert len(ops) == 6 - assert len(block.exits) == 1 - assert block.exits[0].target is graph.returnblock - - def test_tweak_generator_body_graph(self): - def f(n, x, y, z=3): - z *= 10 - yield n + 1 - z -= 10 - # - space = FlowObjSpace() - graph = space.build_flow(f, tweak_for_generator=False) - class Entry: - varnames = ['g_n', 'g_x', 'g_y', 'g_z'] - tweak_generator_body_graph(Entry, graph) - if option.view: - graph.show() - # XXX how to test directly that the graph is correct? :-( - assert len(graph.startblock.inputargs) == 1 - assert graph.signature == Signature(['entry']) - assert graph.defaults == () - - def test_tweak_generator_graph(self): - def f(n, x, y, z): - z *= 10 - yield n + 1 - z -= 10 - # - space = FlowObjSpace() - graph = space.build_flow(f, tweak_for_generator=False) - GeneratorIterator = make_generatoriterator_class(graph) - replace_graph_with_bootstrap(GeneratorIterator, graph) - func1 = attach_next_method(GeneratorIterator, graph) - if option.view: - graph.show() - # - assert func1._generator_next_method_of_ is GeneratorIterator - assert hasattr(GeneratorIterator, 'next') - # - graph_next = space.build_flow(GeneratorIterator.next.im_func) - join_blocks(graph_next) - if option.view: - graph_next.show() - # - graph1 = space.build_flow(func1, tweak_for_generator=False) - tweak_generator_body_graph(GeneratorIterator.Entry, graph1) - if option.view: - graph1.show() - - def test_automatic(self): - def f(n, x, y, z): - z *= 10 - yield n + 1 - z -= 10 - # - space = FlowObjSpace() - graph = space.build_flow(f) # tweak_for_generator=True - if option.view: - graph.show() - block = graph.startblock - assert len(block.exits) == 1 - assert block.exits[0].target is graph.returnblock From noreply at buildbot.pypy.org Sat Oct 13 18:01:38 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 13 Oct 2012 18:01:38 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: merge default Message-ID: <20121013160138.576321C015F@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58104:93f4450b82a3 Date: 2012-10-13 17:01 +0100 http://bitbucket.org/pypy/pypy/changeset/93f4450b82a3/ Log: merge default diff too long, truncating to 2000 out of 43065 lines diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,11 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - libpath = ctypes.util.find_library('db-4.5') - if not libpath: + for c in '56789': + libpath = ctypes.util.find_library('db-4.%s' % c) + if libpath: + break + else: raise ImportError("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' diff --git a/py/_io/capture.py b/py/_io/capture.py --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -176,7 +176,7 @@ class StdCaptureFD(Capture): - """ This class allows to capture writes to FD1 and FD2 + """ This class allows capturing writes to FD1 and FD2 and may connect a NULL file to FD0 (and prevent reads from sys.stdin). If any of the 0,1,2 file descriptors is invalid it will not be captured. @@ -267,8 +267,8 @@ return l class StdCapture(Capture): - """ This class allows to capture writes to sys.stdout|stderr "in-memory" - and will raise errors on tries to read from sys.stdin. It only + """ This class allows capturing writes to sys.stdout|stderr "in-memory" + and will raise errors on read attempts from sys.stdin. It only modifies sys.stdout|stderr|stdin attributes and does not touch underlying File Descriptors (use StdCaptureFD for that). """ diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -1,9 +1,8 @@ -import sys import types -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception +from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - format_someobject_error, AnnotatorError) + AnnotatorError, gather_error, ErrorWrapper) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -38,22 +37,9 @@ self.links_followed = {} # set of links that have ever been followed self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + self.blocked_blocks = {} # set of {blocked_block: (graph, index)} + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +63,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +164,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +181,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +192,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +242,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +265,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +283,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +333,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -414,7 +340,7 @@ self.flowin(graph, block) except BlockedInference, e: self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, e.opindex) except Exception, e: # hack for debug tools only if not hasattr(e, '__annotator_block'): @@ -433,25 +359,24 @@ self.pendingblocks[block] = graph assert block in self.annotated self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -471,14 +396,11 @@ for i in range(len(block.operations)): try: self.bookkeeper.enter((graph, block, i)) - self.consider_op(block.operations[i]) + self.consider_op(block, i) finally: self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +484,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +494,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +530,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell @@ -653,7 +572,8 @@ #___ creating the annotations based on operations ______ - def consider_op(self, op): + def consider_op(self, block, opindex): + op = block.operations[opindex] argcells = [self.binding(a) for a in op.args] consider_meth = getattr(self,'consider_op_'+op.opname, None) @@ -668,16 +588,18 @@ # boom -- in the assert of setbinding() for arg in argcells: if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op) + raise BlockedInference(self, op, opindex) try: resultcell = consider_meth(*argcells) - except Exception: + except Exception, e: graph = self.bookkeeper.position_key[0] - raise_nicer_exception(op, str(graph)) + e.args = e.args + ( + ErrorWrapper(gather_error(self, graph, block, opindex)),) + raise if resultcell is None: resultcell = self.noreturnvalue(op) elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op) # the operation cannot succeed + raise BlockedInference(self, op, opindex) # the operation cannot succeed assert isinstance(resultcell, annmodel.SomeObject) assert isinstance(op.result, Variable) self.setbinding(op.result, resultcell) # bind resultcell to op.result @@ -728,13 +650,14 @@ """This exception signals the type inference engine that the situation is currently blocked, and that it should try to progress elsewhere.""" - def __init__(self, annotator, op): + def __init__(self, annotator, op, opindex): self.annotator = annotator try: self.break_at = annotator.bookkeeper.position_key except AttributeError: self.break_at = None self.op = op + self.opindex = opindex def __repr__(self): if not self.break_at: diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,15 +29,6 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', 'truediv', 'floordiv', 'divmod', 'pow', @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -238,7 +201,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -564,14 +550,30 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - return SomeObject() + raise UnionError("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): return SomeTuple(items = tup1.items + tup2.items) + def eq(tup1tup2): + tup1tup2.union() + return s_Bool + ne = eq + + def lt((tup1, tup2)): + raise Exception("unsupported: (...) < (...)") + def le((tup1, tup2)): + raise Exception("unsupported: (...) <= (...)") + def gt((tup1, tup2)): + raise Exception("unsupported: (...) > (...)") + def ge((tup1, tup2)): + raise Exception("unsupported: (...) >= (...)") + class __extend__(pairtype(SomeDict, SomeDict)): @@ -723,8 +725,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -764,7 +765,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -778,7 +779,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -806,7 +807,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,7 +10,7 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef @@ -148,7 +148,6 @@ self.descs = {} # map Python objects to their XxxDesc wrappers self.methoddescs = {} # map (funcdesc, classdef) to the MethodDesc self.classdefs = [] # list of all ClassDefs - self.pbctypes = {} self.seen_mutable = {} self.listdefs = {} # map position_keys to ListDefs self.dictdefs = {} # map position_keys to DictDefs @@ -167,9 +166,6 @@ self.stats = Stats(self) - # used in SomeObject.__new__ for keeping debugging info - self._isomeobject_coming_from = identity_dict() - delayed_imports() def count(self, category, *args): @@ -275,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() @@ -325,8 +320,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -445,6 +438,12 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if (x is type(None) or # add cases here if needed + x.__module__ == 'pypy.rpython.lltypesystem.lltype'): + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) 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 @@ -455,20 +454,13 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) - elif hasattr(x, '_freeze_') and x._freeze_(): + result = SomePBC([self.getdesc(x)]) + elif hasattr(x, '_freeze_'): + assert x._freeze_() is True # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method # returns True, the instance is considered immutable and becomes @@ -476,16 +468,18 @@ result = SomePBC([self.getdesc(x)]) elif hasattr(x, '__class__') \ and x.__class__.__module__ != '__builtin__': + if hasattr(x, '_cleanup_'): + x._cleanup_() self.see_mutable(x) result = SomeInstance(self.getuniqueclassdef(x.__class__)) elif x is None: return s_None else: - result = SomeObject() + raise Exception("Don't know how to represent %r" % (x,)) if need_const: result.const = x return result - + def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: @@ -509,8 +503,10 @@ elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) - elif (hasattr(pyobj.im_self, '_freeze_') and - pyobj.im_self._freeze_()): # method of frozen + if hasattr(pyobj.im_self, '_cleanup_'): + pyobj.im_self._cleanup_() + if hasattr(pyobj.im_self, '_freeze_'): # method of frozen + assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc(self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc @@ -529,9 +525,9 @@ name) else: # must be a frozen pre-built constant, but let's check - try: - assert pyobj._freeze_() - except AttributeError: + if hasattr(pyobj, '_freeze_'): + assert pyobj._freeze_() is True + else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: @@ -551,11 +547,7 @@ return False def getfrozen(self, pyobj): - result = description.FrozenDesc(self, pyobj) - cls = result.knowntype - if cls not in self.pbctypes: - self.pbctypes[cls] = True - return result + return description.FrozenDesc(self, pyobj) def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, flags={}): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -150,7 +150,7 @@ def builtin_isinstance(s_obj, s_type, variables=None): - r = SomeBool() + r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,8 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + + if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -247,13 +247,16 @@ defs_s = [] if graph is None: signature = self.signature - defaults = self.defaults + defaults = self.defaults else: signature = graph.signature - defaults = graph.defaults + defaults = graph.defaults if defaults: for x in defaults: - defs_s.append(self.bookkeeper.immutablevalue(x)) + if x is NODEFAULT: + defs_s.append(None) + else: + defs_s.append(self.bookkeeper.immutablevalue(x)) try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,8 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype + immutable = False knowntype = object - immutable = False + + def __init__(self): + assert type(self) is not SomeObject def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -105,60 +106,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: - self = new(cls, *args, **kw) - if DEBUG: - try: - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - position_key = bookkeeper.position_key - except AttributeError: - pass - else: - bookkeeper._isomeobject_coming_from[self] = position_key, None + def can_be_none(self): + return True + + def nonnoneify(self): return self - def origin(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] - origin = property(origin) - def caused_by_merge(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] - def set_caused_by_merge(self, nvalue): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return - bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue - caused_by_merge = property(caused_by_merge, set_caused_by_merge) - del set_caused_by_merge +class SomeType(SomeObject): + "Stands for a type. We might not be sure which one it is." + knowntype = type + immutable = True def can_be_none(self): - return True - - def nonnoneify(self): - return self + return False class SomeFloat(SomeObject): "Stands for a float or an integer." @@ -517,6 +486,7 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) @@ -710,14 +680,8 @@ # this is just a performance shortcut if s1 != s2: s1 = pair(s1, s2).union() - if DEBUG: - if s1.caused_by_merge is None and len(somevalues) > 1: - s1.caused_by_merge = somevalues return s1 -def isdegenerated(s_value): - return s_value.__class__ is SomeObject and s_value.knowntype is not type - # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -10,7 +10,6 @@ class BasicAnnotatorPolicy(object): - allow_someobjects = True def event(pol, bookkeeper, what, *args): pass @@ -80,6 +79,3 @@ def specialize__ll_and_arg(pol, *args): from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args) - -class StrictAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -3,9 +3,9 @@ from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF -from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF + unionof, SomeUnicodeString, SomeType +from pypy.annotation.listdef import ListDef +from pypy.annotation.dictdef import DictDef _annotation_cache = {} @@ -78,24 +78,18 @@ return SomeString() elif t is unicode: return SomeUnicodeString() - elif t is list: - return SomeList(MOST_GENERAL_LISTDEF) - elif t is dict: - return SomeDict(MOST_GENERAL_DICTDEF) - # can't do tuple elif t is types.NoneType: return s_None elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) - elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes: + elif t is type: + return SomeType() + elif bookkeeper and not hasattr(t, '_freeze_'): classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) else: - o = SomeObject() - if t != object: - o.knowntype = t - return o + raise AssertionError("annotationoftype(%r)" % (t,)) class Sig(object): diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -24,7 +24,7 @@ assert isinstance(s_list, annmodel.SomeList) return s_list.listdef.listitem.s_value -def somelist(s_type=annmodel.SomeObject()): +def somelist(s_type): return annmodel.SomeList(ListDef(None, s_type)) def dictkey(s_dict): @@ -35,7 +35,7 @@ assert isinstance(s_dict, annmodel.SomeDict) return s_dict.dictdef.dictvalue.s_value -def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()): +def somedict(s_key, s_value): return annmodel.SomeDict(DictDef(None, s_key, s_value)) @@ -205,15 +205,6 @@ annmodel.SomeInteger() ]) - def test_inheritance2(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet._inheritance_nonrunnable, []) - # result should be exactly: - assert s == annmodel.SomeTuple([ - annmodel.SomeInteger(), - annmodel.SomeObject() - ]) - def test_poor_man_range(self): a = self.RPythonAnnotator() s = a.build_types(snippet.poor_man_range, [int]) @@ -336,9 +327,13 @@ def test_flow_type_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_type_info, [object]) + s = a.build_types(snippet.flow_type_info, [int]) a.simplify() - #a.translator.view() + assert s.knowntype == int + + a = self.RPythonAnnotator() + s = a.build_types(snippet.flow_type_info, [str]) + a.simplify() assert s.knowntype == int def test_flow_type_info_2(self): @@ -351,7 +346,7 @@ def test_flow_usertype_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_usertype_info, [object]) + s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit]) #a.translator.view() assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit) @@ -363,13 +358,6 @@ assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit) - def test_flow_identity_info(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_identity_info, [object, object]) - a.simplify() - #a.translator.view() - assert s == a.bookkeeper.immutablevalue((None, None)) - def test_mergefunctions(self): a = self.RPythonAnnotator() s = a.build_types(snippet.mergefunctions, [int]) @@ -431,11 +419,11 @@ # the annotator (it doesn't check that they operate property, though) for example, methname, s_example in [ ('', 'join', annmodel.SomeString()), - ([], 'append', somelist()), - ([], 'extend', somelist()), - ([], 'reverse', somelist()), - ([], 'insert', somelist()), - ([], 'pop', somelist()), + ([], 'append', somelist(annmodel.s_Int)), + ([], 'extend', somelist(annmodel.s_Int)), + ([], 'reverse', somelist(annmodel.s_Int)), + ([], 'insert', somelist(annmodel.s_Int)), + ([], 'pop', somelist(annmodel.s_Int)), ]: constmeth = getattr(example, methname) s_constmeth = iv(constmeth) @@ -497,12 +485,12 @@ def test_simple_slicing(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_slice, [list]) + s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeList) def test_simple_iter_list(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_iter, [list]) + s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeIterator) def test_simple_iter_next(self): @@ -542,11 +530,6 @@ assert isinstance(dictkey(s), annmodel.SomeInteger) assert isinstance(dictvalue(s), annmodel.SomeInteger) - a = self.RPythonAnnotator() - s = a.build_types(snippet.dict_update, [str]) - assert not isinstance(dictkey(s), annmodel.SomeString) - assert not isinstance(dictvalue(s), annmodel.SomeString) - def test_dict_update_2(self): a = self.RPythonAnnotator() def g(n): @@ -568,7 +551,7 @@ def test_dict_keys2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_keys2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_values(self): a = self.RPythonAnnotator() @@ -578,7 +561,7 @@ def test_dict_values2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_items(self): a = self.RPythonAnnotator() @@ -643,25 +626,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_bltin_code_frame_confusion(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_confusion,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - # annotator confused by original bltin code/frame setup, we just get SomeObject here - assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - - def test_bltin_code_frame_reorg(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_reorg,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - assert isinstance(a.binding(f_flowgraph.getreturnvar()), - annmodel.SomeInteger) - assert isinstance(a.binding(g_flowgraph.getreturnvar()), - annmodel.SomeString) - def test_propagation_of_fresh_instances_through_attrs(self): a = self.RPythonAnnotator() s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int]) @@ -748,14 +712,15 @@ assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc) def test_type_is(self): - class C(object): + class B(object): + pass + class C(B): pass def f(x): - if type(x) is C: - return x - raise Exception - a = self.RPythonAnnotator() - s = a.build_types(f, [object]) + assert type(x) is C + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) def test_ann_assert(self): @@ -793,24 +758,30 @@ return None a = self.RPythonAnnotator() - s = a.build_types(f, [list]) + s = a.build_types(f, [somelist(annmodel.s_Int)]) assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list def test_freeze_protocol(self): class Stuff: - def __init__(self, flag): + def __init__(self): self.called = False - self.flag = flag def _freeze_(self): self.called = True - return self.flag - myobj = Stuff(True) + return True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - myobj = Stuff(False) + + def test_cleanup_protocol(self): + class Stuff: + def __init__(self): + self.called = False + def _cleanup_(self): + self.called = True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called @@ -854,7 +825,7 @@ def f(a,b): return bool(a) or bool(b) a = self.RPythonAnnotator() - s = a.build_types(f, [int,list]) + s = a.build_types(f, [int, somelist(annmodel.s_Int)]) assert s.knowntype == bool def test_float(self): @@ -1299,22 +1270,6 @@ assert isinstance(s_item, annmodel.SomeInstance) assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - def test_assert_type_is_list_doesnt_lose_info(self): - class T(object): - pass - def g(l): - assert type(l) is list - return l - def f(): - l = [T()] - return g(l) - a = self.RPythonAnnotator() - s = a.build_types(f, []) - s_item = listitem(s) - assert isinstance(s_item, annmodel.SomeInstance) - assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - - def test_int_str_mul(self): def f(x,a,b): return a*x+x*b @@ -1395,11 +1350,10 @@ except KeyError: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.const = KeyError t.is_type_of = [ev] assert a.binding(et) == t @@ -1412,11 +1366,10 @@ except: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t @@ -1448,11 +1401,10 @@ finally: h() a = self.RPythonAnnotator() - a.build_types(f, [int, list]) + a.build_types(f, [int, somelist(annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) @@ -1474,24 +1426,11 @@ a.build_types(f, []) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_sys_attrs(self): - def f(): - return sys.argv[0] - a = self.RPythonAnnotator() - try: - oldvalue = sys.argv - sys.argv = [] - s = a.build_types(f, []) - finally: - sys.argv = oldvalue - assert s is not None - def test_pow(self): def f(n): n **= 2 @@ -1523,7 +1462,6 @@ a = self.RPythonAnnotator() 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)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] def test_is_true_coalesce2(self): def f(a,b,a1,b1,c,d,e): @@ -1532,9 +1470,12 @@ return d,c return e,c a = self.RPythonAnnotator() - s = a.build_types(f, [int, str, float, list, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) - assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] + s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int), + 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_coalesce_sanity(self): def f(a): @@ -1954,16 +1895,7 @@ t = type(x) return issubclass(t, A) - def f(): - x = g(1) - y = g(0) - return x or y - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert s.knowntype == bool - assert not s.is_constant() - a = self.RPythonAnnotator() - # sanity check + a = self.RPythonAnnotator() x = annmodel.SomeInteger() x.const = 1 s = a.build_types(g, [x]) @@ -2383,8 +2315,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int]) - assert s.__class__ == annmodel.SomeObject - assert s.knowntype == type + assert isinstance(s, annmodel.SomeType) def test_annotate_iter_empty_container(self): def f(): @@ -3075,7 +3006,6 @@ v = -maxint return intmask(v * 10) P = policy.AnnotatorPolicy() - P.allow_someobjects = False a = self.RPythonAnnotator(policy=P) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) @@ -3859,6 +3789,32 @@ a = self.RPythonAnnotator() py.test.raises(Exception, a.build_types, fn, []) + def test_lower_char(self): + def fn(c): + return c.lower() + a = self.RPythonAnnotator() + s = a.build_types(fn, [annmodel.SomeChar()]) + assert s == annmodel.SomeChar() + + def test_isinstance_double_const(self): + class X(object): + def _freeze_(self): + return True + + x = X() + + def f(i): + if i: + x1 = x + else: + x1 = None + print "hello" # this is to force the merge of blocks + return isinstance(x1, X) + + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeBool) + def g(n): return [0,1,2,n] diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -2,20 +2,20 @@ import autopath import py from pypy.annotation.model import * -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF +from pypy.annotation.listdef import ListDef from pypy.rpython.ootypesystem.ootype import ROOT listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) -s1 = SomeObject() +s1 = SomeType() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s1,s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s1, s2, s3, s4, s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -42,7 +42,7 @@ def test_equality(): assert s1 != s2 != s3 != s4 != s5 != s6 - assert s1 == SomeObject() + assert s1 == SomeType() assert s2 == SomeInteger(nonneg=True) assert s3 == SomeInteger(nonneg=False) assert s4 == SomeList(listdef1) @@ -51,19 +51,11 @@ def test_contains(): assert ([(s,t) for s in slist for t in slist if s.contains(t)] == - [(s1,s1), (s1,s2), (s1,s3), (s1,s4), (s1,s6), - (s2,s2), (s2,s6), - (s3,s2), (s3,s3), (s3,s6), - (s4,s4), (s4,s6), - (s6,s6)]) - -def test_union(): - assert ([unionof(s,t) for s in slist for t in slist] == - [s1, s1, s1, s1, s1, - s1, s2, s3, s1, s2, - s1, s3, s3, s1, s3, - s1, s1, s1, s4, s4, - s1, s2, s3, s4, s6]) + [(s1, s1), (s1, s6), + (s2, s2), (s2, s6), + (s3, s2), (s3, s3), (s3, s6), + (s4, s4), (s4, s6), + (s6, s6)]) def test_commonbase_simple(): class A0: @@ -100,9 +92,10 @@ def test_list_contains(): listdef1 = ListDef(None, SomeInteger(nonneg=True)) s1 = SomeList(listdef1) - s2 = SomeList(MOST_GENERAL_LISTDEF) + listdef2 = ListDef(None, SomeInteger(nonneg=False)) + s2 = SomeList(listdef2) assert s1 != s2 - assert s2.contains(s1) + assert not s2.contains(s1) assert s1 != s2 assert not s1.contains(s2) assert s1 != s2 diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -7,7 +7,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -39,14 +39,7 @@ def type(obj, *moreargs): if moreargs: raise Exception, 'type() called with more than one argument' - if obj.is_constant(): - if isinstance(obj, SomeInstance): - r = SomePBC([obj.classdef.classdesc]) - else: - r = immutablevalue(obj.knowntype) - else: - r = SomeObject() - r.knowntype = type + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator @@ -133,9 +126,6 @@ def float(obj): return SomeFloat() - def long(obj): - return SomeObject() # XXX - def delattr(obj, s_attr): if obj.__class__ != SomeObject or obj.knowntype != object: getbookkeeper().warning( @@ -154,18 +144,17 @@ def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - s_method = obj.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)) - else: - getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' % - (obj, s_attr)) - return SomeObject() + 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)) + attr = s_attr.const + s_method = obj.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)) getattr.can_only_throw = [] def bind_callables_under(obj, classdef, name): @@ -586,6 +575,12 @@ def method_isupper(chr): return s_Bool + def method_lower(chr): + return chr + + def method_upper(chr): + return chr + class __extend__(SomeIterator): def iter(itr): diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -2,9 +2,9 @@ """ Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME -Print a report for the static data informations contained in FILENAME +Print a report for the static data information contained in FILENAME -The static data informations are saved in the file staticdata.info when +The static data information is saved in the file staticdata.info when passing --dump_static_data_info to translate.py. Options: diff --git a/pypy/bin/translatorshell.py b/pypy/bin/translatorshell.py --- a/pypy/bin/translatorshell.py +++ b/pypy/bin/translatorshell.py @@ -8,10 +8,10 @@ Example: - t = Translation(func) + t = Translation(func, [int]) # pass the list of args types t.view() # control flow graph - t.annotate([int]) # pass the list of args types + t.annotate() t.view() # graph + annotations under the mouse t.rtype() # use low level operations diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py --- a/pypy/config/test/test_config.py +++ b/pypy/config/test/test_config.py @@ -111,8 +111,8 @@ else: return 'foo' - t = Translation(f) - t.rtype([int]) + t = Translation(f, [int]) + t.rtype() block = t.context.graphs[0].startblock assert len(block.exits[0].target.operations) == 0 diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -129,8 +129,6 @@ # misc BoolOption("verbose", "Print extra information", default=False), - BoolOption("debug", "Record extra annotation information", - cmdline="-d --debug", default=True), BoolOption("insist", "Try hard to go on RTyping", default=False, cmdline="--insist"), StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -101,15 +101,7 @@ def maketestobjspace(config=None): if config is None: config = make_config(option) - try: - space = make_objspace(config) - except OperationError, e: - check_keyboard_interrupt(e) - if option.verbose: - import traceback - traceback.print_exc() - py.test.fail("fatal: cannot initialize objspace: %r" % - (config.objspace.name,)) + space = make_objspace(config) space.startup() # Initialize all builtin modules space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), appsupport.build_pytest_assertion(space)) diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -238,7 +238,7 @@ interpreter`_. .. _`documentation index`: index.html#project-documentation -.. _`getting-started`: getting-started.html +.. _`getting-started`: getting-started-dev.html .. _`PyPy's approach to virtual machine construction`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dls2006/pypy-vm-construction.pdf .. _`the translation document`: translation.html .. _`RPython toolchain`: translation.html diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -23,7 +23,7 @@ The tools required to cross translate from a Linux based host to an ARM based Linux target are: -- A checkout of PyPy's arm-backend-2 branch. +- A checkout of PyPy (default branch). - The GCC ARM cross compiler (on Ubuntu it is the ``gcc-arm-linux-gnueabi package``) but other toolchains should also work. - Scratchbox 2, a cross-compilation engine (``scratchbox2`` Ubuntu package). - A 32-bit PyPy or Python. @@ -147,4 +147,4 @@ return 0 def target(*args): - return main, None \ No newline at end of file + return main, None diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -9,7 +9,7 @@ `import` statements:: from pypy.interpreter.baseobjspace import Wrappable - from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w @@ -41,9 +41,6 @@ llexternal functions. For a typical usage, see `pypy.rlib.rsocket.RSocket.getsockopt_int`. -- Support context managers and the `with` statement. This could be a workaround - before the previous point is available. - Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -27,7 +27,7 @@ ``pypy/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: - >>> t = Translation(snippet.is_perfect_number) + >>> t = Translation(snippet.is_perfect_number, [int]) >>> t.view() After that, the graph viewer pops up, that lets you interactively inspect the @@ -40,7 +40,7 @@ We have a type annotator that can completely infer types for functions like ``is_perfect_number`` (as well as for much larger examples):: - >>> t.annotate([int]) + >>> t.annotate() >>> t.view() Move the mouse over variable names (in red) to see their inferred types. @@ -74,8 +74,8 @@ >>> def myfunc(a, b): return a+b ... - >>> t = Translation(myfunc) - >>> t.annotate([int, int]) + >>> t = Translation(myfunc, [int, int]) + >>> t.annotate() >>> f = t.compile_cli() # or compile_jvm() >>> f(4, 5) 9 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 @@ -18,6 +18,7 @@ .. branch: numpypy_count_nonzero .. branch: numpy-refactor Remove numpy lazy evaluation and simplify everything +.. branch: numpy-reintroduce-jit-drivers .. branch: numpy-fancy-indexing Support for array[array-of-ints] in numpy .. branch: even-more-jit-hooks @@ -35,6 +36,11 @@ .. branch: stdlib-2.7.3 The stdlib was updated to version 2.7.3 +.. branch: numpypy-complex2 +Complex dtype support for numpy +.. branch: kill-someobject +major cleanups including killing some object support + .. "uninteresting" branches that we should just ignore for the whatsnew: .. branch: slightly-shorter-c 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 @@ -474,7 +474,7 @@ if f_type == F_BLOCK_LOOP: self.emit_jump(ops.CONTINUE_LOOP, block, True) break - if self.frame_blocks[i][0] == F_BLOCK_FINALLY_END: + if f_type == F_BLOCK_FINALLY_END: self.error("'continue' not supported inside 'finally' " \ "clause", cont) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -719,8 +719,15 @@ # done by a method call on w_two (and not on w_one, because of the # expected programming style where we say "if x is None" or # "if x is object"). + assert w_two is not None return w_two.is_w(self, w_one) + def is_none(self, w_obj): + """ mostly for checking inputargs that have unwrap_spec and + can accept both w_None and None + """ + return w_obj is None or self.is_w(w_obj, self.w_None) + def id(self, w_obj): w_result = w_obj.immutable_unique_id(self) if w_result is None: @@ -804,7 +811,7 @@ interpreter class (a subclass of Wrappable). """ assert RequiredClass is not None - if can_be_None and self.is_w(w_obj, self.w_None): + if can_be_None and self.is_none(w_obj): return None obj = self.interpclass_w(w_obj) if not isinstance(obj, RequiredClass): # or obj is None diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -205,11 +205,11 @@ code = space.interp_w(Code, w_code) if not space.is_true(space.isinstance(w_globals, space.w_dict)): raise OperationError(space.w_TypeError, space.wrap("expected dict")) - if not space.is_w(w_name, space.w_None): + if not space.is_none(w_name): name = space.str_w(w_name) else: name = None - if not space.is_w(w_argdefs, space.w_None): + if not space.is_none(w_argdefs): defs_w = space.fixedview(w_argdefs) else: defs_w = [] @@ -217,7 +217,7 @@ from pypy.interpreter.pycode import PyCode if isinstance(code, PyCode): nfreevars = len(code.co_freevars) - if space.is_w(w_closure, space.w_None) and nfreevars == 0: + if space.is_none(w_closure) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) @@ -244,7 +244,7 @@ # delicate _all = {'': None} - def _freeze_(self): + def _cleanup_(self): from pypy.interpreter.gateway import BuiltinCode if isinstance(self.code, BuiltinCode): # we have been seen by other means so rtyping should not choke @@ -343,7 +343,7 @@ def fget_func_defaults(self, space): values_w = self.defs_w # the `None in values_w` check here is to ensure that interp-level - # functions with a default of NoneNotWrapped do not get their defaults + # functions with a default of None do not get their defaults # exposed at applevel if not values_w or None in values_w: return space.w_None @@ -424,11 +424,12 @@ w_res = space.w_None return w_res + def descr_function_get(space, w_function, w_obj, w_cls=None): """functionobject.__get__(obj[, type]) -> method""" # this is not defined as a method on Function because it's generally # useful logic: w_function can be any callable. It is used by Method too. - asking_for_bound = (space.is_w(w_cls, space.w_None) or + asking_for_bound = (space.is_none(w_cls) or not space.is_w(w_obj, space.w_None) or space.is_w(w_cls, space.type(space.w_None))) if asking_for_bound: @@ -445,12 +446,15 @@ self.space = space self.w_function = w_function self.w_instance = w_instance # or None + if w_class is None: + w_class = space.w_None self.w_class = w_class # possibly space.w_None - def descr_method__new__(space, w_subtype, w_function, w_instance, w_class=None): + def descr_method__new__(space, w_subtype, w_function, w_instance, + w_class=None): if space.is_w(w_instance, space.w_None): w_instance = None - if w_instance is None and space.is_w(w_class, space.w_None): + if w_instance is None and space.is_none(w_class): raise OperationError(space.w_TypeError, space.wrap("unbound methods must have class")) method = space.allocate_instance(Method, w_subtype) @@ -610,7 +614,7 @@ self.w_function = w_function def descr_classmethod_get(self, space, w_obj, w_klass=None): - if space.is_w(w_klass, space.w_None): + if space.is_none(w_klass): w_klass = space.type(w_obj) return space.wrap(Method(space, self.w_function, w_klass, space.w_None)) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -7,31 +7,29 @@ """ -import types, sys, os -from pypy.tool.compat import md5 +import sys +import os +import types -NoneNotWrapped = object() +import py -from pypy.tool.sourcetools import func_with_new_name +from pypy.interpreter.eval import Code +from pypy.interpreter.argument import Arguments, Signature +from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable, + SpaceCache, DescrMismatch) from pypy.interpreter.error import OperationError -from pypy.interpreter import eval -from pypy.interpreter.function import Function, Method, ClassMethod -from pypy.interpreter.function import FunctionWithFixedCode -from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable -from pypy.interpreter.baseobjspace import Wrappable, SpaceCache, DescrMismatch -from pypy.interpreter.argument import Arguments, Signature -from pypy.tool.sourcetools import NiceCompile, compile2 -from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode from pypy.rlib import rstackovf from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.tool.sourcetools import func_with_new_name, compile2 + # internal non-translatable parts: -import py - class SignatureBuilder(object): "NOT_RPYTHON" def __init__(self, func=None, argnames=None, varargname=None, - kwargname=None, name = None): + kwargname=None, name=None): self.func = func if func is not None: self.name = func.__name__ @@ -60,10 +58,12 @@ if isinstance(el, str): getattr(self, "visit_%s" % (el,))(el, *args) elif isinstance(el, tuple): - if el[0] == 'self': + if el[0] == 'INTERNAL:self': self.visit_self(el[1], *args) else: - self.visit_function(el, *args) + assert False, "not supported any more, use WrappedDefault" + elif isinstance(el, WrappedDefault): + self.visit__W_Root(W_Root, *args) elif isinstance(el, type): for typ in self.bases_order: if issubclass(el, typ): @@ -81,8 +81,8 @@ for el in unwrap_spec: dispatch(el, *extra) + class UnwrapSpecEmit(UnwrapSpecRecipe): From noreply at buildbot.pypy.org Sat Oct 13 18:44:31 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 13 Oct 2012 18:44:31 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (fijal, arigo) Message-ID: <20121013164431.2F3791C015F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58105:716a9d2d6183 Date: 2012-10-13 18:44 +0200 http://bitbucket.org/pypy/pypy/changeset/716a9d2d6183/ Log: (fijal, arigo) Start serious fixing and refactoring in the frontend. diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -18,7 +18,6 @@ from pypy.jit.metainterp import resoperation from pypy.jit.metainterp.resoperation import rop -from pypy.jit.metainterp.jitframe import JITFRAMEPTR from pypy.jit.backend.llgraph import symbolic from pypy.jit.codewriter import longlong from pypy.jit.codewriter.effectinfo import EffectInfo @@ -481,7 +480,6 @@ class Frame(object): OPHANDLERS = [None] * (rop._LAST+1) - _TYPE = JITFRAMEPTR.TO def __init__(self, cpu): self.verbose = False @@ -517,6 +515,7 @@ """Execute all operations in a loop, possibly following to other loops as well. """ + assert self._may_force == -1 assert self._last_exception is None, "exception left behind" verbose = True self.opindex = 0 @@ -578,7 +577,11 @@ if self.verbose: log.trace('finished: %s' % ( ', '.join(map(str, args)),)) - self.fail_args = args + assert len(op.args) <= 1, "FINISH with more than 1 arg" + self.finish_args = op.args + self.fail_args = op.fail_args + self.fail_index = op.fail_index + self._may_force = self.opindex return else: @@ -1066,16 +1069,15 @@ # # Emulate the fast path failindex = frame_descr_index(subframe) - realsubframe = lltype.cast_opaque_ptr(JITFRAMEPTR, subframe) if failindex == self.cpu.done_with_this_frame_int_v: reset_vable(jd, vable) - return self.cpu.get_latest_value_int(realsubframe, 0) + return self.cpu.get_latest_value_int(subframe, 0) if failindex == self.cpu.done_with_this_frame_ref_v: reset_vable(jd, vable) - return self.cpu.get_latest_value_ref(realsubframe, 0) + return self.cpu.get_latest_value_ref(subframe, 0) if failindex == self.cpu.done_with_this_frame_float_v: reset_vable(jd, vable) - return self.cpu.get_latest_value_float(realsubframe, 0) + return self.cpu.get_latest_value_float(subframe, 0) if failindex == self.cpu.done_with_this_frame_void_v: reset_vable(jd, vable) return None @@ -1083,7 +1085,7 @@ assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish assembler_helper = assembler_helper_ptr._obj._callable try: - return assembler_helper(realsubframe, vable) + return assembler_helper(subframe, vable) except LLException, lle: assert self._last_exception is None, "exception left behind" self._last_exception = lle @@ -1320,7 +1322,6 @@ import sys, pdb pdb.post_mortem(sys.exc_info()[2]) raise - del frame.env return result def frame_descr_index(frame): @@ -1392,10 +1393,13 @@ frame._forced = True assert frame._may_force >= 0 call_op = frame.loop.operations[frame._may_force] - guard_op = frame.loop.operations[frame._may_force+1] opnum = call_op.opnum - assert opnum == rop.CALL_MAY_FORCE or opnum == rop.CALL_ASSEMBLER - frame._populate_fail_args(guard_op, skip=call_op.result) + if opnum != rop.FINISH: + assert opnum == rop.CALL_MAY_FORCE or opnum == rop.CALL_ASSEMBLER + guard_op = frame.loop.operations[frame._may_force+1] + frame._populate_fail_args(guard_op, skip=call_op.result) + else: + frame._populate_fail_args(call_op) return frame.fail_index ##def cast_adr_to_int(memocast, adr): @@ -1863,12 +1867,12 @@ COMPILEDLOOP = lltype.Ptr(lltype.OpaqueType("CompiledLoop")) -FRAME = JITFRAMEPTR -#OOFRAME = lltype.Ptr(lltype.OpaqueType("OOFrame")) +FRAME = lltype.Ptr(lltype.OpaqueType("Frame")) +OOFRAME = lltype.Ptr(lltype.OpaqueType("OOFrame")) _TO_OPAQUE[CompiledLoop] = COMPILEDLOOP.TO -#_TO_OPAQUE[Frame] = FRAME.TO -#_TO_OPAQUE[OOFrame] = OOFRAME.TO +_TO_OPAQUE[Frame] = FRAME.TO +_TO_OPAQUE[OOFrame] = OOFRAME.TO s_CompiledLoop = annmodel.SomePtr(COMPILEDLOOP) s_Frame = annmodel.SomePtr(FRAME) diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -12,7 +12,6 @@ from pypy.jit.metainterp.history import REF, INT, FLOAT, STRUCT from pypy.jit.metainterp.warmstate import unwrap from pypy.jit.metainterp.resoperation import rop -from pypy.jit.metainterp.jitframe import JITFRAMEPTR from pypy.jit.backend import model from pypy.jit.backend.llgraph import llimpl, symbolic from pypy.jit.metainterp.typesystem import llhelper, oohelper @@ -216,7 +215,7 @@ else: raise Exception("'%s' args contain: %r" % (op.getopname(), x)) - if op.is_guard(): + if op.is_guard() or op.getopnum() == rop.FINISH: faildescr = op.getdescr() assert isinstance(faildescr, history.AbstractFailDescr) faildescr._fail_args_types = [] @@ -252,9 +251,7 @@ targettoken = op.getdescr() llimpl.compile_add_jump_target(c, targettoken, clt) elif op.getopnum() == rop.FINISH: - faildescr = op.getdescr() - index = self.get_fail_descr_number(faildescr) - llimpl.compile_add_fail(c, index) + pass else: assert False, "unknown operation" diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -153,11 +153,19 @@ necessarily correct after a FINISH.""" return len(jitframe.jf_gcvalues) - def grab_exc_value(self, jitframe): - """Return and clear the exception set by the latest execute_token(), - when it exits due to a failure of a GUARD_EXCEPTION or - GUARD_NO_EXCEPTION. (Returns a GCREF)""" # XXX remove me - return jitframe.jf_excvalue + def get_finish_value_int(self, jitframe): + """Return the result passed to FINISH, which was an int.""" + return jitframe.jf_finish_int + + def get_finish_value_float(self, jitframe): + """Return the result passed to FINISH, which was a FLOATSTORAGE.""" + return jitframe.jf_finish_float + + def get_finish_value_ref(self, jitframe): + """Return and clear the result passed to FINISH, which was a GCREF. + Also used when it exits due to a failure of a GUARD_EXCEPTION or + GUARD_NO_EXCEPTION, to return the exception.""" + return jitframe.jf_finish_ref def redirect_call_assembler(self, oldlooptoken, newlooptoken): """Redirect oldlooptoken to newlooptoken. More precisely, it is diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -1549,7 +1549,6 @@ def resume_in_blackhole(metainterp_sd, jitdriver_sd, jitframe, resumedescr, all_virtuals=None): from pypy.jit.metainterp.resume import blackhole_from_resumedata - #debug_start('jit-blackhole') blackholeinterp = blackhole_from_resumedata( metainterp_sd.blackholeinterpbuilder, jitdriver_sd, @@ -1564,15 +1563,11 @@ current_exc = blackholeinterp._prepare_resume_from_failure( resumedescr.guard_opnum, jitframe, dont_change_position) - #try: _run_forever(blackholeinterp, current_exc) - #finally: - #debug_stop('jit-blackhole') def convert_and_run_from_pyjitpl(metainterp, raising_exception=False): # Get a chain of blackhole interpreters and fill them by copying # 'metainterp.framestack'. - #debug_start('jit-blackhole') metainterp_sd = metainterp.staticdata nextbh = None for frame in metainterp.framestack: @@ -1590,7 +1585,4 @@ firstbh.exception_last_value = current_exc current_exc = lltype.nullptr(rclass.OBJECTPTR.TO) # - #try: _run_forever(firstbh, current_exc) - #finally: - #debug_stop('jit-blackhole') diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -411,71 +411,6 @@ # ____________________________________________________________ -class _DoneWithThisFrameDescr(AbstractFailDescr): - pass - -class DoneWithThisFrameDescrVoid(_DoneWithThisFrameDescr): - def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): - assert jitdriver_sd.result_type == history.VOID - raise metainterp_sd.DoneWithThisFrameVoid() - -class DoneWithThisFrameDescrInt(_DoneWithThisFrameDescr): - def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): - assert jitdriver_sd.result_type == history.INT - result = metainterp_sd.cpu.get_latest_value_int(jitframe, 0) - raise metainterp_sd.DoneWithThisFrameInt(result) - -class DoneWithThisFrameDescrRef(_DoneWithThisFrameDescr): - def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): - assert jitdriver_sd.result_type == history.REF - cpu = metainterp_sd.cpu - result = cpu.get_latest_value_ref(jitframe, 0) - raise metainterp_sd.DoneWithThisFrameRef(cpu, result) - -class DoneWithThisFrameDescrFloat(_DoneWithThisFrameDescr): - def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): - assert jitdriver_sd.result_type == history.FLOAT - result = metainterp_sd.cpu.get_latest_value_float(jitframe, 0) - raise metainterp_sd.DoneWithThisFrameFloat(result) - -class ExitFrameWithExceptionDescrRef(_DoneWithThisFrameDescr): - def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): - cpu = metainterp_sd.cpu - value = cpu.get_latest_value_ref(jitframe, 0) - raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value) - - -class TerminatingLoopToken(JitCellToken): # FIXME: kill? - terminating = True - - def __init__(self, nargs, finishdescr): - self.finishdescr = finishdescr - -def make_done_loop_tokens(): - done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid() - done_with_this_frame_descr_int = DoneWithThisFrameDescrInt() - done_with_this_frame_descr_ref = DoneWithThisFrameDescrRef() - done_with_this_frame_descr_float = DoneWithThisFrameDescrFloat() - exit_frame_with_exception_descr_ref = ExitFrameWithExceptionDescrRef() - - # pseudo loop tokens to make the life of optimize.py easier - return {'loop_tokens_done_with_this_frame_int': [ - TerminatingLoopToken(1, done_with_this_frame_descr_int) - ], - 'loop_tokens_done_with_this_frame_ref': [ - TerminatingLoopToken(1, done_with_this_frame_descr_ref) - ], - 'loop_tokens_done_with_this_frame_float': [ - TerminatingLoopToken(1, done_with_this_frame_descr_float) - ], - 'loop_tokens_done_with_this_frame_void': [ - TerminatingLoopToken(0, done_with_this_frame_descr_void) - ], - 'loop_tokens_exit_frame_with_exception_ref': [ - TerminatingLoopToken(1, exit_frame_with_exception_descr_ref) - ], - } - class ResumeDescr(AbstractFailDescr): pass @@ -698,7 +633,8 @@ # future failure of the GUARD_NOT_FORCED self.save_data(jitframe, all_virtuals) - def save_data(self, key, value): + def save_data(self, jitframe, value): + return # XXXXX globaldata = self.metainterp_sd.globaldata if we_are_translated(): assert key not in globaldata.resume_virtuals @@ -710,6 +646,7 @@ rv.append((key, value)) def fetch_data(self, key): + XXXXX globaldata = self.metainterp_sd.globaldata if we_are_translated(): assert key in globaldata.resume_virtuals @@ -727,8 +664,7 @@ return data def _clone_if_mutable(self): - res = ResumeGuardForcedDescr(self.metainterp_sd, - self.jitdriver_sd) + res = self.__class__(self.metainterp_sd, self.jitdriver_sd) self.copy_all_attributes_into(res) return res @@ -815,6 +751,46 @@ metainterp_sd.stats.add_jitcell_token(jitcell_token) +_DoneWithThisFrameDescr = ResumeGuardForcedDescr # XXX replace me + +class DoneWithThisFrameDescrVoid(_DoneWithThisFrameDescr): + def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): + assert jitdriver_sd is self.jitdriver_sd + assert jitdriver_sd.result_type == history.VOID + raise metainterp_sd.DoneWithThisFrameVoid() + +class DoneWithThisFrameDescrInt(_DoneWithThisFrameDescr): + def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): + assert jitdriver_sd is self.jitdriver_sd + assert jitdriver_sd.result_type == history.INT + result = metainterp_sd.cpu.get_finish_value_int(jitframe) + raise metainterp_sd.DoneWithThisFrameInt(result) + +class DoneWithThisFrameDescrRef(_DoneWithThisFrameDescr): + def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): + assert jitdriver_sd is self.jitdriver_sd + assert jitdriver_sd.result_type == history.REF + cpu = metainterp_sd.cpu + result = cpu.get_finish_value_ref(jitframe) + raise metainterp_sd.DoneWithThisFrameRef(cpu, result) + +class DoneWithThisFrameDescrFloat(_DoneWithThisFrameDescr): + def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): + assert jitdriver_sd is self.jitdriver_sd + assert jitdriver_sd.result_type == history.FLOAT + result = metainterp_sd.cpu.get_finish_value_float(jitframe) + raise metainterp_sd.DoneWithThisFrameFloat(result) + +class ExitFrameWithExceptionDescrRef(_DoneWithThisFrameDescr): + def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): + assert jitdriver_sd is self.jitdriver_sd + cpu = metainterp_sd.cpu + value = cpu.get_finish_value_ref(jitframe) + raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value) + +# ____________________________________________________________ + + def compile_trace(metainterp, resumekey, resume_at_jump_descr=None): """Try to compile a new bridge leading from the beginning of the history to some existing place. @@ -874,6 +850,7 @@ calls back the interpreter. Used temporarily: a fully compiled version of the code may end up replacing it. """ + XXXX # fix me jitcell_token = make_jitcell_token(jitdriver_sd) nb_red_args = jitdriver_sd.num_red_args assert len(redargtypes) == nb_red_args diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py --- a/pypy/jit/metainterp/history.py +++ b/pypy/jit/metainterp/history.py @@ -654,7 +654,6 @@ target_tokens = None failed_states = None retraced_count = 0 - terminating = False # see TerminatingLoopToken in compile.py invalidated = False outermost_jitdriver_sd = None # and more data specified by the backend when the loop is compiled @@ -784,7 +783,7 @@ box = op.getarg(i) if isinstance(box, Box): assert box in seen - if op.is_guard(): + if op.is_guard() or op.getopnum() == rop.FINISH: assert op.getdescr() is not None if hasattr(op.getdescr(), '_debug_suboperations'): ops = op.getdescr()._debug_suboperations diff --git a/pypy/jit/metainterp/jitdriver.py b/pypy/jit/metainterp/jitdriver.py --- a/pypy/jit/metainterp/jitdriver.py +++ b/pypy/jit/metainterp/jitdriver.py @@ -18,7 +18,6 @@ # self.warmstate ... pypy.jit.metainterp.warmspot # self.handle_jitexc_from_bh pypy.jit.metainterp.warmspot # self.no_loop_header ... pypy.jit.metainterp.warmspot - # self.portal_finishtoken... pypy.jit.metainterp.pyjitpl # self.index ... pypy.jit.codewriter.call # self.mainjitcode ... pypy.jit.codewriter.call diff --git a/pypy/jit/metainterp/jitframe.py b/pypy/jit/metainterp/jitframe.py --- a/pypy/jit/metainterp/jitframe.py +++ b/pypy/jit/metainterp/jitframe.py @@ -1,16 +1,6 @@ -from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rpython.annlowlevel import llhelper +from pypy.rpython.lltypesystem import lltype, llmemory -_LONGLONGARRAY = lltype.GcArray(lltype.SignedLongLong) - -JITFRAME = lltype.GcStruct('JITFRAME', - ('jf_descr', llmemory.GCREF), - ('jf_excvalue', llmemory.GCREF), - ('jf_nongcvalues', lltype.Ptr(_LONGLONGARRAY)), - ('jf_gcvalues', lltype.Array(llmemory.GCREF))) -JITFRAMEPTR = lltype.Ptr(JITFRAME) - # Constants used for the 'jit_frame' field of virtualizables/virtualrefs: # # 1. TOKEN_NONE means not in the JIT at all, except as described below. diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -546,6 +546,8 @@ op = self.store_final_boxes_in_guard(op) elif op.can_raise(): self.exception_might_have_happened = True + elif op.getopnum() == rop.FINISH: + op = self.store_final_boxes_in_guard(op) if op.result: if op.result in self.seen_results: raise ValueError, "invalid optimization" diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -1459,8 +1459,6 @@ self._addr2name_keys = [] self._addr2name_values = [] - self.__dict__.update(compile.make_done_loop_tokens()) - def _freeze_(self): return True @@ -1500,18 +1498,6 @@ self.callinfocollection = codewriter.callcontrol.callinfocollection self.has_libffi_call = codewriter.callcontrol.has_libffi_call # - # store this information for fastpath of call_assembler - # (only the paths that can actually be taken) - for jd in self.jitdrivers_sd: - name = {history.INT: 'int', - history.REF: 'ref', - history.FLOAT: 'float', - history.VOID: 'void'}[jd.result_type] - tokens = getattr(self, 'loop_tokens_done_with_this_frame_%s' % name) - jd.portal_finishtoken = tokens[0].finishdescr - num = self.cpu.get_fail_descr_number(tokens[0].finishdescr) - setattr(self.cpu, 'done_with_this_frame_%s_v' % name, num) - # exc_descr = compile.PropagateExceptionDescr() num = self.cpu.get_fail_descr_number(exc_descr) self.cpu.propagate_exception_v = num @@ -1598,8 +1584,6 @@ self.indirectcall_dict = None self.addr2name = None self.loopnumbering = 0 - self.resume_virtuals = {} - self.resume_virtuals_not_translated = [] # ____________________________________________________________ @@ -2204,40 +2188,34 @@ self.raise_continue_running_normally(live_arg_boxes, jitcell_token) def compile_done_with_this_frame(self, exitbox): - self.gen_store_back_in_virtualizable() - # temporarily put a JUMP to a pseudo-loop - sd = self.staticdata result_type = self.jitdriver_sd.result_type if result_type == history.VOID: assert exitbox is None - exits = [] - loop_tokens = sd.loop_tokens_done_with_this_frame_void + self.compile_done([], compile.DoneWithThisFrameDescrVoid) elif result_type == history.INT: - exits = [exitbox] - loop_tokens = sd.loop_tokens_done_with_this_frame_int + self.compile_done([exitbox], compile.DoneWithThisFrameDescrInt) elif result_type == history.REF: - exits = [exitbox] - loop_tokens = sd.loop_tokens_done_with_this_frame_ref + self.compile_done([exitbox], compile.DoneWithThisFrameDescrRef) elif result_type == history.FLOAT: - exits = [exitbox] - loop_tokens = sd.loop_tokens_done_with_this_frame_float + self.compile_done([exitbox], compile.DoneWithThisFrameDescrFloat) else: assert False - # FIXME: kill TerminatingLoopToken? - # FIXME: can we call compile_trace? - token = loop_tokens[0].finishdescr + + def compile_exit_frame_with_exception(self, valuebox): + self.compile_done([valuebox], compile.ExitFrameWithExceptionDescrRef) + + def compile_done(self, exits, DoneCls): + self.record_set_jit_frame() + virtualizable_boxes = None + if (self.jitdriver_sd.virtualizable_info is not None or + self.jitdriver_sd.greenfield_info is not None): + virtualizable_boxes = self.virtualizable_boxes + assert len(self.virtualref_boxes) == 0 + token = DoneCls(self.staticdata, self.jitdriver_sd) + resume.capture_resumedata([], virtualizable_boxes, [], token) self.history.record(rop.FINISH, exits, None, descr=token) target_token = compile.compile_trace(self, self.resumekey) - if target_token is not token: - compile.giveup() - - def compile_exit_frame_with_exception(self, valuebox): - self.gen_store_back_in_virtualizable() - sd = self.staticdata - token = sd.loop_tokens_exit_frame_with_exception_ref[0].finishdescr - self.history.record(rop.FINISH, [valuebox], None, descr=token) - target_token = compile.compile_trace(self, self.resumekey) - if target_token is not token: + if target_token is None: compile.giveup() @specialize.arg(1) @@ -2325,7 +2303,12 @@ virtualizable_box = self.virtualizable_boxes[-1] virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box) vinfo.tracing_before_residual_call(virtualizable) - # + self.record_set_jit_frame() + + def record_set_jit_frame(self): + vinfo = self.jitdriver_sd.virtualizable_info + if vinfo is not None: + virtualizable_box = self.virtualizable_boxes[-1] jit_frame_box = history.BoxPtr() self.history.record(rop.JIT_FRAME, [], jit_frame_box) self.history.record(rop.SETFIELD_GC, [virtualizable_box, @@ -2423,7 +2406,9 @@ # warmstate.py. virtualizable_box = self.virtualizable_boxes[-1] virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box) - assert not vinfo.is_token_nonnull_gcref(virtualizable) + # clear the jit_frame, forgetting whatever stale value it has + # so far, and store the content of the boxes into the virtualizable + vinfo.reset_jit_frame(virtualizable) # fill the virtualizable with the local boxes self.synchronize_virtualizable() # @@ -2459,28 +2444,6 @@ virtualizable) self.virtualizable_boxes.append(virtualizable_box) - def gen_store_back_in_virtualizable(self): - vinfo = self.jitdriver_sd.virtualizable_info - if vinfo is not None: - # xxx only write back the fields really modified - vbox = self.virtualizable_boxes[-1] - for i in range(vinfo.num_static_extra_boxes): - fieldbox = self.virtualizable_boxes[i] - descr = vinfo.static_field_descrs[i] - self.execute_and_record(rop.SETFIELD_GC, descr, vbox, fieldbox) - i = vinfo.num_static_extra_boxes - virtualizable = vinfo.unwrap_virtualizable_box(vbox) - for k in range(vinfo.num_arrays): - descr = vinfo.array_field_descrs[k] - abox = self.execute_and_record(rop.GETFIELD_GC, descr, vbox) - descr = vinfo.array_descrs[k] - for j in range(vinfo.get_array_length(virtualizable, k)): - itembox = self.virtualizable_boxes[i] - i += 1 - self.execute_and_record(rop.SETARRAYITEM_GC, descr, - abox, ConstInt(j), itembox) - assert i + 1 == len(self.virtualizable_boxes) - def replace_box(self, oldbox, newbox): assert isinstance(oldbox, Box) for frame in self.framestack: diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -593,7 +593,7 @@ } is_guard = name.startswith('GUARD') - if is_guard: + if is_guard or name == 'FINISH': assert withdescr baseclass = GuardResOp elif withdescr: diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py --- a/pypy/jit/metainterp/resume.py +++ b/pypy/jit/metainterp/resume.py @@ -55,13 +55,17 @@ def capture_resumedata(framestack, virtualizable_boxes, virtualref_boxes, storage): n = len(framestack)-1 - top = framestack[n] - _ensure_parent_resumedata(framestack, n) - frame_info_list = FrameInfo(top.parent_resumedata_frame_info_list, - top.jitcode, top.pc) + if n >= 0: + top = framestack[n] + _ensure_parent_resumedata(framestack, n) + frame_info_list = FrameInfo(top.parent_resumedata_frame_info_list, + top.jitcode, top.pc) + snapshot = Snapshot(top.parent_resumedata_snapshot, + top.get_list_of_active_boxes(False)) + else: + frame_info_list = None + snapshot = None storage.rd_frame_info_list = frame_info_list - snapshot = Snapshot(top.parent_resumedata_snapshot, - top.get_list_of_active_boxes(False)) if virtualizable_boxes is not None: boxes = virtualref_boxes + virtualizable_boxes else: @@ -1103,11 +1107,9 @@ assert vinfo.is_token_nonnull_gcref(virtualizable) vinfo.reset_token_gcref(virtualizable) else: - # just jumped away from assembler (case 4 in the comment in - # virtualizable.py) into tracing (case 2); check that vable_token - # is and stays 0. Note the call to reset_vable_token() in - # warmstate.py. - assert not vinfo.is_token_nonnull_gcref(virtualizable) + # here, virtualizable.jit_frame may contain a leftover from + # earlier. We have to clean it here. + vinfo.reset_jit_frame(virtualizable) return vinfo.write_from_resume_data_partial(virtualizable, self, numb) def load_value_of_type(self, TYPE, tagged): diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py --- a/pypy/jit/metainterp/test/test_virtualizable.py +++ b/pypy/jit/metainterp/test/test_virtualizable.py @@ -12,7 +12,6 @@ from pypy.jit.metainterp.warmspot import get_stats, get_translator from pypy.jit.metainterp import history from pypy.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin -from pypy.jit.metainterp.jitframe import JITFRAMEPTR def promote_virtualizable(*args): pass @@ -145,11 +144,41 @@ while m > 0: g(xy, n) m -= 1 + promote_virtualizable(xy, 'inst_x') return xy.inst_x res = self.meta_interp(f, [18]) assert res == 10180 self.check_resops(setfield_gc=0, getfield_gc=2) + def test_synchronize_in_return_with_rescall(self): + myjitdriver = JitDriver(greens = [], reds = ['n', 'xy'], + virtualizables = ['xy']) + @dont_look_inside + def rescall(xy, n): + if n > 9999999: + promote_virtualizable(xy, 'inst_x') + def g(xy, n): + while n > 0: + myjitdriver.can_enter_jit(xy=xy, n=n) + myjitdriver.jit_merge_point(xy=xy, n=n) + promote_virtualizable(xy, 'inst_x') + xy.inst_x += 1 + rescall(xy, n) + n -= 1 + def f(n): + xy = self.setup() + xy.inst_x = 10000 + m = 10 + while m > 0: + g(xy, n) + m -= 1 + promote_virtualizable(xy, 'inst_x') + return xy.inst_x + res = self.meta_interp(f, [18]) + assert res == 10180 + # two setfield_gc(virtualizable, jit_frame) + self.check_resops(setfield_gc=2, getfield_gc=2) + def test_virtualizable_and_greens(self): myjitdriver = JitDriver(greens = ['m'], reds = ['n', 'xy'], virtualizables = ['xy']) diff --git a/pypy/jit/metainterp/virtualizable.py b/pypy/jit/metainterp/virtualizable.py --- a/pypy/jit/metainterp/virtualizable.py +++ b/pypy/jit/metainterp/virtualizable.py @@ -216,6 +216,7 @@ self.cast_gcref_to_vtype = cast_gcref_to_vtype def reset_jit_frame(virtualizable): + virtualizable = cast_gcref_to_vtype(virtualizable) virtualizable.jit_frame = jitframe.TOKEN_NONE self.reset_jit_frame = reset_jit_frame diff --git a/pypy/jit/metainterp/virtualref.py b/pypy/jit/metainterp/virtualref.py --- a/pypy/jit/metainterp/virtualref.py +++ b/pypy/jit/metainterp/virtualref.py @@ -12,7 +12,7 @@ # we make the low-level type of an RPython class directly self.JIT_VIRTUAL_REF = lltype.GcStruct('JitVirtualRef', ('super', rclass.OBJECT), - ('jit_frame', jitframe.JITFRAMEPTR), + ('jit_frame', llmemory.GCREF), ('forced', rclass.OBJECTPTR)) self.jit_virtual_ref_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True, flavor='raw', diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py --- a/pypy/jit/metainterp/warmspot.py +++ b/pypy/jit/metainterp/warmspot.py @@ -549,9 +549,8 @@ ASMRESTYPE = lltype.Float else: assert False - from pypy.jit.metainterp.jitframe import JITFRAMEPTR (_, jd._PTR_ASSEMBLER_HELPER_FUNCTYPE) = self.cpu.ts.get_FuncType( - [JITFRAMEPTR, llmemory.GCREF], ASMRESTYPE) + [llmemory.GCREF], ASMRESTYPE) def rewrite_can_enter_jits(self): sublists = {} @@ -804,12 +803,8 @@ vinfo = jd.virtualizable_info - def assembler_call_helper(jitframe, virtualizableref): + def assembler_call_helper(jitframe): fail_descr = self.cpu.get_latest_descr(jitframe) - if vinfo is not None: - virtualizable = lltype.cast_opaque_ptr( - vinfo.VTYPEPTR, virtualizableref) - vinfo.reset_jit_frame(virtualizable) try: fail_descr.handle_fail(self.metainterp_sd, jd, jitframe) except JitException, e: diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py --- a/pypy/jit/metainterp/warmstate.py +++ b/pypy/jit/metainterp/warmstate.py @@ -301,23 +301,22 @@ func_execute_token = self.cpu.make_execute_token(*ARGS) def execute_assembler(loop_token, *args): + # XXX temporary: we need to force the virtualizable, in case + # it contains a jit_frame. Do better later. + if vinfo is not None: + virtualizable = args[index_of_virtualizable] + vinfo.clear_jit_frame(virtualizable) + # # Call the backend to run the 'looptoken' with the given # input args. frame = func_execute_token(loop_token, *args) - fail_descr = self.cpu.get_latest_descr(frame) - # - # If we have a virtualizable, we have to reset its - # 'jit_frame' field afterwards - if vinfo is not None: - virtualizable = args[index_of_virtualizable] - virtualizable = vinfo.cast_gcref_to_vtype(virtualizable) - vinfo.reset_jit_frame(virtualizable) # # Record in the memmgr that we just ran this loop, # so that it will keep it alive for a longer time warmrunnerdesc.memory_manager.keep_loop_alive(loop_token) # # Handle the failure + fail_descr = self.cpu.get_latest_descr(frame) fail_descr.handle_fail(metainterp_sd, jitdriver_sd, frame) # assert 0, "should have raised" From noreply at buildbot.pypy.org Sat Oct 13 18:52:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 13 Oct 2012 18:52:34 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (fijal around, arigo) Message-ID: <20121013165234.040621C015F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58106:ee9cdf23f0a6 Date: 2012-10-13 18:52 +0200 http://bitbucket.org/pypy/pypy/changeset/ee9cdf23f0a6/ Log: (fijal around, arigo) Fixes to the llgraph backend and to tests. diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -488,6 +488,7 @@ self._forced = False self._may_force = -1 self._last_exception = None + self._finish_value = None def getenv(self, v): from pypy.jit.backend.llgraph.runner import Descr @@ -516,6 +517,7 @@ possibly following to other loops as well. """ assert self._may_force == -1 + assert self._finish_value is None assert self._last_exception is None, "exception left behind" verbose = True self.opindex = 0 @@ -578,7 +580,10 @@ log.trace('finished: %s' % ( ', '.join(map(str, args)),)) assert len(op.args) <= 1, "FINISH with more than 1 arg" - self.finish_args = op.args + if len(op.args) == 1: + self._finish_value = self.getenv(op.args[0]) + else: + self._finish_value = "finished, and got no argument" self.fail_args = op.fail_args self.fail_index = op.fail_index self._may_force = self.opindex @@ -1354,14 +1359,30 @@ frame = _from_opaque(frame) return len(frame.fail_args) -def grab_exc_value(frame): +def finish_value_int(frame): frame = _from_opaque(frame) - if frame._last_exception is not None: - result = frame._last_exception.args[1] - frame._last_exception = None - return lltype.cast_opaque_ptr(llmemory.GCREF, result) - else: - return lltype.nullptr(llmemory.GCREF.TO) + x = frame._finish_value + assert isinstance(x, int) + return x + +def finish_value_float(frame): + frame = _from_opaque(frame) + x = frame._finish_value + assert lltype.typeOf(x) is longlong.FLOATSTORAGE + return x + +def finish_value_ref(frame): + frame = _from_opaque(frame) + x = frame._finish_value + if x is None: + if frame._last_exception is not None: + result = frame._last_exception.args[1] + frame._last_exception = None + return lltype.cast_opaque_ptr(llmemory.GCREF, result) + else: + return lltype.nullptr(llmemory.GCREF.TO) + assert lltype.typeOf(x) == llmemory.GCREF + return x ##_pseudo_exceptions = {} @@ -1919,7 +1940,9 @@ setannotation(frame_float_getvalue, s_FloatStorage) setannotation(frame_get_value_count, annmodel.SomeInteger()) -setannotation(grab_exc_value, annmodel.SomePtr(llmemory.GCREF)) +setannotation(finish_value_int, annmodel.SomeInteger()) +setannotation(finish_value_float, s_FloatStorage) +setannotation(finish_value_ref, annmodel.SomePtr(llmemory.GCREF)) setannotation(force, annmodel.SomeInteger()) setannotation(do_arraylen_gc, annmodel.SomeInteger()) diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -309,9 +309,17 @@ assert lltype.typeOf(jitframe) == llmemory.GCREF return llimpl.frame_get_value_count(jitframe) - def grab_exc_value(self, jitframe): + def get_finish_value_int(self, jitframe): assert lltype.typeOf(jitframe) == llmemory.GCREF - return llimpl.grab_exc_value(jitframe) + return llimpl.finish_value_int(jitframe) + + def get_finish_value_float(self, jitframe): + assert lltype.typeOf(jitframe) == llmemory.GCREF + return llimpl.finish_value_float(jitframe) + + def get_finish_value_ref(self, jitframe): + assert lltype.typeOf(jitframe) == llmemory.GCREF + return llimpl.finish_value_ref(jitframe) def redirect_call_assembler(self, oldlooptoken, newlooptoken): if we_are_translated(): diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py --- a/pypy/jit/metainterp/test/support.py +++ b/pypy/jit/metainterp/test/support.py @@ -145,11 +145,11 @@ faildescr = cpu.get_latest_descr(frame) assert faildescr.__class__.__name__.startswith('DoneWithThisFrameDescr') if metainterp.jitdriver_sd.result_type == history.INT: - return cpu.get_latest_value_int(frame, 0) + return cpu.get_finish_value_int(frame) elif metainterp.jitdriver_sd.result_type == history.REF: - return cpu.get_latest_value_ref(frame, 0) + return cpu.get_finish_value_ref(frame) elif metainterp.jitdriver_sd.result_type == history.FLOAT: - return cpu.get_latest_value_float(frame, 0) + return cpu.get_finish_value_float(frame) else: return None diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py --- a/pypy/jit/metainterp/test/test_virtualizable.py +++ b/pypy/jit/metainterp/test/test_virtualizable.py @@ -306,6 +306,7 @@ while m > 0: g(xy2, n) m -= 1 + promote_virtualizable(xy2, 'inst_l2') return xy2.inst_l2[0] assert f(18) == 10360 res = self.meta_interp(f, [18]) @@ -452,6 +453,7 @@ while m > 0: g(xy2, n) m -= 1 + promote_virtualizable(xy2.parent, 'inst_l2') return xy2.parent.inst_l2[0] assert f(18) == 10360 res = self.meta_interp(f, [18]) From noreply at buildbot.pypy.org Sat Oct 13 19:05:15 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 13 Oct 2012 19:05:15 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (fijal, arigo) Message-ID: <20121013170515.7947D1C015F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58107:6d3477e87488 Date: 2012-10-13 19:04 +0200 http://bitbucket.org/pypy/pypy/changeset/6d3477e87488/ Log: (fijal, arigo) Replace save_data/fetch_data with something much simpler: store it on the jitframe. diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -1381,9 +1381,13 @@ return lltype.cast_opaque_ptr(llmemory.GCREF, result) else: return lltype.nullptr(llmemory.GCREF.TO) - assert lltype.typeOf(x) == llmemory.GCREF + #assert lltype.typeOf(x) == llmemory.GCREF return x +def set_finish_value_ref(frame, value): + frame = _from_opaque(frame) + frame._finish_value = value + ##_pseudo_exceptions = {} ##def _get_error(Class): @@ -1943,6 +1947,7 @@ setannotation(finish_value_int, annmodel.SomeInteger()) setannotation(finish_value_float, s_FloatStorage) setannotation(finish_value_ref, annmodel.SomePtr(llmemory.GCREF)) +setannotation(set_finish_value_ref, annmodel.s_None) setannotation(force, annmodel.SomeInteger()) setannotation(do_arraylen_gc, annmodel.SomeInteger()) diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -321,6 +321,11 @@ assert lltype.typeOf(jitframe) == llmemory.GCREF return llimpl.finish_value_ref(jitframe) + def set_finish_value_ref(self, jitframe, value): + assert lltype.typeOf(jitframe) == llmemory.GCREF + #assert lltype.typeOf(value) == llmemory.GCREF + llimpl.set_finish_value_ref(jitframe, value) + def redirect_call_assembler(self, oldlooptoken, newlooptoken): if we_are_translated(): raise ValueError("CALL_ASSEMBLER not supported") diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -167,6 +167,11 @@ GUARD_NO_EXCEPTION, to return the exception.""" return jitframe.jf_finish_ref + def set_finish_value_ref(self, jitframe, value): + """Store on the jitframe a random GCREF value that will be returned + by the following call to get_finish_value_ref().""" + jitframe.jf_finish_ref = value + def redirect_call_assembler(self, oldlooptoken, newlooptoken): """Redirect oldlooptoken to newlooptoken. More precisely, it is enough to redirect all CALL_ASSEMBLERs already compiled that call diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -6,6 +6,7 @@ from pypy.rlib.debug import debug_start, debug_stop, debug_print from pypy.rlib import rstack from pypy.rlib.jit import JitDebugInfo, Counters +from pypy.rlib.rerased import new_erasing_pair from pypy.conftest import option from pypy.tool.sourcetools import func_with_new_name @@ -584,6 +585,10 @@ self.copy_all_attributes_into(res) return res + +erase_list_virtuals, unerase_list_virtuals = ( + new_erasing_pair("list of virtuals")) + class ResumeGuardForcedDescr(ResumeGuardDescr): def __init__(self, metainterp_sd, jitdriver_sd): @@ -634,34 +639,12 @@ self.save_data(jitframe, all_virtuals) def save_data(self, jitframe, value): - return # XXXXX - globaldata = self.metainterp_sd.globaldata - if we_are_translated(): - assert key not in globaldata.resume_virtuals - globaldata.resume_virtuals[key] = value - else: - rv = globaldata.resume_virtuals_not_translated - for key1, value1 in rv: - assert key1 != key - rv.append((key, value)) + llvalue = erase_list_virtuals(value) + self.metainterp_sd.cpu.set_finish_value_ref(jitframe, llvalue) - def fetch_data(self, key): - XXXXX - globaldata = self.metainterp_sd.globaldata - if we_are_translated(): - assert key in globaldata.resume_virtuals - data = globaldata.resume_virtuals[key] - del globaldata.resume_virtuals[key] - else: - rv = globaldata.resume_virtuals_not_translated - for i in range(len(rv)): - if rv[i][0] == key: - data = rv[i][1] - del rv[i] - break - else: - assert 0, "not found: %r" % (key,) - return data + def fetch_data(self, jitframe): + llvalue = self.metainterp_sd.cpu.get_finish_value_ref(jitframe) + return unerase_list_virtuals(llvalue) def _clone_if_mutable(self): res = self.__class__(self.metainterp_sd, self.jitdriver_sd) From noreply at buildbot.pypy.org Sat Oct 13 19:15:15 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 13 Oct 2012 19:15:15 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (fijal, arigo) Message-ID: <20121013171515.463321C015F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58108:37d03a323870 Date: 2012-10-13 19:12 +0200 http://bitbucket.org/pypy/pypy/changeset/37d03a323870/ Log: (fijal, arigo) Yay, we pass the whole test_virtualizable. diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -1381,12 +1381,19 @@ return lltype.cast_opaque_ptr(llmemory.GCREF, result) else: return lltype.nullptr(llmemory.GCREF.TO) - #assert lltype.typeOf(x) == llmemory.GCREF + assert lltype.typeOf(x) == llmemory.GCREF + frame._finish_value = 'deleted by the previous call to finish_value_ref' return x -def set_finish_value_ref(frame, value): +def get_savedata_ref(frame): frame = _from_opaque(frame) - frame._finish_value = value + x = frame._savedata + del frame._savedata + return x + +def set_savedata_ref(frame, value): + frame = _from_opaque(frame) + frame._savedata = value ##_pseudo_exceptions = {} @@ -1947,7 +1954,8 @@ setannotation(finish_value_int, annmodel.SomeInteger()) setannotation(finish_value_float, s_FloatStorage) setannotation(finish_value_ref, annmodel.SomePtr(llmemory.GCREF)) -setannotation(set_finish_value_ref, annmodel.s_None) +setannotation(get_savedata_ref, annmodel.SomePtr(llmemory.GCREF)) +setannotation(set_savedata_ref, annmodel.s_None) setannotation(force, annmodel.SomeInteger()) setannotation(do_arraylen_gc, annmodel.SomeInteger()) diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -321,10 +321,14 @@ assert lltype.typeOf(jitframe) == llmemory.GCREF return llimpl.finish_value_ref(jitframe) - def set_finish_value_ref(self, jitframe, value): + def get_savedata_ref(self, jitframe): + assert lltype.typeOf(jitframe) == llmemory.GCREF + return llimpl.get_savedata_ref(jitframe) + + def set_savedata_ref(self, jitframe, value): assert lltype.typeOf(jitframe) == llmemory.GCREF #assert lltype.typeOf(value) == llmemory.GCREF - llimpl.set_finish_value_ref(jitframe, value) + llimpl.set_savedata_ref(jitframe, value) def redirect_call_assembler(self, oldlooptoken, newlooptoken): if we_are_translated(): diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -165,12 +165,18 @@ """Return and clear the result passed to FINISH, which was a GCREF. Also used when it exits due to a failure of a GUARD_EXCEPTION or GUARD_NO_EXCEPTION, to return the exception.""" + xxxx return jitframe.jf_finish_ref - def set_finish_value_ref(self, jitframe, value): + def get_savedata_ref(self, jitframe): + """Return and clear the last value stored by the frontend with + set_savedata_ref.""" + xxxx + + def set_savedata_ref(self, jitframe, value): """Store on the jitframe a random GCREF value that will be returned - by the following call to get_finish_value_ref().""" - jitframe.jf_finish_ref = value + by the following call to get_savedata_ref().""" + xxxx def redirect_call_assembler(self, oldlooptoken, newlooptoken): """Redirect oldlooptoken to newlooptoken. More precisely, it is diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -1419,7 +1419,7 @@ opnum == rop.GUARD_EXCEPTION or opnum == rop.GUARD_NOT_FORCED): return lltype.cast_opaque_ptr(rclass.OBJECTPTR, - self.cpu.grab_exc_value(jitframe)) + self.cpu.get_finish_value_ref(jitframe)) # elif opnum == rop.GUARD_NO_OVERFLOW: # Produced by int_xxx_ovf(). The pc is just after the opcode. diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -640,10 +640,10 @@ def save_data(self, jitframe, value): llvalue = erase_list_virtuals(value) - self.metainterp_sd.cpu.set_finish_value_ref(jitframe, llvalue) + self.metainterp_sd.cpu.set_savedata_ref(jitframe, llvalue) def fetch_data(self, jitframe): - llvalue = self.metainterp_sd.cpu.get_finish_value_ref(jitframe) + llvalue = self.metainterp_sd.cpu.get_savedata_ref(jitframe) return unerase_list_virtuals(llvalue) def _clone_if_mutable(self): diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -2091,7 +2091,7 @@ opnum == rop.GUARD_NONNULL_CLASS): pass # the pc is already set to the *start* of the opcode elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION: - exception = self.cpu.grab_exc_value(jitframe) + exception = self.cpu.get_finish_value_ref(jitframe) if exception: self.execute_ll_raised(lltype.cast_opaque_ptr(rclass.OBJECTPTR, exception)) From noreply at buildbot.pypy.org Sat Oct 13 20:26:53 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 13 Oct 2012 20:26:53 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Do not wrap unrollers. Message-ID: <20121013182653.974FF1C0188@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58109:f1d90d0488b3 Date: 2012-10-13 19:26 +0100 http://bitbucket.org/pypy/pypy/changeset/f1d90d0488b3/ Log: Do not wrap unrollers. Since they aren't Python objects, it doesn't make much sense to wrap them inside Constant(). Not doing it simplifies the code a bit. + Remove costly isinstance() check. diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -574,18 +574,14 @@ if w_top == self.space.w_None: # finally: block with no unroller active return - try: - unroller = self.space.unwrap(w_top) - except UnwrapException: - pass + elif isinstance(w_top, SuspendedUnroller): + # case of a finally: block + return self.unroll_finally(w_top) else: - if isinstance(unroller, SuspendedUnroller): - # case of a finally: block - return self.unroll_finally(unroller) - # case of an except: block. We popped the exception type - self.popvalue() # Now we pop the exception value - unroller = self.space.unwrap(self.popvalue()) - return self.unroll_finally(unroller) + # case of an except: block. We popped the exception type + self.popvalue() # Now we pop the exception value + unroller = self.popvalue() + return self.unroll_finally(unroller) def unroll_finally(self, unroller): # go on unrolling the stack @@ -667,14 +663,13 @@ # and cannot suppress the exception. # This opcode changed a lot between CPython versions if sys.version_info >= (2, 6): - w_unroller = self.popvalue() + unroller = self.popvalue() w_exitfunc = self.popvalue() - self.pushvalue(w_unroller) + self.pushvalue(unroller) else: w_exitfunc = self.popvalue() - w_unroller = self.peekvalue(0) + unroller = self.peekvalue(0) - unroller = self.space.unwrap(w_unroller) w_None = self.space.w_None if isinstance(unroller, SApplicationException): operr = unroller.operr @@ -890,7 +885,7 @@ # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. - frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(unroller) frame.pushvalue(operationerr.get_w_value(frame.space)) frame.pushvalue(operationerr.w_type) frame.last_exception = operationerr @@ -906,7 +901,7 @@ # any abnormal reason for unrolling a finally: triggers the end of # the block unrolling and the entering the finally: handler. self.cleanupstack(frame) - frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(unroller) return self.handlerposition # jump to the handler diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -6,9 +6,6 @@ self.mergeable = mergeable self.blocklist = blocklist self.next_instr = next_instr - for w1 in self.mergeable: - assert isinstance(w1, (Variable, Constant)) or w1 is None, ( - '%r found in frame state' % w1) def copy(self): "Make a copy of this state in which all Variables are fresh." @@ -109,12 +106,10 @@ from pypy.objspace.flow.flowcontext import SuspendedUnroller i = 0 while i < len(lst): - item = lst[i] - if not (isinstance(item, Constant) and - isinstance(item.value, SuspendedUnroller)): + unroller = lst[i] + if not isinstance(unroller, SuspendedUnroller): i += 1 else: - unroller = item.value vars = unroller.state_unpack_variables(space) key = unroller.__class__, len(vars) try: @@ -132,4 +127,4 @@ arguments = lst[i+1: i+1+argcount] del lst[i+1: i+1+argcount] unroller = unrollerclass.state_pack_variables(space, *arguments) - lst[i] = space.wrap(unroller) + lst[i] = unroller From noreply at buildbot.pypy.org Sat Oct 13 21:14:57 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 13 Oct 2012 21:14:57 +0200 (CEST) Subject: [pypy-commit] pypy default: test, fix c_div for nan in denom Message-ID: <20121013191457.C9D0C1C0253@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r58110:f41eea130430 Date: 2012-10-13 21:12 +0200 http://bitbucket.org/pypy/pypy/changeset/f41eea130430/ Log: test, fix c_div for nan in denom diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py --- a/pypy/rlib/rcomplex.py +++ b/pypy/rlib/rcomplex.py @@ -57,6 +57,9 @@ denom = r2 + i2 * ratio rr = (r1 + i1 * ratio) / denom ir = (i1 - r1 * ratio) / denom + elif isnan(r2): + rr = NAN + ir = NAN else: ratio = r2 / i2 denom = r2 * ratio + i2 diff --git a/pypy/rlib/test/test_rcomplex.py b/pypy/rlib/test/test_rcomplex.py --- a/pypy/rlib/test/test_rcomplex.py +++ b/pypy/rlib/test/test_rcomplex.py @@ -33,6 +33,9 @@ ]: assert c.c_mul(c1, c2) == result +def test_div(): + c.c_div((2., 3.), (float('nan'), 0.)) == (float('nan'), float('nan')) + def parse_testfile2(fname): """Parse a file with test values From noreply at buildbot.pypy.org Sat Oct 13 21:26:53 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 13 Oct 2012 21:26:53 +0200 (CEST) Subject: [pypy-commit] pypy default: fix for None in kwargs Message-ID: <20121013192653.B15CE1C1C5B@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r58111:e537e0093563 Date: 2012-10-13 21:26 +0200 http://bitbucket.org/pypy/pypy/changeset/e537e0093563/ Log: fix for None in kwargs 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 @@ -661,7 +661,7 @@ raise operationerrfmt(space.w_ValueError, "Unknown order: %s", order) if isinstance(w_object, W_NDimArray): - if (not space.is_w(w_dtype, space.w_None) and + if (not space.is_none(w_dtype) and w_object.get_dtype() is not w_dtype): raise OperationError(space.w_NotImplementedError, space.wrap( "copying over different dtypes unsupported")) From noreply at buildbot.pypy.org Sun Oct 14 23:29:07 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 14 Oct 2012 23:29:07 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: merge from default Message-ID: <20121014212907.D4B6E1C015F@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-problems Changeset: r58112:276ef517c34e Date: 2012-10-14 22:41 +0200 http://bitbucket.org/pypy/pypy/changeset/276ef517c34e/ Log: merge from default diff too long, truncating to 2000 out of 45514 lines diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,11 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - libpath = ctypes.util.find_library('db-4.5') - if not libpath: + for c in '56789': + libpath = ctypes.util.find_library('db-4.%s' % c) + if libpath: + break + else: raise ImportError("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' diff --git a/py/_io/capture.py b/py/_io/capture.py --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -176,7 +176,7 @@ class StdCaptureFD(Capture): - """ This class allows to capture writes to FD1 and FD2 + """ This class allows capturing writes to FD1 and FD2 and may connect a NULL file to FD0 (and prevent reads from sys.stdin). If any of the 0,1,2 file descriptors is invalid it will not be captured. @@ -267,8 +267,8 @@ return l class StdCapture(Capture): - """ This class allows to capture writes to sys.stdout|stderr "in-memory" - and will raise errors on tries to read from sys.stdin. It only + """ This class allows capturing writes to sys.stdout|stderr "in-memory" + and will raise errors on read attempts from sys.stdin. It only modifies sys.stdout|stderr|stdin attributes and does not touch underlying File Descriptors (use StdCaptureFD for that). """ diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -1,9 +1,8 @@ -import sys import types -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception +from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - format_someobject_error, AnnotatorError) + AnnotatorError, gather_error, ErrorWrapper) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -38,22 +37,9 @@ self.links_followed = {} # set of links that have ever been followed self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + self.blocked_blocks = {} # set of {blocked_block: (graph, index)} + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +63,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +164,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +181,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +192,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +242,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +265,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +283,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +333,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -414,7 +340,7 @@ self.flowin(graph, block) except BlockedInference, e: self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, e.opindex) except Exception, e: # hack for debug tools only if not hasattr(e, '__annotator_block'): @@ -433,25 +359,24 @@ self.pendingblocks[block] = graph assert block in self.annotated self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -471,14 +396,11 @@ for i in range(len(block.operations)): try: self.bookkeeper.enter((graph, block, i)) - self.consider_op(block.operations[i]) + self.consider_op(block, i) finally: self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +484,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +494,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +530,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell @@ -653,7 +572,8 @@ #___ creating the annotations based on operations ______ - def consider_op(self, op): + def consider_op(self, block, opindex): + op = block.operations[opindex] argcells = [self.binding(a) for a in op.args] consider_meth = getattr(self,'consider_op_'+op.opname, None) @@ -668,16 +588,18 @@ # boom -- in the assert of setbinding() for arg in argcells: if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op) + raise BlockedInference(self, op, opindex) try: resultcell = consider_meth(*argcells) - except Exception: + except Exception, e: graph = self.bookkeeper.position_key[0] - raise_nicer_exception(op, str(graph)) + e.args = e.args + ( + ErrorWrapper(gather_error(self, graph, block, opindex)),) + raise if resultcell is None: resultcell = self.noreturnvalue(op) elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op) # the operation cannot succeed + raise BlockedInference(self, op, opindex) # the operation cannot succeed assert isinstance(resultcell, annmodel.SomeObject) assert isinstance(op.result, Variable) self.setbinding(op.result, resultcell) # bind resultcell to op.result @@ -728,13 +650,14 @@ """This exception signals the type inference engine that the situation is currently blocked, and that it should try to progress elsewhere.""" - def __init__(self, annotator, op): + def __init__(self, annotator, op, opindex): self.annotator = annotator try: self.break_at = annotator.bookkeeper.position_key except AttributeError: self.break_at = None self.op = op + self.opindex = opindex def __repr__(self): if not self.break_at: diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,15 +29,6 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', 'truediv', 'floordiv', 'divmod', 'pow', @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -238,7 +201,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -564,14 +550,30 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - return SomeObject() + raise UnionError("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): return SomeTuple(items = tup1.items + tup2.items) + def eq(tup1tup2): + tup1tup2.union() + return s_Bool + ne = eq + + def lt((tup1, tup2)): + raise Exception("unsupported: (...) < (...)") + def le((tup1, tup2)): + raise Exception("unsupported: (...) <= (...)") + def gt((tup1, tup2)): + raise Exception("unsupported: (...) > (...)") + def ge((tup1, tup2)): + raise Exception("unsupported: (...) >= (...)") + class __extend__(pairtype(SomeDict, SomeDict)): @@ -723,8 +725,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -764,7 +765,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -778,7 +779,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -806,7 +807,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,7 +10,7 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef @@ -148,7 +148,6 @@ self.descs = {} # map Python objects to their XxxDesc wrappers self.methoddescs = {} # map (funcdesc, classdef) to the MethodDesc self.classdefs = [] # list of all ClassDefs - self.pbctypes = {} self.seen_mutable = {} self.listdefs = {} # map position_keys to ListDefs self.dictdefs = {} # map position_keys to DictDefs @@ -167,9 +166,6 @@ self.stats = Stats(self) - # used in SomeObject.__new__ for keeping debugging info - self._isomeobject_coming_from = identity_dict() - delayed_imports() def count(self, category, *args): @@ -275,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() @@ -325,8 +320,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -445,6 +438,12 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if (x is type(None) or # add cases here if needed + x.__module__ == 'pypy.rpython.lltypesystem.lltype'): + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) 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 @@ -455,20 +454,13 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) - elif hasattr(x, '_freeze_') and x._freeze_(): + result = SomePBC([self.getdesc(x)]) + elif hasattr(x, '_freeze_'): + assert x._freeze_() is True # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method # returns True, the instance is considered immutable and becomes @@ -476,16 +468,18 @@ result = SomePBC([self.getdesc(x)]) elif hasattr(x, '__class__') \ and x.__class__.__module__ != '__builtin__': + if hasattr(x, '_cleanup_'): + x._cleanup_() self.see_mutable(x) result = SomeInstance(self.getuniqueclassdef(x.__class__)) elif x is None: return s_None else: - result = SomeObject() + raise Exception("Don't know how to represent %r" % (x,)) if need_const: result.const = x return result - + def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: @@ -509,8 +503,10 @@ elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) - elif (hasattr(pyobj.im_self, '_freeze_') and - pyobj.im_self._freeze_()): # method of frozen + if hasattr(pyobj.im_self, '_cleanup_'): + pyobj.im_self._cleanup_() + if hasattr(pyobj.im_self, '_freeze_'): # method of frozen + assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc(self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc @@ -529,9 +525,9 @@ name) else: # must be a frozen pre-built constant, but let's check - try: - assert pyobj._freeze_() - except AttributeError: + if hasattr(pyobj, '_freeze_'): + assert pyobj._freeze_() is True + else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: @@ -551,11 +547,7 @@ return False def getfrozen(self, pyobj): - result = description.FrozenDesc(self, pyobj) - cls = result.knowntype - if cls not in self.pbctypes: - self.pbctypes[cls] = True - return result + return description.FrozenDesc(self, pyobj) def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, flags={}): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -150,7 +150,7 @@ def builtin_isinstance(s_obj, s_type, variables=None): - r = SomeBool() + r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,8 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + + if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -247,13 +247,16 @@ defs_s = [] if graph is None: signature = self.signature - defaults = self.defaults + defaults = self.defaults else: signature = graph.signature - defaults = graph.defaults + defaults = graph.defaults if defaults: for x in defaults: - defs_s.append(self.bookkeeper.immutablevalue(x)) + if x is NODEFAULT: + defs_s.append(None) + else: + defs_s.append(self.bookkeeper.immutablevalue(x)) try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,8 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype + immutable = False knowntype = object - immutable = False + + def __init__(self): + assert type(self) is not SomeObject def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -105,60 +106,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: - self = new(cls, *args, **kw) - if DEBUG: - try: - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - position_key = bookkeeper.position_key - except AttributeError: - pass - else: - bookkeeper._isomeobject_coming_from[self] = position_key, None + def can_be_none(self): + return True + + def nonnoneify(self): return self - def origin(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] - origin = property(origin) - def caused_by_merge(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] - def set_caused_by_merge(self, nvalue): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return - bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue - caused_by_merge = property(caused_by_merge, set_caused_by_merge) - del set_caused_by_merge +class SomeType(SomeObject): + "Stands for a type. We might not be sure which one it is." + knowntype = type + immutable = True def can_be_none(self): - return True - - def nonnoneify(self): - return self + return False class SomeFloat(SomeObject): "Stands for a float or an integer." @@ -517,6 +486,7 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) @@ -710,14 +680,8 @@ # this is just a performance shortcut if s1 != s2: s1 = pair(s1, s2).union() - if DEBUG: - if s1.caused_by_merge is None and len(somevalues) > 1: - s1.caused_by_merge = somevalues return s1 -def isdegenerated(s_value): - return s_value.__class__ is SomeObject and s_value.knowntype is not type - # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -10,7 +10,6 @@ class BasicAnnotatorPolicy(object): - allow_someobjects = True def event(pol, bookkeeper, what, *args): pass @@ -80,6 +79,3 @@ def specialize__ll_and_arg(pol, *args): from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args) - -class StrictAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -3,9 +3,9 @@ from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF -from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF + unionof, SomeUnicodeString, SomeType +from pypy.annotation.listdef import ListDef +from pypy.annotation.dictdef import DictDef _annotation_cache = {} @@ -78,24 +78,18 @@ return SomeString() elif t is unicode: return SomeUnicodeString() - elif t is list: - return SomeList(MOST_GENERAL_LISTDEF) - elif t is dict: - return SomeDict(MOST_GENERAL_DICTDEF) - # can't do tuple elif t is types.NoneType: return s_None elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) - elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes: + elif t is type: + return SomeType() + elif bookkeeper and not hasattr(t, '_freeze_'): classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) else: - o = SomeObject() - if t != object: - o.knowntype = t - return o + raise AssertionError("annotationoftype(%r)" % (t,)) class Sig(object): diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -24,7 +24,7 @@ assert isinstance(s_list, annmodel.SomeList) return s_list.listdef.listitem.s_value -def somelist(s_type=annmodel.SomeObject()): +def somelist(s_type): return annmodel.SomeList(ListDef(None, s_type)) def dictkey(s_dict): @@ -35,7 +35,7 @@ assert isinstance(s_dict, annmodel.SomeDict) return s_dict.dictdef.dictvalue.s_value -def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()): +def somedict(s_key, s_value): return annmodel.SomeDict(DictDef(None, s_key, s_value)) @@ -205,15 +205,6 @@ annmodel.SomeInteger() ]) - def test_inheritance2(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet._inheritance_nonrunnable, []) - # result should be exactly: - assert s == annmodel.SomeTuple([ - annmodel.SomeInteger(), - annmodel.SomeObject() - ]) - def test_poor_man_range(self): a = self.RPythonAnnotator() s = a.build_types(snippet.poor_man_range, [int]) @@ -336,9 +327,13 @@ def test_flow_type_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_type_info, [object]) + s = a.build_types(snippet.flow_type_info, [int]) a.simplify() - #a.translator.view() + assert s.knowntype == int + + a = self.RPythonAnnotator() + s = a.build_types(snippet.flow_type_info, [str]) + a.simplify() assert s.knowntype == int def test_flow_type_info_2(self): @@ -351,7 +346,7 @@ def test_flow_usertype_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_usertype_info, [object]) + s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit]) #a.translator.view() assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit) @@ -363,13 +358,6 @@ assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit) - def test_flow_identity_info(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_identity_info, [object, object]) - a.simplify() - #a.translator.view() - assert s == a.bookkeeper.immutablevalue((None, None)) - def test_mergefunctions(self): a = self.RPythonAnnotator() s = a.build_types(snippet.mergefunctions, [int]) @@ -431,11 +419,11 @@ # the annotator (it doesn't check that they operate property, though) for example, methname, s_example in [ ('', 'join', annmodel.SomeString()), - ([], 'append', somelist()), - ([], 'extend', somelist()), - ([], 'reverse', somelist()), - ([], 'insert', somelist()), - ([], 'pop', somelist()), + ([], 'append', somelist(annmodel.s_Int)), + ([], 'extend', somelist(annmodel.s_Int)), + ([], 'reverse', somelist(annmodel.s_Int)), + ([], 'insert', somelist(annmodel.s_Int)), + ([], 'pop', somelist(annmodel.s_Int)), ]: constmeth = getattr(example, methname) s_constmeth = iv(constmeth) @@ -497,12 +485,12 @@ def test_simple_slicing(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_slice, [list]) + s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeList) def test_simple_iter_list(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_iter, [list]) + s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeIterator) def test_simple_iter_next(self): @@ -542,11 +530,6 @@ assert isinstance(dictkey(s), annmodel.SomeInteger) assert isinstance(dictvalue(s), annmodel.SomeInteger) - a = self.RPythonAnnotator() - s = a.build_types(snippet.dict_update, [str]) - assert not isinstance(dictkey(s), annmodel.SomeString) - assert not isinstance(dictvalue(s), annmodel.SomeString) - def test_dict_update_2(self): a = self.RPythonAnnotator() def g(n): @@ -568,7 +551,7 @@ def test_dict_keys2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_keys2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_values(self): a = self.RPythonAnnotator() @@ -578,7 +561,7 @@ def test_dict_values2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_items(self): a = self.RPythonAnnotator() @@ -643,25 +626,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_bltin_code_frame_confusion(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_confusion,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - # annotator confused by original bltin code/frame setup, we just get SomeObject here - assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - - def test_bltin_code_frame_reorg(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_reorg,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - assert isinstance(a.binding(f_flowgraph.getreturnvar()), - annmodel.SomeInteger) - assert isinstance(a.binding(g_flowgraph.getreturnvar()), - annmodel.SomeString) - def test_propagation_of_fresh_instances_through_attrs(self): a = self.RPythonAnnotator() s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int]) @@ -748,14 +712,15 @@ assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc) def test_type_is(self): - class C(object): + class B(object): + pass + class C(B): pass def f(x): - if type(x) is C: - return x - raise Exception - a = self.RPythonAnnotator() - s = a.build_types(f, [object]) + assert type(x) is C + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) def test_ann_assert(self): @@ -793,24 +758,30 @@ return None a = self.RPythonAnnotator() - s = a.build_types(f, [list]) + s = a.build_types(f, [somelist(annmodel.s_Int)]) assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list def test_freeze_protocol(self): class Stuff: - def __init__(self, flag): + def __init__(self): self.called = False - self.flag = flag def _freeze_(self): self.called = True - return self.flag - myobj = Stuff(True) + return True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - myobj = Stuff(False) + + def test_cleanup_protocol(self): + class Stuff: + def __init__(self): + self.called = False + def _cleanup_(self): + self.called = True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called @@ -854,7 +825,7 @@ def f(a,b): return bool(a) or bool(b) a = self.RPythonAnnotator() - s = a.build_types(f, [int,list]) + s = a.build_types(f, [int, somelist(annmodel.s_Int)]) assert s.knowntype == bool def test_float(self): @@ -1299,22 +1270,6 @@ assert isinstance(s_item, annmodel.SomeInstance) assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - def test_assert_type_is_list_doesnt_lose_info(self): - class T(object): - pass - def g(l): - assert type(l) is list - return l - def f(): - l = [T()] - return g(l) - a = self.RPythonAnnotator() - s = a.build_types(f, []) - s_item = listitem(s) - assert isinstance(s_item, annmodel.SomeInstance) - assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - - def test_int_str_mul(self): def f(x,a,b): return a*x+x*b @@ -1395,11 +1350,10 @@ except KeyError: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.const = KeyError t.is_type_of = [ev] assert a.binding(et) == t @@ -1412,11 +1366,10 @@ except: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t @@ -1448,11 +1401,10 @@ finally: h() a = self.RPythonAnnotator() - a.build_types(f, [int, list]) + a.build_types(f, [int, somelist(annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) @@ -1474,24 +1426,11 @@ a.build_types(f, []) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_sys_attrs(self): - def f(): - return sys.argv[0] - a = self.RPythonAnnotator() - try: - oldvalue = sys.argv - sys.argv = [] - s = a.build_types(f, []) - finally: - sys.argv = oldvalue - assert s is not None - def test_pow(self): def f(n): n **= 2 @@ -1523,7 +1462,6 @@ a = self.RPythonAnnotator() 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)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] def test_is_true_coalesce2(self): def f(a,b,a1,b1,c,d,e): @@ -1532,9 +1470,12 @@ return d,c return e,c a = self.RPythonAnnotator() - s = a.build_types(f, [int, str, float, list, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) - assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] + s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int), + 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_coalesce_sanity(self): def f(a): @@ -1954,16 +1895,7 @@ t = type(x) return issubclass(t, A) - def f(): - x = g(1) - y = g(0) - return x or y - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert s.knowntype == bool - assert not s.is_constant() - a = self.RPythonAnnotator() - # sanity check + a = self.RPythonAnnotator() x = annmodel.SomeInteger() x.const = 1 s = a.build_types(g, [x]) @@ -2383,8 +2315,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int]) - assert s.__class__ == annmodel.SomeObject - assert s.knowntype == type + assert isinstance(s, annmodel.SomeType) def test_annotate_iter_empty_container(self): def f(): @@ -3075,7 +3006,6 @@ v = -maxint return intmask(v * 10) P = policy.AnnotatorPolicy() - P.allow_someobjects = False a = self.RPythonAnnotator(policy=P) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) @@ -3859,6 +3789,32 @@ a = self.RPythonAnnotator() py.test.raises(Exception, a.build_types, fn, []) + def test_lower_char(self): + def fn(c): + return c.lower() + a = self.RPythonAnnotator() + s = a.build_types(fn, [annmodel.SomeChar()]) + assert s == annmodel.SomeChar() + + def test_isinstance_double_const(self): + class X(object): + def _freeze_(self): + return True + + x = X() + + def f(i): + if i: + x1 = x + else: + x1 = None + print "hello" # this is to force the merge of blocks + return isinstance(x1, X) + + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeBool) + def g(n): return [0,1,2,n] diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -2,20 +2,20 @@ import autopath import py from pypy.annotation.model import * -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF +from pypy.annotation.listdef import ListDef from pypy.rpython.ootypesystem.ootype import ROOT listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) -s1 = SomeObject() +s1 = SomeType() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s1,s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s1, s2, s3, s4, s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -42,7 +42,7 @@ def test_equality(): assert s1 != s2 != s3 != s4 != s5 != s6 - assert s1 == SomeObject() + assert s1 == SomeType() assert s2 == SomeInteger(nonneg=True) assert s3 == SomeInteger(nonneg=False) assert s4 == SomeList(listdef1) @@ -51,19 +51,11 @@ def test_contains(): assert ([(s,t) for s in slist for t in slist if s.contains(t)] == - [(s1,s1), (s1,s2), (s1,s3), (s1,s4), (s1,s6), - (s2,s2), (s2,s6), - (s3,s2), (s3,s3), (s3,s6), - (s4,s4), (s4,s6), - (s6,s6)]) - -def test_union(): - assert ([unionof(s,t) for s in slist for t in slist] == - [s1, s1, s1, s1, s1, - s1, s2, s3, s1, s2, - s1, s3, s3, s1, s3, - s1, s1, s1, s4, s4, - s1, s2, s3, s4, s6]) + [(s1, s1), (s1, s6), + (s2, s2), (s2, s6), + (s3, s2), (s3, s3), (s3, s6), + (s4, s4), (s4, s6), + (s6, s6)]) def test_commonbase_simple(): class A0: @@ -100,9 +92,10 @@ def test_list_contains(): listdef1 = ListDef(None, SomeInteger(nonneg=True)) s1 = SomeList(listdef1) - s2 = SomeList(MOST_GENERAL_LISTDEF) + listdef2 = ListDef(None, SomeInteger(nonneg=False)) + s2 = SomeList(listdef2) assert s1 != s2 - assert s2.contains(s1) + assert not s2.contains(s1) assert s1 != s2 assert not s1.contains(s2) assert s1 != s2 diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -7,7 +7,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -39,14 +39,7 @@ def type(obj, *moreargs): if moreargs: raise Exception, 'type() called with more than one argument' - if obj.is_constant(): - if isinstance(obj, SomeInstance): - r = SomePBC([obj.classdef.classdesc]) - else: - r = immutablevalue(obj.knowntype) - else: - r = SomeObject() - r.knowntype = type + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator @@ -133,9 +126,6 @@ def float(obj): return SomeFloat() - def long(obj): - return SomeObject() # XXX - def delattr(obj, s_attr): if obj.__class__ != SomeObject or obj.knowntype != object: getbookkeeper().warning( @@ -154,18 +144,17 @@ def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - s_method = obj.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)) - else: - getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' % - (obj, s_attr)) - return SomeObject() + 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)) + attr = s_attr.const + s_method = obj.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)) getattr.can_only_throw = [] def bind_callables_under(obj, classdef, name): @@ -586,6 +575,12 @@ def method_isupper(chr): return s_Bool + def method_lower(chr): + return chr + + def method_upper(chr): + return chr + class __extend__(SomeIterator): def iter(itr): diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -2,9 +2,9 @@ """ Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME -Print a report for the static data informations contained in FILENAME +Print a report for the static data information contained in FILENAME -The static data informations are saved in the file staticdata.info when +The static data information is saved in the file staticdata.info when passing --dump_static_data_info to translate.py. Options: diff --git a/pypy/bin/translatorshell.py b/pypy/bin/translatorshell.py --- a/pypy/bin/translatorshell.py +++ b/pypy/bin/translatorshell.py @@ -8,10 +8,10 @@ Example: - t = Translation(func) + t = Translation(func, [int]) # pass the list of args types t.view() # control flow graph - t.annotate([int]) # pass the list of args types + t.annotate() t.view() # graph + annotations under the mouse t.rtype() # use low level operations diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py --- a/pypy/config/test/test_config.py +++ b/pypy/config/test/test_config.py @@ -111,8 +111,8 @@ else: return 'foo' - t = Translation(f) - t.rtype([int]) + t = Translation(f, [int]) + t.rtype() block = t.context.graphs[0].startblock assert len(block.exits[0].target.operations) == 0 diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -129,8 +129,6 @@ # misc BoolOption("verbose", "Print extra information", default=False), - BoolOption("debug", "Record extra annotation information", - cmdline="-d --debug", default=True), BoolOption("insist", "Try hard to go on RTyping", default=False, cmdline="--insist"), StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -101,15 +101,7 @@ def maketestobjspace(config=None): if config is None: config = make_config(option) - try: - space = make_objspace(config) - except OperationError, e: - check_keyboard_interrupt(e) - if option.verbose: - import traceback - traceback.print_exc() - py.test.fail("fatal: cannot initialize objspace: %r" % - (config.objspace.name,)) + space = make_objspace(config) space.startup() # Initialize all builtin modules space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), appsupport.build_pytest_assertion(space)) diff --git a/pypy/doc/architecture.rst b/pypy/doc/architecture.rst --- a/pypy/doc/architecture.rst +++ b/pypy/doc/architecture.rst @@ -238,7 +238,7 @@ interpreter`_. .. _`documentation index`: index.html#project-documentation -.. _`getting-started`: getting-started.html +.. _`getting-started`: getting-started-dev.html .. _`PyPy's approach to virtual machine construction`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dls2006/pypy-vm-construction.pdf .. _`the translation document`: translation.html .. _`RPython toolchain`: translation.html diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -23,7 +23,7 @@ The tools required to cross translate from a Linux based host to an ARM based Linux target are: -- A checkout of PyPy's arm-backend-2 branch. +- A checkout of PyPy (default branch). - The GCC ARM cross compiler (on Ubuntu it is the ``gcc-arm-linux-gnueabi package``) but other toolchains should also work. - Scratchbox 2, a cross-compilation engine (``scratchbox2`` Ubuntu package). - A 32-bit PyPy or Python. @@ -147,4 +147,4 @@ return 0 def target(*args): - return main, None \ No newline at end of file + return main, None diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -9,7 +9,7 @@ `import` statements:: from pypy.interpreter.baseobjspace import Wrappable - from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w @@ -41,9 +41,6 @@ llexternal functions. For a typical usage, see `pypy.rlib.rsocket.RSocket.getsockopt_int`. -- Support context managers and the `with` statement. This could be a workaround - before the previous point is available. - Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -27,7 +27,7 @@ ``pypy/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: - >>> t = Translation(snippet.is_perfect_number) + >>> t = Translation(snippet.is_perfect_number, [int]) >>> t.view() After that, the graph viewer pops up, that lets you interactively inspect the @@ -40,7 +40,7 @@ We have a type annotator that can completely infer types for functions like ``is_perfect_number`` (as well as for much larger examples):: - >>> t.annotate([int]) + >>> t.annotate() >>> t.view() Move the mouse over variable names (in red) to see their inferred types. @@ -74,8 +74,8 @@ >>> def myfunc(a, b): return a+b ... - >>> t = Translation(myfunc) - >>> t.annotate([int, int]) + >>> t = Translation(myfunc, [int, int]) + >>> t.annotate() >>> f = t.compile_cli() # or compile_jvm() >>> f(4, 5) 9 diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -115,13 +115,16 @@ which data structures would be more appropriate? For example, a dict implemented as a hash table will suffer "stm collisions" in all threads whenever one thread writes anything to it; but there could be other - implementations. + implementations. Maybe alternate strategies can be implemented at the + level of the Python interpreter (see list/dict strategies, + ``pypy/objspace/std/{list,dict}object.py``). * More generally, there is the idea that we would need some kind of "debugger"-like tool to "debug" things that are not bugs, but stm conflicts. How would this tool look like to the end Python programmers? Like a profiler? Or like a debugger with breakpoints - on aborted transactions? + on aborted transactions? It would probably be all app-level, with + a few hooks e.g. for transaction conflicts. * Find good ways to have libraries using internally threads and atomics, but not exposing threads to the user. Right now there is a rough draft 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 @@ -18,6 +18,7 @@ .. branch: numpypy_count_nonzero .. branch: numpy-refactor Remove numpy lazy evaluation and simplify everything +.. branch: numpy-reintroduce-jit-drivers .. branch: numpy-fancy-indexing Support for array[array-of-ints] in numpy .. branch: even-more-jit-hooks @@ -35,6 +36,11 @@ .. branch: stdlib-2.7.3 The stdlib was updated to version 2.7.3 +.. branch: numpypy-complex2 +Complex dtype support for numpy +.. branch: kill-someobject +major cleanups including killing some object support + .. "uninteresting" branches that we should just ignore for the whatsnew: .. branch: slightly-shorter-c 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 @@ -474,7 +474,7 @@ if f_type == F_BLOCK_LOOP: self.emit_jump(ops.CONTINUE_LOOP, block, True) break - if self.frame_blocks[i][0] == F_BLOCK_FINALLY_END: + if f_type == F_BLOCK_FINALLY_END: self.error("'continue' not supported inside 'finally' " \ "clause", cont) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -208,11 +208,11 @@ def int_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def uint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) - + def bigint_w(self, space): raise OperationError(space.w_TypeError, typed_unwrap_error_msg(space, "integer", self)) @@ -292,8 +292,6 @@ """Base class for the interpreter-level implementations of object spaces. http://pypy.readthedocs.org/en/latest/objspace.html""" - full_exceptions = True # full support for exceptions (normalization & more) - def __init__(self, config=None): "NOT_RPYTHON: Basic initialization of objects." self.fromcache = InternalSpaceCache(self).getorbuild @@ -721,8 +719,15 @@ # done by a method call on w_two (and not on w_one, because of the # expected programming style where we say "if x is None" or # "if x is object"). + assert w_two is not None return w_two.is_w(self, w_one) + def is_none(self, w_obj): + """ mostly for checking inputargs that have unwrap_spec and + can accept both w_None and None + """ + return w_obj is None or self.is_w(w_obj, self.w_None) + def id(self, w_obj): w_result = w_obj.immutable_unique_id(self) if w_result is None: @@ -806,7 +811,7 @@ interpreter class (a subclass of Wrappable). """ assert RequiredClass is not None - if can_be_None and self.is_w(w_obj, self.w_None): + if can_be_None and self.is_none(w_obj): return None obj = self.interpclass_w(w_obj) if not isinstance(obj, RequiredClass): # or obj is None @@ -1124,13 +1129,9 @@ def exception_is_valid_obj_as_class_w(self, w_obj): if not self.isinstance_w(w_obj, self.w_type): return False - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_obj, self.w_BaseException)) def exception_is_valid_class_w(self, w_cls): - if not self.full_exceptions: - return True return self.is_true(self.issubtype(w_cls, self.w_BaseException)) def exception_getclass(self, w_obj): @@ -1381,7 +1382,7 @@ if not self.is_true(self.isinstance(w_obj, self.w_str)): raise OperationError(self.w_TypeError, self.wrap('argument must be a string')) - return self.str_w(w_obj) + return self.str_w(w_obj) def unicode_w(self, w_obj): return w_obj.unicode_w(self) @@ -1702,7 +1703,7 @@ 'ValueError', 'ZeroDivisionError', ] - + if sys.platform.startswith("win"): ObjSpace.ExceptionTable += ['WindowsError'] diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -45,11 +45,6 @@ def async(self, space): "Check if this is an exception that should better not be caught." - if not space.full_exceptions: - # flow objspace does not support such exceptions and more - # importantly, raises KeyboardInterrupt if you try to access - # space.w_KeyboardInterrupt - return False return (self.match(space, space.w_SystemExit) or self.match(space, space.w_KeyboardInterrupt)) @@ -166,9 +161,7 @@ # Or 'Class' can also be an old-style class and 'inst' an old-style # instance of it. # - # Note that 'space.full_exceptions' is set to False by the flow - # object space; in this case we must assume that we are in a - # non-advanced case, and ignore the advanced cases. Old-style + # The flow object space only deals with non-advanced case. Old-style # classes and instances *are* advanced. # # input (w_type, w_value)... becomes... advanced case? @@ -183,9 +176,8 @@ # w_type = self.w_type w_value = self.get_w_value(space) - if space.full_exceptions: - while space.is_true(space.isinstance(w_type, space.w_tuple)): - w_type = space.getitem(w_type, space.wrap(0)) + while space.is_true(space.isinstance(w_type, space.w_tuple)): + w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): # this is for all cases of the form (Class, something) @@ -199,8 +191,7 @@ # raise Type, Instance: let etype be the exact type of value w_type = w_valuetype else: - if space.full_exceptions and space.is_true( - space.isinstance(w_value, space.w_tuple)): + if space.is_true(space.isinstance(w_value, space.w_tuple)): # raise Type, tuple: assume the tuple contains the # constructor args w_value = space.call(w_type, w_value) diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -205,11 +205,11 @@ code = space.interp_w(Code, w_code) if not space.is_true(space.isinstance(w_globals, space.w_dict)): raise OperationError(space.w_TypeError, space.wrap("expected dict")) - if not space.is_w(w_name, space.w_None): + if not space.is_none(w_name): name = space.str_w(w_name) else: name = None - if not space.is_w(w_argdefs, space.w_None): + if not space.is_none(w_argdefs): defs_w = space.fixedview(w_argdefs) else: defs_w = [] @@ -217,7 +217,7 @@ from pypy.interpreter.pycode import PyCode if isinstance(code, PyCode): nfreevars = len(code.co_freevars) - if space.is_w(w_closure, space.w_None) and nfreevars == 0: + if space.is_none(w_closure) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) @@ -244,7 +244,7 @@ # delicate _all = {'': None} From noreply at buildbot.pypy.org Sun Oct 14 23:29:09 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 14 Oct 2012 23:29:09 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: fix merge Message-ID: <20121014212909.247DD1C0185@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-problems Changeset: r58113:aab748525531 Date: 2012-10-14 23:18 +0200 http://bitbucket.org/pypy/pypy/changeset/aab748525531/ Log: fix merge 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 @@ -498,6 +498,7 @@ self.w_int64dtype, self.w_uint64dtype, self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, self.w_complex128dtype, + self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( From noreply at buildbot.pypy.org Mon Oct 15 00:18:06 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 15 Oct 2012 00:18:06 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: creating string array works, add more failing tests Message-ID: <20121014221806.2C0BC1C0185@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-problems Changeset: r58114:194672a6657e Date: 2012-10-15 00:17 +0200 http://bitbucket.org/pypy/pypy/changeset/194672a6657e/ Log: creating string array works, add more failing tests 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 @@ -684,6 +684,7 @@ arr = W_NDimArray.from_shape(shape, dtype, order=order) arr_iter = arr.create_iter(arr.get_shape()) for w_elem in elems_w: + print 'setting',arr_iter.offset,'to',w_elem arr_iter.setitem(dtype.coerce(space, w_elem)) arr_iter.next() return arr 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 @@ -446,6 +446,7 @@ int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype complex_type = interp_dtype.get_dtype_cache(space).w_complex128dtype float_type = interp_dtype.get_dtype_cache(space).w_float64dtype + str_dtype = interp_dtype.get_dtype_cache(space).w_stringdtype if isinstance(w_obj, interp_boxes.W_GenericBox): dtype = w_obj.get_dtype(space) if current_guess is None: @@ -472,6 +473,15 @@ current_guess is complex_type or current_guess is float_type): return complex_type return current_guess + elif space.isinstance_w(w_obj, space.w_str): + if (current_guess is None): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + elif current_guess.num ==18: + if current_guess.itemtype.size < space.len_w(w_obj): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + return current_guess if current_guess is complex_type: return complex_type return interp_dtype.get_dtype_cache(space).w_float64dtype 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 @@ -2254,6 +2254,12 @@ a = array(['abc']) assert repr(a) == "array(['abc'])" assert str(a.dtype) == '|S3' + a = array(['abc','defg','ab']) + assert str(a.dtype) == '|S4' + assert a[0] == 'abc' + assert a[1] == 'defg' + assert a[2] == 'ab' + assert repr(a) == "array(['abc', 'defg', ab'])" class AppTestPyPy(BaseNumpyAppTest): From noreply at buildbot.pypy.org Mon Oct 15 02:32:53 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 15 Oct 2012 02:32:53 +0200 (CEST) Subject: [pypy-commit] pypy py3k: rework py3k's bytes workaround directly to WrappedDefault Message-ID: <20121015003253.6849B1C0185@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58115:d4d809ec6f36 Date: 2012-10-14 17:33 -0700 http://bitbucket.org/pypy/pypy/changeset/d4d809ec6f36/ Log: rework py3k's bytes workaround directly to WrappedDefault diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -852,8 +852,7 @@ def _getdefaults(self, space): "NOT_RPYTHON" defs_w = [] - unwrap_spec = self._code._unwrap_spec[-len(self._staticdefs):] - for i, (name, defaultval) in enumerate(self._staticdefs): + for name, defaultval in self._staticdefs: if name.startswith('w_'): assert defaultval is None, ( "%s: default value for '%s' can only be None; " @@ -861,11 +860,7 @@ self._code.identifier, name)) defs_w.append(None) else: - spec = unwrap_spec[i] - if isinstance(defaultval, str) and spec not in [str]: - defs_w.append(space.wrapbytes(defaultval)) - else: - defs_w.append(space.wrap(defaultval)) + defs_w.append(space.wrap(defaultval)) if self._code._unwrap_spec: UNDEFINED = object() alldefs_w = [UNDEFINED] * len(self._code.sig[0]) @@ -881,7 +876,11 @@ if isinstance(spec, tuple) and spec[0] is W_Root: assert False, "use WrappedDefault" if isinstance(spec, WrappedDefault): - w_default = space.wrap(spec.default_value) + default_value = spec.default_value + if isinstance(default_value, str): + w_default = space.wrapbytes(default_value) + else: + w_default = space.wrap(default_value) assert isinstance(w_default, W_Root) assert argname.startswith('w_') argname = argname[2:] 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 @@ -611,6 +611,16 @@ never_called py.test.raises(AssertionError, space.wrap, gateway.interp2app_temp(g)) + def test_unwrap_spec_default_applevel_bytes(self): + space = self.space + @gateway.unwrap_spec(w_x=WrappedDefault('foo')) + def g(space, w_x): + return w_x + w_g = space.wrap(gateway.interp2app_temp(g)) + args = argument.Arguments(space, []) + w_res = space.call_args(w_g, args) + assert space.eq_w(w_res, space.wrapbytes('foo')) + class AppTestPyTestMark: @py.test.mark.unlikely_to_exist From noreply at buildbot.pypy.org Mon Oct 15 02:32:54 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 15 Oct 2012 02:32:54 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fix new None handling in exec Message-ID: <20121015003254.A6ED71C0185@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58116:bf06f3cfdcdc Date: 2012-10-14 17:33 -0700 http://bitbucket.org/pypy/pypy/changeset/bf06f3cfdcdc/ Log: fix new None handling in exec diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -107,6 +107,10 @@ return codeobj.exec_code(space, w_globals, w_locals) def exec_(space, w_prog, w_globals=None, w_locals=None): + if w_globals is None: + w_globals = space.w_None + if w_locals is None: + w_locals = space.w_None ec = space.getexecutioncontext() frame = ec.gettopframe_nohidden() frame.exec_(w_prog, w_globals, w_locals) From noreply at buildbot.pypy.org Mon Oct 15 02:54:00 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 15 Oct 2012 02:54:00 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Store return values in the exception, not in the stack Message-ID: <20121015005400.0DD1E1C015F@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58117:74d25d92e89a Date: 2012-10-14 20:12 +0100 http://bitbucket.org/pypy/pypy/changeset/74d25d92e89a/ Log: Store return values in the exception, not in the stack diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -31,6 +31,10 @@ class StopFlowing(Exception): pass +class Return(Exception): + def __init__(self, value): + self.value = value + class FSException(Exception): def __init__(self, w_type, w_value): assert w_type is not None @@ -375,9 +379,8 @@ except StopFlowing: pass - except Return: - w_result = self.popvalue() - assert w_result is not None + except Return as exc: + w_result = exc.value link = Link([w_result], graph.returnblock) self.recorder.crnt_block.closeblock(link) @@ -553,8 +556,7 @@ w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: - self.pushvalue(w_returnvalue) # XXX ping pong - raise Return + raise Return(w_returnvalue) else: unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) @@ -587,9 +589,7 @@ # go on unrolling the stack block = self.unrollstack(unroller.kind) if block is None: - w_result = unroller.nomoreblocks() - self.pushvalue(w_result) - raise Return + unroller.nomoreblocks() else: return block.handle(self, unroller) @@ -773,7 +773,7 @@ self.w_returnvalue = w_returnvalue def nomoreblocks(self): - return self.w_returnvalue + raise Return(self.w_returnvalue) def state_unpack_variables(self, space): return [self.w_returnvalue] From noreply at buildbot.pypy.org Mon Oct 15 08:12:05 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 15 Oct 2012 08:12:05 +0200 (CEST) Subject: [pypy-commit] pypy py3k: py3k does not allow utf-8 surrogates. Message-ID: <20121015061205.5A4D31C0250@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58118:c6ea5993265c Date: 2012-10-11 23:06 +0200 http://bitbucket.org/pypy/pypy/changeset/c6ea5993265c/ Log: py3k does not allow utf-8 surrogates. diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -51,12 +51,10 @@ def PyUnicode_DecodeUTF8(space, string): result, consumed = runicode.str_decode_utf_8( string, len(string), "strict", - final=True, errorhandler=decode_error_handler(space), - allow_surrogates=True) + final=True, errorhandler=decode_error_handler(space)) return result def PyUnicode_EncodeUTF8(space, uni): return runicode.unicode_encode_utf_8( uni, len(uni), "strict", - errorhandler=encode_error_handler(space), - allow_surrogates=True) + errorhandler=encode_error_handler(space)) From noreply at buildbot.pypy.org Mon Oct 15 08:12:06 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 15 Oct 2012 08:12:06 +0200 (CEST) Subject: [pypy-commit] pypy py3k: compile() and eval() accept unicode strings with a "-*- coding: -*-" cookie, Message-ID: <20121015061206.992A91C0250@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58119:7ac22e106432 Date: 2012-10-15 08:10 +0200 http://bitbucket.org/pypy/pypy/changeset/7ac22e106432/ Log: compile() and eval() accept unicode strings with a "-*- coding: -*-" cookie, it is simply ignored. diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py --- a/pypy/interpreter/astcompiler/consts.py +++ b/pypy/interpreter/astcompiler/consts.py @@ -20,3 +20,4 @@ PyCF_SOURCE_IS_UTF8 = 0x0100 PyCF_DONT_IMPLY_DEDENT = 0x0200 PyCF_ONLY_AST = 0x0400 +PyCF_IGNORE_COOKIE = 0x0800 diff --git a/pypy/interpreter/pyparser/pyparse.py b/pypy/interpreter/pyparser/pyparse.py --- a/pypy/interpreter/pyparser/pyparse.py +++ b/pypy/interpreter/pyparser/pyparse.py @@ -113,7 +113,8 @@ textsrc = bytessrc elif compile_info.flags & consts.PyCF_SOURCE_IS_UTF8: enc = 'utf-8' - if _check_for_encoding(bytessrc) is not None: + if (not compile_info.flags & consts.PyCF_IGNORE_COOKIE and + _check_for_encoding(bytessrc) is not None): raise error.SyntaxError("coding declaration in unicode string", filename=compile_info.filename) textsrc = bytessrc diff --git a/pypy/interpreter/pyparser/test/test_pyparse.py b/pypy/interpreter/pyparser/test/test_pyparse.py --- a/pypy/interpreter/pyparser/test/test_pyparse.py +++ b/pypy/interpreter/pyparser/test/test_pyparse.py @@ -167,11 +167,16 @@ input = "\xEF\xBB\xBF# coding: utf-8\nx" self.parse(input, info=info) assert info.encoding == "utf-8" + # input = "# coding: utf-8\nx" info.flags |= consts.PyCF_SOURCE_IS_UTF8 exc = py.test.raises(SyntaxError, self.parse, input, info=info).value - info.flags &= ~consts.PyCF_SOURCE_IS_UTF8 assert exc.msg == "coding declaration in unicode string" + info.flags |= consts.PyCF_IGNORE_COOKIE + self.parse(input, info=info) + assert info.encoding == "utf-8" + info.flags &= ~(consts.PyCF_SOURCE_IS_UTF8 | consts.PyCF_IGNORE_COOKIE) + # input = "\xEF\xBB\xBF# coding: latin-1\nx" exc = py.test.raises(SyntaxError, self.parse, input).value assert exc.msg == "UTF-8 BOM with non-utf8 coding cookie" diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -25,6 +25,13 @@ in addition to any features explicitly specified. """ + ec = space.getexecutioncontext() + if flags & ~(ec.compiler.compiler_flags | consts.PyCF_ONLY_AST | + consts.PyCF_DONT_IMPLY_DEDENT | consts.PyCF_SOURCE_IS_UTF8): + raise OperationError(space.w_ValueError, + space.wrap("compile() unrecognized flags")) + + flags |= consts.PyCF_SOURCE_IS_UTF8 ast_node = None w_ast_type = space.gettypeobject(ast.AST.typedef) source_str = None @@ -32,17 +39,11 @@ ast_node = space.interp_w(ast.mod, w_source) ast_node.sync_app_attrs(space) elif space.isinstance_w(w_source, space.w_bytes): - source_str = space.bytes_w(w_source) + source_str = space.bytes0_w(w_source) else: - source_str = space.str_w(w_source) - # This flag tells the parser to reject any coding cookies it sees. - flags |= consts.PyCF_SOURCE_IS_UTF8 + source_str = space.str0_w(w_source) + flags |= consts.PyCF_IGNORE_COOKIE - ec = space.getexecutioncontext() - if flags & ~(ec.compiler.compiler_flags | consts.PyCF_ONLY_AST | - consts.PyCF_DONT_IMPLY_DEDENT | consts.PyCF_SOURCE_IS_UTF8): - raise OperationError(space.w_ValueError, - space.wrap("compile() unrecognized flags")) if not dont_inherit: caller = ec.gettopframe_nohidden() if caller: From noreply at buildbot.pypy.org Mon Oct 15 18:15:11 2012 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 15 Oct 2012 18:15:11 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: start creating some charts Message-ID: <20121015161511.33A6A1C0B66@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4854:ac2f2f220865 Date: 2012-10-15 13:14 -0300 http://bitbucket.org/pypy/extradoc/changeset/ac2f2f220865/ Log: start creating some charts diff --git a/talk/vmil2012/presentation/charts.ods b/talk/vmil2012/presentation/charts.ods new file mode 100644 index 0000000000000000000000000000000000000000..8e9d322d576cf9475b73264bb28b5143e4d2ed4d GIT binary patch [cut] From noreply at buildbot.pypy.org Mon Oct 15 18:22:04 2012 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 15 Oct 2012 18:22:04 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: add guards/other operations relation chart for a single benchmark Message-ID: <20121015162204.4C76A1C0FFC@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4855:45045d60d638 Date: 2012-10-15 13:21 -0300 http://bitbucket.org/pypy/extradoc/changeset/45045d60d638/ Log: add guards/other operations relation chart for a single benchmark diff --git a/talk/vmil2012/presentation/charts.ods b/talk/vmil2012/presentation/charts.ods index 8e9d322d576cf9475b73264bb28b5143e4d2ed4d..94300512c367f6ea2553953adde39281e950b27c GIT binary patch [cut] From noreply at buildbot.pypy.org Mon Oct 15 21:02:59 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 15 Oct 2012 21:02:59 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fix None default Message-ID: <20121015190259.369A01C0FB8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58120:d52e58eeee9a Date: 2012-10-15 12:01 -0700 http://bitbucket.org/pypy/pypy/changeset/d52e58eeee9a/ Log: fix None default diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -20,7 +20,8 @@ sock = space.allocate_instance(W_RSocket, w_subtype) return space.wrap(sock) - @unwrap_spec(family=int, type=int, proto=int) + @unwrap_spec(family=int, type=int, proto=int, + w_fileno=WrappedDefault(None)) def descr_init(self, space, family=AF_INET, type=SOCK_STREAM, proto=0, w_fileno=None): try: From noreply at buildbot.pypy.org Mon Oct 15 21:03:00 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 15 Oct 2012 21:03:00 +0200 (CEST) Subject: [pypy-commit] pypy py3k: don't export SSL_CTX_clear_options unless we have it Message-ID: <20121015190300.5E25F1C0FB8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58121:448a96a744bc Date: 2012-10-15 12:02 -0700 http://bitbucket.org/pypy/pypy/changeset/448a96a744bc/ Log: don't export SSL_CTX_clear_options unless we have it diff --git a/pypy/rlib/ropenssl.py b/pypy/rlib/ropenssl.py --- a/pypy/rlib/ropenssl.py +++ b/pypy/rlib/ropenssl.py @@ -221,7 +221,9 @@ ssl_external('SSL_CTX_use_certificate_chain_file', [SSL_CTX, rffi.CCHARP], rffi.INT) ssl_external('SSL_CTX_get_options', [SSL_CTX], rffi.INT, macro=True) ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.INT], rffi.INT, macro=True) -ssl_external('SSL_CTX_clear_options', [SSL_CTX, rffi.INT], rffi.INT, macro=True) +if HAVE_SSL_CTX_CLEAR_OPTIONS: + ssl_external('SSL_CTX_clear_options', [SSL_CTX, rffi.INT], rffi.INT, + macro=True) ssl_external('SSL_CTX_ctrl', [SSL_CTX, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT) ssl_external('SSL_CTX_set_verify', [SSL_CTX, rffi.INT, rffi.VOIDP], lltype.Void) ssl_external('SSL_CTX_get_verify_mode', [SSL_CTX], rffi.INT) From noreply at buildbot.pypy.org Mon Oct 15 21:03:01 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 15 Oct 2012 21:03:01 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fix for py3 map Message-ID: <20121015190301.821B81C0FB8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58122:1abae2e871af Date: 2012-10-15 12:03 -0700 http://bitbucket.org/pypy/pypy/changeset/1abae2e871af/ Log: fix for py3 map 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 @@ -31,7 +31,7 @@ assert operator.attrgetter('x','z','y')(a) == ('X', 'Z', 'Y') raises(TypeError, operator.attrgetter('x', (), 'y'), a) - data = map(str, range(20)) + data = list(map(str, range(20))) assert operator.itemgetter(2,10,5)(data) == ('2', '10', '5') raises(TypeError, operator.itemgetter(2, 'x', 5), data) From noreply at buildbot.pypy.org Mon Oct 15 21:13:28 2012 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 15 Oct 2012 21:13:28 +0200 (CEST) Subject: [pypy-commit] buildbot default: copy ctypes_resource_cache to checkout used for testing Message-ID: <20121015191328.486761C0088@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r709:72f31d60f4cf Date: 2012-10-15 16:12 -0300 http://bitbucket.org/pypy/buildbot/changeset/72f31d60f4cf/ Log: copy ctypes_resource_cache to checkout used for testing diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -440,7 +440,7 @@ # download corresponding nightly build self.addStep(ShellCmd( description="Clear pypy-c", - command= ['rm', '-rf', 'pypy-c'], + command=['rm', '-rf', 'pypy-c'], workdir='.')) extension = get_extension(platform) name = build_name(platform, pypyjit, translationArgs, placeholder='%(revision)s') + extension @@ -469,6 +469,11 @@ description="move header files", command=['cp', '-vr', 'pypy-c/include', 'build'], 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'], + workdir='.')) add_translated_tests(self, prefix, platform, app_tests, lib_python, pypyjit) From noreply at buildbot.pypy.org Mon Oct 15 21:13:29 2012 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 15 Oct 2012 21:13:29 +0200 (CEST) Subject: [pypy-commit] buildbot default: merge heads Message-ID: <20121015191329.657BD1C0088@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r710:4aaabe5cd63d Date: 2012-10-15 16:12 -0300 http://bitbucket.org/pypy/buildbot/changeset/4aaabe5cd63d/ Log: merge heads diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -231,7 +231,6 @@ JITWIN64 = "pypy-c-jit-win-x86-64" JITFREEBSD64 = 'pypy-c-jit-freebsd-7-x86-64' -JITONLYLINUX32 = "jitonly-own-linux-x86-32" JITBACKENDONLYLINUXARMEL = "jitbackendonly-own-linux-armel" JITBACKENDONLYLINUXARMELXDIST = "jitbackendonly-own-linux-armel-xdist" JITONLYLINUXPPC64 = "jitonly-own-linux-ppc-64" @@ -309,69 +308,55 @@ 'builders': [ {"name": LINUX32, - "slavenames": ["bigdogvm1", "tannit32"], + "slavenames": ["allegro32", "tannit32"], "builddir": LINUX32, "factory": pypyOwnTestFactory, "category": 'linux32', # this build needs 4 CPUs - "locks": [TannitCPU.access('exclusive')], + #"locks": [TannitCPU.access('exclusive')], }, {"name": LINUX64, - "slavenames": ["tannit64"], + "slavenames": ["allegro64", "tannit64"], "builddir": LINUX64, "factory": pypyOwnTestFactory, "category": 'linux64', # this build needs 4 CPUs - "locks": [TannitCPU.access('exclusive')], - }, - {"name": LINUX64 + "2", - "slavenames": ["allegro64"], - "builddir": LINUX64 + "2", - "factory": pypyOwnTestFactory, - "category": 'linux64', - # no locks, this is not a tannit build + #"locks": [TannitCPU.access('exclusive')], }, {"name": APPLVLLINUX32, - "slavenames": ["bigdogvm1", "tannit32"], + "slavenames": ["allegro32", "tannit32"], "builddir": APPLVLLINUX32, "factory": pypyTranslatedAppLevelTestFactory, 'category': 'linux32', - "locks": [TannitCPU.access('counting')], + #"locks": [TannitCPU.access('counting')], }, {"name": APPLVLLINUX64, - "slavenames": ["tannit64"], + "slavenames": ["allegro64", "tannit64"], "builddir": APPLVLLINUX64, "factory": pypyTranslatedAppLevelTestFactory64, "category": "linux64", - "locks": [TannitCPU.access('counting')], + #"locks": [TannitCPU.access('counting')], }, {"name": OJITLINUX32, - "slavenames": ["bigdogvm1", "tannit32"], + "slavenames": ["allegro32", "tannit32"], "builddir": OJITLINUX32, "factory": pypy_OjitTranslatedTestFactory, "category": 'linux32', - "locks": [TannitCPU.access('counting')], + #"locks": [TannitCPU.access('counting')], }, {"name" : JITLINUX32, - "slavenames": ["bigdogvm1", "tannit32"], + "slavenames": ["allegro32", "tannit32"], 'builddir' : JITLINUX32, 'factory' : pypyJITTranslatedTestFactory, 'category' : 'linux32', - "locks": [TannitCPU.access('counting')], + #"locks": [TannitCPU.access('counting')], }, {'name': JITLINUX64, - 'slavenames': ['tannit64'], + 'slavenames': ["allegro64", 'tannit64'], 'builddir': JITLINUX64, 'factory': pypyJITTranslatedTestFactory64, 'category': 'linux64', - "locks": [TannitCPU.access('counting')], - }, - {"name": JITONLYLINUX32, - "slavenames": ["tannit32", "bigdogvm1"], - "builddir": JITONLYLINUX32, - "factory": pypyJitOnlyOwnTestFactory, - "category": 'linux32', - "locks": [TannitCPU.access('counting')], + #"locks": [TannitCPU.access('counting')], }, {"name": JITBENCH, "slavenames": ["tannit32"], diff --git a/bot2/pypybuildbot/summary.py b/bot2/pypybuildbot/summary.py --- a/bot2/pypybuildbot/summary.py +++ b/bot2/pypybuildbot/summary.py @@ -804,6 +804,8 @@ branch_key = (len(self.branch_order_prefixes)+1, branch) for i, catprefix in enumerate(self.categories): if category.startswith(catprefix): + # kill '-' to make 'linux32' sort before 'linux-armel' + category = category.replace('-', '') break else: i = len(self.categories) From noreply at buildbot.pypy.org Tue Oct 16 01:49:43 2012 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 16 Oct 2012 01:49:43 +0200 (CEST) Subject: [pypy-commit] buildbot default: Add a larger timeout to lib-python tests (same as for app tests) Message-ID: <20121015234943.B597A1C0B66@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r711:64a87dc4885f Date: 2012-10-15 20:49 -0300 http://bitbucket.org/pypy/buildbot/changeset/64a87dc4885f/ Log: Add a larger timeout to lib-python tests (same as for app tests) diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -325,7 +325,9 @@ description="lib-python test", command=prefix + ["python", "pypy/test_all.py", "--pypy=pypy/translator/goal/pypy-c", + "--timeout=1800", "--resultlog=cpython.log", "lib-python"], + timeout=4000, logfiles={'pytestLog': 'cpython.log'})) if pypyjit: From noreply at buildbot.pypy.org Tue Oct 16 02:40:53 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 16 Oct 2012 02:40:53 +0200 (CEST) Subject: [pypy-commit] pypy py3k: py3 syntax Message-ID: <20121016004053.52B081C0088@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58123:b3d780283e57 Date: 2012-10-15 17:37 -0700 http://bitbucket.org/pypy/pypy/changeset/b3d780283e57/ Log: py3 syntax diff --git a/pypy/objspace/std/test/test_proxy_internals.py b/pypy/objspace/std/test/test_proxy_internals.py --- a/pypy/objspace/std/test/test_proxy_internals.py +++ b/pypy/objspace/std/test/test_proxy_internals.py @@ -59,7 +59,7 @@ try: try: 1/0 - except ZeroDivisionError, e: + except ZeroDivisionError as e: ex = self.get_proxy(e) raise ex except ZeroDivisionError: @@ -76,8 +76,8 @@ e = sys.exc_info() tb = self.get_proxy(e[2]) - raises(ZeroDivisionError, "raise e[0], e[1], tb") - raises(ZeroDivisionError, "raise e[0], self.get_proxy(e[1]), tb") + raises(ZeroDivisionError, "raise e[0](e[1]).with_traceback(tb)") + raises(ZeroDivisionError, "raise e[0](self.get_proxy(e[1])).with_traceback(tb)") import traceback assert len(traceback.format_tb(tb)) == 1 @@ -131,7 +131,7 @@ last_tb = e[2] tb = get_proxy(e[2]) try: - raise e[0], e[1], tb + raise e[0](e[1]).with_traceback(tb) except: e = sys.exc_info() From noreply at buildbot.pypy.org Tue Oct 16 02:40:54 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 16 Oct 2012 02:40:54 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fdopen now resides in os Message-ID: <20121016004054.7E5521C0088@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58124:07a3678977b9 Date: 2012-10-15 17:38 -0700 http://bitbucket.org/pypy/pypy/changeset/07a3678977b9/ Log: fdopen now resides in os diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -52,6 +52,7 @@ def setup_class(cls): cls.space = space cls.w_posix = space.appexec([], GET_POSIX) + cls.w_os = space.appexec([], "(): import os as m ; return m") cls.w_path = space.wrap(str(path)) cls.w_path2 = space.wrap(str(path2)) cls.w_pdir = space.wrap(str(pdir)) @@ -844,10 +845,9 @@ assert hasattr(os, 'kill') def test_pipe_flush(self): - os = self.posix - ffd, gfd = os.pipe() - f = os.fdopen(ffd, 'r') - g = os.fdopen(gfd, 'w') + ffd, gfd = self.posix.pipe() + f = self.os.fdopen(ffd, 'r') + g = self.os.fdopen(gfd, 'w') g.write('he') g.flush() x = f.read(1) From noreply at buildbot.pypy.org Tue Oct 16 02:40:55 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 16 Oct 2012 02:40:55 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fix None handling Message-ID: <20121016004055.BB1DC1C0B66@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58125:3b9d43911b4d Date: 2012-10-15 17:38 -0700 http://bitbucket.org/pypy/pypy/changeset/3b9d43911b4d/ Log: fix None handling diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -307,11 +307,11 @@ character at the same position in y. If there is a third argument, it must be a string, whose characters will be mapped to None in the result.""" - if space.is_w(w_y, space.w_None): + if space.is_none(w_y): y = None else: y = space.unicode_w(w_y) - if space.is_w(w_z, space.w_None): + if space.is_none(w_z): z = None else: z = space.unicode_w(w_z) From noreply at buildbot.pypy.org Tue Oct 16 02:40:56 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 16 Oct 2012 02:40:56 +0200 (CEST) Subject: [pypy-commit] pypy py3k: use py3 __next__/builtins.next() Message-ID: <20121016004056.DBC3C1C0B66@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58126:a496b3369dae Date: 2012-10-15 17:39 -0700 http://bitbucket.org/pypy/pypy/changeset/a496b3369dae/ Log: use py3 __next__/builtins.next() diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py --- a/lib_pypy/itertools.py +++ b/lib_pypy/itertools.py @@ -46,22 +46,18 @@ """ def __init__(self, *iterables): self._iterables_iter = iter(map(iter, iterables)) - # little trick for the first chain.next() call + # little trick for the first chain.__next__() call self._cur_iterable_iter = iter([]) def __iter__(self): return self - def next(self): + def __next__(self): while True: try: - return self._cur_iterable_iter.next() + return next(self._cur_iterable_iter) except StopIteration: - self._cur_iterable_iter = self._iterables_iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iterable_iter)) + self._cur_iterable_iter = next(self._iterables_iter) class compress(object): @@ -72,10 +68,10 @@ def __iter__(self): return self - def next(self): + def __next__(self): while True: - next_item = self.data.next() - next_selector = self.selectors.next() + next_item = next(self.data) + next_selector = next(self.selectors) if bool(next_selector): return next_item @@ -104,7 +100,7 @@ def __iter__(self): return self - def next(self): + def __next__(self): self.times += 1 return self.times @@ -137,20 +133,16 @@ def __iter__(self): return self - def next(self): + def __next__(self): # XXX Could probably be improved try: - next_elt = self._cur_iter.next() + next_elt = next(self._cur_iter) if self._must_save: self._saved.append(next_elt) except StopIteration: self._cur_iter = iter(self._saved) - next_elt = self._cur_iter.next() + next_elt = next(self._cur_iter) self._must_save = False - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iter)) return next_elt @@ -179,17 +171,12 @@ def __iter__(self): return self - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) + def __next__(self): + value = next(self._iter) if self._dropped: return value while self._predicate(value): - value = self._iter.next() + value = next(self._iter) self._dropped = True return value @@ -222,14 +209,9 @@ def __iter__(self): return self - def next(self): + def __next__(self): while self.currkey == self.tgtkey: - try: - self.currvalue = self.it.next() # Exit on StopIteration - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self.it)) + self.currvalue = next(self.it) # Exit on StopIteration self.currkey = self.keyfunc(self.currvalue) self.tgtkey = self.currkey return (self.currkey, self._grouper(self.tgtkey)) @@ -237,7 +219,7 @@ def _grouper(self, tgtkey): while self.currkey == tgtkey: yield self.currvalue - self.currvalue = self.it.next() # Exit on StopIteration + self.currvalue = next(self.it) # Exit on StopIteration self.currkey = self.keyfunc(self.currvalue) @@ -269,17 +251,12 @@ if predicate(x): yield x """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) + def __next__(self): + next_elt = next(self._iter) while True: if self._predicate(next_elt): return next_elt - next_elt = self._iter.next() + next_elt = next(self._iter) class ifilterfalse(_ifilter_base): """Make an iterator that filters elements from iterable returning @@ -295,17 +272,12 @@ if not predicate(x): yield x """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) + def __next__(self): + next_elt = next(self._iter) while True: if not self._predicate(next_elt): return next_elt - next_elt = self._iter.next() + next_elt = next(self._iter) @@ -325,7 +297,7 @@ def imap(function, *iterables): iterables = map(iter, iterables) while True: - args = [i.next() for i in iterables] + args = [next(i) for i in iterables] if function is None: yield tuple(args) else: @@ -339,13 +311,8 @@ def __iter__(self): return self - def next(self): - try: - args = [it.next() for it in self._iters] - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (it)) + def __next__(self): + args = [next(it) for it in self._iters] if self._func is None: return tuple(args) else: @@ -369,9 +336,9 @@ def __init__(self, iterable, *args): s = slice(*args) self.start, self.stop, self.step = s.start or 0, s.stop, s.step - if not isinstance(self.start, (int, long)): + if not isinstance(self.start, int): raise ValueError("Start argument must be an integer") - if self.stop is not None and not isinstance(self.stop, (int,long)): + if self.stop is not None and not isinstance(self.stop, int): raise ValueError("Stop argument must be an integer or None") if self.step is None: self.step = 1 @@ -385,17 +352,12 @@ def __iter__(self): return self - def next(self): - if self.donext is None: - try: - self.donext = self.it.next - except AttributeError: - raise TypeError + def __next__(self): nextindex = self.start if self.stop is not None and nextindex >= self.stop: raise StopIteration while self.cnt <= nextindex: - nextitem = self.donext() + nextitem = next(self.it) self.cnt += 1 self.start += self.step return nextitem @@ -411,7 +373,7 @@ def izip(*iterables): iterables = map(iter, iterables) while iterables: - result = [i.next() for i in iterables] + result = [next(i) for i in iterables] yield tuple(result) """ def __init__(self, *iterables): @@ -421,14 +383,10 @@ def __iter__(self): return self - def next(self): + def __next__(self): if not self._iterators: raise StopIteration() - try: - return tuple([i.next() for i in self._iterators]) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (i)) + return tuple([next(i) for i in self._iterators]) class product(object): @@ -469,7 +427,7 @@ def __iter__(self): return self - def next(self): + def __next__(self): if not self.cont: raise StopIteration l = [] @@ -508,8 +466,8 @@ def __iter__(self): return self - def next(self): - # next() *need* to decrement self._times when consumed + def __next__(self): + # __next__() *need* to decrement self._times when consumed if self._times is not None: if self._times <= 0: raise StopIteration() @@ -541,7 +499,7 @@ def starmap(function, iterable): iterable = iter(iterable) while True: - yield function(*iterable.next()) + yield function(*next(iterable)) """ def __init__(self, function, iterable): self._func = function @@ -550,13 +508,9 @@ def __iter__(self): return self - def next(self): + def __next__(self): # CPython raises a TypeError when the iterator doesn't return a tuple - try: - t = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) + t = next(self._iter) if not isinstance(t, tuple): raise TypeError("iterator must return a tuple") return self._func(*t) @@ -583,13 +537,8 @@ def __iter__(self): return self - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) + def __next__(self): + value = next(self._iter) if not self._predicate(value): raise StopIteration() return value @@ -604,11 +553,7 @@ def __getitem__(self, i): # iterates until 'i' if not done yet while i>= len(self.data): - try: - self.data.append( self._iter.next() ) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) + self.data.append(next(self._iter)) return self.data[i] @@ -626,7 +571,7 @@ self.tee_data = TeeData(iter(iterable)) self.pos = 0 - def next(self): + def __next__(self): data = self.tee_data[self.pos] self.pos += 1 return data @@ -649,18 +594,18 @@ of tee() Equivalent to : - + def tee(iterable, n=2): - def gen(next, data={}, cnt=[0]): - for i in count(): - if i == cnt[0]: - item = data[i] = next() - cnt[0] += 1 - else: - item = data.pop(i) - yield item it = iter(iterable) - return tuple([gen(it.next) for i in range(n)]) + deques = [collections.deque() for i in range(n)] + def gen(mydeque): + while True: + if not mydeque: # when the local deque is empty + newval = next(it) # fetch a new value and + for d in deques: # load it to all the deques + d.append(newval) + yield mydeque.popleft() + return tuple(gen(d) for d in deques) """ if isinstance(iterable, TeeObject): # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) From noreply at buildbot.pypy.org Tue Oct 16 11:58:15 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 16 Oct 2012 11:58:15 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Derive FSFrame directly from PyFrame Message-ID: <20121016095815.1EC5A1C01C4@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58127:33478c5d1f9f Date: 2012-10-16 10:57 +0100 http://bitbucket.org/pypy/pypy/changeset/33478c5d1f9f/ Log: Derive FSFrame directly from PyFrame + Refactor opcode patching tests diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -6,9 +6,10 @@ import collections from pypy.tool.error import source_lines +from pypy.tool.stdlib_opcode import host_bytecode_spec from pypy.interpreter import pyframe from pypy.interpreter.argument import ArgumentsForTranslation -from pypy.interpreter.pyopcode import Return, BytecodeCorruption +from pypy.interpreter.pyopcode import BytecodeCorruption from pypy.objspace.flow.model import (Constant, Variable, Block, Link, UnwrapException, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, @@ -224,7 +225,8 @@ "cmp_exc_match", ] -class FlowSpaceFrame(pyframe.CPythonFrame): +class FlowSpaceFrame(pyframe.PyFrame): + opcode_method_names = host_bytecode_spec.method_names def __init__(self, space, graph, code): self.graph = graph diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1,19 +1,32 @@ from __future__ import with_statement import new import py, sys -from pypy.objspace.flow.model import Constant -from pypy.objspace.flow.model import mkentrymap, c_last_exception +from contextlib import contextmanager + +from pypy.objspace.flow.model import Constant, mkentrymap, c_last_exception from pypy.translator.simplify import simplify_graph from pypy.objspace.flow.objspace import FlowObjSpace from pypy.objspace.flow.flowcontext import FlowingError, FlowSpaceFrame from pypy import conftest -from pypy.tool.stdlib_opcode import bytecode_spec -from pypy.interpreter.pyframe import PyFrame +from pypy.tool.stdlib_opcode import bytecode_spec, host_bytecode_spec import os import operator is_operator = getattr(operator, 'is_', operator.eq) # it's not there 2.2 + at contextmanager +def patching_opcodes(*opcodes): + meth_names = host_bytecode_spec.method_names + opnums = [bytecode_spec.opmap[name] for name in opcodes] + old_name = {} + for name, num in zip(opcodes, opnums): + old_name[num] = meth_names[num] + meth_names[num] = name + yield + for name in opcodes: + meth_names[num] = old_name[num] + + class Base: def codetest(self, func, **kwds): import inspect @@ -875,26 +888,11 @@ c.co_filename, c.co_name, c.co_firstlineno, c.co_lnotab) - def patch_opcodes(self, *opcodes): - flow_meth_names = FlowSpaceFrame.opcode_method_names - pyframe_meth_names = PyFrame.opcode_method_names - for name in opcodes: - num = bytecode_spec.opmap[name] - setattr(self, 'old_' + name, flow_meth_names[num]) - flow_meth_names[num] = pyframe_meth_names[num] - - def unpatch_opcodes(self, *opcodes): - flow_meth_names = FlowSpaceFrame.opcode_method_names - for name in opcodes: - num = bytecode_spec.opmap[name] - flow_meth_names[num] = getattr(self, 'old_' + name) - def test_callmethod_opcode(self): """ Tests code generated by pypy-c compiled with CALL_METHOD bytecode """ - self.patch_opcodes('CALL_METHOD', 'LOOKUP_METHOD') - try: + with patching_opcodes('CALL_METHOD', 'LOOKUP_METHOD'): class X: def m(self): return 3 @@ -912,17 +910,13 @@ all_ops = self.all_operations(graph) assert all_ops['simple_call'] == 2 assert all_ops['getattr'] == 1 - finally: - self.unpatch_opcodes('CALL_METHOD', 'LOOKUP_METHOD') + @py.test.mark.skipif('sys.version_info < (2, 7)') def test_build_list_from_arg_opcode(self): """ Tests code generated by pypy-c compiled with BUILD_LIST_FROM_ARG bytecode """ - if sys.version_info < (2, 7): - py.test.skip("2.7 only test") - self.patch_opcodes('BUILD_LIST_FROM_ARG') - try: + with patching_opcodes('BUILD_LIST_FROM_ARG'): def f(): return [i for i in "abc"] @@ -936,8 +930,6 @@ all_ops = self.all_operations(graph) assert all_ops == {'newlist': 1, 'getattr': 1, 'simple_call': 1, 'iter': 1, 'next': 1} - finally: - self.unpatch_opcodes('BUILD_LIST_FROM_ARG') def test_dont_capture_RuntimeError(self): class Foo: From noreply at buildbot.pypy.org Tue Oct 16 15:45:07 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 16 Oct 2012 15:45:07 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Flowspacify dropvaluesuntil() Message-ID: <20121016134507.B47CE1C027A@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58128:91340fe60db1 Date: 2012-10-16 11:11 +0100 http://bitbucket.org/pypy/pypy/changeset/91340fe60db1/ Log: Flowspacify dropvaluesuntil() diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -261,6 +261,11 @@ self.valuestackdepth = code.co_nlocals self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals) + def dropvaluesuntil(self, finaldepth): + for n in range(finaldepth, self.valuestackdepth): + self.locals_stack_w[n] = None + self.valuestackdepth = finaldepth + def save_locals_stack(self): return self.locals_stack_w[:self.valuestackdepth] From noreply at buildbot.pypy.org Tue Oct 16 15:45:08 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 16 Oct 2012 15:45:08 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Flowspacify stack manipulation methods Message-ID: <20121016134508.E761B1C027A@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58129:0e6cc47af479 Date: 2012-10-16 11:29 +0100 http://bitbucket.org/pypy/pypy/changeset/0e6cc47af479/ Log: Flowspacify stack manipulation methods diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -261,6 +261,32 @@ self.valuestackdepth = code.co_nlocals self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals) + def pushvalue(self, w_object): + depth = self.valuestackdepth + self.locals_stack_w[depth] = w_object + self.valuestackdepth = depth + 1 + + def popvalue(self): + depth = self.valuestackdepth - 1 + assert depth >= self.pycode.co_nlocals, "pop from empty value stack" + w_object = self.locals_stack_w[depth] + self.locals_stack_w[depth] = None + self.valuestackdepth = depth + return w_object + + def peekvalue(self, index_from_top=0): + # NOTE: top of the stack is peekvalue(0). + index = self.valuestackdepth + ~index_from_top + assert index >= self.pycode.co_nlocals, ( + "peek past the bottom of the stack") + return self.locals_stack_w[index] + + def settopvalue(self, w_object, index_from_top=0): + index = self.valuestackdepth + ~index_from_top + assert index >= self.pycode.co_nlocals, ( + "settop past the bottom of the stack") + self.locals_stack_w[index] = w_object + def dropvaluesuntil(self, finaldepth): for n in range(finaldepth, self.valuestackdepth): self.locals_stack_w[n] = None From noreply at buildbot.pypy.org Tue Oct 16 15:47:46 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 16 Oct 2012 15:47:46 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Flowspacify more stack manipulation methods Message-ID: <20121016134746.AD61C1C027A@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58130:40efd825a611 Date: 2012-10-16 14:47 +0100 http://bitbucket.org/pypy/pypy/changeset/40efd825a611/ Log: Flowspacify more stack manipulation methods diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -287,6 +287,22 @@ "settop past the bottom of the stack") self.locals_stack_w[index] = w_object + def peekvalues(self, n): + values_w = [None] * n + base = self.valuestackdepth - n + while True: + n -= 1 + if n < 0: + break + values_w[n] = self.locals_stack_w[base+n] + return values_w + + def dropvalues(self, n): + finaldepth = self.valuestackdepth - n + for n in range(finaldepth, self.valuestackdepth): + self.locals_stack_w[n] = None + self.valuestackdepth = finaldepth + def dropvaluesuntil(self, finaldepth): for n in range(finaldepth, self.valuestackdepth): self.locals_stack_w[n] = None From noreply at buildbot.pypy.org Tue Oct 16 15:59:43 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 16 Oct 2012 15:59:43 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Flowspacify LOAD_CONST Message-ID: <20121016135943.826331C1C86@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58131:40ecef084733 Date: 2012-10-16 14:59 +0100 http://bitbucket.org/pypy/pypy/changeset/40ecef084733/ Log: Flowspacify LOAD_CONST diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -735,6 +735,10 @@ raise FlowingError(self, "Local variable referenced before assignment") self.pushvalue(w_value) + def LOAD_CONST(self, constindex, next_instr): + w_const = self.getconstant_w(constindex) + self.pushvalue(w_const) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) From noreply at buildbot.pypy.org Tue Oct 16 16:05:12 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 16 Oct 2012 16:05:12 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Flowspacify STORE_FAST Message-ID: <20121016140512.273B21C1C86@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58132:19009e068be6 Date: 2012-10-16 15:04 +0100 http://bitbucket.org/pypy/pypy/changeset/19009e068be6/ Log: Flowspacify STORE_FAST diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -754,6 +754,11 @@ def LOAD_DEREF(self, varindex, next_instr): self.pushvalue(self.closure[varindex]) + def STORE_FAST(self, varindex, next_instr): + w_newvalue = self.popvalue() + assert w_newvalue is not None + self.locals_stack_w[varindex] = w_newvalue + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. From noreply at buildbot.pypy.org Tue Oct 16 16:14:47 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Tue, 16 Oct 2012 16:14:47 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: a tracing animation Message-ID: <20121016141447.EBEC81C1C86@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4856:49193cf19991 Date: 2012-10-16 15:47 +0200 http://bitbucket.org/pypy/extradoc/changeset/49193cf19991/ Log: a tracing animation diff too long, truncating to 2000 out of 6074 lines diff --git a/talk/vmil2012/presentation/figures/loop01.pdf b/talk/vmil2012/presentation/figures/loop01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1130862f839edbd6c30e365636c2f99a169436b4 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop02.pdf b/talk/vmil2012/presentation/figures/loop02.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2dbbdc618b810859f61f478f6c20d15200be0184 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop03.pdf b/talk/vmil2012/presentation/figures/loop03.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8bde4c82041b97789ebf11e5a556dda5797295d8 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop04.pdf b/talk/vmil2012/presentation/figures/loop04.pdf new file mode 100644 index 0000000000000000000000000000000000000000..52dde49c93ea82865530539d4404266f969e4225 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop05.pdf b/talk/vmil2012/presentation/figures/loop05.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f2746064c1e70fc381ccbe280108eb63e78175e4 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop06.pdf b/talk/vmil2012/presentation/figures/loop06.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9c08496235998659365181e25542f27f4b562e0a GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop07.pdf b/talk/vmil2012/presentation/figures/loop07.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6d30e1130ffdaa9d42b3d530741700311432bb1b GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop08.pdf b/talk/vmil2012/presentation/figures/loop08.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c354aa9de62aba9f6465754d0fe4fb3da3b20994 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop09.pdf b/talk/vmil2012/presentation/figures/loop09.pdf new file mode 100644 index 0000000000000000000000000000000000000000..72539d44d7728ffbe0f6a8f34ee3ca5d8e8ba3d3 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop10.pdf b/talk/vmil2012/presentation/figures/loop10.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0df3db7aa9b8a3631474034cf72ed890f1f657e1 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop11.pdf b/talk/vmil2012/presentation/figures/loop11.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d2dfd1cd909d4e7a0364aedab8f8c860b5113495 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop12.pdf b/talk/vmil2012/presentation/figures/loop12.pdf new file mode 100644 index 0000000000000000000000000000000000000000..35d4320d0c27786c18bac2cac9441a079c1755ee GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/tracing.svg b/talk/vmil2012/presentation/figures/tracing.svg new file mode 100644 --- /dev/null +++ b/talk/vmil2012/presentation/figures/tracing.svg @@ -0,0 +1,5998 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4857:6e637df4d030 Date: 2012-10-16 15:48 +0200 http://bitbucket.org/pypy/extradoc/changeset/6e637df4d030/ Log: some tweaks to the text diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -80,7 +80,7 @@ \titlepage \end{frame} -\section{Introduction} +%\section{Introduction} \begin{frame} \frametitle{Tracing JITs Compile by Observing an Interpreter} @@ -103,11 +103,13 @@ \item Operations that check whether conditions are still true \item When a guard fails, execution of the trace stops and continues in the interpreter \pause + \item \emph{This talk:} describe technology and design decisions around guards + \pause \begin{block}{Guard Characteristics} \begin{itemize} \item lots of them, up to 20\% guards \item most never fail - \item costly to implement + \item need big information attached to them \end{itemize} \end{block} \end{itemize} @@ -139,7 +141,7 @@ \frametitle{Running Example} \end{frame} -\section{High-Level} +%\section{High-Level} \begin{frame} \frametitle{Symbolic Frame Capturing} @@ -170,8 +172,8 @@ \item Some optimizations make it necessary to store extra information in symbolic frames \item examples: \begin{itemize} + \item allocation removal (need to allocate objects before resuming) \item delayed heap stores (need to do stores before resuming interpreter) - \item allocation removal (need to allocate objects before resuming) \end{itemize} \item can be compressed using similar techniques \end{itemize} @@ -186,7 +188,7 @@ \end{itemize} In case of failure \begin{itemize} - \item execution jumps to compensation code, decodes and stores mapping + \item execution jumps to shared compensation code, decodes and stores mapping \item returns to interpreter that rebuilds state \end{itemize} \end{frame} @@ -218,7 +220,7 @@ \frametitle{Patching Guards for Bridges} \end{frame} -\section{Evaluation} +%\section{Evaluation} %as in paper %fancy graphs From noreply at buildbot.pypy.org Tue Oct 16 16:14:50 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Tue, 16 Oct 2012 16:14:50 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: tweaks Message-ID: <20121016141450.4ADA61C1C86@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4858:07449cda3736 Date: 2012-10-16 16:12 +0200 http://bitbucket.org/pypy/extradoc/changeset/07449cda3736/ Log: tweaks diff --git a/talk/vmil2012/presentation/figures/loop01.pdf b/talk/vmil2012/presentation/figures/loop01.pdf index 1130862f839edbd6c30e365636c2f99a169436b4..e6c075684fae55993a394eac2bc7e0cfe8a768fc GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop02.pdf b/talk/vmil2012/presentation/figures/loop02.pdf index 2dbbdc618b810859f61f478f6c20d15200be0184..9a1af0aaaee636e7086e08c948c67cd19f8ea316 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop03.pdf b/talk/vmil2012/presentation/figures/loop03.pdf index 8bde4c82041b97789ebf11e5a556dda5797295d8..77ecf61308cc25eebf3da0d2f01321dba6c526b5 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop04.pdf b/talk/vmil2012/presentation/figures/loop04.pdf index 52dde49c93ea82865530539d4404266f969e4225..52505a0fcf4d47abe122c7b7eadf6ab0b32534a8 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop05.pdf b/talk/vmil2012/presentation/figures/loop05.pdf index f2746064c1e70fc381ccbe280108eb63e78175e4..cb6747ad1838ceb8ec934960e6a4db23c0f55b5f GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop06.pdf b/talk/vmil2012/presentation/figures/loop06.pdf index 9c08496235998659365181e25542f27f4b562e0a..9488959701fcff0fcd2f1bc4ff469411ed086de4 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop07.pdf b/talk/vmil2012/presentation/figures/loop07.pdf index 6d30e1130ffdaa9d42b3d530741700311432bb1b..87391036f019b6670bebb6e355c2f104b210c4f3 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop08.pdf b/talk/vmil2012/presentation/figures/loop08.pdf index c354aa9de62aba9f6465754d0fe4fb3da3b20994..699a8b22d0815268bd2aacd5972df10cc25da7d1 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop09.pdf b/talk/vmil2012/presentation/figures/loop09.pdf index 72539d44d7728ffbe0f6a8f34ee3ca5d8e8ba3d3..1b2d8530dd395230f1ad4ea37043744432b596fa GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop10.pdf b/talk/vmil2012/presentation/figures/loop10.pdf index 0df3db7aa9b8a3631474034cf72ed890f1f657e1..66cefeef09a4bb9a49894ae98d2c1ba8cbb65bf0 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop11.pdf b/talk/vmil2012/presentation/figures/loop11.pdf index d2dfd1cd909d4e7a0364aedab8f8c860b5113495..14e26e44fd368dbcef592ece42fbe3a356acff93 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop12.pdf b/talk/vmil2012/presentation/figures/loop12.pdf index 35d4320d0c27786c18bac2cac9441a079c1755ee..bd6611b3122bed949fa58cc3e4b8cfa0f2b88678 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/tracing.svg b/talk/vmil2012/presentation/figures/tracing.svg --- a/talk/vmil2012/presentation/figures/tracing.svg +++ b/talk/vmil2012/presentation/figures/tracing.svg @@ -40,13 +40,13 @@ inkscape:window-height="776" id="namedview24385" showgrid="false" - inkscape:zoom="1.1882274" - inkscape:cx="412.42356" - inkscape:cy="460.60716" + inkscape:zoom="0.5941137" + inkscape:cx="340.25415" + inkscape:cy="397.92978" inkscape:window-x="0" inkscape:window-y="24" inkscape:window-maximized="1" - inkscape:current-layer="layer4" + inkscape:current-layer="layer11" fit-margin-top="2" fit-margin-left="2" fit-margin-right="2" From noreply at buildbot.pypy.org Tue Oct 16 16:15:16 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 16 Oct 2012 16:15:16 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: in-progress Message-ID: <20121016141516.996061C1C86@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58133:a76d3d679e8a Date: 2012-10-15 16:33 +0200 http://bitbucket.org/pypy/pypy/changeset/a76d3d679e8a/ Log: in-progress diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -1064,33 +1064,10 @@ raise Exception("Nonsense type %s" % TYPE) subframe = self.cpu._execute_token(loop_token) - jd = loop_token.outermost_jitdriver_sd - assert jd is not None, ("call_assembler(): the loop_token needs " - "to have 'outermost_jitdriver_sd'") - if jd.index_of_virtualizable != -1: - vable = args[jd.index_of_virtualizable] - else: - vable = lltype.nullptr(llmemory.GCREF.TO) - # - # Emulate the fast path - failindex = frame_descr_index(subframe) - if failindex == self.cpu.done_with_this_frame_int_v: - reset_vable(jd, vable) - return self.cpu.get_latest_value_int(subframe, 0) - if failindex == self.cpu.done_with_this_frame_ref_v: - reset_vable(jd, vable) - return self.cpu.get_latest_value_ref(subframe, 0) - if failindex == self.cpu.done_with_this_frame_float_v: - reset_vable(jd, vable) - return self.cpu.get_latest_value_float(subframe, 0) - if failindex == self.cpu.done_with_this_frame_void_v: - reset_vable(jd, vable) - return None - # assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish assembler_helper = assembler_helper_ptr._obj._callable try: - return assembler_helper(subframe, vable) + return assembler_helper(subframe) except LLException, lle: assert self._last_exception is None, "exception left behind" self._last_exception = lle @@ -1845,6 +1822,7 @@ return 0 def reset_vable(jd, vable): + xxxxxxxxxxxxx if jd.index_of_virtualizable != -1: fielddescr = jd.jit_frame_descr do_setfield_gc_ptr(vable, fielddescr.ofs, diff --git a/pypy/jit/backend/llsupport/jitframe.py b/pypy/jit/backend/llsupport/jitframe.py new file mode 100644 --- /dev/null +++ b/pypy/jit/backend/llsupport/jitframe.py @@ -0,0 +1,10 @@ + + +_LONGLONGARRAY = lltype.GcArray(lltype.SignedLongLong) + +JITFRAME = lltype.GcStruct('JITFRAME', + ('jf_descr', llmemory.GCREF), + ('jf_excvalue', llmemory.GCREF), + ('jf_nongcvalues', lltype.Ptr(_LONGLONGARRAY)), + ('jf_gcvalues', lltype.Array(llmemory.GCREF))) +JITFRAMEPTR = lltype.Ptr(JITFRAME) diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -6,8 +6,8 @@ from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin from pypy.jit.codewriter.policy import StopAtXPolicy from pypy.rpython.annlowlevel import hlstr +from pypy.rpython.lltypesystem import llmemory from pypy.jit.metainterp.warmspot import get_stats -from pypy.jit.metainterp.jitframe import JITFRAMEPTR class RecursiveTests: @@ -824,7 +824,7 @@ # at the level 2 is set to a non-zero value when doing the # call to the level 3 only. This used to fail when the test # is run via pypy.jit.backend.x86.test.test_recursive. - assert ll_subframe.jit_frame == lltype.nullptr(JITFRAMEPTR.TO) + assert ll_subframe.jit_frame == lltype.nullptr(llmemory.GCREF.TO) def main(codeno): frame = Frame() diff --git a/pypy/jit/metainterp/test/test_warmspot.py b/pypy/jit/metainterp/test/test_warmspot.py --- a/pypy/jit/metainterp/test/test_warmspot.py +++ b/pypy/jit/metainterp/test/test_warmspot.py @@ -6,7 +6,6 @@ from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin from pypy.jit.metainterp.optimizeopt import ALL_OPTS_NAMES -from pypy.jit.metainterp.jitframe import JITFRAMEPTR class Exit(Exception): From noreply at buildbot.pypy.org Tue Oct 16 16:15:17 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 16 Oct 2012 16:15:17 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: hg backout 458e381ff84d: I think we don't need KEEPALIVE any more Message-ID: <20121016141517.EC3171C1C86@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58134:afc1fe7ce0cb Date: 2012-10-15 16:34 +0200 http://bitbucket.org/pypy/pypy/changeset/afc1fe7ce0cb/ Log: hg backout 458e381ff84d: I think we don't need KEEPALIVE any more diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -800,9 +800,6 @@ self.overflow_flag = ovf return z - def op_keepalive(self, _, x): - pass - # ---------- # delegating to the builtins do_xxx() (done automatically for simple cases) diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py --- a/pypy/jit/backend/x86/regalloc.py +++ b/pypy/jit/backend/x86/regalloc.py @@ -1441,9 +1441,6 @@ if jump_op is not None and jump_op.getdescr() is descr: self._compute_hint_frame_locations_from_descr(descr) - def consider_keepalive(self, op): - pass - def not_implemented_op(self, op): not_implemented("not implemented operation: %s" % op.getopname()) diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py --- a/pypy/jit/metainterp/executor.py +++ b/pypy/jit/metainterp/executor.py @@ -274,9 +274,6 @@ assert isinstance(x, r_longlong) # 32-bit return BoxFloat(x) -def do_keepalive(cpu, _, x): - pass - # ____________________________________________________________ ##def do_force_token(cpu): diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -1391,16 +1391,12 @@ resbox = self.metainterp.execute_and_record_varargs( rop.CALL_MAY_FORCE, allboxes, descr=descr) self.metainterp.vrefs_after_residual_call() - vablebox = None if assembler_call: - vablebox = self.metainterp.direct_assembler_call( - assembler_call_jd) + self.metainterp.direct_assembler_call(assembler_call_jd) if resbox is not None: self.make_result_of_lastop(resbox) self.metainterp.vable_after_residual_call() self.generate_guard(rop.GUARD_NOT_FORCED, None) - if vablebox is not None: - self.metainterp.history.record(rop.KEEPALIVE, [vablebox], None) self.metainterp.handle_possible_exception() if effectinfo.oopspecindex == effectinfo.OS_LIBFFI_CALL: self.metainterp.direct_libffi_call() @@ -2519,15 +2515,6 @@ token = warmrunnerstate.get_assembler_token(greenargs) op = op.copy_and_change(rop.CALL_ASSEMBLER, args=args, descr=token) self.history.operations.append(op) - # - # To fix an obscure issue, make sure the vable stays alive - # longer than the CALL_ASSEMBLER operation. We do it by - # inserting explicitly an extra KEEPALIVE operation. - jd = token.outermost_jitdriver_sd - if jd.index_of_virtualizable >= 0: - return args[jd.index_of_virtualizable] - else: - return None def direct_libffi_call(self): """Generate a direct call to C code, patching the CALL_MAY_FORCE diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -508,7 +508,6 @@ 'COPYUNICODECONTENT/5', 'QUASIIMMUT_FIELD/1d', # [objptr], descr=SlowMutateDescr 'RECORD_KNOWN_CLASS/2', # [objptr, clsptr] - 'KEEPALIVE/1', '_CANRAISE_FIRST', # ----- start of can_raise operations ----- '_CALL_FIRST', From noreply at buildbot.pypy.org Tue Oct 16 16:15:19 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 16 Oct 2012 16:15:19 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Fixes to compile_tmp_callback Message-ID: <20121016141519.10DB21C1C86@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58135:97d07c32e868 Date: 2012-10-15 16:41 +0200 http://bitbucket.org/pypy/pypy/changeset/97d07c32e868/ Log: Fixes to compile_tmp_callback diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -1061,6 +1061,7 @@ raise Exception("Nonsense type %s" % TYPE) subframe = self.cpu._execute_token(loop_token) + jd = loop_token.outermost_jitdriver_sd assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish assembler_helper = assembler_helper_ptr._obj._callable try: diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -823,7 +823,7 @@ class PropagateExceptionDescr(AbstractFailDescr): def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): cpu = metainterp_sd.cpu - exception = cpu.grab_exc_value(jitframe) + exception = cpu.get_finish_value_ref(jitframe) assert exception, "PropagateExceptionDescr: no exception??" raise metainterp_sd.ExitFrameWithExceptionRef(cpu, exception) @@ -833,7 +833,6 @@ calls back the interpreter. Used temporarily: a fully compiled version of the code may end up replacing it. """ - XXXX # fix me jitcell_token = make_jitcell_token(jitdriver_sd) nb_red_args = jitdriver_sd.num_red_args assert len(redargtypes) == nb_red_args @@ -872,6 +871,7 @@ ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken) ] operations[1].setfailargs([]) + operations[2].setfailargs([]) operations = get_deep_immutable_oplist(operations) cpu.compile_loop(inputargs, operations, jitcell_token, log=False) if memory_manager is not None: # for tests diff --git a/pypy/jit/metainterp/test/test_compile.py b/pypy/jit/metainterp/test/test_compile.py --- a/pypy/jit/metainterp/test/test_compile.py +++ b/pypy/jit/metainterp/test/test_compile.py @@ -165,7 +165,7 @@ portal_runner_ptr = llhelper(lltype.Ptr(FUNC), ll_portal_runner) portal_runner_adr = llmemory.cast_ptr_to_adr(portal_runner_ptr) portal_calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, None) - portal_finishtoken = compile.DoneWithThisFrameDescrInt() + portal_finishtoken = compile.DoneWithThisFrameDescrInt(None, None) num_red_args = 2 result_type = INT # @@ -184,7 +184,7 @@ jit_frame = cpu.execute_token(loop_token, -156, -178) fail_descr = cpu.get_latest_descr(jit_frame) assert isinstance(fail_descr, compile.PropagateExceptionDescr) - got = cpu.grab_exc_value(jit_frame) + got = cpu.get_finish_value_ref(jit_frame) assert lltype.cast_opaque_ptr(lltype.Ptr(EXC), got) == llexc # class FakeMetaInterpSD: From noreply at buildbot.pypy.org Tue Oct 16 16:15:20 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 16 Oct 2012 16:15:20 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Fix tests Message-ID: <20121016141520.3D5831C1C86@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58136:363e0ca83d9d Date: 2012-10-15 17:08 +0200 http://bitbucket.org/pypy/pypy/changeset/363e0ca83d9d/ Log: Fix tests diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -479,6 +479,7 @@ # ------------------------------ class Frame(object): + _carry_around_for_tests = True OPHANDLERS = [None] * (rop._LAST+1) def __init__(self, cpu): diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -820,14 +820,14 @@ # ____________________________________________________________ -class PropagateExceptionDescr(AbstractFailDescr): +class PropagateExceptionDescr(ResumeDescr): def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): cpu = metainterp_sd.cpu exception = cpu.get_finish_value_ref(jitframe) assert exception, "PropagateExceptionDescr: no exception??" raise metainterp_sd.ExitFrameWithExceptionRef(cpu, exception) -def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redargtypes, +def compile_tmp_callback(metainterp_sd, jitdriver_sd, greenboxes, redargtypes, memory_manager=None): """Make a LoopToken that corresponds to assembler code that just calls back the interpreter. Used temporarily: a fully compiled @@ -850,12 +850,16 @@ result_type = jitdriver_sd.result_type if result_type == history.INT: result = BoxInt() + DoneCls = DoneWithThisFrameDescrInt elif result_type == history.REF: result = BoxPtr() + DoneCls = DoneWithThisFrameDescrRef elif result_type == history.FLOAT: result = BoxFloat() + DoneCls = DoneWithThisFrameDescrFloat elif result_type == history.VOID: result = None + DoneCls = DoneWithThisFrameDescrVoid else: assert 0, "bad result_type" if result is not None: @@ -865,14 +869,16 @@ # jd = jitdriver_sd faildescr = PropagateExceptionDescr() + finishdescr = DoneCls(metainterp_sd, jitdriver_sd) operations = [ ResOperation(rop.CALL, callargs, result, descr=jd.portal_calldescr), ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr), - ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken) + ResOperation(rop.FINISH, finishargs, None, descr=finishdescr) ] operations[1].setfailargs([]) operations[2].setfailargs([]) operations = get_deep_immutable_oplist(operations) + cpu = metainterp_sd.cpu cpu.compile_loop(inputargs, operations, jitcell_token, log=False) if memory_manager is not None: # for tests memory_manager.keep_loop_alive(jitcell_token) diff --git a/pypy/jit/metainterp/test/test_compile.py b/pypy/jit/metainterp/test/test_compile.py --- a/pypy/jit/metainterp/test/test_compile.py +++ b/pypy/jit/metainterp/test/test_compile.py @@ -165,18 +165,21 @@ portal_runner_ptr = llhelper(lltype.Ptr(FUNC), ll_portal_runner) portal_runner_adr = llmemory.cast_ptr_to_adr(portal_runner_ptr) portal_calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, None) - portal_finishtoken = compile.DoneWithThisFrameDescrInt(None, None) num_red_args = 2 result_type = INT # - loop_token = compile_tmp_callback(cpu, FakeJitDriverSD(), + class FakeMetaInterpSD: + pass + FakeMetaInterpSD.cpu = cpu + # + loop_token = compile_tmp_callback(FakeMetaInterpSD, FakeJitDriverSD(), [ConstInt(12), ConstInt(34)], "ii") # raiseme = None # only two arguments must be passed in jit_frame = cpu.execute_token(loop_token, -156, -178) fail_descr = cpu.get_latest_descr(jit_frame) - assert fail_descr is FakeJitDriverSD().portal_finishtoken + assert isinstance(fail_descr, compile.DoneWithThisFrameDescrInt) # EXC = lltype.GcStruct('EXC') llexc = lltype.malloc(EXC) diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -797,59 +797,6 @@ res = self.meta_interp(main, [0], inline=True) assert res == main(0) - def test_directly_call_assembler_virtualizable_reset_token(self): - from pypy.rpython.lltypesystem import lltype - from pypy.rlib.debug import llinterpcall - - class Thing(object): - def __init__(self, val): - self.val = val - - class Frame(object): - _virtualizable2_ = ['thing'] - - driver = JitDriver(greens = ['codeno'], reds = ['i', 'frame'], - virtualizables = ['frame'], - get_printable_location = lambda codeno : str(codeno)) - - @dont_look_inside - def check_frame(subframe): - if we_are_translated(): - llinterpcall(lltype.Void, check_ll_frame, subframe) - def check_ll_frame(ll_subframe): - # This is called with the low-level Struct that is the frame. - # Check that the jit_frame was correctly reset to zero. - # Note that in order for that test to catch failures, it needs - # three levels of recursion: the jit_frame of the subframe - # at the level 2 is set to a non-zero value when doing the - # call to the level 3 only. This used to fail when the test - # is run via pypy.jit.backend.x86.test.test_recursive. - assert ll_subframe.jit_frame == lltype.nullptr(llmemory.GCREF.TO) - - def main(codeno): - frame = Frame() - frame.thing = Thing(0) - portal(codeno, frame) - return frame.thing.val - - def portal(codeno, frame): - i = 0 - while i < 5: - driver.can_enter_jit(frame=frame, codeno=codeno, i=i) - driver.jit_merge_point(frame=frame, codeno=codeno, i=i) - nextval = frame.thing.val - if codeno < 2: - subframe = Frame() - subframe.thing = Thing(nextval) - nextval = portal(codeno + 1, subframe) - check_frame(subframe) - frame.thing = Thing(nextval + 1) - i += 1 - return frame.thing.val - - res = self.meta_interp(main, [0], inline=True) - assert res == main(0) - def test_directly_call_assembler_virtualizable_force1(self): class Thing(object): def __init__(self, val): diff --git a/pypy/jit/metainterp/test/test_virtualref.py b/pypy/jit/metainterp/test/test_virtualref.py --- a/pypy/jit/metainterp/test/test_virtualref.py +++ b/pypy/jit/metainterp/test/test_virtualref.py @@ -110,7 +110,9 @@ if str(box._getrepr_()).endswith('JitVirtualRef')] assert len(bxs2) == 1 JIT_VIRTUAL_REF = self.vrefinfo.JIT_VIRTUAL_REF - someframe = lltype.malloc(jitframe.JITFRAMEPTR.TO, 5) + JITFRAME = lltype.GcStruct('SOME_JIT_FRAME') + someframe = lltype.malloc(JITFRAME) + someframe = lltype.cast_opaque_ptr(llmemory.GCREF, someframe) bxs2[0].getref(lltype.Ptr(JIT_VIRTUAL_REF)).jit_frame = someframe # # try reloading from blackhole.py's point of view diff --git a/pypy/jit/metainterp/test/test_warmspot.py b/pypy/jit/metainterp/test/test_warmspot.py --- a/pypy/jit/metainterp/test/test_warmspot.py +++ b/pypy/jit/metainterp/test/test_warmspot.py @@ -1,5 +1,5 @@ import py -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, llmemory from pypy.jit.metainterp.warmspot import get_stats from pypy.rlib.jit import JitDriver, set_param, unroll_safe from pypy.jit.backend.llgraph import runner @@ -331,6 +331,8 @@ exc_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) cls.exc_vtable = exc_vtable + cls.FAKEFRAME = lltype.GcStruct('FAKEFRAME') + class FakeFailDescr(object): def __init__(self, no): self.no = no @@ -377,7 +379,7 @@ return "not callable" def get_latest_descr(self, frame): - assert lltype.typeOf(frame) == JITFRAMEPTR + assert frame._obj.container._TYPE == cls.FAKEFRAME return FakeFailDescr(self._fail_index) driver = JitDriver(reds = ['red'], greens = ['green']) @@ -401,14 +403,15 @@ [jd] = self.desc.jitdrivers_sd cpu = self.desc.cpu - fakeframe = lltype.malloc(JITFRAMEPTR.TO, 5) + fakeframe = lltype.malloc(self.FAKEFRAME) + fakeframe = lltype.cast_opaque_ptr(llmemory.GCREF, fakeframe) cpu._fail_index = 0 - assert jd._assembler_call_helper(fakeframe, 0) == 3 + assert jd._assembler_call_helper(fakeframe) == 3 cpu._fail_index = 1 - assert jd._assembler_call_helper(fakeframe, 0) == 10 + assert jd._assembler_call_helper(fakeframe) == 10 try: cpu._fail_index = 3 - jd._assembler_call_helper(fakeframe, 0) + jd._assembler_call_helper(fakeframe) except LLException, lle: assert lle[0] == self.exc_vtable else: diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py --- a/pypy/jit/metainterp/warmstate.py +++ b/pypy/jit/metainterp/warmstate.py @@ -574,7 +574,6 @@ unwrap_greenkey = self.make_unwrap_greenkey() jit_getter = self.make_jitcell_getter() jd = self.jitdriver_sd - cpu = self.cpu def can_inline_greenargs(*greenargs): if can_never_inline(*greenargs): @@ -611,8 +610,9 @@ if cell.counter == -1: # used to be a valid entry bridge, cell.counter = 0 # but was freed in the meantime. memmgr = warmrunnerdesc.memory_manager - procedure_token = compile_tmp_callback(cpu, jd, greenkey, - redargtypes, memmgr) + procedure_token = compile_tmp_callback( + warmrunnerdesc.metainterp_sd, jd, + greenkey, redargtypes, memmgr) cell.set_procedure_token(procedure_token) return procedure_token self.get_assembler_token = get_assembler_token diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py --- a/pypy/rpython/lltypesystem/lltype.py +++ b/pypy/rpython/lltypesystem/lltype.py @@ -1049,6 +1049,8 @@ # this must be an opaque ptr originating from an integer assert isinstance(obj, _opaque) return cast_int_to_ptr(obj.ORIGTYPE, container) + if getattr(container, '_carry_around_for_tests', False): + return p if container is not obj: p = _ptr(Ptr(typeOf(container)), container, p._solid) return p From noreply at buildbot.pypy.org Tue Oct 16 16:15:21 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 16 Oct 2012 16:15:21 +0200 (CEST) Subject: [pypy-commit] pypy default: (fijal, arigo) Kill this outdated piece of code. Message-ID: <20121016141521.7A5C71C1C86@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58137:1f2fd0a735a8 Date: 2012-10-15 18:55 +0200 http://bitbucket.org/pypy/pypy/changeset/1f2fd0a735a8/ Log: (fijal, arigo) Kill this outdated piece of code. diff too long, truncating to 2000 out of 2380 lines diff --git a/pypy/jit/backend/llvm/__init__.py b/pypy/jit/backend/llvm/__init__.py deleted file mode 100644 diff --git a/pypy/jit/backend/llvm/compile.py b/pypy/jit/backend/llvm/compile.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/compile.py +++ /dev/null @@ -1,732 +0,0 @@ -import py -from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp.history import Const, INT -from pypy.jit.backend.llvm import llvm_rffi -from pypy.jit.metainterp import resoperation -from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.llsupport import symbolic -from pypy.jit.backend.llvm.runner import SizeDescr, CallDescr -from pypy.jit.backend.llvm.runner import FieldDescr, ArrayDescr - -# ____________________________________________________________ - -class LLVMJITCompiler(object): - FUNC = lltype.FuncType([], lltype.Signed) - lastovf = lltype.nullptr(llvm_rffi.LLVMValueRef.TO) - - def __init__(self, cpu, loop): - self.cpu = cpu - self.loop = loop - - def compile(self): - self.start_generating_function() - self.generate_initial_arguments_load() - self.generate_loop_body() - self.close_phi_nodes() - self.done_generating_function() - - def start_generating_function(self): - func = llvm_rffi.LLVMAddFunction(self.cpu.module, "", self.cpu.ty_func) - self.compiling_func = func - self.builder = llvm_rffi.LLVMCreateBuilder() - self.vars = {} - - def generate_initial_arguments_load(self): - loop = self.loop - func = self.compiling_func - bb_entry = llvm_rffi.LLVMAppendBasicBlock(func, "entry") - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_entry) - self.cpu._ensure_in_args(len(loop.inputargs)) - self.phi_incoming_blocks = [bb_entry] - self.phi_incoming_values = [] - for i in range(len(loop.inputargs)): - ty = self.cpu._get_pointer_type(loop.inputargs[i]) - llvmconstptr = self.cpu._make_const(self.cpu.in_out_args[i], ty) - res = llvm_rffi.LLVMBuildLoad(self.builder, llvmconstptr, "") - self.phi_incoming_values.append([res]) - self.bb_start = llvm_rffi.LLVMAppendBasicBlock(func, "") - llvm_rffi.LLVMBuildBr(self.builder, self.bb_start) - # - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, self.bb_start) - for v in loop.inputargs: - ty = self.cpu._get_var_type(v) - phi = llvm_rffi.LLVMBuildPhi(self.builder, ty, "") - self.vars[v] = phi - - def generate_loop_body(self): - func = self.compiling_func - self.pending_blocks = [(self.loop.operations, self.bb_start, False)] - while self.pending_blocks: - operations, bb, exc = self.pending_blocks.pop() - self._generate_branch(operations, bb, exc) - self.bb_start = lltype.nullptr(llvm_rffi.LLVMBasicBlockRef.TO) - - def close_phi_nodes(self): - incoming_blocks = lltype.malloc( - rffi.CArray(llvm_rffi.LLVMBasicBlockRef), - len(self.phi_incoming_blocks), flavor='raw') - incoming_values = lltype.malloc( - rffi.CArray(llvm_rffi.LLVMValueRef), - len(self.phi_incoming_blocks), flavor='raw') - for j in range(len(self.phi_incoming_blocks)): - incoming_blocks[j] = self.phi_incoming_blocks[j] - loop = self.loop - for i in range(len(loop.inputargs)): - phi = self.vars[loop.inputargs[i]] - incoming = self.phi_incoming_values[i] - for j in range(len(self.phi_incoming_blocks)): - incoming_values[j] = incoming[j] - llvm_rffi.LLVMAddIncoming(phi, incoming_values, incoming_blocks, - len(self.phi_incoming_blocks)) - lltype.free(incoming_values, flavor='raw') - lltype.free(incoming_blocks, flavor='raw') - - def done_generating_function(self): - llvm_rffi.LLVMDisposeBuilder(self.builder) - llvm_rffi.LLVMDumpValue(self.compiling_func) # xxx for debugging - # - func_addr = llvm_rffi.LLVM_EE_getPointerToFunction(self.cpu.ee, - self.compiling_func) - if not we_are_translated(): - print '--- function is at %r ---' % (func_addr,) - # - func_ptr = rffi.cast(lltype.Ptr(self.FUNC), func_addr) - index = self.loop._llvm_compiled_index - if index < 0: - self.loop._llvm_compiled_index = len(self.cpu.compiled_functions) - self.cpu.compiled_functions.append(func_ptr) - else: - self.cpu.compiled_functions[index] = func_ptr - - def _generate_branch(self, operations, basicblock, exc): - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, basicblock) - # The flag 'exc' is set to True if we are a branch handling a - # GUARD_EXCEPTION or GUARD_NO_EXCEPTION. In this case, we have to - # store away the exception into self.backup_exc_xxx, *unless* the - # branch starts with a further GUARD_EXCEPTION/GUARD_NO_EXCEPTION. - if exc: - opnum = operations[0].getopnum() - if opnum not in (rop.GUARD_EXCEPTION, rop.GUARD_NO_EXCEPTION): - self._store_away_exception() - # Normal handling of the operations follows. - for op in operations: - self._generate_op(op) - - def _generate_op(self, op): - opnum = op.getopnum() - for i, name in all_operations: - if opnum == i: - meth = getattr(self, name) - meth(op) - return - else: - raise MissingOperation(resoperation.opname[opnum]) - - def _store_away_exception(self): - # etype, evalue: ty_char_ptr - etype = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_type, "") - llvm_rffi.LLVMBuildStore(self.builder, - self.cpu.const_null_charptr, - self.cpu.const_exc_type) - llvm_rffi.LLVMBuildStore(self.builder, - etype, - self.cpu.const_backup_exc_type) - evalue = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_value, "") - llvm_rffi.LLVMBuildStore(self.builder, - self.cpu.const_null_charptr, - self.cpu.const_exc_value) - llvm_rffi.LLVMBuildStore(self.builder, - evalue, - self.cpu.const_backup_exc_value) - - def getintarg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_int(v.getint()) - else: - return self._cast_to_int(value_ref) - - def _cast_to_int(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_int: - return value_ref - else: - return llvm_rffi.LLVMBuildZExt(self.builder, value_ref, - self.cpu.ty_int, "") - - def getbitarg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_bit(v.getint()) - else: - return self._cast_to_bit(value_ref) - - def _cast_to_bit(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_bit: - return value_ref - else: - return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref, - self.cpu.ty_bit, "") - - def getchararg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_char(v.getint()) - else: - return self._cast_to_char(value_ref) - - def _cast_to_char(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_char: - return value_ref - elif ty == self.cpu.ty_int or ty == self.cpu.ty_unichar: - return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref, - self.cpu.ty_char, "") - elif ty == self.cpu.ty_bit: - return llvm_rffi.LLVMBuildZExt(self.builder, value_ref, - self.cpu.ty_char, "") - else: - raise AssertionError("type is not an int nor a bit") - - def getunichararg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_unichar(v.getint()) - else: - return self._cast_to_unichar(value_ref) - - def _cast_to_unichar(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_unichar: - return value_ref - elif ty == self.cpu.ty_int: - return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref, - self.cpu.ty_char, "") - elif ty == self.cpu.ty_bit or ty == self.cpu.ty_char: - return llvm_rffi.LLVMBuildZExt(self.builder, value_ref, - self.cpu.ty_char, "") - else: - raise AssertionError("type is not an int nor a bit") - - def getptrarg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - return self.cpu._make_const(v.getaddr(self.cpu), - self.cpu.ty_char_ptr) - else: - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_int: - value_ref = llvm_rffi.LLVMBuildIntToPtr(self.builder, - value_ref, - self.cpu.ty_char_ptr, - "") - else: - assert (ty != self.cpu.ty_bit and - ty != self.cpu.ty_char and - ty != self.cpu.ty_unichar) - return value_ref - - for _opname, _llvmname in [('INT_ADD', 'Add'), - ('INT_SUB', 'Sub'), - ('INT_MUL', 'Mul'), - ('INT_FLOORDIV', 'SDiv'), - ('INT_MOD', 'SRem'), - ('INT_LSHIFT', 'Shl'), - ('INT_RSHIFT', 'AShr'), - ('UINT_RSHIFT', 'LShr'), - ('INT_AND', 'And'), - ('INT_OR', 'Or'), - ('INT_XOR', 'Xor'), - ]: - exec py.code.Source(''' - def generate_%s(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuild%s( - self.builder, - self.getintarg(op.args[0]), - self.getintarg(op.args[1]), - "") - ''' % (_opname, _llvmname)).compile() - - for _opname, _predicate in [('INT_LT', llvm_rffi.Predicate.SLT), - ('INT_LE', llvm_rffi.Predicate.SLE), - ('INT_EQ', llvm_rffi.Predicate.EQ), - ('INT_NE', llvm_rffi.Predicate.NE), - ('INT_GT', llvm_rffi.Predicate.SGT), - ('INT_GE', llvm_rffi.Predicate.SGE), - ('UINT_LT', llvm_rffi.Predicate.ULT), - ('UINT_LE', llvm_rffi.Predicate.ULE), - ('UINT_GT', llvm_rffi.Predicate.UGT), - ('UINT_GE', llvm_rffi.Predicate.UGE)]: - exec py.code.Source(''' - def generate_%s(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, - %d, - self.getintarg(op.args[0]), - self.getintarg(op.args[1]), - "") - ''' % (_opname, _predicate)).compile() - - def generate_INT_NEG(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildNeg(self.builder, - self.getintarg(op.args[0]), - "") - - def generate_INT_INVERT(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildNot(self.builder, - self.getintarg(op.args[0]), - "") - - def generate_INT_IS_TRUE(self, op): - v = op.args[0] - try: - value_ref = self.vars[v] - if llvm_rffi.LLVMTypeOf(value_ref) != self.cpu.ty_bit: - raise KeyError - except KeyError: - res = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.NE, - self.getintarg(op.args[0]), - self.cpu.const_zero, - "") - else: - res = value_ref # value_ref: ty_bit. this is a no-op - self.vars[op.result] = res - - def generate_BOOL_NOT(self, op): - v = op.args[0] - try: - value_ref = self.vars[v] - if llvm_rffi.LLVMTypeOf(value_ref) != self.cpu.ty_bit: - raise KeyError - except KeyError: - res = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - self.getintarg(op.args[0]), - self.cpu.const_zero, - "") - else: - # value_ref: ty_bit - res = llvm_rffi.LLVMBuildNot(self.builder, value_ref, "") - self.vars[op.result] = res - - def generate_INT_ADD_OVF(self, op): - self._generate_ovf_op(op, self.cpu.f_add_ovf) - - def generate_INT_SUB_OVF(self, op): - self._generate_ovf_op(op, self.cpu.f_sub_ovf) - - def generate_INT_MUL_OVF(self, op): - self._generate_ovf_op(op, self.cpu.f_mul_ovf) - - def _generate_ovf_op(self, op, f_intrinsic): - self._generate_ovf_test(f_intrinsic, - self.getintarg(op.args[0]), - self.getintarg(op.args[1]), - op.result) - - def _generate_ovf_test(self, f_intrinsic, arg0, arg1, result): - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 2, - flavor='raw') - arglist[0] = arg0 - arglist[1] = arg1 - tmp = llvm_rffi.LLVMBuildCall(self.builder, f_intrinsic, - arglist, 2, "") - lltype.free(arglist, flavor='raw') - self.vars[result] = llvm_rffi.LLVMBuildExtractValue(self.builder, - tmp, 0, "") - self.lastovf = llvm_rffi.LLVMBuildExtractValue(self.builder, tmp, 1, - "") - - def generate_GUARD_FALSE(self, op): - self._generate_guard(op, self.getbitarg(op.args[0]), True) - - def generate_GUARD_TRUE(self, op): - self._generate_guard(op, self.getbitarg(op.args[0]), False) - - def generate_GUARD_VALUE(self, op): - if op.args[0].type == INT: - arg0 = self.getintarg(op.args[0]) - arg1 = self.getintarg(op.args[1]) - else: - arg0 = self.getptrarg(op.args[0]) - arg1 = self.getptrarg(op.args[1]) - equal = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - arg0, arg1, "") - self._generate_guard(op, equal, False) - - def generate_GUARD_CLASS(self, op): - loc = self._generate_field_gep(op.args[0], self.cpu.fielddescr_vtable) - cls = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - equal = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - cls, - self.getintarg(op.args[1]), "") - self._generate_guard(op, equal, False) - - def generate_GUARD_NO_EXCEPTION(self, op): - # etype: ty_char_ptr - etype = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_type, "") - eisnull = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - etype, - self.cpu.const_null_charptr, "") - self._generate_guard(op, eisnull, False, exc=True) - - def generate_GUARD_EXCEPTION(self, op): - v = op.args[0] - assert isinstance(v, Const) - # etype, expectedtype: ty_char_ptr - expectedtype = self.cpu._make_const(v.getint(), self.cpu.ty_char_ptr) - etype = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_type, "") - eisequal = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - etype, - expectedtype, "") - self._generate_guard(op, eisequal, False, exc=True) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_value, - "") - - def generate_GUARD_NO_OVERFLOW(self, op): - self._generate_guard(op, self.lastovf, True) - - def generate_GUARD_OVERFLOW(self, op): - self._generate_guard(op, self.lastovf, False) - - def _generate_guard(self, op, verify_condition, reversed, exc=False): - func = self.compiling_func - bb_on_track = llvm_rffi.LLVMAppendBasicBlock(func, "") - bb_off_track = llvm_rffi.LLVMAppendBasicBlock(func, "") - llvm_rffi.LLVMBuildCondBr(self.builder, verify_condition, - bb_on_track, bb_off_track) - if reversed: - bb_on_track, bb_off_track = bb_off_track, bb_on_track - # generate the on-track part first, and the off-track part later - self.pending_blocks.append((op.suboperations, bb_off_track, exc)) - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_on_track) - - def generate_JUMP(self, op): - if op.jump_target is self.loop: - basicblock = llvm_rffi.LLVMGetInsertBlock(self.builder) - self.phi_incoming_blocks.append(basicblock) - for i in range(len(op.args)): - incoming = self.phi_incoming_values[i] - v = op.args[i] - if v.type == INT: - value_ref = self.getintarg(v) - else: - value_ref = self.getptrarg(v) - incoming.append(value_ref) - llvm_rffi.LLVMBuildBr(self.builder, self.bb_start) - else: - index = op.jump_target._llvm_compiled_index - assert index >= 0 - self._generate_fail(op.args, index) - - def generate_FAIL(self, op): - i = len(self.cpu.fail_ops) - self.cpu.fail_ops.append(op) - self._generate_fail(op.args, ~i) - - def _generate_fail(self, args, index): - self.cpu._ensure_out_args(len(args)) - for i in range(len(args)): - v = args[i] - if v.type == INT: - value_ref = self.getintarg(v) - ty = self.cpu.ty_int_ptr - else: - value_ref = self.getptrarg(v) - ty = self.cpu.ty_char_ptr_ptr - llvmconstptr = self.cpu._make_const(self.cpu.in_out_args[i], ty) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, - llvmconstptr) - llvm_rffi.LLVMBuildRet(self.builder, self.cpu._make_const_int(index)) - - def _generate_field_gep(self, v_structure, fielddescr): - assert isinstance(fielddescr, FieldDescr) - indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 1, - flavor='raw') - indices[0] = self.cpu._make_const_int(fielddescr.offset) - location = llvm_rffi.LLVMBuildGEP(self.builder, - self.getptrarg(v_structure), - indices, 1, "") - lltype.free(indices, flavor='raw') - ty = self.cpu.types_ptr_by_index[fielddescr.size_index] - location = llvm_rffi.LLVMBuildBitCast(self.builder, location, ty, "") - return location - - def generate_GETFIELD_GC(self, op): - loc = self._generate_field_gep(op.args[0], op.getdescr()) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - generate_GETFIELD_GC_PURE = generate_GETFIELD_GC - generate_GETFIELD_RAW = generate_GETFIELD_GC - generate_GETFIELD_RAW_PURE = generate_GETFIELD_GC - - def generate_SETFIELD_GC(self, op): - fielddescr = op.getdescr() - loc = self._generate_field_gep(op.args[0], fielddescr) - assert isinstance(fielddescr, FieldDescr) - getarg = self.cpu.getarg_by_index[fielddescr.size_index] - value_ref = getarg(self, op.args[1]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def generate_CALL(self, op): - calldescr = op.getdescr() - assert isinstance(calldescr, CallDescr) - ty_function_ptr = self.cpu.get_calldescr_ty_function_ptr(calldescr) - v = op.args[0] - if isinstance(v, Const): - func = self.cpu._make_const(v.getint(), ty_function_ptr) - else: - func = self.getintarg(v) - func = llvm_rffi.LLVMBuildIntToPtr(self.builder, - func, - ty_function_ptr, "") - nb_args = len(op.args) - 1 - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), nb_args, - flavor='raw') - for i in range(nb_args): - v = op.args[1 + i] - index = calldescr.args_indices[i] - getarg = self.cpu.getarg_by_index[index] - value_ref = getarg(self, v) - arglist[i] = value_ref - res = llvm_rffi.LLVMBuildCall(self.builder, - func, arglist, nb_args, "") - lltype.free(arglist, flavor='raw') - if op.result is not None: - assert calldescr.res_index >= 0 - self.vars[op.result] = res - - generate_CALL_PURE = generate_CALL - - def generate_CAST_PTR_TO_INT(self, op): - res = llvm_rffi.LLVMBuildPtrToInt(self.builder, - self.getptrarg(op.args[0]), - self.cpu.ty_int, "") - self.vars[op.result] = res - - def generate_CAST_INT_TO_PTR(self, op): - res = llvm_rffi.LLVMBuildIntToPtr(self.builder, - self.getintarg(op.args[0]), - self.cpu.ty_char_ptr, "") - self.vars[op.result] = res - - def generate_OOIS(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.EQ, - self.getptrarg(op.args[0]), - self.getptrarg(op.args[1]), "") - - def generate_OOISNOT(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.NE, - self.getptrarg(op.args[0]), - self.getptrarg(op.args[1]), "") - - def generate_OOISNULL(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.EQ, - self.getptrarg(op.args[0]), - self.cpu.const_null_charptr, "") - - def generate_OONONNULL(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.NE, - self.getptrarg(op.args[0]), - self.cpu.const_null_charptr, "") - - def generate_SAME_AS(self, op): - if op.args[0].type == INT: - self.vars[op.result] = self.getintarg(op.args[0]) - else: - self.vars[op.result] = self.getptrarg(op.args[0]) - - def _generate_len_gep(self, array_ref, ty, const_index_length): - array = llvm_rffi.LLVMBuildBitCast(self.builder, - array_ref, ty, "") - indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 2, - flavor='raw') - indices[0] = self.cpu.const_zero - indices[1] = const_index_length - loc = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 2, "") - lltype.free(indices, flavor='raw') - return loc - - def _generate_len(self, op, ty, const_index_length): - loc = self._generate_len_gep(self.getptrarg(op.args[0]), - ty, const_index_length) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - def generate_ARRAYLEN_GC(self, op): - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - self._generate_len(op, arraydescr.ty_array_ptr, - self.cpu.const_array_index_length) - - def _generate_gep(self, op, ty, const_index_array): - array = llvm_rffi.LLVMBuildBitCast(self.builder, - self.getptrarg(op.args[0]), - ty, "") - indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 3, - flavor='raw') - indices[0] = self.cpu.const_zero - indices[1] = const_index_array - indices[2] = self.getintarg(op.args[1]) - location = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 3, "") - lltype.free(indices, flavor='raw') - return location - - def _generate_array_gep(self, op): - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - location = self._generate_gep(op, arraydescr.ty_array_ptr, - self.cpu.const_array_index_array) - return location - - def generate_GETARRAYITEM_GC(self, op): - loc = self._generate_array_gep(op) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - generate_GETARRAYITEM_GC_PURE = generate_GETARRAYITEM_GC - - def generate_SETARRAYITEM_GC(self, op): - loc = self._generate_array_gep(op) - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - getarg = self.cpu.getarg_by_index[arraydescr.itemsize_index] - value_ref = getarg(self, op.args[2]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def generate_STRLEN(self, op): - self._generate_len(op, self.cpu.ty_string_ptr, - self.cpu.const_string_index_length) - - def generate_UNICODELEN(self, op): - self._generate_len(op, self.cpu.ty_unicode_ptr, - self.cpu.const_unicode_index_length) - - def generate_STRGETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_string_ptr, - self.cpu.const_string_index_array) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - def generate_UNICODEGETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_unicode_ptr, - self.cpu.const_unicode_index_array) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - def generate_STRSETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_string_ptr, - self.cpu.const_string_index_array) - value_ref = self.getchararg(op.args[2]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def generate_UNICODESETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_unicode_ptr, - self.cpu.const_unicode_index_array) - value_ref = self.getunichararg(op.args[2]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def _generate_new(self, size_ref): - malloc_func = self.cpu._make_const(self.cpu.malloc_fn_ptr, - self.cpu.ty_malloc_fn) - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 1, - flavor='raw') - arglist[0] = size_ref - res = llvm_rffi.LLVMBuildCall(self.builder, malloc_func, - arglist, 1, "") - lltype.free(arglist, flavor='raw') - return res - - def generate_NEW(self, op): - sizedescr = op.getdescr() - assert isinstance(sizedescr, SizeDescr) - res = self._generate_new(self.cpu._make_const_int(sizedescr.size)) - self.vars[op.result] = res - - def generate_NEW_WITH_VTABLE(self, op): - sizedescr = self.cpu.class_sizes[op.args[0].getint()] - res = self._generate_new(self.cpu._make_const_int(sizedescr.size)) - self.vars[op.result] = res - loc = self._generate_field_gep(op.result, self.cpu.vtable_descr) - value_ref = self.getintarg(op.args[0]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def _generate_new_array(self, op, ty_array, const_item_size, - const_index_array, const_index_length): - length_ref = self.getintarg(op.args[0]) - if const_item_size == self.cpu.const_one: - arraysize_ref = length_ref - else: - arraysize_ref = llvm_rffi.LLVMBuildMul(self.builder, - length_ref, - const_item_size, - "") - size_ref = llvm_rffi.LLVMBuildAdd(self.builder, - const_index_array, - arraysize_ref, - "") - res = self._generate_new(size_ref) - loc = self._generate_len_gep(res, ty_array, const_index_length) - llvm_rffi.LLVMBuildStore(self.builder, - length_ref, - loc, "") - self.vars[op.result] = res - - def generate_NEW_ARRAY(self, op): - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - self._generate_new_array(op, arraydescr.ty_array_ptr, - self.cpu._make_const_int(arraydescr.itemsize), - self.cpu.const_array_index_array, - self.cpu.const_array_index_length) - - def generate_NEWSTR(self, op): - self._generate_new_array(op, self.cpu.ty_string_ptr, - self.cpu.const_one, - self.cpu.const_string_index_array, - self.cpu.const_string_index_length) - - def generate_NEWUNICODE(self, op): - self._generate_new_array(op, self.cpu.ty_unicode_ptr, - self.cpu._make_const_int(self.cpu.size_of_unicode), - self.cpu.const_unicode_index_array, - self.cpu.const_unicode_index_length) - - def generate_DEBUG_MERGE_POINT(self, op): - pass - -# ____________________________________________________________ - -class MissingOperation(Exception): - pass - -all_operations = {} -for _key, _value in rop.__dict__.items(): - if 'A' <= _key <= 'Z': - assert _value not in all_operations - methname = 'generate_' + _key - if hasattr(LLVMJITCompiler, methname): - all_operations[_value] = methname -all_operations = unrolling_iterable(all_operations.items()) diff --git a/pypy/jit/backend/llvm/demo1.c b/pypy/jit/backend/llvm/demo1.c deleted file mode 100644 --- a/pypy/jit/backend/llvm/demo1.c +++ /dev/null @@ -1,17 +0,0 @@ -/* LLVM includes */ -#include "llvm-c/Analysis.h" -#include "llvm-c/Transforms/Scalar.h" -#include "llvm-c/ExecutionEngine.h" -#include "demo2.h" - -/* The following list of functions seems to be necessary to force the - * functions to be included in pypy_cache_llvm.so. The list is never - * used. Actually, any single function seems to be enough... - */ -void* llvm_c_functions[] = { - (void*) LLVMModuleCreateWithName, - (void*) _LLVM_EE_getPointerToFunction, - (void*) _LLVM_Intrinsic_add_ovf, - (void*) _LLVM_Intrinsic_sub_ovf, - (void*) _LLVM_Intrinsic_mul_ovf -}; diff --git a/pypy/jit/backend/llvm/demo2.cpp b/pypy/jit/backend/llvm/demo2.cpp deleted file mode 100644 --- a/pypy/jit/backend/llvm/demo2.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* LLVM includes */ -#include -#include "llvm-c/ExecutionEngine.h" -#include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Intrinsics.h" -#include "demo2.h" - -using namespace llvm; - - -/* Set the flag to true. - */ -void _LLVM_SetFlags(void) -{ - //PerformTailCallOpt = true; -} - -/* This piece of code regroups conveniently a part of the initialization. - */ -LLVMExecutionEngineRef _LLVM_EE_Create(LLVMModuleRef M) -{ - LLVMModuleProviderRef mp = LLVMCreateModuleProviderForExistingModule(M); - LLVMExecutionEngineRef ee; - char* errormsg; - int error = LLVMCreateJITCompiler(&ee, mp, 0 /*Fast*/, &errormsg); - if (error) - { - fprintf(stderr, "Error creating the JIT compiler:\n%s", errormsg); - abort(); - } - return ee; -} - -/* Missing pieces of the C interface... - */ -void *_LLVM_EE_getPointerToFunction(LLVMExecutionEngineRef EE, - LLVMValueRef F) -{ - return unwrap(EE)->getPointerToFunction(unwrap(F)); -} - -static LLVMValueRef _LLVM_Intrinsic_ovf(LLVMModuleRef M, LLVMTypeRef Ty, - Intrinsic::ID num) -{ - const Type *array_of_types[1]; - Function *F; - array_of_types[0] = unwrap(Ty); - F = Intrinsic::getDeclaration(unwrap(M), num, array_of_types, 1); - return wrap(F); -} - -LLVMValueRef _LLVM_Intrinsic_add_ovf(LLVMModuleRef M, LLVMTypeRef Ty) -{ - return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::sadd_with_overflow); -} - -LLVMValueRef _LLVM_Intrinsic_sub_ovf(LLVMModuleRef M, LLVMTypeRef Ty) -{ - return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::ssub_with_overflow); -} - -LLVMValueRef _LLVM_Intrinsic_mul_ovf(LLVMModuleRef M, LLVMTypeRef Ty) -{ - return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::smul_with_overflow); -} diff --git a/pypy/jit/backend/llvm/demo2.h b/pypy/jit/backend/llvm/demo2.h deleted file mode 100644 --- a/pypy/jit/backend/llvm/demo2.h +++ /dev/null @@ -1,16 +0,0 @@ - -#ifdef __cplusplus -extern "C" { -#endif - -void _LLVM_SetFlags(void); -LLVMExecutionEngineRef _LLVM_EE_Create(LLVMModuleRef M); -void *_LLVM_EE_getPointerToFunction(LLVMExecutionEngineRef EE, - LLVMValueRef F); -LLVMValueRef _LLVM_Intrinsic_add_ovf(LLVMModuleRef M, LLVMTypeRef Ty); -LLVMValueRef _LLVM_Intrinsic_sub_ovf(LLVMModuleRef M, LLVMTypeRef Ty); -LLVMValueRef _LLVM_Intrinsic_mul_ovf(LLVMModuleRef M, LLVMTypeRef Ty); - -#ifdef __cplusplus -} -#endif diff --git a/pypy/jit/backend/llvm/llvm_rffi.py b/pypy/jit/backend/llvm/llvm_rffi.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/llvm_rffi.py +++ /dev/null @@ -1,371 +0,0 @@ -import py, os, sys -import pypy -from pypy.rpython.lltypesystem import lltype, rffi -from pypy.translator.tool.cbuild import ExternalCompilationInfo, log - -if not sys.platform.startswith('linux'): - py.test.skip("Linux only for now") - -# ____________________________________________________________ - -llvm_config = 'llvm-config' -cachename = os.path.join(os.path.dirname(pypy.__file__), '_cache') -dirname = os.path.join(cachename, 'libs') -libname = os.path.join(dirname, 'pypy_cache_llvm.so') -cname = os.path.join(os.path.dirname(__file__), 'demo1.c') -cppname = os.path.join(os.path.dirname(__file__), 'demo2.cpp') -o1name = os.path.join(dirname, 'demo1.o') -o2name = os.path.join(dirname, 'demo2.o') - -if (not os.path.isfile(libname) or - os.path.getmtime(cname) > os.path.getmtime(libname) or - os.path.getmtime(cppname) > os.path.getmtime(libname)): - g = os.popen('%s --version' % llvm_config, 'r') - data = g.read() - g.close() - if not data.startswith('2.'): - py.test.skip("llvm (version 2) is required") - - if not os.path.isdir(dirname): - if not os.path.isdir(cachename): - os.mkdir(cachename) - os.mkdir(dirname) - - def do(cmdline): - log(cmdline) - err = os.system(cmdline) - if err: - raise Exception("gcc command failed") - - do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cname, o1name, llvm_config)) - do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cppname, o2name, llvm_config)) - do("g++ -g -shared '%s' '%s' -o '%s'" % (o1name, o2name, libname) + - " `%s --cflags --ldflags --libs jit engine`" % llvm_config) - -ctypes_compilation_info = ExternalCompilationInfo( - library_dirs = [dirname], - libraries = ['pypy_cache_llvm'], -) - -compilation_info = ExternalCompilationInfo.from_linker_flags( - os.popen("%s --ldflags --libs jit engine" % llvm_config, 'r').read()) - -compilation_info = compilation_info.merge(ExternalCompilationInfo( - link_extra = [o1name, o2name], - use_cpp_linker = True, - )) - -compilation_info._with_ctypes = ctypes_compilation_info - -_teardown = None - -def set_teardown_function(fn): - global _teardown - _teardown = fn - -def teardown_now(): - global _teardown - fn = _teardown - _teardown = None - if fn is not None: - fn() - -# ____________________________________________________________ - -Debug = True - -def llexternal(name, args, result, **kwds): - ll = rffi.llexternal(name, args, result, - compilation_info=compilation_info, - **kwds) - if Debug: - def func(*args): - print name - res = ll(*args) - print '\t->', res - return res - return func - else: - return ll - -def opaqueptr(name): - return rffi.VOIDP # lltype.Ptr(rffi.COpaque(name)) - -LLVMModuleRef = opaqueptr('struct LLVMOpaqueModule') -LLVMTypeRef = opaqueptr('struct LLVMOpaqueType') -LLVMValueRef = opaqueptr('struct LLVMOpaqueValue') -LLVMBasicBlockRef = opaqueptr('struct LLVMOpaqueBasicBlock') -LLVMBuilderRef = opaqueptr('struct LLVMOpaqueBuilder') -LLVMModuleProviderRef = opaqueptr('struct LLVMOpaqueModuleProvider') -LLVMGenericValueRef = opaqueptr('struct LLVMOpaqueGenericValue') -LLVMExecutionEngineRef = opaqueptr('struct LLVMOpaqueExecutionEngine') - -class Predicate: - EQ = 32 # equal - NE = 33 # not equal - UGT = 34 # unsigned greater than - UGE = 35 # unsigned greater or equal - ULT = 36 # unsigned less than - ULE = 37 # unsigned less or equal - SGT = 38 # signed greater than - SGE = 39 # signed greater or equal - SLT = 40 # signed less than - SLE = 41 # signed less or equal - -class CallConv: - C = 0 - Fast = 8 - Cold = 9 - X86Stdcall = 64 - X86Fastcall = 65 - -# ____________________________________________________________ - -LLVMDisposeMessage = llexternal('LLVMDisposeMessage', [rffi.CCHARP], - lltype.Void) - -LLVMModuleCreateWithName = llexternal('LLVMModuleCreateWithName', - [rffi.CCHARP], - LLVMModuleRef) -LLVMDumpModule = llexternal('LLVMDumpModule', [LLVMModuleRef], lltype.Void) - -LLVMInt1Type = llexternal('LLVMInt1Type', [], LLVMTypeRef) -LLVMInt8Type = llexternal('LLVMInt8Type', [], LLVMTypeRef) -LLVMInt16Type = llexternal('LLVMInt16Type', [], LLVMTypeRef) -LLVMInt32Type = llexternal('LLVMInt32Type', [], LLVMTypeRef) -LLVMInt64Type = llexternal('LLVMInt64Type', [], LLVMTypeRef) -LLVMFunctionType = llexternal('LLVMFunctionType', - [LLVMTypeRef, # return type - rffi.CArrayPtr(LLVMTypeRef), # param types - rffi.UINT, # param count - rffi.INT], # flag: is_vararg - LLVMTypeRef) -LLVMStructType = llexternal('LLVMStructType', - [rffi.CArrayPtr(LLVMTypeRef), # element types - rffi.UINT, # element count - rffi.INT], # flag: packed - LLVMTypeRef) -LLVMArrayType = llexternal('LLVMArrayType', [LLVMTypeRef, # element type - rffi.UINT], # element count - LLVMTypeRef) -LLVMPointerType = llexternal('LLVMPointerType', [LLVMTypeRef, # element type - rffi.UINT], # address space - LLVMTypeRef) -LLVMVoidType = llexternal('LLVMVoidType', [], LLVMTypeRef) - -LLVMTypeOf = llexternal('LLVMTypeOf', [LLVMValueRef], LLVMTypeRef) -LLVMDumpValue = llexternal('LLVMDumpValue', [LLVMValueRef], lltype.Void) -LLVMConstNull = llexternal('LLVMConstNull', [LLVMTypeRef], LLVMValueRef) -LLVMConstInt = llexternal('LLVMConstInt', [LLVMTypeRef, # type - rffi.ULONGLONG, # value - rffi.INT], # flag: is_signed - LLVMValueRef) -LLVMConstIntToPtr = llexternal('LLVMConstIntToPtr', - [LLVMValueRef, # constant integer value - LLVMTypeRef], # type of the result - LLVMValueRef) - -LLVMAddFunction = llexternal('LLVMAddFunction', - [LLVMModuleRef, # module - rffi.CCHARP, # name - LLVMTypeRef], # function type - LLVMValueRef) -LLVMSetFunctionCallConv = llexternal('LLVMSetFunctionCallConv', - [LLVMValueRef, # function - rffi.UINT], # new call conv - lltype.Void) -LLVMGetParam = llexternal('LLVMGetParam', - [LLVMValueRef, # function - rffi.UINT], # index - LLVMValueRef) - -LLVMAppendBasicBlock = llexternal('LLVMAppendBasicBlock', - [LLVMValueRef, # function - rffi.CCHARP], # name - LLVMBasicBlockRef) - -LLVMSetInstructionCallConv = llexternal('LLVMSetInstructionCallConv', - [LLVMValueRef, # call instruction - rffi.UINT], # new call conv - lltype.Void) -LLVMSetTailCall = llexternal('LLVMSetTailCall', - [LLVMValueRef, # call instruction - rffi.INT], # flag: is_tail - lltype.Void) -LLVMAddIncoming = llexternal('LLVMAddIncoming', - [LLVMValueRef, # phi node - rffi.CArrayPtr(LLVMValueRef), # incoming values - rffi.CArrayPtr(LLVMBasicBlockRef), # incom.blocks - rffi.UINT], # count - lltype.Void) -LLVMCreateBuilder = llexternal('LLVMCreateBuilder', [], LLVMBuilderRef) -LLVMPositionBuilderAtEnd = llexternal('LLVMPositionBuilderAtEnd', - [LLVMBuilderRef, # builder - LLVMBasicBlockRef], # block - lltype.Void) -LLVMGetInsertBlock = llexternal('LLVMGetInsertBlock', [LLVMBuilderRef], - LLVMBasicBlockRef) -LLVMDisposeBuilder = llexternal('LLVMDisposeBuilder', [LLVMBuilderRef], - lltype.Void) - -LLVMBuildRet = llexternal('LLVMBuildRet', [LLVMBuilderRef, # builder, - LLVMValueRef], # result - LLVMValueRef) -LLVMBuildBr = llexternal('LLVMBuildBr', [LLVMBuilderRef, # builder, - LLVMBasicBlockRef],# destination block - LLVMValueRef) -LLVMBuildCondBr = llexternal('LLVMBuildCondBr', - [LLVMBuilderRef, # builder - LLVMValueRef, # condition - LLVMBasicBlockRef, # block if true - LLVMBasicBlockRef], # block if false - LLVMValueRef) - -for _name in ['Add', 'Sub', 'Mul', 'SDiv', 'SRem', 'Shl', 'LShr', 'AShr', - 'And', 'Or', 'Xor']: - globals()['LLVMBuild' + _name] = llexternal('LLVMBuild' + _name, - [LLVMBuilderRef, # builder - LLVMValueRef, # left-hand side - LLVMValueRef, # right-hand side - rffi.CCHARP], # name of result - LLVMValueRef) - -for _name in ['Neg', 'Not']: - globals()['LLVMBuild' + _name] = llexternal('LLVMBuild' + _name, - [LLVMBuilderRef, # builder - LLVMValueRef, # argument - rffi.CCHARP], # name of result - LLVMValueRef) - -LLVMBuildLoad = llexternal('LLVMBuildLoad', - [LLVMBuilderRef, # builder - LLVMValueRef, # pointer location - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildStore = llexternal('LLVMBuildStore', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMValueRef], # pointer location - LLVMValueRef) -LLVMBuildGEP = llexternal('LLVMBuildGEP', # GEP = 'getelementptr' - [LLVMBuilderRef, # builder - LLVMValueRef, # base pointer - rffi.CArrayPtr(LLVMValueRef), # indices - rffi.UINT, # num indices - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildTrunc = llexternal('LLVMBuildTrunc', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildZExt = llexternal('LLVMBuildZExt', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildPtrToInt = llexternal('LLVMBuildPtrToInt', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildIntToPtr = llexternal('LLVMBuildIntToPtr', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildBitCast = llexternal('LLVMBuildBitCast', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildICmp = llexternal('LLVMBuildICmp', - [LLVMBuilderRef, # builder - rffi.INT, # predicate (see Predicate above) - LLVMValueRef, # left-hand side - LLVMValueRef, # right-hand side - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildPhi = llexternal('LLVMBuildPhi', - [LLVMBuilderRef, # builder - LLVMTypeRef, # type of value - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildCall = llexternal('LLVMBuildCall', - [LLVMBuilderRef, # builder - LLVMValueRef, # function - rffi.CArrayPtr(LLVMValueRef), # arguments - rffi.UINT, # argument count - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildSelect = llexternal('LLVMBuildSelect', - [LLVMBuilderRef, # builder - LLVMValueRef, # if - LLVMValueRef, # then - LLVMValueRef, # else - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildExtractValue = llexternal('LLVMBuildExtractValue', - [LLVMBuilderRef, # builder - LLVMValueRef, # aggregated value - rffi.UINT, # index - rffi.CCHARP], # name of result - LLVMValueRef) - -LLVMCreateModuleProviderForExistingModule = llexternal( - 'LLVMCreateModuleProviderForExistingModule', [LLVMModuleRef], - LLVMModuleProviderRef) - -# ____________________________________________________________ - -LLVMCreateGenericValueOfInt = llexternal('LLVMCreateGenericValueOfInt', - [LLVMTypeRef, # type - rffi.ULONGLONG, # value - rffi.INT], # flag: is_signed - LLVMGenericValueRef) -LLVMDisposeGenericValue = llexternal('LLVMDisposeGenericValue', - [LLVMGenericValueRef], lltype.Void) - -LLVMGenericValueToInt = llexternal('LLVMGenericValueToInt', - [LLVMGenericValueRef, - rffi.INT], # flag: is_signed - rffi.ULONGLONG) - -LLVMCreateJITCompiler = llexternal('LLVMCreateJITCompiler', - [rffi.CArrayPtr(LLVMExecutionEngineRef), - LLVMModuleProviderRef, - rffi.INT, # "fast" - rffi.CArrayPtr(rffi.CCHARP)], # -> error - rffi.INT) -LLVMDisposeExecutionEngine = llexternal('LLVMDisposeExecutionEngine', - [LLVMExecutionEngineRef], - lltype.Void) - -LLVMRunFunction = llexternal('LLVMRunFunction', - [LLVMExecutionEngineRef, - LLVMValueRef, # function - rffi.UINT, # num args - rffi.CArrayPtr(LLVMGenericValueRef)], # args - LLVMGenericValueRef) # return value - -LLVM_SetFlags = llexternal('_LLVM_SetFlags', [], lltype.Void) -LLVM_EE_Create = llexternal('_LLVM_EE_Create', [LLVMModuleRef], - LLVMExecutionEngineRef) -LLVM_EE_getPointerToFunction = llexternal('_LLVM_EE_getPointerToFunction', - [LLVMExecutionEngineRef, - LLVMValueRef], # function - rffi.VOIDP) -LLVM_Intrinsic_add_ovf = llexternal('_LLVM_Intrinsic_add_ovf', - [LLVMModuleRef, LLVMTypeRef], - LLVMValueRef) -LLVM_Intrinsic_sub_ovf = llexternal('_LLVM_Intrinsic_sub_ovf', - [LLVMModuleRef, LLVMTypeRef], - LLVMValueRef) -LLVM_Intrinsic_mul_ovf = llexternal('_LLVM_Intrinsic_mul_ovf', - [LLVMModuleRef, LLVMTypeRef], - LLVMValueRef) diff --git a/pypy/jit/backend/llvm/runner.py b/pypy/jit/backend/llvm/runner.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/runner.py +++ /dev/null @@ -1,731 +0,0 @@ -import sys -from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr -from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rlib.objectmodel import we_are_translated, specialize -from pypy.rlib import runicode -from pypy.jit.metainterp.history import AbstractDescr, INT -from pypy.jit.metainterp.history import BoxInt, BoxPtr -from pypy.jit.backend.model import AbstractCPU -from pypy.jit.backend.llvm import llvm_rffi -from pypy.jit.metainterp import history -from pypy.jit.metainterp.resoperation import rop, ResOperation -from pypy.jit.backend.llsupport import symbolic -from pypy.jit.metainterp.typesystem import llhelper - -history.TreeLoop._llvm_compiled_index = -1 - - -class LLVMCPU(object): - ts = llhelper - RAW_VALUE = rffi.CFixedArray(rffi.ULONGLONG, 1) - SIGNED_VALUE = rffi.CFixedArray(lltype.Signed, 1) - POINTER_VALUE = rffi.CFixedArray(llmemory.GCREF, 1) - - SIZE_GCPTR = 0 - SIZE_INT = 1 - SIZE_CHAR = 2 - SIZE_UNICHAR = 3 - - def __init__(self, rtyper, stats=None, translate_support_code=False, - annmixlevel=None, gcdescr=None): - self.rtyper = rtyper - self.translate_support_code = translate_support_code - self.compiled_functions = [] - self.fail_ops = [] - self.in_out_args = [] - if translate_support_code: - get_size = llmemory.sizeof - else: - get_size = rffi.sizeof - self._arraydescrs = [ - ArrayDescr(get_size(llmemory.GCREF), self.SIZE_GCPTR), # 0 - ArrayDescr(get_size(lltype.Signed), self.SIZE_INT), # 1 - ArrayDescr(get_size(lltype.Char), self.SIZE_CHAR), # 2 - ArrayDescr(get_size(lltype.UniChar), self.SIZE_UNICHAR), # 3 - ] - self._descr_caches = {} - self.fielddescr_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr') - if sys.maxint == 2147483647: - self.size_of_int = 4 - else: - self.size_of_int = 8 - if runicode.MAXUNICODE > 0xffff: - self.size_of_unicode = 4 - else: - self.size_of_unicode = 2 - self.gcarray_gcref = lltype.GcArray(llmemory.GCREF) - self.gcarray_signed = lltype.GcArray(lltype.Signed) - self.gcarray_char = lltype.GcArray(lltype.Char) - self.gcarray_unichar = lltype.GcArray(lltype.UniChar) - basesize, _, ofs_length = symbolic.get_array_token( - self.gcarray_signed, self.translate_support_code) - self.array_index_array = basesize - self.array_index_length = ofs_length - basesize, _, ofs_length = symbolic.get_array_token( - rstr.STR, self.translate_support_code) - self.string_index_array = basesize - self.string_index_length = ofs_length - basesize, _, ofs_length = symbolic.get_array_token( - rstr.UNICODE, self.translate_support_code) - self.unicode_index_array = basesize - self.unicode_index_length = ofs_length - self.vtable_descr = self.fielddescrof(rclass.OBJECT, 'typeptr') - self._ovf_error_instance = self._get_prebuilt_error(OverflowError) - self._zer_error_instance = self._get_prebuilt_error(ZeroDivisionError) - # - # temporary (Boehm only) - from pypy.translator.tool.cbuild import ExternalCompilationInfo - compilation_info = ExternalCompilationInfo(libraries=['gc']) - self.malloc_fn_ptr = rffi.llexternal("GC_malloc", - [rffi.SIZE_T], - llmemory.GCREF, - compilation_info=compilation_info, - sandboxsafe=True, - _nowrapper=True) - assert rffi.sizeof(rffi.SIZE_T) == self.size_of_int - - def set_class_sizes(self, class_sizes): - self.class_sizes = class_sizes - - def setup_once(self): - if not we_are_translated(): - llvm_rffi.teardown_now() - llvm_rffi.LLVM_SetFlags() - self.module = llvm_rffi.LLVMModuleCreateWithName("pypyjit") - if self.size_of_int == 4: - self.ty_int = llvm_rffi.LLVMInt32Type() - else: - self.ty_int = llvm_rffi.LLVMInt64Type() - if self.size_of_unicode == 2: - self.ty_unichar = llvm_rffi.LLVMInt16Type() - else: - self.ty_unichar = llvm_rffi.LLVMInt32Type() - self.ty_void = llvm_rffi.LLVMVoidType() - self.ty_bit = llvm_rffi.LLVMInt1Type() - self.ty_char = llvm_rffi.LLVMInt8Type() - self.ty_char_ptr = llvm_rffi.LLVMPointerType(self.ty_char, 0) - self.ty_char_ptr_ptr = llvm_rffi.LLVMPointerType(self.ty_char_ptr, 0) - self.ty_int_ptr = llvm_rffi.LLVMPointerType(self.ty_int, 0) - self.ty_int_ptr_ptr = llvm_rffi.LLVMPointerType(self.ty_int_ptr, 0) - self.ty_unichar_ptr = llvm_rffi.LLVMPointerType(self.ty_unichar, 0) - self.const_zero = self._make_const_int(0) - self.const_one = self._make_const_int(1) - self.const_null_charptr = self._make_const(0, self.ty_char_ptr) - # - from pypy.jit.backend.llvm.compile import LLVMJITCompiler - self.types_by_index = [self.ty_char_ptr, # SIZE_GCPTR - self.ty_int, # SIZE_INT - self.ty_char, # SIZE_CHAR - self.ty_unichar] # SIZE_UNICHAR - self.types_ptr_by_index = [self.ty_char_ptr_ptr, # SIZE_GCPTR - self.ty_int_ptr, # SIZE_INT - self.ty_char_ptr, # SIZE_CHAR - self.ty_unichar_ptr] # SIZE_UNICHAR - self.getarg_by_index = [LLVMJITCompiler.getptrarg, # SIZE_GCPTR - LLVMJITCompiler.getintarg, # SIZE_INT - LLVMJITCompiler.getchararg, # SIZE_CHAR - LLVMJITCompiler.getunichararg] # SIZE_UNICHAR - for i in range(len(self.types_by_index)): - arraydescr = self._arraydescrs[i] - (arraydescr.ty_array_ptr, - self.const_array_index_length, - self.const_array_index_array) = \ - self._build_ty_array_ptr(self.array_index_array, - self.types_by_index[i], - self.array_index_length) - (self.ty_string_ptr, - self.const_string_index_length, - self.const_string_index_array) = \ - self._build_ty_array_ptr(self.string_index_array, - self.ty_char, - self.string_index_length) - (self.ty_unicode_ptr, - self.const_unicode_index_length, - self.const_unicode_index_array) = \ - self._build_ty_array_ptr(self.unicode_index_array, - self.ty_unichar, - self.unicode_index_length) - # - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), 0, - flavor='raw') - self.ty_func = llvm_rffi.LLVMFunctionType(self.ty_int, arglist, 0, - False) - lltype.free(arglist, flavor='raw') - # - self.f_add_ovf = llvm_rffi.LLVM_Intrinsic_add_ovf(self.module, - self.ty_int) - self.f_sub_ovf = llvm_rffi.LLVM_Intrinsic_sub_ovf(self.module, - self.ty_int) - self.f_mul_ovf = llvm_rffi.LLVM_Intrinsic_mul_ovf(self.module, - self.ty_int) - if we_are_translated(): - addr = llop.get_exception_addr(llmemory.Address) - self.exc_type = rffi.cast(rffi.CArrayPtr(lltype.Signed), addr) - addr = llop.get_exc_value_addr(llmemory.Address) - self.exc_value = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), addr) - else: - self.exc_type = lltype.malloc(rffi.CArray(lltype.Signed), 1, - zero=True, flavor='raw') - self.exc_value = lltype.malloc(rffi.CArray(llmemory.GCREF), 1, - zero=True, flavor='raw') - self.backup_exc_type = lltype.malloc(rffi.CArray(lltype.Signed), 1, - zero=True, flavor='raw') - self.backup_exc_value = lltype.malloc(rffi.CArray(llmemory.GCREF), 1, - zero=True, flavor='raw') - self.const_exc_type = self._make_const(self.exc_type, - self.ty_char_ptr_ptr) - self.const_exc_value = self._make_const(self.exc_value, - self.ty_char_ptr_ptr) - self.const_backup_exc_type = self._make_const(self.backup_exc_type, - self.ty_char_ptr_ptr) - self.const_backup_exc_value = self._make_const(self.backup_exc_value, - self.ty_char_ptr_ptr) - # - self._setup_prebuilt_error('ovf') - self._setup_prebuilt_error('zer') - # - # temporary (Boehm only) - param_types = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), 1, - flavor='raw') - param_types[0] = self.ty_int - self.ty_malloc_fn = llvm_rffi.LLVMPointerType( - llvm_rffi.LLVMFunctionType(self.ty_char_ptr, param_types, 1, 0), - 0) - lltype.free(param_types, flavor='raw') - # - self.ee = llvm_rffi.LLVM_EE_Create(self.module) - if not we_are_translated(): - llvm_rffi.set_teardown_function(self._teardown) - - def _teardown(self): - llvm_rffi.LLVMDisposeExecutionEngine(self.ee) - - def _get_prebuilt_error(self, Class): - "NOT_RPYTHON" - if self.rtyper is not None: # normal case - bk = self.rtyper.annotator.bookkeeper - clsdef = bk.getuniqueclassdef(Class) - ll_inst = self.rtyper.exceptiondata.get_standard_ll_exc_instance( - self.rtyper, clsdef) - else: - # for tests, a random emulated ll_inst will do - ll_inst = lltype.malloc(rclass.OBJECT) - ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, - immortal=True) - return ll_inst - - @specialize.arg(1) - def _setup_prebuilt_error(self, prefix): - ll_inst = getattr(self, '_' + prefix + '_error_instance') - setattr(self, '_' + prefix + '_error_type', - rffi.cast(lltype.Signed, ll_inst.typeptr)) - setattr(self, '_' + prefix + '_error_value', - lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst)) - setattr(self, 'const_' + prefix + '_error_type', - self._make_const(ll_inst.typeptr, self.ty_char_ptr)) - setattr(self, 'const_' + prefix + '_error_value', - self._make_const(ll_inst, self.ty_char_ptr)) - - def _build_ty_array_ptr(self, basesize, ty_item, ofs_length): - pad1 = ofs_length - pad2 = basesize - ofs_length - self.size_of_int - assert pad1 >= 0 and pad2 >= 0 - const_index_length = self._make_const_int(pad1) - const_index_array = self._make_const_int(pad1 + 1 + pad2) - # build the type "struct{pad1.., length, pad2.., array{type}}" - typeslist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), - pad1+pad2+2, flavor='raw') - # add the first padding - for n in range(pad1): - typeslist[n] = self.ty_char - # add the length field - typeslist[pad1] = self.ty_int - # add the second padding - for n in range(pad1+1, pad1+1+pad2): - typeslist[n] = self.ty_char - # add the array field - typeslist[pad1+1+pad2] = llvm_rffi.LLVMArrayType(ty_item, 0) - # done - ty_array = llvm_rffi.LLVMStructType(typeslist, - pad1+pad2+2, - 1) - lltype.free(typeslist, flavor='raw') - ty_array_ptr = llvm_rffi.LLVMPointerType(ty_array, 0) - return (ty_array_ptr, const_index_length, const_index_array) - - # ------------------------------ - # Compilation - - def compile_operations(self, loop, _guard_op=None): - from pypy.jit.backend.llvm.compile import LLVMJITCompiler - compiler = LLVMJITCompiler(self, loop) - compiler.compile() - - def _ensure_in_args(self, count): - while len(self.in_out_args) < count: - self.in_out_args.append(lltype.malloc(self.RAW_VALUE, flavor='raw')) - - _ensure_out_args = _ensure_in_args - - def _make_const_int(self, value): - return llvm_rffi.LLVMConstInt(self.ty_int, value, True) - - def _make_const_char(self, value): - assert (value & ~255) == 0, "value is not in range(256)" - return llvm_rffi.LLVMConstInt(self.ty_char, value, True) - - def _make_const_unichar(self, value): - #xxx assert something about 'value' - return llvm_rffi.LLVMConstInt(self.ty_unichar, value, True) - - def _make_const_bit(self, value): - assert (value & ~1) == 0, "value is not 0 or 1" - return llvm_rffi.LLVMConstInt(self.ty_bit, value, True) - - @specialize.arglltype(1) - def _make_const(self, value, ty_result): - value_as_signed = rffi.cast(lltype.Signed, value) - llvmconstint = self._make_const_int(value_as_signed) - llvmconstptr = llvm_rffi.LLVMConstIntToPtr(llvmconstint, ty_result) - return llvmconstptr - - def _get_var_type(self, v): - if v.type == INT: - return self.ty_int - else: - return self.ty_char_ptr - - def _get_pointer_type(self, v): - if v.type == INT: - return self.ty_int_ptr - else: - return self.ty_char_ptr_ptr - - # ------------------------------ - # Execution - - def set_future_value_int(self, index, intvalue): - p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index]) - p[0] = intvalue - - def set_future_value_ref(self, index, ptrvalue): - p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index]) - p[0] = ptrvalue - - def execute_operations(self, loop): - index = loop._llvm_compiled_index - assert index >= 0 - while True: - func_ptr = self.compiled_functions[index] - print 'execute_operations: %d (at 0x%x)' % ( - index, rffi.cast(lltype.Signed, func_ptr)) - index = func_ptr() - print '\t--->', index - if index < 0: - break - return self.fail_ops[~index] - - def get_latest_value_int(self, index): - p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index]) - return p[0] - - def get_latest_value_ref(self, index): - p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index]) - return p[0] - - def get_exception(self): - return self.backup_exc_type[0] - - def get_exc_value(self): - return self.backup_exc_value[0] - - def clear_exception(self): - self.backup_exc_type[0] = 0 - self.backup_exc_value[0] = lltype.nullptr(llmemory.GCREF.TO) - - # XXX wrong, but untested - - def set_overflow_error(self): - self.backup_exc_type[0] = self._ovf_error_type - self.backup_exc_value[0] = self._ovf_error_value - - def set_zero_division_error(self): - self.backup_exc_type[0] = self._zer_error_type - self.backup_exc_value[0] = self._zer_error_value - - @staticmethod - def cast_adr_to_int(x): - return rffi.cast(lltype.Signed, x) - - @staticmethod - def cast_int_to_adr(x): - assert x == 0 or x > (1<<20) or x < (-1<<20) - if we_are_translated(): - return rffi.cast(llmemory.Address, x) - else: - # indirect casting because the above doesn't work with ll2ctypes - return llmemory.cast_ptr_to_adr(rffi.cast(llmemory.GCREF, x)) - - def _get_size_index(self, TYPE): - if isinstance(TYPE, lltype.Ptr): - if TYPE.TO._gckind == 'gc': - return self.SIZE_GCPTR - else: - return self.SIZE_INT - else: - if TYPE == lltype.Signed or TYPE == lltype.Unsigned: - return self.SIZE_INT - elif TYPE == lltype.Char or TYPE == lltype.Bool: - return self.SIZE_CHAR - elif TYPE == lltype.UniChar: - return self.SIZE_UNICHAR - else: - raise BadSizeError(TYPE) - - def sizeof(self, S): - try: - return self._descr_caches['size', S] - except KeyError: - pass - descr = SizeDescr(symbolic.get_size(S, self.translate_support_code)) - self._descr_caches['size', S] = descr - return descr - - def fielddescrof(self, S, fieldname): - try: - return self._descr_caches['field', S, fieldname] - except KeyError: - pass - ofs, _ = symbolic.get_field_token(S, fieldname, - self.translate_support_code) - size_index = self._get_size_index(getattr(S, fieldname)) - descr = FieldDescr(ofs, size_index) - self._descr_caches['field', S, fieldname] = descr - return descr - - def arraydescrof(self, A): - basesize, _, ofs_length = symbolic.get_array_token(A, - self.translate_support_code) - if isinstance(basesize, int): # else Symbolics, can't be compared... - assert self.array_index_array == basesize - assert self.array_index_length == ofs_length - itemsize_index = self._get_size_index(A.OF) - return self._arraydescrs[itemsize_index] - - def calldescrof(self, FUNC, ARGS, RESULT): - args_indices = [self._get_size_index(ARG) for ARG in ARGS] - if RESULT is lltype.Void: - res_index = -1 - else: - res_index = self._get_size_index(RESULT) - # - key = ('call', tuple(args_indices), res_index) - try: - descr = self._descr_caches[key] - except KeyError: - descr = CallDescr(args_indices, res_index) - self._descr_caches[key] = descr - return descr - - def get_calldescr_ty_function_ptr(self, calldescr): - if not calldescr.ty_function_ptr: - # - args_indices = calldescr.args_indices - param_types = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), - len(args_indices), flavor='raw') - for i in range(len(args_indices)): - param_types[i] = self.types_by_index[args_indices[i]] - # - res_index = calldescr.res_index - if res_index < 0: - ty_result = self.ty_void - else: - ty_result = self.types_by_index[res_index] - # - ty_func = llvm_rffi.LLVMFunctionType(ty_result, param_types, - len(args_indices), 0) - lltype.free(param_types, flavor='raw') - ty_funcptr = llvm_rffi.LLVMPointerType(ty_func, 0) - calldescr.ty_function_ptr = ty_funcptr - # - return calldescr.ty_function_ptr - - # ------------------------------ - # do_xxx methods - - def do_arraylen_gc(self, args, arraydescr): - array = args[0].getref_base() - p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) - res = len(p) - return BoxInt(res) - - def do_strlen(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) - res = len(p.chars) - return BoxInt(res) - - def do_strgetitem(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) - res = ord(p.chars[args[1].getint()]) - return BoxInt(res) - - def do_unicodelen(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) - res = len(p.chars) - return BoxInt(res) - - def do_unicodegetitem(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) - res = ord(p.chars[args[1].getint()]) - return BoxInt(res) - - def do_getarrayitem_gc(self, args, arraydescr): - array = args[0].getref_base() - index = args[1].getint() - assert isinstance(arraydescr, ArrayDescr) - itemsize_index = arraydescr.itemsize_index - if itemsize_index == self.SIZE_GCPTR: - p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) - res = p[index] - return BoxPtr(res) - elif itemsize_index == self.SIZE_INT: - p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) - res = p[index] - elif itemsize_index == self.SIZE_CHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_char), array) - res = ord(p[index]) - elif itemsize_index == self.SIZE_UNICHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_unichar), array) - res = ord(p[index]) - else: - raise BadSizeError - return BoxInt(res) - - @specialize.argtype(1) - def _do_getfield(self, struct, fielddescr): - assert isinstance(fielddescr, FieldDescr) - size_index = fielddescr.size_index - if size_index == self.SIZE_GCPTR: - p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct) - res = p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] - return BoxPtr(res) - elif size_index == self.SIZE_INT: - p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct) - res = p[fielddescr.offset / rffi.sizeof(lltype.Signed)] - elif size_index == self.SIZE_CHAR: - p = rffi.cast(rffi.CArrayPtr(lltype.Char), struct) - res = ord(p[fielddescr.offset / rffi.sizeof(lltype.Char)]) - elif size_index == self.SIZE_UNICHAR: - p = rffi.cast(rffi.CArrayPtr(lltype.UniChar), struct) - res = ord(p[fielddescr.offset / rffi.sizeof(lltype.UniChar)]) - else: - raise BadSizeError - return BoxInt(res) - - def do_getfield_gc(self, args, fielddescr): - struct = args[0].getref_base() - return self._do_getfield(struct, fielddescr) - - def do_getfield_raw(self, args, fielddescr): - struct = args[0].getaddr(self) - return self._do_getfield(struct, fielddescr) - - def do_new(self, args, sizedescr): - assert isinstance(sizedescr, SizeDescr) - res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, sizedescr.size)) - return BoxPtr(res) - - def do_new_with_vtable(self, args, descr=None): - assert descr is None - sizedescr = self.class_sizes[args[0].getint()] - res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, sizedescr.size)) - self._do_setfield(res, args[0], self.vtable_descr) - return BoxPtr(res) - - def _allocate_new_array(self, args, item_size, index_array, index_length): - length = args[0].getint() - #try: - size = index_array + length * item_size - #except OverflowError: - # ... - res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, size)) - p = rffi.cast(rffi.CArrayPtr(lltype.Signed), res) - p[index_length / rffi.sizeof(lltype.Signed)] = length - return BoxPtr(res) - - def do_new_array(self, args, arraydescr): - assert isinstance(arraydescr, ArrayDescr) - return self._allocate_new_array(args, arraydescr.itemsize, - self.array_index_array, - self.array_index_length) - - def do_setarrayitem_gc(self, args, arraydescr): - array = args[0].getref_base() - index = args[1].getint() - assert isinstance(arraydescr, ArrayDescr) - itemsize_index = arraydescr.itemsize_index - if itemsize_index == self.SIZE_GCPTR: - p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) - res = args[2].getref_base() - p[index] = res - elif itemsize_index == self.SIZE_INT: - p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) - res = args[2].getint() - p[index] = res - elif itemsize_index == self.SIZE_CHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_char), array) - res = chr(args[2].getint()) - p[index] = res - elif itemsize_index == self.SIZE_UNICHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_unichar), array) - res = unichr(args[2].getint()) - p[index] = res - else: - raise BadSizeError - - @specialize.argtype(1) - def _do_setfield(self, struct, v_value, fielddescr): - assert isinstance(fielddescr, FieldDescr) - size_index = fielddescr.size_index - if size_index == self.SIZE_GCPTR: - p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct) - res = v_value.getref_base() - p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] = res - elif size_index == self.SIZE_INT: - p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct) - res = v_value.getint() - p[fielddescr.offset / rffi.sizeof(lltype.Signed)] = res - elif size_index == self.SIZE_CHAR: - p = rffi.cast(rffi.CArrayPtr(lltype.Char), struct) - res = chr(v_value.getint()) - p[fielddescr.offset / rffi.sizeof(lltype.Char)] = res - elif size_index == self.SIZE_UNICHAR: - p = rffi.cast(rffi.CArrayPtr(lltype.UniChar), struct) - res = unichr(v_value.getint()) - p[fielddescr.offset / rffi.sizeof(lltype.UniChar)] = res - else: - raise BadSizeError - - def do_setfield_gc(self, args, fielddescr): - struct = args[0].getref_base() - self._do_setfield(struct, args[1], fielddescr) - - def do_setfield_raw(self, args, fielddescr): - struct = args[0].getaddr(self) - self._do_setfield(struct, args[1], fielddescr) - - def do_newstr(self, args, descr=None): - return self._allocate_new_array(args, 1, - self.string_index_array, - self.string_index_length) - - def do_newunicode(self, args, descr=None): - return self._allocate_new_array(args, self.size_of_unicode, - self.unicode_index_array, - self.unicode_index_length) - - def do_strsetitem(self, args, descr=None): - s = args[0].getref_base() - res = chr(args[2].getint()) - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) - p.chars[args[1].getint()] = res - - def do_unicodesetitem(self, args, descr=None): - s = args[0].getref_base() - res = unichr(args[2].getint()) - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) - p.chars[args[1].getint()] = res - - def _get_loop_for_call(self, argnum, calldescr): - loop = calldescr._generated_mp - if loop is None: - args = [BoxInt() for i in range(argnum + 1)] - if calldescr.res_index < 0: - result = None - elif calldescr.res_index == self.SIZE_GCPTR: - result = BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) - else: - result = BoxInt(0) - result_list = [] - if result is not None: - result_list.append(result) - operations = [ - ResOperation(rop.CALL, args, result, calldescr), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None), - ResOperation(rop.FAIL, result_list, None)] - operations[1].suboperations = [ResOperation(rop.FAIL, [], None)] - loop = history.TreeLoop('call') - loop.inputargs = args - loop.operations = operations - self.compile_operations(loop) - calldescr._generated_mp = loop - return loop - - def do_call(self, args, calldescr): - assert isinstance(calldescr, CallDescr) - num_args = len(calldescr.args_indices) - assert num_args == len(args) - 1 - loop = self._get_loop_for_call(num_args, calldescr) - history.set_future_values(self, args) - self.execute_operations(loop) - # Note: if an exception is set, the rest of the code does a bit of - # nonsense but nothing wrong (the return value should be ignored) - if calldescr.res_index < 0: - return None - elif calldescr.res_index == self.SIZE_GCPTR: - return BoxPtr(self.get_latest_value_ref(0)) - else: - return BoxInt(self.get_latest_value_int(0)) - - def do_cast_int_to_ptr(self, args, descr=None): - int = args[0].getint() - res = rffi.cast(llmemory.GCREF, int) - return BoxPtr(res) - - def do_cast_ptr_to_int(self, args, descr=None): - ptr = args[0].getref_base() - res = rffi.cast(lltype.Signed, ptr) - return BoxInt(res) - - -class SizeDescr(AbstractDescr): - def __init__(self, size): - self.size = size - -class FieldDescr(AbstractDescr): - def __init__(self, offset, size_index): - self.offset = offset - self.size_index = size_index # index in cpu.types_by_index - def is_pointer_field(self): - return self.size_index == LLVMCPU.SIZE_GCPTR - -class ArrayDescr(AbstractDescr): - def __init__(self, itemsize, itemsize_index): - self.itemsize = itemsize - self.itemsize_index = itemsize_index # index in cpu.types_by_index - self.ty_array_ptr = lltype.nullptr(llvm_rffi.LLVMTypeRef.TO) - # ^^^ set by setup_once() - def is_array_of_pointers(self): - return self.itemsize_index == LLVMCPU.SIZE_GCPTR - -class CallDescr(AbstractDescr): - ty_function_ptr = lltype.nullptr(llvm_rffi.LLVMTypeRef.TO) - args_indices = [0] # dummy value to make annotation happy - res_index = 0 - _generated_mp = None - # - def __init__(self, args_indices, res_index): - self.args_indices = args_indices # indices in cpu.types_by_index - self.res_index = res_index # index in cpu.types_by_index, or -1 - -# ____________________________________________________________ - -class BadSizeError(Exception): - pass - -import pypy.jit.metainterp.executor -pypy.jit.metainterp.executor.make_execute_list(LLVMCPU) diff --git a/pypy/jit/backend/llvm/test/__init__.py b/pypy/jit/backend/llvm/test/__init__.py deleted file mode 100644 diff --git a/pypy/jit/backend/llvm/test/conftest.py b/pypy/jit/backend/llvm/test/conftest.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/test/conftest.py +++ /dev/null @@ -1,4 +0,0 @@ -import py - -def pytest_ignore_collect(path): - return True diff --git a/pypy/jit/backend/llvm/test/test_1st.py b/pypy/jit/backend/llvm/test/test_1st.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/test/test_1st.py +++ /dev/null @@ -1,122 +0,0 @@ -import py -from pypy.jit.metainterp.history import ResOperation, BoxInt, ConstInt,\ - BoxPtr, ConstPtr, TreeLoop -from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.llvm.runner import LLVMCPU - - -def test_simple_case(): - v1 = BoxInt() - v2 = BoxInt() - v3 = BoxInt() - v4 = BoxInt() - loop = TreeLoop('test') - loop.inputargs = [v1] - loop.operations = [ - ResOperation(rop.INT_ADD, [v1, v1], v2), - ResOperation(rop.INT_INVERT, [v2], v3), - ResOperation(rop.UINT_RSHIFT, [v1, ConstInt(3)], v4), From noreply at buildbot.pypy.org Tue Oct 16 16:15:23 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 16 Oct 2012 16:15:23 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121016141523.1A40F1C1C86@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58138:b9b11f265aff Date: 2012-10-16 16:14 +0200 http://bitbucket.org/pypy/pypy/changeset/b9b11f265aff/ Log: merge heads diff too long, truncating to 2000 out of 14821 lines 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 @@ -661,7 +661,7 @@ raise operationerrfmt(space.w_ValueError, "Unknown order: %s", order) if isinstance(w_object, W_NDimArray): - if (not space.is_w(w_dtype, space.w_None) and + if (not space.is_none(w_dtype) and w_object.get_dtype() is not w_dtype): raise OperationError(space.w_NotImplementedError, space.wrap( "copying over different dtypes unsupported")) 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 @@ -424,39 +424,44 @@ self._done = True @jit.unroll_safe - def get_index(self, space): - return [space.wrap(i) for i in self.indexes] + def get_index(self, space, shapelen): + return [space.wrap(self.indexes[i]) for i in range(shapelen)] getitem_int_driver = jit.JitDriver(name = 'numpy_getitem_int', - greens = ['shapelen', 'indexlen', 'dtype'], + greens = ['shapelen', 'indexlen', + 'prefixlen', 'dtype'], reds = ['arr', 'res', 'iter', 'indexes_w', 'prefix_w']) def getitem_array_int(space, arr, res, iter_shape, indexes_w, prefix_w): shapelen = len(iter_shape) + prefixlen = len(prefix_w) indexlen = len(indexes_w) dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) + indexlen = len(indexes_w) while not iter.done(): getitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, dtype=dtype, arr=arr, res=res, iter=iter, indexes_w=indexes_w, - prefix_w=prefix_w) + prefix_w=prefix_w, + prefixlen=prefixlen) # prepare the index - index_w = [None] * len(indexes_w) - for i in range(len(indexes_w)): + index_w = [None] * indexlen + for i in range(indexlen): if iter.idx_w[i] is not None: index_w[i] = iter.idx_w[i].getitem() else: index_w[i] = indexes_w[i] - res.descr_setitem(space, space.newtuple(prefix_w + - iter.get_index(space)), + res.descr_setitem(space, space.newtuple(prefix_w[:prefixlen] + + iter.get_index(space, shapelen)), arr.descr_getitem(space, space.newtuple(index_w))) iter.next() return res setitem_int_driver = jit.JitDriver(name = 'numpy_setitem_int', - greens = ['shapelen', 'indexlen', 'dtype'], + greens = ['shapelen', 'indexlen', + 'prefixlen', 'dtype'], reds = ['arr', 'iter', 'indexes_w', 'prefix_w', 'val_arr']) @@ -464,21 +469,24 @@ prefix_w): shapelen = len(iter_shape) indexlen = len(indexes_w) + prefixlen = len(prefix_w) dtype = arr.get_dtype() iter = PureShapeIterator(iter_shape, indexes_w) while not iter.done(): setitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen, dtype=dtype, arr=arr, iter=iter, indexes_w=indexes_w, - prefix_w=prefix_w, val_arr=val_arr) + prefix_w=prefix_w, val_arr=val_arr, + prefixlen=prefixlen) # prepare the index - index_w = [None] * len(indexes_w) - for i in range(len(indexes_w)): + index_w = [None] * indexlen + for i in range(indexlen): if iter.idx_w[i] is not None: index_w[i] = iter.idx_w[i].getitem() else: index_w[i] = indexes_w[i] - w_idx = space.newtuple(prefix_w + iter.get_index(space)) + w_idx = space.newtuple(prefix_w[:prefixlen] + iter.get_index(space, + shapelen)) arr.descr_setitem(space, space.newtuple(index_w), val_arr.descr_getitem(space, w_idx)) iter.next() diff --git a/pypy/module/oracle/interp_cursor.py b/pypy/module/oracle/interp_cursor.py --- a/pypy/module/oracle/interp_cursor.py +++ b/pypy/module/oracle/interp_cursor.py @@ -1,5 +1,4 @@ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, unwrap_spec diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,24 +1,22 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import (PyCode, BytecodeCorruption, cpython_magic, +from pypy.interpreter.pycode import (BytecodeCorruption, cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) from pypy.interpreter.astcompiler.consts import CO_GENERATOR -class HostCode(PyCode): +class HostCode(object): """ A wrapper around a native code object of the host interpreter """ opnames = host_bytecode_spec.method_names - def __init__(self, space, argcount, nlocals, stacksize, flags, + def __init__(self, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, - name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic=cpython_magic): + name, firstlineno, lnotab, freevars): """Initialize a new code object""" - self.space = space self.co_name = name assert nlocals >= 0 self.co_argcount = argcount @@ -26,43 +24,39 @@ self.co_stacksize = stacksize self.co_flags = flags self.co_code = code - self.co_consts_w = consts - self.co_names_w = [space.wrap(aname) for aname in names] + self.consts = consts + self.names = names self.co_varnames = varnames self.co_freevars = freevars - self.co_cellvars = cellvars self.co_filename = filename self.co_name = name self.co_firstlineno = firstlineno self.co_lnotab = lnotab - self.hidden_applevel = hidden_applevel - self.magic = magic - self._signature = cpython_code_signature(self) - self._initialize() + self.signature = cpython_code_signature(self) - def _initialize(self): - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] + @classmethod + def _from_code(cls, code): + """Initialize the code object from a real (CPython) one. + """ + return cls(code.co_argcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + list(code.co_consts), + list(code.co_names), + list(code.co_varnames), + code.co_filename, + code.co_name, + code.co_firstlineno, + code.co_lnotab, + list(code.co_freevars)) - if self.co_cellvars: - argcount = self.co_argcount - assert argcount >= 0 # annotator hint - if self.co_flags & CO_VARARGS: - argcount += 1 - if self.co_flags & CO_VARKEYWORDS: - argcount += 1 - # Cell vars could shadow already-set arguments. - # See comment in PyCode._initialize() - argvars = self.co_varnames - cellvars = self.co_cellvars - for i in range(len(cellvars)): - cellname = cellvars[i] - for j in range(argcount): - if cellname == argvars[j]: - # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad - self._args_as_cellvars[i] = j + @property + def formalargcount(self): + """Total number of arguments passed into the frame, including *vararg + and **varkwarg, if they exist.""" + return self.signature.scope_length() def read(self, pos): """ diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -1,15 +1,18 @@ +"""Implements the core parts of flow graph creation, in tandem +with pypy.objspace.flow.objspace. +""" + +import sys import collections + from pypy.tool.error import source_lines from pypy.interpreter import pyframe -from pypy.interpreter.nestedscope import Cell -from pypy.interpreter.pycode import CO_NEWLOCALS from pypy.interpreter.argument import ArgumentsForTranslation from pypy.interpreter.pyopcode import Return, BytecodeCorruption from pypy.objspace.flow.model import (Constant, Variable, Block, Link, - UnwrapException, SpaceOperation, FunctionGraph, c_last_exception) + UnwrapException, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, recursively_flatten) -from pypy.objspace.flow.bytecode import HostCode from pypy.objspace.flow.specialcase import (rpython_print_item, rpython_print_newline) @@ -67,6 +70,14 @@ self.last_exception = last_exception def fixeggblocks(graph): + varnames = graph.func.func_code.co_varnames + for block in graph.iterblocks(): + if isinstance(block, SpamBlock): + for name, w_value in zip(varnames, block.framestate.mergeable): + if isinstance(w_value, Variable): + w_value.rename(name) + del block.framestate # memory saver + # EggBlocks reuse the variables of their previous block, # which is deemed not acceptable for simplicity of the operations # that will be performed later on the flow graph. @@ -87,9 +98,6 @@ for a in block.inputargs: mapping[a] = Variable(a) block.renamevariables(mapping) - for block in graph.iterblocks(): - if isinstance(link, SpamBlock): - del link.framestate # memory saver # ____________________________________________________________ @@ -98,9 +106,6 @@ def append(self, operation): raise NotImplementedError - def bytecode_trace(self, frame): - pass - def guessbool(self, frame, w_condition, **kwds): raise AssertionError, "cannot guessbool(%s)" % (w_condition,) @@ -110,31 +115,13 @@ def __init__(self, block): self.crnt_block = block - # saved state at the join point most recently seen - self.last_join_point = None - self.enterspamblock = isinstance(block, SpamBlock) + # Final frame state after the operations in the block + # If this is set, no new space op may be recorded. + self.final_state = None def append(self, operation): self.crnt_block.operations.append(operation) - def bytecode_trace(self, frame): - if self.enterspamblock: - # If we have a SpamBlock, the first call to bytecode_trace() - # occurs as soon as frame.resume() starts, before interpretation - # really begins. - varnames = frame.pycode.getvarnames() - for name, w_value in zip(varnames, frame.getfastscope()): - if isinstance(w_value, Variable): - w_value.rename(name) - self.enterspamblock = False - else: - # At this point, we progress to the next bytecode. When this - # occurs, we no longer allow any more operations to be recorded in - # the same block. We will continue, to figure out where the next - # such operation *would* appear, and we make a join point just - # before. - self.last_join_point = frame.getstate() - def guessbool(self, frame, w_condition): block = self.crnt_block vars = block.getvariables() @@ -235,69 +222,45 @@ class FlowSpaceFrame(pyframe.CPythonFrame): - def __init__(self, space, func, constargs=None): - code = HostCode._from_code(space, func.func_code) + def __init__(self, space, graph, code): + self.graph = graph + func = graph.func self.pycode = code self.space = space self.w_globals = Constant(func.func_globals) - self.locals_stack_w = [None] * (code.co_nlocals + code.co_stacksize) - self.valuestackdepth = code.co_nlocals self.lastblock = None - if func.func_closure is not None: - cl = [c.cell_contents for c in func.func_closure] - closure = [Cell(Constant(value)) for value in cl] - else: - closure = [] - self.initialize_frame_scopes(closure, code) + self.init_closure(func.func_closure) self.f_lineno = code.co_firstlineno self.last_instr = 0 - if constargs is None: - constargs = {} - formalargcount = code.getformalargcount() - arg_list = [Variable() for i in range(formalargcount)] - for position, value in constargs.items(): - arg_list[position] = Constant(value) - self.setfastscope(arg_list) - + self.init_locals_stack(code) self.w_locals = None # XXX: only for compatibility with PyFrame self.joinpoints = {} - self._init_graph(func) - self.pendingblocks = collections.deque([self.graph.startblock]) - def initialize_frame_scopes(self, closure, code): - if not (code.co_flags & CO_NEWLOCALS): - raise ValueError("The code object for a function should have " - "the flag CO_NEWLOCALS set.") - if len(closure) != len(code.co_freevars): - raise ValueError("code object received a closure with " - "an unexpected number of free variables") - self.cells = [Cell() for _ in code.co_cellvars] + closure + def init_closure(self, closure): + if closure is None: + self.closure = [] + else: + self.closure = [self.space.wrap(c.cell_contents) for c in closure] + assert len(self.closure) == len(self.pycode.co_freevars) - def _init_graph(self, func): - # CallableFactory.pycall may add class_ to functions that are methods - name = func.func_name - class_ = getattr(func, 'class_', None) - if class_ is not None: - name = '%s.%s' % (class_.__name__, name) - for c in "<>&!": - name = name.replace(c, '_') + def init_locals_stack(self, code): + """ + Initialize the locals and the stack. - initialblock = SpamBlock(self.getstate()) - if self.pycode.is_generator: - initialblock.operations.append( - SpaceOperation('generator_mark', [], Variable())) - graph = FunctionGraph(name, initialblock) - graph.func = func - # attach a signature and defaults to the graph - # so that it becomes even more interchangeable with the function - # itself - graph.signature = self.pycode.signature() - graph.defaults = func.func_defaults or () - graph.is_generator = self.pycode.is_generator - self.graph = graph + The locals are ordered according to self.pycode.signature. + """ + self.valuestackdepth = code.co_nlocals + self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals) + + def save_locals_stack(self): + return self.locals_stack_w[:self.valuestackdepth] + + def restore_locals_stack(self, items_w): + self.locals_stack_w[:len(items_w)] = items_w + self.dropvaluesuntil(len(items_w)) def getstate(self): # getfastscope() can return real None, for undefined locals @@ -309,9 +272,7 @@ data.append(self.last_exception.w_type) data.append(self.last_exception.w_value) recursively_flatten(self.space, data) - nonmergeable = (self.get_blocklist(), - self.last_instr) # == next_instr when between bytecodes - return FrameState(data, nonmergeable) + return FrameState(data, self.get_blocklist(), self.last_instr) def setstate(self, state): """ Reset the frame to the given state. """ @@ -323,8 +284,8 @@ self.last_exception = None else: self.last_exception = FSException(data[-2], data[-1]) - blocklist, self.last_instr = state.nonmergeable - self.set_blocklist(blocklist) + self.last_instr = state.next_instr + self.set_blocklist(state.blocklist) def recording(self, block): """ Setup recording of the block and return the recorder. """ @@ -347,8 +308,8 @@ def record(self, spaceop): """Record an operation into the active block""" recorder = self.recorder - if getattr(recorder, 'last_join_point', None) is not None: - self.mergeblock(recorder.crnt_block, recorder.last_join_point) + if getattr(recorder, 'final_state', None) is not None: + self.mergeblock(recorder.crnt_block, recorder.final_state) raise StopFlowing recorder.append(spaceop) @@ -369,14 +330,16 @@ return self.recorder.guessexception(self, *exceptions) def build_flow(self): + graph = self.graph + self.pendingblocks = collections.deque([graph.startblock]) while self.pendingblocks: block = self.pendingblocks.popleft() try: self.recorder = self.recording(block) self.frame_finished_execution = False - next_instr = self.last_instr while True: - next_instr = self.handle_bytecode(next_instr) + self.last_instr = self.handle_bytecode(self.last_instr) + self.recorder.final_state = self.getstate() except ImplicitOperationError, e: if isinstance(e.w_type, Constant): @@ -386,14 +349,14 @@ msg = "implicit %s shouldn't occur" % exc_cls.__name__ w_type = Constant(AssertionError) w_value = Constant(AssertionError(msg)) - link = Link([w_type, w_value], self.graph.exceptblock) + link = Link([w_type, w_value], graph.exceptblock) self.recorder.crnt_block.closeblock(link) except FSException, e: if e.w_type is 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([e.w_type, e.w_value], graph.exceptblock) self.recorder.crnt_block.closeblock(link) except StopFlowing: @@ -402,7 +365,7 @@ except Return: w_result = self.popvalue() assert w_result is not None - link = Link([w_result], self.graph.returnblock) + link = Link([w_result], graph.returnblock) self.recorder.crnt_block.closeblock(link) del self.recorder @@ -414,37 +377,35 @@ candidates = self.joinpoints.setdefault(next_instr, []) for block in candidates: newstate = block.framestate.union(currentstate) - if newstate is not None: - # yes - finished = newstate == block.framestate + if newstate is None: + continue + elif newstate == block.framestate: + outputargs = currentstate.getoutputargs(newstate) + currentblock.closeblock(Link(outputargs, block)) + return + else: break else: - # no newstate = currentstate.copy() - finished = False block = None - if finished: - newblock = block - else: - newblock = SpamBlock(newstate) + newblock = SpamBlock(newstate) # unconditionally link the current block to the newblock outputargs = currentstate.getoutputargs(newstate) link = Link(outputargs, newblock) currentblock.closeblock(link) - # phew - if not finished: - if block is not None: - # to simplify the graph, we patch the old block to point - # directly at the new block which is its generalization - block.dead = True - block.operations = () - block.exitswitch = None - outputargs = block.framestate.getoutputargs(newstate) - block.recloseblock(Link(outputargs, newblock)) - candidates.remove(block) - candidates.insert(0, newblock) - self.pendingblocks.append(newblock) + + if block is not None: + # to simplify the graph, we patch the old block to point + # directly at the new block which is its generalization + block.dead = True + block.operations = () + block.exitswitch = None + outputargs = block.framestate.getoutputargs(newstate) + block.recloseblock(Link(outputargs, newblock)) + candidates.remove(block) + candidates.insert(0, newblock) + self.pendingblocks.append(newblock) # hack for unrolling iterables, don't use this def replace_in_stack(self, oldvalue, newvalue): @@ -460,17 +421,12 @@ break def handle_bytecode(self, next_instr): + next_instr, methodname, oparg = self.pycode.read(next_instr) try: - while True: - self.last_instr = next_instr - self.recorder.bytecode_trace(self) - next_instr, methodname, oparg = self.pycode.read(next_instr) - res = getattr(self, methodname)(oparg, next_instr) - if res is not None: - next_instr = res + res = getattr(self, methodname)(oparg, next_instr) + return res if res is not None else next_instr except FSException, operr: - next_instr = self.handle_operation_error(operr) - return next_instr + return self.handle_operation_error(operr) def handle_operation_error(self, operr): block = self.unrollstack(SApplicationException.kind) @@ -481,6 +437,18 @@ next_instr = block.handle(self, unroller) return next_instr + def getlocalvarname(self, index): + return self.pycode.co_varnames[index] + + def getconstant_w(self, index): + return self.space.wrap(self.pycode.consts[index]) + + def getname_u(self, index): + return self.pycode.names[index] + + def getname_w(self, index): + return Constant(self.pycode.names[index]) + def BAD_OPCODE(self, _, next_instr): raise FlowingError(self, "This operation is not RPython") @@ -685,19 +653,13 @@ # Note: RPython context managers receive None in lieu of tracebacks # and cannot suppress the exception. # This opcode changed a lot between CPython versions - if (self.pycode.magic >= 0xa0df2ef - # Implementation since 2.7a0: 62191 (introduce SETUP_WITH) - or self.pycode.magic >= 0xa0df2d1): - # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization) + if sys.version_info >= (2, 6): w_unroller = self.popvalue() w_exitfunc = self.popvalue() self.pushvalue(w_unroller) - elif self.pycode.magic >= 0xa0df28c: - # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode) + else: w_exitfunc = self.popvalue() w_unroller = self.peekvalue(0) - else: - raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4") unroller = self.space.unwrap(w_unroller) w_None = self.space.w_None @@ -710,6 +672,12 @@ else: self.space.call_function(w_exitfunc, w_None, w_None, w_None) + def LOAD_FAST(self, varindex, next_instr): + w_value = self.locals_stack_w[varindex] + if w_value is None: + raise FlowingError(self, "Local variable referenced before assignment") + self.pushvalue(w_value) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) @@ -722,6 +690,9 @@ self.pushvalue(w_value) LOOKUP_METHOD = LOAD_ATTR + def LOAD_DEREF(self, varindex, next_instr): + self.pushvalue(self.closure[varindex]) + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. @@ -729,6 +700,12 @@ self.pushvalue(self.space.newlist([])) self.pushvalue(last_val) + def MAKE_FUNCTION(self, numdefaults, next_instr): + w_codeobj = self.popvalue() + defaults = self.popvalues(numdefaults) + fn = self.space.newfunction(w_codeobj, self.w_globals, defaults) + self.pushvalue(fn) + # XXX Unimplemented 2.7 opcodes ---------------- # Set literals, set comprehensions @@ -744,6 +721,12 @@ def MAP_ADD(self, oparg, next_instr): raise NotImplementedError("MAP_ADD") + # Closures + + STORE_DEREF = BAD_OPCODE + LOAD_CLOSURE = BAD_OPCODE + MAKE_CLOSURE = BAD_OPCODE + def make_arguments(self, nargs): return ArgumentsForTranslation(self.space, self.peekvalues(nargs)) def argument_factory(self, *args): diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -2,10 +2,10 @@ from pypy.objspace.flow.model import * class FrameState: - def __init__(self, mergeable, nonmergeable): + def __init__(self, mergeable, blocklist, next_instr): self.mergeable = mergeable - self.nonmergeable = nonmergeable - self.next_instr = self.nonmergeable[1] + self.blocklist = blocklist + self.next_instr = next_instr for w1 in self.mergeable: assert isinstance(w1, (Variable, Constant)) or w1 is None, ( '%r found in frame state' % w1) @@ -17,7 +17,7 @@ if isinstance(w, Variable): w = Variable() newstate.append(w) - return FrameState(newstate, self.nonmergeable) + return FrameState(newstate, self.blocklist, self.next_instr) def getvariables(self): return [w for w in self.mergeable if isinstance(w, Variable)] @@ -29,7 +29,8 @@ # nonmergeable states assert isinstance(other, FrameState) assert len(self.mergeable) == len(other.mergeable) - assert self.nonmergeable == other.nonmergeable + assert self.blocklist == other.blocklist + assert self.next_instr == other.next_instr for w1, w2 in zip(self.mergeable, other.mergeable): if not (w1 == w2 or (isinstance(w1, Variable) and isinstance(w2, Variable))): @@ -50,7 +51,7 @@ newstate.append(union(w1, w2)) except UnionError: return None - return FrameState(newstate, self.nonmergeable) + return FrameState(newstate, self.blocklist, self.next_instr) def getoutputargs(self, targetstate): "Return the output arguments needed to link self to targetstate." diff --git a/pypy/objspace/flow/generator.py b/pypy/objspace/flow/generator.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/flow/generator.py @@ -0,0 +1,186 @@ +"""Flow graph building for generators""" + +from pypy.objspace.flow.model import Block, Link, SpaceOperation, checkgraph +from pypy.objspace.flow.model import Variable, Constant +from pypy.translator.unsimplify import insert_empty_startblock +from pypy.translator.unsimplify import split_block +from pypy.translator.simplify import eliminate_empty_blocks, simplify_graph +from pypy.tool.sourcetools import func_with_new_name +from pypy.interpreter.argument import Signature + + +class AbstractPosition(object): + _immutable_ = True + _attrs_ = () + +def bootstrap_generator(graph): + # This is the first copy of the graph. We replace it with + # a small bootstrap graph. + GeneratorIterator = make_generatoriterator_class(graph) + replace_graph_with_bootstrap(GeneratorIterator, graph) + # We attach a 'next' method to the GeneratorIterator class + # that will invoke the real function, based on a second + # copy of the graph. + attach_next_method(GeneratorIterator, graph) + return graph + +def tweak_generator_graph(graph): + # This is the second copy of the graph. Tweak it. + GeneratorIterator = graph.func._generator_next_method_of_ + tweak_generator_body_graph(GeneratorIterator.Entry, graph) + + +def make_generatoriterator_class(graph): + class GeneratorIterator(object): + class Entry(AbstractPosition): + _immutable_ = True + varnames = get_variable_names(graph.startblock.inputargs) + + def __init__(self, entry): + self.current = entry + + def __iter__(self): + return self + + return GeneratorIterator + +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)) + 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)) + graph.startblock = newblock + +def attach_next_method(GeneratorIterator, graph): + func = graph.func + func = func_with_new_name(func, '%s__next' % (func.func_name,)) + func._generator_next_method_of_ = GeneratorIterator + func._always_inline_ = True + # + def next(self): + entry = self.current + self.current = None + assert entry is not None # else, recursive generator invocation + (next_entry, return_value) = func(entry) + self.current = next_entry + return return_value + GeneratorIterator.next = next + return func # for debugging + +def get_variable_names(variables): + seen = set() + result = [] + for v in variables: + name = v._name.strip('_') + while name in seen: + name += '_' + result.append('g_' + name) + seen.add(name) + return result + +def _insert_reads(block, varnames): + 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])) + block.inputargs = [v_entry1] + +def tweak_generator_body_graph(Entry, graph): + # First, always run simplify_graph in order to reduce the number of + # variables passed around + simplify_graph(graph) + # + assert graph.startblock.operations[0].opname == 'generator_mark' + graph.startblock.operations.pop(0) + # + insert_empty_startblock(None, graph) + _insert_reads(graph.startblock, Entry.varnames) + Entry.block = graph.startblock + # + 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)) + # + for block in list(graph.iterblocks()): + for exit in block.exits: + if exit.target is graph.returnblock: + exit.args = [] + 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 + del block.operations[index] + newlink = split_block(None, block, index) + newblock = newlink.target + # + class Resume(AbstractPosition): + _immutable_ = True + block = newblock + Resume.__name__ = 'Resume%d' % len(mappings) + mappings.append(Resume) + varnames = get_variable_names(newlink.args) + # + _insert_reads(newblock, varnames) + # + v_resume = Variable('resume') + block.operations.append( + SpaceOperation('simple_call', [Constant(Resume)], + v_resume)) + 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] + 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 + link1 = Link([block.inputargs[0]], Resume.block) + link1.exitcase = True + nextblock = Block([Variable('entry')]) + link2 = Link([block.inputargs[0]], nextblock) + link2.exitcase = False + block.closeblock(link1, link2) + block = nextblock + block.closeblock(Link([Constant(AssertionError), + Constant(AssertionError("bad generator class"))], + graph.exceptblock)) + graph.startblock = regular_entry_block + graph.signature = Signature(['entry']) + graph.defaults = () + checkgraph(graph) + eliminate_empty_blocks(graph) diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -1,14 +1,23 @@ -# ______________________________________________________________________ +"""Implements the core parts of flow graph creation, in tandem +with pypy.objspace.flow.flowcontext. +""" + import __builtin__ import sys import types +from inspect import CO_NEWLOCALS + from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.argument import ArgumentsForTranslation from pypy.objspace.flow.model import (Constant, Variable, WrapException, UnwrapException, checkgraph, SpaceOperation) +from pypy.objspace.flow.bytecode import HostCode from pypy.objspace.flow import operation from pypy.objspace.flow.flowcontext import (FlowSpaceFrame, fixeggblocks, FSException, FlowingError) +from pypy.objspace.flow.generator import (tweak_generator_graph, + bootstrap_generator) +from pypy.objspace.flow.pygraph import PyGraph from pypy.objspace.flow.specialcase import SPECIAL_CASES from pypy.rlib.unroll import unrolling_iterable, _unroller from pypy.rlib import rstackovf, rarithmetic @@ -37,6 +46,17 @@ } } +def _assert_rpythonic(func): + """Raise ValueError if ``func`` is obviously not RPython""" + if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): + raise ValueError("%r is tagged as NOT_RPYTHON" % (func,)) + if func.func_code.co_cellvars: + raise ValueError("RPython functions cannot create closures") + if not (func.func_code.co_flags & CO_NEWLOCALS): + raise ValueError("The code object for a RPython function should have " + "the flag CO_NEWLOCALS set.") + + # ______________________________________________________________________ class FlowObjSpace(object): """NOT_RPYTHON. @@ -94,6 +114,17 @@ else: return self.w_False + def newfunction(self, w_code, w_globals, defaults_w): + try: + code = self.unwrap(w_code) + globals = self.unwrap(w_globals) + defaults = tuple([self.unwrap(value) for value in defaults_w]) + except UnwrapException: + raise FlowingError(self.frame, "Dynamically created function must" + " have constant default values.") + fn = types.FunctionType(code, globals, code.co_name, defaults) + return Constant(fn) + def wrap(self, obj): if isinstance(obj, (Variable, Constant)): raise TypeError("already wrapped: " + repr(obj)) @@ -232,18 +263,25 @@ w_type = w_instclass return FSException(w_type, w_value) - def build_flow(self, func, constargs={}, tweak_for_generator=True): + def build_flow(self, func): """ """ - if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): - raise Exception, "%r is tagged as NOT_RPYTHON" % (func,) - frame = self.frame = FlowSpaceFrame(self, func, constargs) + _assert_rpythonic(func) + code = HostCode._from_code(func.func_code) + if (code.is_generator and + not hasattr(func, '_generator_next_method_of_')): + graph = PyGraph(func, code) + block = graph.startblock + for name, w_value in zip(code.co_varnames, block.framestate.mergeable): + if isinstance(w_value, Variable): + w_value.rename(name) + return bootstrap_generator(graph) + graph = PyGraph(func, code) + frame = self.frame = FlowSpaceFrame(self, graph, code) frame.build_flow() - graph = frame.graph fixeggblocks(graph) checkgraph(graph) - if graph.is_generator and tweak_for_generator: - from pypy.translator.generator import tweak_generator_graph + if code.is_generator: tweak_generator_graph(graph) return graph diff --git a/pypy/objspace/flow/pygraph.py b/pypy/objspace/flow/pygraph.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/flow/pygraph.py @@ -0,0 +1,39 @@ +""" +Implements flow graphs for Python callables +""" +from pypy.objspace.flow.model import (FunctionGraph, Constant, Variable, + SpaceOperation) +from pypy.objspace.flow.framestate import FrameState + +class PyGraph(FunctionGraph): + """ + Flow graph for a Python function + """ + + def __init__(self, func, code): + from pypy.objspace.flow.flowcontext import SpamBlock + data = [None] * code.co_nlocals + for i in range(code.formalargcount): + data[i] = Variable() + state = FrameState(data + [Constant(None), Constant(None)], [], 0) + initialblock = SpamBlock(state) + if code.is_generator: + initialblock.operations.append( + SpaceOperation('generator_mark', [], Variable())) + + super(PyGraph, self).__init__(self._sanitize_funcname(func), initialblock) + self.func = func + self.signature = code.signature + self.defaults = func.func_defaults or () + + @staticmethod + def _sanitize_funcname(func): + # CallableFactory.pycall may add class_ to functions that are methods + name = func.func_name + class_ = getattr(func, 'class_', None) + if class_ is not None: + name = '%s.%s' % (class_.__name__, name) + for c in "<>&!": + name = name.replace(c, '_') + return name + diff --git a/pypy/objspace/flow/test/test_framestate.py b/pypy/objspace/flow/test/test_framestate.py --- a/pypy/objspace/flow/test/test_framestate.py +++ b/pypy/objspace/flow/test/test_framestate.py @@ -2,6 +2,8 @@ from pypy.rlib.unroll import SpecTag from pypy.objspace.flow.objspace import FlowObjSpace from pypy.objspace.flow.flowcontext import FlowSpaceFrame +from pypy.objspace.flow.bytecode import HostCode +from pypy.objspace.flow.pygraph import PyGraph class TestFrameState: def setup_class(cls): @@ -12,8 +14,11 @@ func = func.im_func except AttributeError: pass - frame = FlowSpaceFrame(self.space, func) + code = HostCode._from_code(func.func_code) + graph = PyGraph(func, code) + frame = FlowSpaceFrame(self.space, graph, code) # hack the frame + frame.setstate(graph.startblock.framestate) frame.locals_stack_w[frame.pycode.co_nlocals-1] = Constant(None) return frame diff --git a/pypy/objspace/flow/test/test_generator.py b/pypy/objspace/flow/test/test_generator.py --- a/pypy/objspace/flow/test/test_generator.py +++ b/pypy/objspace/flow/test/test_generator.py @@ -1,18 +1,127 @@ -from pypy.objspace.flow.test.test_objspace import Base +from pypy.conftest import option +from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.objspace.flow.model import Variable +from pypy.objspace.flow.generator import (make_generatoriterator_class, + replace_graph_with_bootstrap, get_variable_names, attach_next_method) +from pypy.translator.simplify import join_blocks -class TestGenerator(Base): +# ____________________________________________________________ - def test_simple_generator(self): - def f(n): +def f_gen(n): + i = 0 + while i < n: + yield i + i += 1 + +class GeneratorIterator(object): + def __init__(self, entry): + self.current = entry + def next(self): + e = self.current + self.current = None + if isinstance(e, Yield1): + n = e.n_0 + i = e.i_0 + i += 1 + else: + n = e.n_0 i = 0 - while i < n: - yield i - yield i - i += 1 - graph = self.codetest(f, tweak_for_generator=False) - ops = self.all_operations(graph) - assert ops == {'generator_mark': 1, - 'lt': 1, 'is_true': 1, - 'yield': 2, - 'inplace_add': 1} + if i < n: + e = Yield1() + e.n_0 = n + e.i_0 = i + self.current = e + return i + raise StopIteration + + def __iter__(self): + return self + +class AbstractPosition(object): + _immutable_ = True +class Entry1(AbstractPosition): + _immutable_ = True +class Yield1(AbstractPosition): + _immutable_ = True + +def f_explicit(n): + e = Entry1() + e.n_0 = n + return GeneratorIterator(e) + +def test_explicit(): + assert list(f_gen(10)) == list(f_explicit(10)) + +def test_get_variable_names(): + lst = get_variable_names([Variable('a'), Variable('b_'), Variable('a')]) + assert lst == ['g_a', 'g_b', 'g_a_'] + +# ____________________________________________________________ + + +class TestGenerator: + + def test_replace_graph_with_bootstrap(self): + def func(n, x, y, z): + yield n + yield n + # + graph = FlowObjSpace().build_flow(func) + if option.view: + graph.show() + block = graph.startblock + ops = block.operations + assert ops[0].opname == 'simple_call' # e = Entry1() + assert ops[1].opname == 'setattr' # e.g_n = n + assert ops[1].args[1].value == 'g_n' + assert ops[2].opname == 'setattr' # e.g_x = x + assert ops[2].args[1].value == 'g_x' + assert ops[3].opname == 'setattr' # e.g_y = y + assert ops[3].args[1].value == 'g_y' + assert ops[4].opname == 'setattr' # e.g_z = z + assert ops[4].args[1].value == 'g_z' + assert ops[5].opname == 'simple_call' # g = GeneratorIterator(e) + assert ops[5].args[1] == ops[0].result + assert len(ops) == 6 + assert len(block.exits) == 1 + assert block.exits[0].target is graph.returnblock + + def test_tweak_generator_graph(self): + def f(n, x, y, z): + z *= 10 + yield n + 1 + z -= 10 + # + space = FlowObjSpace() + graph = space.build_flow(f) + GeneratorIterator = make_generatoriterator_class(graph) + replace_graph_with_bootstrap(GeneratorIterator, graph) + func1 = attach_next_method(GeneratorIterator, graph) + if option.view: + graph.show() + # + assert func1._generator_next_method_of_ is GeneratorIterator + assert hasattr(GeneratorIterator, 'next') + # + graph_next = space.build_flow(GeneratorIterator.next.im_func) + join_blocks(graph_next) + if option.view: + graph_next.show() + # + graph1 = space.build_flow(func1) + if option.view: + graph1.show() + + def test_automatic(self): + def f(n, x, y, z): + z *= 10 + yield n + 1 + z -= 10 + # + graph = FlowObjSpace().build_flow(f) + if option.view: + graph.show() + block = graph.startblock + assert len(block.exits) == 1 + assert block.exits[0].target is graph.returnblock diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1054,6 +1054,80 @@ with py.test.raises(FlowingError): self.codetest(f) + @py.test.mark.xfail(reason="closures aren't supported") + def test_cellvar_store(self): + def f(): + x = 5 + return x + lambda: x # turn x into a cell variable + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + + @py.test.mark.xfail(reason="closures aren't supported") + def test_arg_as_cellvar(self): + def f(x, y, z): + a, b, c = 1, 2, 3 + z = b + return z + lambda: (a, b, x, z) # make cell variables + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + assert not graph.startblock.operations + assert graph.startblock.exits[0].args[0].value == 2 + + def test_lambda(self): + def f(): + g = lambda m, n: n*m + return g + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + g = graph.startblock.exits[0].args[0].value + assert g(4, 4) == 16 + + def test_lambda_with_defaults(self): + def f(): + g = lambda m, n=5: n*m + return g + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + g = graph.startblock.exits[0].args[0].value + assert g(4) == 20 + + def f2(x): + g = lambda m, n=x: n*m + return g + with py.test.raises(FlowingError): + self.codetest(f2) + + @py.test.mark.xfail(reason="closures aren't supported") + def test_closure(self): + def f(): + m = 5 + return lambda n: m * n + graph = self.codetest(f) + assert len(graph.startblock.exits) == 1 + assert graph.startblock.exits[0].target == graph.returnblock + g = graph.startblock.exits[0].args[0].value + assert g(4) == 20 + + def test_closure_error(self): + def f(): + m = 5 + return lambda n: m * n + with py.test.raises(ValueError) as excinfo: + self.codetest(f) + assert "closure" in str(excinfo.value) + + def test_unbound_local(self): + def f(): + x += 1 + with py.test.raises(FlowingError): + self.codetest(f) + DATA = {'x': 5, 'y': 6} diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py --- a/pypy/objspace/std/bytearraytype.py +++ b/pypy/objspace/std/bytearraytype.py @@ -1,7 +1,6 @@ -import sys -from pypy.interpreter import gateway from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import interp2app from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, SMM @@ -163,9 +162,9 @@ bytearray(sequence) -> bytearray initialized from sequence\'s items If the argument is a bytearray, the return value is the same object.''', - __new__ = gateway.interp2app(descr__new__), + __new__ = interp2app(descr__new__), __hash__ = None, - __reduce__ = gateway.interp2app(descr_bytearray__reduce__), - fromhex = gateway.interp2app(descr_fromhex, as_classmethod=True) + __reduce__ = interp2app(descr_bytearray__reduce__), + fromhex = interp2app(descr_fromhex, as_classmethod=True) ) bytearray_typedef.registermethods(globals()) diff --git a/pypy/rlib/rcomplex.py b/pypy/rlib/rcomplex.py --- a/pypy/rlib/rcomplex.py +++ b/pypy/rlib/rcomplex.py @@ -57,6 +57,9 @@ denom = r2 + i2 * ratio rr = (r1 + i1 * ratio) / denom ir = (i1 - r1 * ratio) / denom + elif isnan(r2): + rr = NAN + ir = NAN else: ratio = r2 / i2 denom = r2 * ratio + i2 diff --git a/pypy/rlib/test/test_rcomplex.py b/pypy/rlib/test/test_rcomplex.py --- a/pypy/rlib/test/test_rcomplex.py +++ b/pypy/rlib/test/test_rcomplex.py @@ -33,6 +33,9 @@ ]: assert c.c_mul(c1, c2) == result +def test_div(): + c.c_div((2., 3.), (float('nan'), 0.)) == (float('nan'), float('nan')) + def parse_testfile2(fname): """Parse a file with test values diff --git a/pypy/rpython/microbench/__init__.py b/pypy/rpython/microbench/__init__.py deleted file mode 100644 diff --git a/pypy/rpython/microbench/autopath.py b/pypy/rpython/microbench/autopath.py deleted file mode 100644 --- a/pypy/rpython/microbench/autopath.py +++ /dev/null @@ -1,131 +0,0 @@ -""" -self cloning, automatic path configuration - -copy this into any subdirectory of pypy from which scripts need -to be run, typically all of the test subdirs. -The idea is that any such script simply issues - - import autopath - -and this will make sure that the parent directory containing "pypy" -is in sys.path. - -If you modify the master "autopath.py" version (in pypy/tool/autopath.py) -you can directly run it which will copy itself on all autopath.py files -it finds under the pypy root directory. - -This module always provides these attributes: - - pypydir pypy root directory path - this_dir directory where this autopath.py resides - -""" - -def __dirinfo(part): - """ return (partdir, this_dir) and insert parent of partdir - into sys.path. If the parent directories don't have the part - an EnvironmentError is raised.""" - - import sys, os - try: - head = this_dir = os.path.realpath(os.path.dirname(__file__)) - except NameError: - head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0])) - - error = None - while head: - partdir = head - head, tail = os.path.split(head) - if tail == part: - checkfile = os.path.join(partdir, os.pardir, 'pypy', '__init__.py') - if not os.path.exists(checkfile): - error = "Cannot find %r" % (os.path.normpath(checkfile),) - break - else: - error = "Cannot find the parent directory %r of the path %r" % ( - partdir, this_dir) - if not error: - # check for bogus end-of-line style (e.g. files checked out on - # Windows and moved to Unix) - f = open(__file__.replace('.pyc', '.py'), 'r') - data = f.read() - f.close() - if data.endswith('\r\n') or data.endswith('\r'): - error = ("Bad end-of-line style in the .py files. Typically " - "caused by a zip file or a checkout done on Windows and " - "moved to Unix or vice-versa.") - if error: - raise EnvironmentError("Invalid source tree - bogus checkout! " + - error) - - pypy_root = os.path.join(head, '') - try: - sys.path.remove(head) - except ValueError: - pass - sys.path.insert(0, head) - - munged = {} - for name, mod in sys.modules.items(): - if '.' in name: - continue - fn = getattr(mod, '__file__', None) - if not isinstance(fn, str): - continue - newname = os.path.splitext(os.path.basename(fn))[0] - if not newname.startswith(part + '.'): - continue - path = os.path.join(os.path.dirname(os.path.realpath(fn)), '') - if path.startswith(pypy_root) and newname != part: - modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep) - if newname != '__init__': - modpaths.append(newname) - modpath = '.'.join(modpaths) - if modpath not in sys.modules: - munged[modpath] = mod - - for name, mod in munged.iteritems(): - if name not in sys.modules: - sys.modules[name] = mod - if '.' in name: - prename = name[:name.rfind('.')] - postname = name[len(prename)+1:] - if prename not in sys.modules: - __import__(prename) - if not hasattr(sys.modules[prename], postname): - setattr(sys.modules[prename], postname, mod) - - return partdir, this_dir - -def __clone(): - """ clone master version of autopath.py into all subdirs """ - from os.path import join, walk - if not this_dir.endswith(join('pypy','tool')): - raise EnvironmentError("can only clone master version " - "'%s'" % join(pypydir, 'tool',_myname)) - - - def sync_walker(arg, dirname, fnames): - if _myname in fnames: - fn = join(dirname, _myname) - f = open(fn, 'rwb+') - try: - if f.read() == arg: - print "checkok", fn - else: - print "syncing", fn - f = open(fn, 'w') - f.write(arg) - finally: - f.close() - s = open(join(pypydir, 'tool', _myname), 'rb').read() - walk(pypydir, sync_walker, s) - -_myname = 'autopath.py' - -# set guaranteed attributes - -pypydir, this_dir = __dirinfo('pypy') - -if __name__ == '__main__': - __clone() diff --git a/pypy/rpython/microbench/dict.py b/pypy/rpython/microbench/dict.py deleted file mode 100644 --- a/pypy/rpython/microbench/dict.py +++ /dev/null @@ -1,65 +0,0 @@ -from pypy.rpython.microbench.microbench import MetaBench - -class str_dict__set_item: - __metaclass__ = MetaBench - - def init(): - return {} - args = ['obj', 'i'] - def loop(obj, i): - obj['foo'] = i - obj['bar'] = i - -class str_dict__get_item: - __metaclass__ = MetaBench - - def init(): - return {'foo': 0, 'bar': 1} - args = ['obj', 'i'] - def loop(obj, i): - return obj['foo'] + obj['bar'] - -class int_dict__set_item: - __metaclass__ = MetaBench - - def init(): - return {} - args = ['obj', 'i'] - def loop(obj, i): - obj[42] = i - obj[43] = i - -class int_dict__get_item: - __metaclass__ = MetaBench - - def init(): - return {42: 0, 43: 1} - args = ['obj', 'i'] - def loop(obj, i): - return obj[42] + obj[43] - - -class Foo: - pass - -obj1 = Foo() -obj2 = Foo() - -class obj_dict__set_item: - __metaclass__ = MetaBench - - def init(): - return {} - args = ['obj', 'i'] - def loop(obj, i): - obj[obj1] = i - obj[obj2] = i - -class obj_dict__get_item: - __metaclass__ = MetaBench - - def init(): - return {obj1: 0, obj2: 1} - args = ['obj', 'i'] - def loop(obj, i): - return obj[obj1] + obj[obj2] diff --git a/pypy/rpython/microbench/indirect.py b/pypy/rpython/microbench/indirect.py deleted file mode 100644 --- a/pypy/rpython/microbench/indirect.py +++ /dev/null @@ -1,24 +0,0 @@ -from pypy.rpython.microbench.microbench import MetaBench - -def f1(x): - return x - -def f2(x): - return x+1 - -def f3(x): - return x+2 - -def f4(x): - return x+3 - -FUNCS = [f1, f2, f3, f4] - -class indirect__call: - __metaclass__ = MetaBench - - def init(): - return FUNCS - args = ['obj', 'i'] - def loop(obj, i): - return obj[i%4](i) diff --git a/pypy/rpython/microbench/list.py b/pypy/rpython/microbench/list.py deleted file mode 100644 --- a/pypy/rpython/microbench/list.py +++ /dev/null @@ -1,79 +0,0 @@ -from pypy.rpython.microbench.microbench import MetaBench - -class list__append: - __metaclass__ = MetaBench - def init(): - return [] - args = ['obj', 'i'] - def loop(obj, i): - obj.append(i) - -class list__get_item: - __metaclass__ = MetaBench - LOOPS = 100000000 - def init(): - obj = [] - for i in xrange(1000): - obj.append(i) - return obj - args = ['obj', 'i'] - def loop(obj, i): - return obj[i%1000] - -class list__set_item: - __metaclass__ = MetaBench - LOOPS = 100000000 - def init(): - obj = [] - for i in xrange(1000): - obj.append(i) - return obj - args = ['obj', 'i'] - def loop(obj, i): - obj[i%1000] = i - -class fixed_list__get_item: - __metaclass__ = MetaBench - LOOPS = 100000000 - def init(): - return [0] * 1000 - args = ['obj', 'i'] - def loop(obj, i): - return obj[i%1000] - -class fixed_list__set_item: - __metaclass__ = MetaBench - LOOPS = 100000000 - def init(): - return [0] * 1000 - args = ['obj', 'i'] - def loop(obj, i): - obj[i%1000] = i - -class list__iteration__int: - __metaclass__ = MetaBench - LOOPS = 100000 - def init(): - obj = [0]*1000 - obj[0] = 42 - return obj - args = ['obj'] - def loop(obj): - tot = 0 - for item in obj: - tot += item - return tot - -class list__iteration__string: - __metaclass__ = MetaBench - LOOPS = 100000 - def init(): - obj = ['foo']*1000 - obj[0] = 'bar' - return obj - args = ['obj'] - def loop(obj): - tot = 0 - for item in obj: - tot += len(item) - return tot diff --git a/pypy/rpython/microbench/microbench.py b/pypy/rpython/microbench/microbench.py deleted file mode 100644 --- a/pypy/rpython/microbench/microbench.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python - -import sys -import autopath -from time import clock -import subprocess -from pypy.translator.interactive import Translation - -LOOPS = 10000000 - -class MetaBench(type): - def __new__(self, cls_name, bases, cls_dict): - loop = cls_dict['loop'] - loop._dont_inline_ = True - myglob = { - 'init': cls_dict['init'], - 'loop': loop, - 'LOOPS': cls_dict.get('LOOPS', LOOPS), - 'clock': clock, - } - args = ', '.join(cls_dict['args']) - source = """ -def %(cls_name)s(): - obj = init() - start = clock() - for i in xrange(LOOPS): - loop(%(args)s) - return clock() - start -""" % locals() - exec source in myglob - func = myglob[cls_name] - func.benchmark = True - return func - - -def run_benchmark(exe): - from pypy.translator.cli.test.runtest import CliFunctionWrapper - from pypy.translator.jvm.test.runtest import JvmGeneratedSourceWrapper - - if exe.__class__ in [CliFunctionWrapper,JvmGeneratedSourceWrapper]: - stdout, stderr, retval = exe.run() - else: - assert isinstance(exe, str) - bench = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = bench.communicate() - retval = bench.wait() - - if retval != 0: - print 'Running benchmark failed' - print 'Standard Output:' - print stdout - print '-' * 40 - print 'Standard Error:' - print stderr - raise SystemExit(-1) - - mydict = {} - for line in stdout.splitlines(): - name, res = line.split(':') - mydict[name.strip()] = float(res) - return mydict - -def import_benchmarks(): - modules = sys.argv[1:] - if len(modules) == 0: - # import all the microbenchs - from glob import glob - for module in glob('*.py'): - if module not in ('__init__.py', 'autopath.py', 'microbench.py'): - modules.append(module) - - for module in modules: - module = module.rstrip('.py') - exec 'from %s import *' % module in globals() - -def main(): - import_benchmarks() - benchmarks = [] - for name, thing in globals().iteritems(): - if getattr(thing, 'benchmark', False): - benchmarks.append((name, thing)) - benchmarks.sort() - - def entry_point(argv): - for name, func in benchmarks: - print name, ':', func() - return 0 - - t = Translation(entry_point, standalone=True, backend='c') - c_exe = t.compile() - t = Translation(entry_point, standalone=True, backend='cli') - cli_exe = t.compile() - t = Translation(entry_point, standalone=True, backend='jvm') - jvm_exe = t.compile() - - c_res = run_benchmark(c_exe) - cli_res = run_benchmark(cli_exe) - jvm_res = run_benchmark(jvm_exe) - - print 'benchmark genc gencli cli_ratio genjvm jvm_ratio' - print - for name, _ in benchmarks: - c_time = c_res[name] - cli_time = cli_res[name] - jvm_time = jvm_res[name] - if c_time == 0: - cli_ratio = '%10s' % '---' - else: - cli_ratio = '%10.2f' % (cli_time/c_time) - if c_time == 0: - jvm_ratio = '%10s' % '---' - else: - jvm_ratio = '%10.2f' % (jvm_time/c_time) - print '%-32s %10.2f %10.2f %s %10.2f %s' % (name, c_time, cli_time, cli_ratio, jvm_time, jvm_ratio) - -if __name__ == '__main__': - main() diff --git a/pypy/rpython/microbench/rdict.py b/pypy/rpython/microbench/rdict.py deleted file mode 100644 --- a/pypy/rpython/microbench/rdict.py +++ /dev/null @@ -1,70 +0,0 @@ -from pypy.rlib.objectmodel import r_dict -from pypy.rpython.microbench.microbench import MetaBench - -class Obj: - def __init__(self, x): - self.x = x - -def myhash(obj): - return obj.x - -def mycmp(obj1, obj2): - return obj1.x == obj2.x - -class Space: - def myhash(self, obj): - return obj.x - - def mycmp(self, obj1, obj2): - return obj1.x == obj2.x - - def _freeze_(self): - return True - -space = Space() -obj1 = Obj(1) -obj2 = Obj(2) - -class r_dict__set_item: - __metaclass__ = MetaBench - - def init(): - return r_dict(mycmp, myhash) - args = ['obj', 'i'] - def loop(obj, i): - obj[obj1] = i - obj[obj2] = i - -class r_dict__get_item: - __metaclass__ = MetaBench - - def init(): - res = r_dict(mycmp, myhash) - res[obj1] = 42 - res[obj2] = 43 - return res - args = ['obj', 'i'] - def loop(obj, i): - return obj[obj1] + obj[obj2] - -class r_dict__frozen_pbc__set_item: - __metaclass__ = MetaBench - - def init(): - return r_dict(space.mycmp, space.myhash) - args = ['obj', 'i'] - def loop(obj, i): - obj[obj1] = i - obj[obj2] = i - -class r_dict__frozen_pbc__get_item: - __metaclass__ = MetaBench - - def init(): - res = r_dict(space.mycmp, space.myhash) - res[obj1] = 42 - res[obj2] = 43 - return res - args = ['obj', 'i'] - def loop(obj, i): - return obj[obj1] + obj[obj2] diff --git a/pypy/translator/generator.py b/pypy/translator/generator.py deleted file mode 100644 --- a/pypy/translator/generator.py +++ /dev/null @@ -1,184 +0,0 @@ -from pypy.objspace.flow.model import Block, Link, SpaceOperation, checkgraph -from pypy.objspace.flow.model import Variable, Constant, FunctionGraph -from pypy.translator.unsimplify import insert_empty_startblock -from pypy.translator.unsimplify import split_block -from pypy.translator.simplify import eliminate_empty_blocks, simplify_graph -from pypy.tool.sourcetools import func_with_new_name -from pypy.interpreter.argument import Signature - - -class AbstractPosition(object): - _immutable_ = True - _attrs_ = () - - -def tweak_generator_graph(graph): - if not hasattr(graph.func, '_generator_next_method_of_'): - # This is the first copy of the graph. We replace it with - # a small bootstrap graph. - GeneratorIterator = make_generatoriterator_class(graph) - replace_graph_with_bootstrap(GeneratorIterator, graph) - # We attach a 'next' method to the GeneratorIterator class - # that will invoke the real function, based on a second - # copy of the graph. - attach_next_method(GeneratorIterator, graph) - else: - # This is the second copy of the graph. Tweak it. - GeneratorIterator = graph.func._generator_next_method_of_ - tweak_generator_body_graph(GeneratorIterator.Entry, graph) - - -def make_generatoriterator_class(graph): - class GeneratorIterator(object): - class Entry(AbstractPosition): - _immutable_ = True - varnames = get_variable_names(graph.startblock.inputargs) - - def __init__(self, entry): - self.current = entry - - def __iter__(self): - return self - - return GeneratorIterator - -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)) - 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)) - graph.startblock = newblock - -def attach_next_method(GeneratorIterator, graph): - func = graph.func - func = func_with_new_name(func, '%s__next' % (func.func_name,)) - func._generator_next_method_of_ = GeneratorIterator - func._always_inline_ = True - # - def next(self): - entry = self.current - self.current = None - assert entry is not None # else, recursive generator invocation - (next_entry, return_value) = func(entry) - self.current = next_entry - return return_value - GeneratorIterator.next = next - return func # for debugging - -def get_variable_names(variables): - seen = set() - result = [] - for v in variables: - name = v._name.strip('_') - while name in seen: - name += '_' - result.append('g_' + name) - seen.add(name) - return result - -def _insert_reads(block, varnames): - 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])) - block.inputargs = [v_entry1] - -def tweak_generator_body_graph(Entry, graph): - # First, always run simplify_graph in order to reduce the number of - # variables passed around - simplify_graph(graph) - # - assert graph.startblock.operations[0].opname == 'generator_mark' - graph.startblock.operations.pop(0) - # - insert_empty_startblock(None, graph) - _insert_reads(graph.startblock, Entry.varnames) - Entry.block = graph.startblock - # - 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)) - # - for block in list(graph.iterblocks()): - for exit in block.exits: - if exit.target is graph.returnblock: - exit.args = [] - 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 - del block.operations[index] - newlink = split_block(None, block, index) - newblock = newlink.target - # - class Resume(AbstractPosition): - _immutable_ = True - block = newblock - Resume.__name__ = 'Resume%d' % len(mappings) - mappings.append(Resume) - varnames = get_variable_names(newlink.args) - # - _insert_reads(newblock, varnames) - # - v_resume = Variable('resume') - block.operations.append( - SpaceOperation('simple_call', [Constant(Resume)], - v_resume)) - for i, name in enumerate(varnames): From noreply at buildbot.pypy.org Tue Oct 16 16:18:30 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 16 Oct 2012 16:18:30 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Flowspacify STORE_GLOBAL Message-ID: <20121016141830.19D441C1C86@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58139:f790da70aa4e Date: 2012-10-16 15:18 +0100 http://bitbucket.org/pypy/pypy/changeset/f790da70aa4e/ Log: Flowspacify STORE_GLOBAL diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -759,6 +759,11 @@ assert w_newvalue is not None self.locals_stack_w[varindex] = w_newvalue + def STORE_GLOBAL(self, nameindex, next_instr): + varname = self.getname_u(nameindex) + raise FlowingError(self, + "Attempting to modify global variable %r." % (varname)) + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. From noreply at buildbot.pypy.org Tue Oct 16 16:37:01 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 16 Oct 2012 16:37:01 +0200 (CEST) Subject: [pypy-commit] buildbot default: refactor the build scheduling: now we use tannit only for benchmarks and allegro for all the linux tests. This means that we can start everything at the same time Message-ID: <20121016143701.376481C1C8B@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r712:dc071dcef875 Date: 2012-10-16 16:36 +0200 http://bitbucket.org/pypy/buildbot/changeset/dc071dcef875/ Log: refactor the build scheduling: now we use tannit only for benchmarks and allegro for all the linux tests. This means that we can start everything at the same time diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -249,37 +249,37 @@ 'change_source': [], 'schedulers': [ - # first of all, we run the benchmarks: the two translations take ~2800 - # seconds and are executed in parallel. Running benchmarks takes ~3400 - # seconds and is executed sequentially. In total, 2800 + (3300*2) ~= - # 160 minutes + # the benchmarks run on tannit and speed.python.org. + # All the other linux tests run on allegro Nightly("nightly-0-00", [ + # benchmarks JITBENCH, # on tannit32, uses 1 core (in part exclusively) JITBENCH64, # on tannit64, uses 1 core (in part exclusively) JITBENCH64_2, # on speed.python.org, uses 1 core (in part exclusively) CPYTHON_64, # on speed.python.org, uses 1 core (in part exclusively) + + # linux tests + LINUX32, # on allegro32, uses 4 cores + LINUX64, # on allegro64, uses 4 cores + JITLINUX32, # on allegro32, uses 1 core + JITLINUX64, # on allegro64, uses 1 core + OJITLINUX32, # on allegro32, uses 1 core + APPLVLLINUX32, # on allegro32, uses 1 core + APPLVLLINUX64, # on allegro64, uses 1 core + + # other platforms MACOSX32, # on minime - ], branch=None, hour=0, minute=0), - # - # then, we schedule all the rest. The locks will take care not to run - # all of them in parallel - Nightly("nighly-3-00", [ - LINUX32, # on tannit32, uses 4 cores - LINUX64, # on tannit64, uses 4 cores - JITLINUX32, # on tannit32, uses 1 core - JITLINUX64, # on tannit64, uses 1 core - OJITLINUX32, # on tannit32, uses 1 core - APPLVLLINUX32, # on tannit32, uses 1 core - APPLVLLINUX64, # on tannit64, uses 1 core - # JITWIN32, # on aurora #JITFREEBSD64, # on headless JITMACOSX64, # on mvt's machine - ], branch=None, hour=3, minute=0), + ], branch=None, hour=0, minute=0), - Nightly("nighly-4-00-py3k", [ - LINUX32, # on tannit32, uses 4 cores - ], branch='py3k', hour=4, minute=0), + Nightly("nighly-0-00-py3k", [ + LINUX32, + LINUX64, + APPLVLLINUX32, + APPLVLLINUX64, + ], branch='py3k', hour=0, minute=0), # Nightly("nighly-ppc", [ JITONLYLINUXPPC64, # on gcc1 @@ -308,7 +308,7 @@ 'builders': [ {"name": LINUX32, - "slavenames": ["allegro32", "tannit32"], + "slavenames": ["allegro32"], "builddir": LINUX32, "factory": pypyOwnTestFactory, "category": 'linux32', @@ -316,7 +316,7 @@ #"locks": [TannitCPU.access('exclusive')], }, {"name": LINUX64, - "slavenames": ["allegro64", "tannit64"], + "slavenames": ["allegro64"], "builddir": LINUX64, "factory": pypyOwnTestFactory, "category": 'linux64', @@ -324,35 +324,35 @@ #"locks": [TannitCPU.access('exclusive')], }, {"name": APPLVLLINUX32, - "slavenames": ["allegro32", "tannit32"], + "slavenames": ["allegro32"], "builddir": APPLVLLINUX32, "factory": pypyTranslatedAppLevelTestFactory, 'category': 'linux32', #"locks": [TannitCPU.access('counting')], }, {"name": APPLVLLINUX64, - "slavenames": ["allegro64", "tannit64"], + "slavenames": ["allegro64"], "builddir": APPLVLLINUX64, "factory": pypyTranslatedAppLevelTestFactory64, "category": "linux64", #"locks": [TannitCPU.access('counting')], }, {"name": OJITLINUX32, - "slavenames": ["allegro32", "tannit32"], + "slavenames": ["allegro32"], "builddir": OJITLINUX32, "factory": pypy_OjitTranslatedTestFactory, "category": 'linux32', #"locks": [TannitCPU.access('counting')], }, {"name" : JITLINUX32, - "slavenames": ["allegro32", "tannit32"], + "slavenames": ["allegro32"], 'builddir' : JITLINUX32, 'factory' : pypyJITTranslatedTestFactory, 'category' : 'linux32', #"locks": [TannitCPU.access('counting')], }, {'name': JITLINUX64, - 'slavenames': ["allegro64", 'tannit64'], + 'slavenames': ["allegro64"], 'builddir': JITLINUX64, 'factory': pypyJITTranslatedTestFactory64, 'category': 'linux64', From noreply at buildbot.pypy.org Tue Oct 16 16:47:09 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 16 Oct 2012 16:47:09 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: rst link Message-ID: <20121016144709.170E91C1C8B@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: extradoc Changeset: r4859:31f807248b38 Date: 2012-09-26 11:50 +0200 http://bitbucket.org/pypy/extradoc/changeset/31f807248b38/ Log: rst link diff --git a/blog/draft/py3k-status-update-6.rst b/blog/draft/py3k-status-update-6.rst --- a/blog/draft/py3k-status-update-6.rst +++ b/blog/draft/py3k-status-update-6.rst @@ -58,7 +58,7 @@ Finally, I would like to thank Amaury Forgeot d'Arc and Ariel Ben-Yehuda for their work on the branch; among other things, Amaury recently worked on ``cpyext`` and on the PyPy ``_cffi_backend``, while Ariel submitted a patch to -implement `PEP 3138`. +implement `PEP 3138`_. .. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html .. _`py3k proposal`: http://pypy.org/py3donate.html From noreply at buildbot.pypy.org Tue Oct 16 16:47:10 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 16 Oct 2012 16:47:10 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: merge heads Message-ID: <20121016144710.39F601C1C8B@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: extradoc Changeset: r4860:7274e147df46 Date: 2012-10-16 16:46 +0200 http://bitbucket.org/pypy/extradoc/changeset/7274e147df46/ Log: merge heads diff --git a/blog/draft/py3k-status-update-6.rst b/blog/draft/py3k-status-update-6.rst --- a/blog/draft/py3k-status-update-6.rst +++ b/blog/draft/py3k-status-update-6.rst @@ -58,7 +58,7 @@ Finally, I would like to thank Amaury Forgeot d'Arc and Ariel Ben-Yehuda for their work on the branch; among other things, Amaury recently worked on ``cpyext`` and on the PyPy ``_cffi_backend``, while Ariel submitted a patch to -implement `PEP 3138`. +implement `PEP 3138`_. .. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html .. _`py3k proposal`: http://pypy.org/py3donate.html From noreply at buildbot.pypy.org Tue Oct 16 16:57:07 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 16 Oct 2012 16:57:07 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Random changes, mostly documentation fixes Message-ID: <20121016145707.2A0301C1C8B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58140:ad4967674c4f Date: 2012-10-16 16:56 +0200 http://bitbucket.org/pypy/pypy/changeset/ad4967674c4f/ Log: Random changes, mostly documentation fixes diff --git a/pypy/jit/backend/llsupport/jitframe.py b/pypy/jit/backend/llsupport/jitframe.py --- a/pypy/jit/backend/llsupport/jitframe.py +++ b/pypy/jit/backend/llsupport/jitframe.py @@ -2,9 +2,17 @@ _LONGLONGARRAY = lltype.GcArray(lltype.SignedLongLong) -JITFRAME = lltype.GcStruct('JITFRAME', - ('jf_descr', llmemory.GCREF), - ('jf_excvalue', llmemory.GCREF), - ('jf_nongcvalues', lltype.Ptr(_LONGLONGARRAY)), - ('jf_gcvalues', lltype.Array(llmemory.GCREF))) +JITFRAME = lltype.GcStruct( + 'JITFRAME', + + # Once the execute_token() returns, the field 'jf_descr' stores the + # descr of the last executed operation (either a GUARD, or FINISH). + ('jf_descr', llmemory.GCREF), + + # For the front-end: a GCREF for the savedata + ('jf_savedata', llmemory.GCREF), + + # XXX + ('jf_nongcvalues', lltype.Ptr(_LONGLONGARRAY)), + ('jf_gcvalues', lltype.Array(llmemory.GCREF))) JITFRAMEPTR = lltype.Ptr(JITFRAME) diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -1,7 +1,6 @@ from pypy.rlib.debug import debug_start, debug_print, debug_stop from pypy.rlib.rarithmetic import intmask from pypy.jit.metainterp import history -from pypy.jit.codewriter.longlong import longlong2floatstorage from pypy.rpython.lltypesystem import lltype @@ -127,56 +126,51 @@ def get_latest_descr(self, jitframe): """Return the descr of the last operation executed by the jitframe.""" - return jitframe.jf_descr + raise NotImplementedError def get_latest_value_int(self, jitframe, index): - """Returns the value for the index'th argument to the - last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns an int.""" - return intmask(jitframe.jf_nongcvalues[index]) + """Returns the value for the index'th 'fail_args' of the + last executed operation. Returns an int.""" + raise NotImplementedError def get_latest_value_float(self, jitframe, index): - """Returns the value for the index'th argument to the - last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a FLOATSTORAGE.""" - return longlong2floatstorage(jitframe.jf_nongcvalues[index]) + """Returns the value for the index'th 'fail_args' of the + last executed operation. Returns a FLOATSTORAGE.""" + raise NotImplementedError def get_latest_value_ref(self, jitframe, index): - """Returns the value for the index'th argument to the - last executed operation (from 'fail_args' if it was a guard, - or from 'args' if it was a FINISH). Returns a GCREF.""" - return jitframe.jf_gcvalues[index] + """Returns the value for the index'th 'fail_args' of the + last executed operation. Returns a GCREF.""" + raise NotImplementedError def get_latest_value_count(self, jitframe): """Return how many values are ready to be returned by - get_latest_value_xxx(). Only after a guard failure; not - necessarily correct after a FINISH.""" - return len(jitframe.jf_gcvalues) + get_latest_value_xxx().""" + raise NotImplementedError def get_finish_value_int(self, jitframe): """Return the result passed to FINISH, which was an int.""" - return jitframe.jf_finish_int + raise NotImplementedError def get_finish_value_float(self, jitframe): """Return the result passed to FINISH, which was a FLOATSTORAGE.""" - return jitframe.jf_finish_float + raise NotImplementedError def get_finish_value_ref(self, jitframe): """Return and clear the result passed to FINISH, which was a GCREF. Also used when it exits due to a failure of a GUARD_EXCEPTION or GUARD_NO_EXCEPTION, to return the exception.""" - xxxx - return jitframe.jf_finish_ref + raise NotImplementedError def get_savedata_ref(self, jitframe): """Return and clear the last value stored by the frontend with set_savedata_ref.""" - xxxx + raise NotImplementedError def set_savedata_ref(self, jitframe, value): """Store on the jitframe a random GCREF value that will be returned by the following call to get_savedata_ref().""" - xxxx + raise NotImplementedError def redirect_call_assembler(self, oldlooptoken, newlooptoken): """Redirect oldlooptoken to newlooptoken. More precisely, it is diff --git a/pypy/jit/backend/x86/arch.py b/pypy/jit/backend/x86/arch.py --- a/pypy/jit/backend/x86/arch.py +++ b/pypy/jit/backend/x86/arch.py @@ -21,13 +21,15 @@ # +--------------------+ <== aligned to 16 bytes if WORD == 4: + # enough for calls with up to 7 arguments, or 7 scratch stores SCRATCH_SIZE = 7 # total size: 32 bytes else: + # enough for calls with up to 6+3 arguments, or 3 scratch stores SCRATCH_SIZE = 3 # total size: 32 bytes # All the rest of the data is in a GC-managed variable-size "frame". # This frame object's address is always stored in the register EBP/RBP. -# A frame is a jit.backend.llsupport.llmodel.FRAME = GcArray(Signed). +# A frame is a jit.backend.llsupport.jitframe.JITFRAME. # The following locations are indices in this array. # The frame's fixed size gives the standard fixed part at the From noreply at buildbot.pypy.org Tue Oct 16 17:37:14 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 16 Oct 2012 17:37:14 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Flowspacify CALL_FUNCTION and friends Message-ID: <20121016153714.2B9151C1C85@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58141:68eaeee93b2b Date: 2012-10-16 16:36 +0100 http://bitbucket.org/pypy/pypy/changeset/68eaeee93b2b/ Log: Flowspacify CALL_FUNCTION and friends (remove useless speed hack in CALL_FUNCTION) diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -771,6 +771,48 @@ self.pushvalue(self.space.newlist([])) self.pushvalue(last_val) + def call_function(self, oparg, w_star=None, w_starstar=None): + n_arguments = oparg & 0xff + n_keywords = (oparg>>8) & 0xff + if n_keywords: + keywords = [None] * n_keywords + keywords_w = [None] * n_keywords + while True: + n_keywords -= 1 + if n_keywords < 0: + break + w_value = self.popvalue() + w_key = self.popvalue() + key = self.space.str_w(w_key) + keywords[n_keywords] = key + keywords_w[n_keywords] = w_value + else: + keywords = None + keywords_w = None + arguments = self.popvalues(n_arguments) + args = self.argument_factory(arguments, keywords, keywords_w, w_star, + w_starstar) + w_function = self.popvalue() + w_result = self.space.call_args(w_function, args) + self.pushvalue(w_result) + + def CALL_FUNCTION(self, oparg, next_instr): + self.call_function(oparg) + CALL_METHOD = CALL_FUNCTION + + def CALL_FUNCTION_VAR(self, oparg, next_instr): + w_varargs = self.popvalue() + self.call_function(oparg, w_varargs) + + def CALL_FUNCTION_KW(self, oparg, next_instr): + w_varkw = self.popvalue() + self.call_function(oparg, None, w_varkw) + + def CALL_FUNCTION_VAR_KW(self, oparg, next_instr): + w_varkw = self.popvalue() + w_varargs = self.popvalue() + self.call_function(oparg, w_varargs, w_varkw) + def MAKE_FUNCTION(self, numdefaults, next_instr): w_codeobj = self.popvalue() defaults = self.popvalues(numdefaults) diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -427,10 +427,6 @@ raise FSException(self.w_ImportError, self.wrap("cannot import name '%s'" % w_name.value)) - def call_valuestack(self, w_func, nargs, frame): - args = frame.make_arguments(nargs) - return self.call_args(w_func, args) - def call_method(self, w_obj, methname, *arg_w): w_meth = self.getattr(w_obj, self.wrap(methname)) return self.call_function(w_meth, *arg_w) From noreply at buildbot.pypy.org Tue Oct 16 17:44:30 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 16 Oct 2012 17:44:30 +0200 (CEST) Subject: [pypy-commit] pypy default: remove sanity check that does not seem to do all that much Message-ID: <20121016154430.BBB8C1C1C85@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58142:ea4083c44885 Date: 2012-10-16 17:44 +0200 http://bitbucket.org/pypy/pypy/changeset/ea4083c44885/ Log: remove sanity check that does not seem to do all that much diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -603,8 +603,9 @@ if tobox is not None: # sanity check: see whether the current struct value # corresponds to what the cache thinks the value is - resbox = executor.execute(self.metainterp.cpu, self.metainterp, - rop.GETFIELD_GC, fielddescr, box) + #resbox = executor.execute(self.metainterp.cpu, self.metainterp, + # rop.GETFIELD_GC, fielddescr, box) + # XXX the sanity check does not seem to do anything, remove? return tobox resbox = self.execute_with_descr(opnum, fielddescr, box) self.metainterp.heapcache.getfield_now_known(box, fielddescr, resbox) From noreply at buildbot.pypy.org Tue Oct 16 18:18:35 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 16 Oct 2012 18:18:35 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: Start fixing casting to stuff Message-ID: <20121016161835.671AB1C1C7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: numpypy-problems Changeset: r58143:80f65c2bf92c Date: 2012-10-16 18:18 +0200 http://bitbucket.org/pypy/pypy/changeset/80f65c2bf92c/ Log: Start fixing casting to stuff diff --git a/pypy/module/micronumpy/stdobjspace.py b/pypy/module/micronumpy/stdobjspace.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/stdobjspace.py @@ -0,0 +1,11 @@ + +from pypy.objspace.std import stringobject +from pypy.module.micronumpy import interp_boxes + +def delegate_stringbox2stringobj(space, w_box): + return space.wrap(w_box.dtype.itemtype.to_str(w_box)) + +def register_delegates(typeorder): + typeorder[interp_boxes.W_StringBox] = [ + (stringobject.W_StringObject, delegate_stringbox2stringobj), + ] diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1494,7 +1494,7 @@ # builder.append(arr.storage[i]) # i += 1 #return builder.build() - def to_str(self, item): + def to_str(self, item): builder = StringBuilder() assert isinstance(item, interp_boxes.W_StringBox) i = 0 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 @@ -182,6 +182,10 @@ (complexobject.W_ComplexObject, smallintobject.delegate_SmallInt2Complex), ] + if config.objspace.usemodules.micronumpy: + from pypy.module.micronumpy.stdobjspace import register_delegates + register_delegates(self.typeorder) + self.typeorder[boolobject.W_BoolObject] += [ (intobject.W_IntObject, boolobject.delegate_Bool2IntObject), (floatobject.W_FloatObject, floatobject.delegate_Bool2Float), From noreply at buildbot.pypy.org Tue Oct 16 19:07:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 16 Oct 2012 19:07:34 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Add an assert that fails in this branch for now. Message-ID: <20121016170734.274A91C1C86@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58144:d1f619c8a44c Date: 2012-10-16 17:20 +0200 http://bitbucket.org/pypy/pypy/changeset/d1f619c8a44c/ Log: Add an assert that fails in this branch for now. diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -774,6 +774,9 @@ virtualizables = ['frame'], get_printable_location = lambda codeno : str(codeno)) + class Oups(Exception): + pass + def main(codeno): frame = Frame() frame.thing = Thing(0) @@ -790,6 +793,8 @@ subframe = Frame() subframe.thing = Thing(nextval) nextval = portal(1, subframe) + if subframe.thing.val != nextval: + raise Oups frame.thing = Thing(nextval + 1) i += 1 return frame.thing.val From noreply at buildbot.pypy.org Tue Oct 16 19:07:35 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 16 Oct 2012 19:07:35 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (fijal, arigo) work in progress Message-ID: <20121016170735.788CF1C1C86@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58145:254e7646834e Date: 2012-10-16 19:07 +0200 http://bitbucket.org/pypy/pypy/changeset/254e7646834e/ Log: (fijal, arigo) work in progress diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -641,7 +641,7 @@ count_jumps = _stats.exec_jumps log.trace('ran %d operations, %d jumps' % (count, count_jumps)) - def _normalizedcontainer(self): + def _normalizedcontainer(self, check="ignored"): return self # for lltype # ---------- diff --git a/pypy/jit/metainterp/heapcache.py b/pypy/jit/metainterp/heapcache.py --- a/pypy/jit/metainterp/heapcache.py +++ b/pypy/jit/metainterp/heapcache.py @@ -19,7 +19,7 @@ # escapes. self.dependencies = {} # contains frame boxes that are not virtualizables - self.nonstandard_virtualizables = {} + #self.nonstandard_virtualizables = {} # heap cache # maps descrs to {from_box, to_box} dicts @@ -136,11 +136,11 @@ def class_now_known(self, box): self.known_class_boxes[box] = None - def is_nonstandard_virtualizable(self, box): - return box in self.nonstandard_virtualizables + #def is_nonstandard_virtualizable(self, box): + # return box in self.nonstandard_virtualizables - def nonstandard_virtualizables_now_known(self, box): - self.nonstandard_virtualizables[box] = None + #def nonstandard_virtualizables_now_known(self, box): + # self.nonstandard_virtualizables[box] = None def is_unescaped(self, box): return self.new_boxes.get(box, False) diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -719,8 +719,8 @@ standard_box = self.metainterp.virtualizable_boxes[-1] if standard_box is box: return False - if self.metainterp.heapcache.is_nonstandard_virtualizable(box): - return True + #if self.metainterp.heapcache.is_nonstandard_virtualizable(box): + # return True eqbox = self.metainterp.execute_and_record(rop.PTR_EQ, None, box, standard_box) eqbox = self.implement_guard_value(pc, eqbox) @@ -728,9 +728,30 @@ if isstandard: self.metainterp.replace_box(box, standard_box) else: - self.metainterp.heapcache.nonstandard_virtualizables_now_known(box) + self._force_virtualizable_if_necessary(box, pc) + pass #self.metainterp.heapcache.nonstandard_virtualizables_now_known(box) return not isstandard + def _force_virtualizable_if_necessary(self, box, orgpc): + vinfo = self.metainterp.jitdriver_sd.virtualizable_info + if vinfo is None: + return # xxx? + if self.metainterp.heapcache.is_unescaped(box): + return + jfbox = self._opimpl_getfield_gc_any(box, vinfo.jit_frame_descr) + if not self._establish_nullity(jfbox, orgpc): + return # jfbox is NULL + cpu = self.metainterp.cpu + descr = cpu.jitframe_get_jfdescr_descr() + jfdescrbox = self._opimpl_getfield_gc_any(jfbox, descr) + jfdescrbox = self.implement_guard_value(pc, jfdescrbox) + jfdescr = jfdescrbox.getref_base() + descr = cpu.jitframe_cast_jfdescr_to_descr(jfdescr) + if not descr: + return + import pdb; pdb.set_trace() + xxx + def _get_virtualizable_field_index(self, fielddescr): # Get the index of a fielddescr. Must only be called for # the "standard" virtualizable. From noreply at buildbot.pypy.org Tue Oct 16 20:34:51 2012 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 16 Oct 2012 20:34:51 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: add charts for guard failure rates combined for all benchmarks and for go Message-ID: <20121016183451.0C6991C027A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4861:d77accf0fda6 Date: 2012-10-16 15:31 -0300 http://bitbucket.org/pypy/extradoc/changeset/d77accf0fda6/ Log: add charts for guard failure rates combined for all benchmarks and for go diff --git a/talk/vmil2012/presentation/figures/data.tex b/talk/vmil2012/presentation/figures/data.tex new file mode 100644 --- /dev/null +++ b/talk/vmil2012/presentation/figures/data.tex @@ -0,0 +1,45 @@ + +\addplot[red] coordinates { +(0.000000,1.000000) (0.006494,0.148545) (0.012987,0.143156) (0.019481,0.074262) (0.025974,0.070332) (0.032468,0.047160) (0.038961,0.046744) (0.045455,0.041526) (0.051948,0.032187) (0.058442,0.027040) (0.064935,0.020597) (0.071429,0.018534) (0.077922,0.017118) (0.084416,0.016888) (0.090909,0.011212) (0.097403,0.009493) (0.103896,0.007359) (0.110390,0.007268) (0.116883,0.006596) (0.123377,0.005563) (0.129870,0.005529) (0.136364,0.005470) (0.142857,0.003591) (0.149351,0.002948) (0.155844,0.002945) (0.162338,0.002749) (0.168831,0.002558) (0.175325,0.001651) (0.181818,0.001644) (0.188312,0.001592) (0.194805,0.001582) (0.201299,0.001365) (0.207792,0.001362) (0.214286,0.000933) (0.220779,0.000887) (0.227273,0.000871) (0.233766,0.000863) (0.240260,0.000843) (0.246753,0.000726) (0.253247,0.000695) (0.259740,0.000594) (0.266234,0.000558) (0.272727,0.000534) (0.279221,0.000498) (0.285714,0.000389) (0.292208,0.000389) (0.298701,0.000382) (0.305195,0.000381) (0.311688,0.000376) (0.318182,0.000364) (0.324675,0.000340) (0.331169,0.000312) (0.337662,0.000237) (0.344156,0.000219) (0.350649,0.000204) (0.357143,0.000202) (0.363636,0.000202) (0.370130,0.000193) (0.376623,0.000174) (0.383117,0.000162) (0.389610,0.000139) (0.396104,0.000137) (0.402597,0.000135) (0.409091,0.000130) (0.415584,0.000130) (0.422078,0.000122) (0.428571,0.000119) (0.435065,0.000104) (0.441558,0.000101) (0.448052,0.000097) (0.454545,0.000087) (0.461039,0.000079) (0.467532,0.000069) (0.474026,0.000058) (0.480519,0.000051) (0.487013,0.000041) (0.493506,0.000040) (0.500000,0.000035) (0.506494,0.000029) (0.512987,0.000028) (0.519481,0.000028) (0.525974,0.000027) (0.532468,0.000026) (0.538961,0.000026) (0.545455,0.000024) (0.551948,0.000021) (0.558442,0.000018) (0.564935,0.000018) (0.571429,0.000017) (0.577922,0.000016) (0.584416,0.000015) (0.590909,0.000015) (0.597403,0.000014) (0.603896,0.000014) (0.610390,0.000011) (0.616883,0.000011) (0.623377,0.000011) (0.629870,0.000011) (0.636364,0.000011) (0.642857,0.000011) (0.649351,0.000011) (0.655844,0.000011) (0.662338,0.000010) (0.668831,0.000009) (0.675325,0.000007) (0.681818,0.000007) (0.688312,0.000007) (0.694805,0.000007) (0.701299,0.000007) (0.707792,0.000006) (0.714286,0.000006) (0.720779,0.000005) (0.727273,0.000005) (0.733766,0.000005) (0.740260,0.000005) (0.746753,0.000004) (0.753247,0.000004) (0.759740,0.000003) (0.766234,0.000003) (0.772727,0.000003) (0.779221,0.000003) (0.785714,0.000002) (0.792208,0.000002) (0.798701,0.000002) (0.805195,0.000002) (0.811688,0.000002) (0.818182,0.000002) (0.824675,0.000002) (0.831169,0.000002) (0.837662,0.000002) (0.844156,0.000002) (0.850649,0.000002) (0.857143,0.000002) (0.863636,0.000002) (0.870130,0.000001) (0.876623,0.000001) (0.883117,0.000001) (0.889610,0.000001) (0.896104,0.000001) (0.902597,0.000001) (0.909091,0.000001) (0.915584,0.000001) (0.922078,0.000001) (0.928571,0.000001) (0.935065,0.000001) (0.941558,0.000001) (0.948052,0.000000) (0.954545,0.000000) (0.961039,0.000000) (0.967532,0.000000) (0.974026,0.000000) (0.980519,0.000000) (0.987013,0.000000) (0.993506,0.000000) (1.000000,0.000000) +}; + +\addplot[green] coordinates { +(0.000000,1.000000) (0.012195,0.997326) (0.024390,0.701335) (0.036585,0.503352) (0.048780,0.496172) (0.060976,0.459611) (0.073171,0.381570) (0.085366,0.349645) (0.097561,0.315892) (0.109756,0.312117) (0.121951,0.242322) (0.134146,0.213275) (0.146341,0.186336) (0.158537,0.114441) (0.170732,0.077514) (0.182927,0.054374) (0.195122,0.047764) (0.207317,0.043576) (0.219512,0.039644) (0.231707,0.029204) (0.243902,0.029145) (0.256098,0.027214) (0.268293,0.023030) (0.280488,0.016877) (0.292683,0.016283) (0.304878,0.015489) (0.317073,0.014624) (0.329268,0.014572) (0.341463,0.014451) (0.353659,0.009960) (0.365854,0.009811) (0.378049,0.009299) (0.390244,0.009197) (0.402439,0.009182) (0.414634,0.009178) (0.426829,0.007813) (0.439024,0.007797) (0.451220,0.007786) (0.463415,0.007715) (0.475610,0.007381) (0.487805,0.007172) (0.500000,0.006791) (0.512195,0.006783) (0.524390,0.006634) (0.536585,0.006366) (0.548780,0.005879) (0.560976,0.004203) (0.573171,0.004074) (0.585366,0.003983) (0.597561,0.003260) (0.609756,0.003252) (0.621951,0.003181) (0.634146,0.002945) (0.646341,0.002670) (0.658537,0.002399) (0.670732,0.002159) (0.682927,0.002143) (0.695122,0.001817) (0.707317,0.001793) (0.719512,0.001785) (0.731707,0.001577) (0.743902,0.001573) (0.756098,0.001243) (0.768293,0.001073) (0.780488,0.000598) (0.792683,0.000590) (0.804878,0.000492) (0.817073,0.000440) (0.829268,0.000240) (0.841463,0.000201) (0.853659,0.000201) (0.865854,0.000197) (0.878049,0.000177) (0.890244,0.000079) (0.902439,0.000079) (0.914634,0.000067) (0.926829,0.000031) (0.939024,0.000028) (0.951220,0.000024) (0.963415,0.000012) (0.975610,0.000008) (0.987805,0.000004) (1.000000,0.000004) +}; + +\addplot[blue] coordinates { +(0.000000,1.000000) (0.009009,0.274799) (0.018018,0.254401) (0.027027,0.254401) (0.036036,0.254400) (0.045045,0.253942) (0.054054,0.176493) (0.063063,0.170575) (0.072072,0.170575) (0.081081,0.166477) (0.090090,0.103439) (0.099099,0.087880) (0.108108,0.085545) (0.117117,0.085441) (0.126126,0.077913) (0.135135,0.075639) (0.144144,0.059419) (0.153153,0.052926) (0.162162,0.051446) (0.171171,0.040551) (0.180180,0.036356) (0.189189,0.031443) (0.198198,0.026162) (0.207207,0.023960) (0.216216,0.020391) (0.225225,0.018926) (0.234234,0.018265) (0.243243,0.018091) (0.252252,0.018011) (0.261261,0.015999) (0.270270,0.011937) (0.279279,0.010101) (0.288288,0.010101) (0.297297,0.009964) (0.306306,0.009956) (0.315315,0.009498) (0.324324,0.006923) (0.333333,0.006919) (0.342342,0.005088) (0.351351,0.004699) (0.360360,0.004400) (0.369369,0.004132) (0.378378,0.003324) (0.387387,0.003266) (0.396396,0.003017) (0.405405,0.002900) (0.414414,0.002389) (0.423423,0.001747) (0.432432,0.001717) (0.441441,0.001660) (0.450450,0.001634) (0.459459,0.001542) (0.468468,0.001353) (0.477477,0.001264) (0.486486,0.001263) (0.495495,0.001131) (0.504505,0.001046) (0.513514,0.000934) (0.522523,0.000928) (0.531532,0.000856) (0.540541,0.000850) (0.549550,0.000821) (0.558559,0.000745) (0.567568,0.000679) (0.576577,0.000581) (0.585586,0.000480) (0.594595,0.000316) (0.603604,0.000260) (0.612613,0.000256) (0.621622,0.000209) (0.630631,0.000195) (0.639640,0.000163) (0.648649,0.000161) (0.657658,0.000145) (0.666667,0.000136) (0.675676,0.000134) (0.684685,0.000128) (0.693694,0.000123) (0.702703,0.000117) (0.711712,0.000100) (0.720721,0.000099) (0.729730,0.000095) (0.738739,0.000088) (0.747748,0.000087) (0.756757,0.000065) (0.765766,0.000058) (0.774775,0.000052) (0.783784,0.000051) (0.792793,0.000045) (0.801802,0.000043) (0.810811,0.000033) (0.819820,0.000031) (0.828829,0.000028) (0.837838,0.000023) (0.846847,0.000019) (0.855856,0.000018) (0.864865,0.000017) (0.873874,0.000017) (0.882883,0.000016) (0.891892,0.000016) (0.900901,0.000016) (0.909910,0.000016) (0.918919,0.000015) (0.927928,0.000015) (0.936937,0.000012) (0.945946,0.000011) (0.954955,0.000009) (0.963964,0.000006) (0.972973,0.000005) (0.981982,0.000003) (0.990991,0.000001) (1.000000,0.000000) +}; + +\addplot[cyan] coordinates { +(0.000000,1.000000) (0.004505,0.536162) (0.009009,0.533859) (0.013514,0.483711) (0.018018,0.468958) (0.022523,0.385926) (0.027027,0.368855) (0.031532,0.330881) (0.036036,0.273385) (0.040541,0.223088) (0.045045,0.201529) (0.049550,0.188300) (0.054054,0.184877) (0.058559,0.165360) (0.063063,0.160965) (0.067568,0.151293) (0.072072,0.125402) (0.076577,0.121903) (0.081081,0.121395) (0.085586,0.117212) (0.090090,0.117117) (0.094595,0.099425) (0.099099,0.096936) (0.103604,0.096847) (0.108108,0.096552) (0.112613,0.096421) (0.117117,0.083108) (0.121622,0.076876) (0.126126,0.068604) (0.130631,0.064969) (0.135135,0.056385) (0.139640,0.056383) (0.144144,0.049812) (0.148649,0.049576) (0.153153,0.042719) (0.157658,0.042151) (0.162162,0.038817) (0.166667,0.038467) (0.171171,0.038437) (0.175676,0.038161) (0.180180,0.037712) (0.184685,0.037469) (0.189189,0.037434) (0.193694,0.037419) (0.198198,0.037035) (0.202703,0.037000) (0.207207,0.036987) (0.211712,0.035969) (0.216216,0.034370) (0.220721,0.033375) (0.225225,0.031819) (0.229730,0.031613) (0.234234,0.029056) (0.238739,0.028685) (0.243243,0.026102) (0.247748,0.023276) (0.252252,0.018629) (0.256757,0.018545) (0.261261,0.015560) (0.265766,0.013442) (0.270270,0.013322) (0.274775,0.011983) (0.279279,0.011599) (0.283784,0.008508) (0.288288,0.008463) (0.292793,0.008461) (0.297297,0.008456) (0.301802,0.007547) (0.306306,0.007021) (0.310811,0.006568) (0.315315,0.006344) (0.319820,0.005826) (0.324324,0.004751) (0.328829,0.004749) (0.333333,0.004749) (0.337838,0.003794) (0.342342,0.003082) (0.346847,0.002806) (0.351351,0.002767) (0.355856,0.002535) (0.360360,0.002472) (0.364865,0.002390) (0.369369,0.002320) (0.373874,0.002290) (0.378378,0.002275) (0.382883,0.002210) (0.387387,0.002049) (0.391892,0.001854) (0.396396,0.001647) (0.400901,0.001502) (0.405405,0.001322) (0.409910,0.001200) (0.414414,0.001161) (0.418919,0.001159) (0.423423,0.001146) (0.427928,0.001144) (0.432432,0.001116) (0.436937,0.001066) (0.441441,0.001059) (0.445946,0.001018) (0.450450,0.000873) (0.454955,0.000864) (0.459459,0.000840) (0.463964,0.000777) (0.468468,0.000766) (0.472973,0.000747) (0.477477,0.000729) (0.481982,0.000729) (0.486486,0.000621) (0.490991,0.000597) (0.495495,0.000590) (0.500000,0.000582) (0.504505,0.000577) (0.509009,0.000562) (0.513514,0.000558) (0.518018,0.000523) (0.522523,0.000478) (0.527027,0.000469) (0.531532,0.000456) (0.536036,0.000434) (0.540541,0.000432) (0.545045,0.000425) (0.549550,0.000425) (0.554054,0.000417) (0.558559,0.000412) (0.563063,0.000352) (0.567568,0.000332) (0.572072,0.000330) (0.576577,0.000326) (0.581081,0.000313) (0.585586,0.000289) (0.590090,0.000267) (0.594595,0.000247) (0.599099,0.000247) (0.603604,0.000217) (0.608108,0.000204) (0.612613,0.000195) (0.617117,0.000182) (0.621622,0.000165) (0.626126,0.000165) (0.630631,0.000163) (0.635135,0.000137) (0.639640,0.000137) (0.644144,0.000132) (0.648649,0.000130) (0.653153,0.000130) (0.657658,0.000122) (0.662162,0.000122) (0.666667,0.000122) (0.671171,0.000119) (0.675676,0.000115) (0.680180,0.000104) (0.684685,0.000104) (0.689189,0.000100) (0.693694,0.000096) (0.698198,0.000093) (0.702703,0.000087) (0.707207,0.000087) (0.711712,0.000087) (0.716216,0.000085) (0.720721,0.000085) (0.725225,0.000078) (0.729730,0.000074) (0.734234,0.000063) (0.738739,0.000059) (0.743243,0.000059) (0.747748,0.000059) (0.752252,0.000056) (0.756757,0.000056) (0.761261,0.000056) (0.765766,0.000054) (0.770270,0.000052) (0.774775,0.000052) (0.779279,0.000048) (0.783784,0.000046) (0.788288,0.000043) (0.792793,0.000041) (0.797297,0.000039) (0.801802,0.000039) (0.806306,0.000037) (0.810811,0.000037) (0.815315,0.000035) (0.819820,0.000035) (0.824324,0.000035) (0.828829,0.000033) (0.833333,0.000030) (0.837838,0.000030) (0.842342,0.000028) (0.846847,0.000028) (0.851351,0.000026) (0.855856,0.000026) (0.860360,0.000026) (0.864865,0.000024) (0.869369,0.000022) (0.873874,0.000020) (0.878378,0.000020) (0.882883,0.000017) (0.887387,0.000017) (0.891892,0.000017) (0.896396,0.000013) (0.900901,0.000013) (0.905405,0.000013) (0.909910,0.000011) (0.914414,0.000011) (0.918919,0.000011) (0.923423,0.000011) (0.927928,0.000011) (0.932432,0.000009) (0.936937,0.000009) (0.941441,0.000009) (0.945946,0.000009) (0.950450,0.000007) (0.954955,0.000007) (0.959459,0.000007) (0.963964,0.000004) (0.968468,0.000004) (0.972973,0.000004) (0.977477,0.000002) (0.981982,0.000002) (0.986486,0.000002) (0.990991,0.000002) (0.995495,0.000002) (1.000000,0.000002) +}; + +\addplot[magenta] coordinates { +(0.000000,1.000000) (0.033333,0.333289) (0.066667,0.333230) (0.100000,0.330941) (0.133333,0.089999) (0.166667,0.087891) (0.200000,0.074485) (0.233333,0.074414) (0.266667,0.074281) (0.300000,0.003317) (0.333333,0.002204) (0.366667,0.000795) (0.400000,0.000294) (0.433333,0.000133) (0.466667,0.000099) (0.500000,0.000099) (0.533333,0.000067) (0.566667,0.000033) (0.600000,0.000032) (0.633333,0.000031) (0.666667,0.000025) (0.700000,0.000019) (0.733333,0.000010) (0.766667,0.000005) (0.800000,0.000003) (0.833333,0.000003) (0.866667,0.000003) (0.900000,0.000001) (0.933333,0.000001) (0.966667,0.000001) (1.000000,0.000001) +}; + +\addplot[yellow] coordinates { +(0.000000,1.000000) (0.017544,0.993592) (0.035088,0.506431) (0.052632,0.496860) (0.070175,0.003334) (0.087719,0.003334) (0.105263,0.003290) (0.122807,0.003290) (0.140351,0.003290) (0.157895,0.003289) (0.175439,0.003250) (0.192982,0.000768) (0.210526,0.000464) (0.228070,0.000216) (0.245614,0.000205) (0.263158,0.000137) (0.280702,0.000133) (0.298246,0.000121) (0.315789,0.000105) (0.333333,0.000081) (0.350877,0.000067) (0.368421,0.000058) (0.385965,0.000055) (0.403509,0.000053) (0.421053,0.000052) (0.438596,0.000043) (0.456140,0.000034) (0.473684,0.000030) (0.491228,0.000029) (0.508772,0.000023) (0.526316,0.000022) (0.543860,0.000022) (0.561404,0.000022) (0.578947,0.000020) (0.596491,0.000019) (0.614035,0.000018) (0.631579,0.000014) (0.649123,0.000012) (0.666667,0.000011) (0.684211,0.000010) (0.701754,0.000006) (0.719298,0.000006) (0.736842,0.000005) (0.754386,0.000004) (0.771930,0.000004) (0.789474,0.000004) (0.807018,0.000003) (0.824561,0.000003) (0.842105,0.000002) (0.859649,0.000002) (0.877193,0.000001) (0.894737,0.000001) (0.912281,0.000001) (0.929825,0.000001) (0.947368,0.000000) (0.964912,0.000000) (0.982456,0.000000) (1.000000,0.000000) +}; + +\addplot[black] coordinates { +(0.000000,1.000000) (0.001953,0.247783) (0.003906,0.056979) (0.005859,0.026968) (0.007812,0.019062) (0.009766,0.014136) (0.011719,0.011763) (0.013672,0.009968) (0.015625,0.009263) (0.017578,0.007132) (0.019531,0.006664) (0.021484,0.006547) (0.023438,0.006214) (0.025391,0.006190) (0.027344,0.005569) (0.029297,0.004773) (0.031250,0.004590) (0.033203,0.004576) (0.035156,0.004534) (0.037109,0.004497) (0.039062,0.004348) (0.041016,0.004135) (0.042969,0.003889) (0.044922,0.003631) (0.046875,0.003618) (0.048828,0.003285) (0.050781,0.003143) (0.052734,0.003024) (0.054688,0.003020) (0.056641,0.002903) (0.058594,0.002661) (0.060547,0.002589) (0.062500,0.002268) (0.064453,0.002194) (0.066406,0.002187) (0.068359,0.001941) (0.070312,0.001798) (0.072266,0.001740) (0.074219,0.001716) (0.076172,0.001704) (0.078125,0.001658) (0.080078,0.001649) (0.082031,0.001550) (0.083984,0.001484) (0.085938,0.001468) (0.087891,0.001432) (0.089844,0.001429) (0.091797,0.001423) (0.093750,0.001376) (0.095703,0.001359) (0.097656,0.001281) (0.099609,0.001224) (0.101562,0.001212) (0.103516,0.001182) (0.105469,0.001181) (0.107422,0.001174) (0.109375,0.001089) (0.111328,0.001037) (0.113281,0.001024) (0.115234,0.000993) (0.117188,0.000955) (0.119141,0.000955) (0.121094,0.000954) (0.123047,0.000954) (0.125000,0.000902) (0.126953,0.000889) (0.128906,0.000887) (0.130859,0.000881) (0.132812,0.000856) (0.134766,0.000823) (0.136719,0.000694) (0.138672,0.000676) (0.140625,0.000675) (0.142578,0.000675) (0.144531,0.000625) (0.146484,0.000616) (0.148438,0.000603) (0.150391,0.000591) (0.152344,0.000575) (0.154297,0.000573) (0.156250,0.000553) (0.158203,0.000514) (0.160156,0.000491) (0.162109,0.000467) (0.164062,0.000429) (0.166016,0.000426) (0.167969,0.000426) (0.169922,0.000421) (0.171875,0.000419) (0.173828,0.000418) (0.175781,0.000413) (0.177734,0.000408) (0.179688,0.000408) (0.181641,0.000388) (0.183594,0.000385) (0.185547,0.000355) (0.187500,0.000336) (0.189453,0.000334) (0.191406,0.000324) (0.193359,0.000303) (0.195312,0.000296) (0.197266,0.000291) (0.199219,0.000267) (0.201172,0.000265) (0.203125,0.000264) (0.205078,0.000261) (0.207031,0.000260) (0.208984,0.000259) (0.210938,0.000259) (0.212891,0.000251) (0.214844,0.000248) (0.216797,0.000245) (0.218750,0.000237) (0.220703,0.000215) (0.222656,0.000209) (0.224609,0.000208) (0.226562,0.000204) (0.228516,0.000201) (0.230469,0.000199) (0.232422,0.000197) (0.234375,0.000195) (0.236328,0.000179) (0.238281,0.000178) (0.240234,0.000178) (0.242188,0.000178) (0.244141,0.000178) (0.246094,0.000178) (0.248047,0.000178) (0.250000,0.000178) (0.251953,0.000171) (0.253906,0.000171) (0.255859,0.000170) (0.257812,0.000169) (0.259766,0.000166) (0.261719,0.000164) (0.263672,0.000163) (0.265625,0.000161) (0.267578,0.000160) (0.269531,0.000158) (0.271484,0.000155) (0.273438,0.000152) (0.275391,0.000148) (0.277344,0.000148) (0.279297,0.000148) (0.281250,0.000147) (0.283203,0.000147) (0.285156,0.000147) (0.287109,0.000146) (0.289062,0.000146) (0.291016,0.000145) (0.292969,0.000138) (0.294922,0.000136) (0.296875,0.000135) (0.298828,0.000134) (0.300781,0.000133) (0.302734,0.000132) (0.304688,0.000127) (0.306641,0.000125) (0.308594,0.000125) (0.310547,0.000124) (0.312500,0.000122) (0.314453,0.000121) (0.316406,0.000120) (0.318359,0.000119) (0.320312,0.000118) (0.322266,0.000118) (0.324219,0.000113) (0.326172,0.000110) (0.328125,0.000109) (0.330078,0.000107) (0.332031,0.000106) (0.333984,0.000104) (0.335938,0.000102) (0.337891,0.000097) (0.339844,0.000095) (0.341797,0.000092) (0.343750,0.000091) (0.345703,0.000089) (0.347656,0.000088) (0.349609,0.000086) (0.351562,0.000086) (0.353516,0.000086) (0.355469,0.000085) (0.357422,0.000085) (0.359375,0.000084) (0.361328,0.000083) (0.363281,0.000081) (0.365234,0.000081) (0.367188,0.000081) (0.369141,0.000077) (0.371094,0.000076) (0.373047,0.000076) (0.375000,0.000075) (0.376953,0.000074) (0.378906,0.000074) (0.380859,0.000067) (0.382812,0.000066) (0.384766,0.000065) (0.386719,0.000065) (0.388672,0.000062) (0.390625,0.000060) (0.392578,0.000055) (0.394531,0.000055) (0.396484,0.000051) (0.398438,0.000049) (0.400391,0.000049) (0.402344,0.000048) (0.404297,0.000046) (0.406250,0.000045) (0.408203,0.000044) (0.410156,0.000044) (0.412109,0.000044) (0.414062,0.000043) (0.416016,0.000042) (0.417969,0.000042) (0.419922,0.000041) (0.421875,0.000040) (0.423828,0.000040) (0.425781,0.000040) (0.427734,0.000038) (0.429688,0.000038) (0.431641,0.000037) (0.433594,0.000036) (0.435547,0.000035) (0.437500,0.000035) (0.439453,0.000034) (0.441406,0.000034) (0.443359,0.000034) (0.445312,0.000033) (0.447266,0.000032) (0.449219,0.000031) (0.451172,0.000031) (0.453125,0.000031) (0.455078,0.000029) (0.457031,0.000028) (0.458984,0.000027) (0.460938,0.000027) (0.462891,0.000027) (0.464844,0.000027) (0.466797,0.000026) (0.468750,0.000025) (0.470703,0.000025) (0.472656,0.000025) (0.474609,0.000024) (0.476562,0.000024) (0.478516,0.000023) (0.480469,0.000023) (0.482422,0.000023) (0.484375,0.000023) (0.486328,0.000023) (0.488281,0.000023) (0.490234,0.000023) (0.492188,0.000023) (0.494141,0.000023) (0.496094,0.000023) (0.498047,0.000023) (0.500000,0.000023) (0.501953,0.000023) (0.503906,0.000022) (0.505859,0.000022) (0.507812,0.000022) (0.509766,0.000022) (0.511719,0.000022) (0.513672,0.000021) (0.515625,0.000021) (0.517578,0.000021) (0.519531,0.000021) (0.521484,0.000021) (0.523438,0.000021) (0.525391,0.000021) (0.527344,0.000020) (0.529297,0.000020) (0.531250,0.000019) (0.533203,0.000019) (0.535156,0.000019) (0.537109,0.000019) (0.539062,0.000018) (0.541016,0.000018) (0.542969,0.000018) (0.544922,0.000018) (0.546875,0.000018) (0.548828,0.000018) (0.550781,0.000017) (0.552734,0.000017) (0.554688,0.000017) (0.556641,0.000017) (0.558594,0.000017) (0.560547,0.000016) (0.562500,0.000016) (0.564453,0.000016) (0.566406,0.000015) (0.568359,0.000015) (0.570312,0.000015) (0.572266,0.000015) (0.574219,0.000014) (0.576172,0.000014) (0.578125,0.000014) (0.580078,0.000014) (0.582031,0.000013) (0.583984,0.000013) (0.585938,0.000013) (0.587891,0.000013) (0.589844,0.000013) (0.591797,0.000012) (0.593750,0.000012) (0.595703,0.000012) (0.597656,0.000012) (0.599609,0.000012) (0.601562,0.000012) (0.603516,0.000012) (0.605469,0.000012) (0.607422,0.000011) (0.609375,0.000011) (0.611328,0.000011) (0.613281,0.000011) (0.615234,0.000011) (0.617188,0.000011) (0.619141,0.000011) (0.621094,0.000010) (0.623047,0.000010) (0.625000,0.000009) (0.626953,0.000009) (0.628906,0.000009) (0.630859,0.000009) (0.632812,0.000009) (0.634766,0.000009) (0.636719,0.000009) (0.638672,0.000009) (0.640625,0.000009) (0.642578,0.000009) (0.644531,0.000009) (0.646484,0.000009) (0.648438,0.000009) (0.650391,0.000009) (0.652344,0.000009) (0.654297,0.000009) (0.656250,0.000009) (0.658203,0.000009) (0.660156,0.000009) (0.662109,0.000009) (0.664062,0.000009) (0.666016,0.000009) (0.667969,0.000009) (0.669922,0.000008) (0.671875,0.000008) (0.673828,0.000008) (0.675781,0.000008) (0.677734,0.000008) (0.679688,0.000008) (0.681641,0.000008) (0.683594,0.000008) (0.685547,0.000008) (0.687500,0.000008) (0.689453,0.000008) (0.691406,0.000008) (0.693359,0.000008) (0.695312,0.000008) (0.697266,0.000008) (0.699219,0.000007) (0.701172,0.000007) (0.703125,0.000007) (0.705078,0.000007) (0.707031,0.000007) (0.708984,0.000007) (0.710938,0.000007) (0.712891,0.000007) (0.714844,0.000006) (0.716797,0.000006) (0.718750,0.000006) (0.720703,0.000006) (0.722656,0.000006) (0.724609,0.000006) (0.726562,0.000006) (0.728516,0.000006) (0.730469,0.000006) (0.732422,0.000005) (0.734375,0.000005) (0.736328,0.000005) (0.738281,0.000005) (0.740234,0.000005) (0.742188,0.000005) (0.744141,0.000005) (0.746094,0.000005) (0.748047,0.000005) (0.750000,0.000005) (0.751953,0.000005) (0.753906,0.000005) (0.755859,0.000004) (0.757812,0.000004) (0.759766,0.000004) (0.761719,0.000004) (0.763672,0.000004) (0.765625,0.000004) (0.767578,0.000004) (0.769531,0.000004) (0.771484,0.000004) (0.773438,0.000004) (0.775391,0.000004) (0.777344,0.000004) (0.779297,0.000004) (0.781250,0.000004) (0.783203,0.000004) (0.785156,0.000004) (0.787109,0.000004) (0.789062,0.000004) (0.791016,0.000004) (0.792969,0.000004) (0.794922,0.000004) (0.796875,0.000004) (0.798828,0.000004) (0.800781,0.000004) (0.802734,0.000003) (0.804688,0.000003) (0.806641,0.000003) (0.808594,0.000003) (0.810547,0.000003) (0.812500,0.000003) (0.814453,0.000003) (0.816406,0.000003) (0.818359,0.000003) (0.820312,0.000003) (0.822266,0.000003) (0.824219,0.000003) (0.826172,0.000003) (0.828125,0.000003) (0.830078,0.000003) (0.832031,0.000003) (0.833984,0.000003) (0.835938,0.000003) (0.837891,0.000003) (0.839844,0.000003) (0.841797,0.000003) (0.843750,0.000003) (0.845703,0.000003) (0.847656,0.000003) (0.849609,0.000003) (0.851562,0.000003) (0.853516,0.000002) (0.855469,0.000002) (0.857422,0.000002) (0.859375,0.000002) (0.861328,0.000002) (0.863281,0.000002) (0.865234,0.000002) (0.867188,0.000002) (0.869141,0.000002) (0.871094,0.000002) (0.873047,0.000002) (0.875000,0.000002) (0.876953,0.000002) (0.878906,0.000002) (0.880859,0.000002) (0.882812,0.000002) (0.884766,0.000002) (0.886719,0.000002) (0.888672,0.000002) (0.890625,0.000002) (0.892578,0.000002) (0.894531,0.000002) (0.896484,0.000002) (0.898438,0.000002) (0.900391,0.000001) (0.902344,0.000001) (0.904297,0.000001) (0.906250,0.000001) (0.908203,0.000001) (0.910156,0.000001) (0.912109,0.000001) (0.914062,0.000001) (0.916016,0.000001) (0.917969,0.000001) (0.919922,0.000001) (0.921875,0.000001) (0.923828,0.000001) (0.925781,0.000001) (0.927734,0.000001) (0.929688,0.000001) (0.931641,0.000001) (0.933594,0.000001) (0.935547,0.000001) (0.937500,0.000001) (0.939453,0.000001) (0.941406,0.000001) (0.943359,0.000001) (0.945312,0.000001) (0.947266,0.000001) (0.949219,0.000001) (0.951172,0.000001) (0.953125,0.000001) (0.955078,0.000001) (0.957031,0.000001) (0.958984,0.000001) (0.960938,0.000000) (0.962891,0.000000) (0.964844,0.000000) (0.966797,0.000000) (0.968750,0.000000) (0.970703,0.000000) (0.972656,0.000000) (0.974609,0.000000) (0.976562,0.000000) (0.978516,0.000000) (0.980469,0.000000) (0.982422,0.000000) (0.984375,0.000000) (0.986328,0.000000) (0.988281,0.000000) (0.990234,0.000000) (0.992188,0.000000) (0.994141,0.000000) (0.996094,0.000000) (0.998047,0.000000) (1.000000,0.000000) +}; + +\addplot[gray] coordinates { +(0.000000,1.000000) (0.017241,0.487558) (0.034483,0.386091) (0.051724,0.126229) (0.068966,0.108863) (0.086207,0.100941) (0.103448,0.097250) (0.120690,0.060934) (0.137931,0.054349) (0.155172,0.025283) (0.172414,0.025270) (0.189655,0.025262) (0.206897,0.025238) (0.224138,0.025208) (0.241379,0.022267) (0.258621,0.016262) (0.275862,0.016261) (0.293103,0.012610) (0.310345,0.009401) (0.327586,0.008822) (0.344828,0.008804) (0.362069,0.008801) (0.379310,0.007326) (0.396552,0.006830) (0.413793,0.003673) (0.431034,0.003672) (0.448276,0.003642) (0.465517,0.001939) (0.482759,0.001709) (0.500000,0.000965) (0.517241,0.000962) (0.534483,0.000277) (0.551724,0.000119) (0.568966,0.000093) (0.586207,0.000088) (0.603448,0.000050) (0.620690,0.000048) (0.637931,0.000043) (0.655172,0.000042) (0.672414,0.000025) (0.689655,0.000021) (0.706897,0.000011) (0.724138,0.000011) (0.741379,0.000011) (0.758621,0.000011) (0.775862,0.000011) (0.793103,0.000010) (0.810345,0.000009) (0.827586,0.000008) (0.844828,0.000006) (0.862069,0.000005) (0.879310,0.000004) (0.896552,0.000003) (0.913793,0.000002) (0.931034,0.000002) (0.948276,0.000001) (0.965517,0.000001) (0.982759,0.000001) (1.000000,0.000000) +}; + +\addplot[darkgray] coordinates { +(0.000000,1.000000) (0.035714,0.909090) (0.071429,0.409043) (0.107143,0.409043) (0.142857,0.045445) (0.178571,0.045445) (0.214286,0.045437) (0.250000,0.045437) (0.285714,0.001856) (0.321429,0.000157) (0.357143,0.000150) (0.392857,0.000148) (0.428571,0.000138) (0.464286,0.000116) (0.500000,0.000070) (0.535714,0.000048) (0.571429,0.000032) (0.607143,0.000032) (0.642857,0.000032) (0.678571,0.000016) (0.714286,0.000009) (0.750000,0.000008) (0.785714,0.000008) (0.821429,0.000008) (0.857143,0.000006) (0.892857,0.000005) (0.928571,0.000002) (0.964286,0.000001) (1.000000,0.000001) +}; + +\addplot[lightgray] coordinates { +(0.000000,1.000000) (0.004292,0.333547) (0.008584,0.333312) (0.012876,0.166857) (0.017167,0.166758) (0.021459,0.166551) (0.025751,0.166414) (0.030043,0.166294) (0.034335,0.165678) (0.038627,0.153140) (0.042918,0.084910) (0.047210,0.084877) (0.051502,0.083928) (0.055794,0.083394) (0.060086,0.083329) (0.064378,0.083328) (0.068670,0.083313) (0.072961,0.083313) (0.077253,0.083302) (0.081545,0.083301) (0.085837,0.083292) (0.090129,0.083239) (0.094421,0.083209) (0.098712,0.083176) (0.103004,0.083169) (0.107296,0.083125) (0.111588,0.083071) (0.115880,0.083067) (0.120172,0.083054) (0.124464,0.082872) (0.128755,0.082758) (0.133047,0.082151) (0.137339,0.081810) (0.141631,0.081809) (0.145923,0.081721) (0.150215,0.081378) (0.154506,0.081001) (0.158798,0.063929) (0.163090,0.041639) (0.167382,0.017348) (0.171674,0.012510) (0.175966,0.011755) (0.180258,0.004971) (0.184549,0.004140) (0.188841,0.003972) (0.193133,0.002505) (0.197425,0.002447) (0.201717,0.002335) (0.206009,0.002075) (0.210300,0.001713) (0.214592,0.001685) (0.218884,0.001622) (0.223176,0.001588) (0.227468,0.001512) (0.231760,0.001506) (0.236052,0.001486) (0.240343,0.001475) (0.244635,0.001291) (0.248927,0.001284) (0.253219,0.001203) (0.257511,0.001158) (0.261803,0.001088) (0.266094,0.001087) (0.270386,0.001028) (0.274678,0.001019) (0.278970,0.001010) (0.283262,0.000943) (0.287554,0.000860) (0.291845,0.000808) (0.296137,0.000797) (0.300429,0.000788) (0.304721,0.000773) (0.309013,0.000769) (0.313305,0.000686) (0.317597,0.000640) (0.321888,0.000621) (0.326180,0.000604) (0.330472,0.000548) (0.334764,0.000478) (0.339056,0.000468) (0.343348,0.000444) (0.347639,0.000424) (0.351931,0.000419) (0.356223,0.000404) (0.360515,0.000388) (0.364807,0.000384) (0.369099,0.000381) (0.373391,0.000333) (0.377682,0.000327) (0.381974,0.000318) (0.386266,0.000301) (0.390558,0.000271) (0.394850,0.000262) (0.399142,0.000255) (0.403433,0.000243) (0.407725,0.000238) (0.412017,0.000237) (0.416309,0.000235) (0.420601,0.000230) (0.424893,0.000209) (0.429185,0.000189) (0.433476,0.000174) (0.437768,0.000165) (0.442060,0.000164) (0.446352,0.000153) (0.450644,0.000151) (0.454936,0.000150) (0.459227,0.000140) (0.463519,0.000136) (0.467811,0.000136) (0.472103,0.000118) (0.476395,0.000117) (0.480687,0.000112) (0.484979,0.000111) (0.489270,0.000106) (0.493562,0.000106) (0.497854,0.000106) (0.502146,0.000106) (0.506438,0.000106) (0.510730,0.000102) (0.515021,0.000092) (0.519313,0.000087) (0.523605,0.000082) (0.527897,0.000079) (0.532189,0.000077) (0.536481,0.000076) (0.540773,0.000075) (0.545064,0.000074) (0.549356,0.000073) (0.553648,0.000068) (0.557940,0.000068) (0.562232,0.000066) (0.566524,0.000063) (0.570815,0.000063) (0.575107,0.000062) (0.579399,0.000061) (0.583691,0.000061) (0.587983,0.000060) (0.592275,0.000059) (0.596567,0.000053) (0.600858,0.000050) (0.605150,0.000047) (0.609442,0.000046) (0.613734,0.000042) (0.618026,0.000042) (0.622318,0.000041) (0.626609,0.000040) (0.630901,0.000035) (0.635193,0.000035) (0.639485,0.000033) (0.643777,0.000033) (0.648069,0.000032) (0.652361,0.000032) (0.656652,0.000031) (0.660944,0.000031) (0.665236,0.000031) (0.669528,0.000031) (0.673820,0.000030) (0.678112,0.000029) (0.682403,0.000028) (0.686695,0.000027) (0.690987,0.000026) (0.695279,0.000025) (0.699571,0.000023) (0.703863,0.000022) (0.708155,0.000022) (0.712446,0.000021) (0.716738,0.000019) (0.721030,0.000018) (0.725322,0.000017) (0.729614,0.000016) (0.733906,0.000013) (0.738197,0.000012) (0.742489,0.000011) (0.746781,0.000011) (0.751073,0.000011) (0.755365,0.000011) (0.759657,0.000011) (0.763948,0.000011) (0.768240,0.000011) (0.772532,0.000011) (0.776824,0.000011) (0.781116,0.000011) (0.785408,0.000010) (0.789700,0.000010) (0.793991,0.000009) (0.798283,0.000009) (0.802575,0.000009) (0.806867,0.000009) (0.811159,0.000008) (0.815451,0.000007) (0.819742,0.000005) (0.824034,0.000005) (0.828326,0.000005) (0.832618,0.000005) (0.836910,0.000005) (0.841202,0.000004) (0.845494,0.000004) (0.849785,0.000004) (0.854077,0.000004) (0.858369,0.000004) (0.862661,0.000004) (0.866953,0.000004) (0.871245,0.000003) (0.875536,0.000003) (0.879828,0.000003) (0.884120,0.000003) (0.888412,0.000003) (0.892704,0.000002) (0.896996,0.000002) (0.901288,0.000002) (0.905579,0.000002) (0.909871,0.000002) (0.914163,0.000002) (0.918455,0.000001) (0.922747,0.000001) (0.927039,0.000001) (0.931330,0.000001) (0.935622,0.000001) (0.939914,0.000001) (0.944206,0.000001) (0.948498,0.000001) (0.952790,0.000001) (0.957082,0.000001) (0.961373,0.000001) (0.965665,0.000001) (0.969957,0.000001) (0.974249,0.000001) (0.978541,0.000001) (0.982833,0.000001) (0.987124,0.000001) (0.991416,0.000001) (0.995708,0.000001) (1.000000,0.000001) +}; + +\addplot[brown] coordinates { +(0.000000,1.000000) (0.000834,0.872400) (0.001668,0.683224) (0.002502,0.608314) (0.003336,0.542330) (0.004170,0.519721) (0.005004,0.447508) (0.005838,0.440065) (0.006672,0.420670) (0.007506,0.418862) (0.008340,0.418009) (0.009174,0.379519) (0.010008,0.357223) (0.010842,0.353534) (0.011676,0.333568) (0.012510,0.319704) (0.013344,0.268160) (0.014178,0.251065) (0.015013,0.226789) (0.015847,0.220089) (0.016681,0.215066) (0.017515,0.213903) (0.018349,0.213091) (0.019183,0.197153) (0.020017,0.187389) (0.020851,0.177430) (0.021685,0.173396) (0.022519,0.170787) (0.023353,0.160834) (0.024187,0.160045) (0.025021,0.157071) (0.025855,0.146612) (0.026689,0.144178) (0.027523,0.137699) (0.028357,0.136683) (0.029191,0.124833) (0.030025,0.121453) (0.030859,0.119189) (0.031693,0.115002) (0.032527,0.114249) (0.033361,0.107546) (0.034195,0.107268) (0.035029,0.104187) (0.035863,0.096624) (0.036697,0.089912) (0.037531,0.089585) (0.038365,0.087446) (0.039199,0.087298) (0.040033,0.084823) (0.040867,0.083414) (0.041701,0.083212) (0.042535,0.082227) (0.043369,0.079913) (0.044204,0.075734) (0.045038,0.073337) (0.045872,0.073039) (0.046706,0.072381) (0.047540,0.069693) (0.048374,0.067325) (0.049208,0.065996) (0.050042,0.057532) (0.050876,0.055707) (0.051710,0.055669) (0.052544,0.049083) (0.053378,0.048652) (0.054212,0.048015) (0.055046,0.045918) (0.055880,0.045234) (0.056714,0.042272) (0.057548,0.041798) (0.058382,0.040969) (0.059216,0.040163) (0.060050,0.040016) (0.060884,0.038778) (0.061718,0.038686) (0.062552,0.038456) (0.063386,0.033439) (0.064220,0.032381) (0.065054,0.031115) (0.065888,0.030103) (0.066722,0.029385) (0.067556,0.026654) (0.068390,0.025877) (0.069224,0.024467) (0.070058,0.024427) (0.070892,0.024134) (0.071726,0.024036) (0.072560,0.021379) (0.073394,0.020813) (0.074229,0.020166) (0.075063,0.020056) (0.075897,0.019981) (0.076731,0.019791) (0.077565,0.019672) (0.078399,0.019356) (0.079233,0.019269) (0.080067,0.019134) (0.080901,0.018119) (0.081735,0.017905) (0.082569,0.017878) (0.083403,0.017865) (0.084237,0.017769) (0.085071,0.017758) (0.085905,0.017065) (0.086739,0.016959) (0.087573,0.016686) (0.088407,0.015666) (0.089241,0.014908) (0.090075,0.014542) (0.090909,0.014518) (0.091743,0.014200) (0.092577,0.013865) (0.093411,0.013736) (0.094245,0.013273) (0.095079,0.013197) (0.095913,0.012997) (0.096747,0.012759) (0.097581,0.012642) (0.098415,0.012344) (0.099249,0.012031) (0.100083,0.011973) (0.100917,0.011805) (0.101751,0.011594) (0.102585,0.011387) (0.103420,0.011332) (0.104254,0.011246) (0.105088,0.010925) (0.105922,0.010566) (0.106756,0.010269) (0.107590,0.010235) (0.108424,0.010220) (0.109258,0.010135) (0.110092,0.010071) (0.110926,0.010048) (0.111760,0.010002) (0.112594,0.009762) (0.113428,0.009756) (0.114262,0.009751) (0.115096,0.009730) (0.115930,0.009551) (0.116764,0.009536) (0.117598,0.009404) (0.118432,0.009399) (0.119266,0.009298) (0.120100,0.009263) (0.120934,0.009245) (0.121768,0.009137) (0.122602,0.009120) (0.123436,0.009097) (0.124270,0.008816) (0.125104,0.008646) (0.125938,0.008484) (0.126772,0.008405) (0.127606,0.008149) (0.128440,0.008032) (0.129274,0.007872) (0.130108,0.007866) (0.130942,0.007823) (0.131776,0.007801) (0.132611,0.007718) (0.133445,0.007481) (0.134279,0.007373) (0.135113,0.007345) (0.135947,0.007296) (0.136781,0.007269) (0.137615,0.007233) (0.138449,0.006991) (0.139283,0.006905) (0.140117,0.006795) (0.140951,0.006738) (0.141785,0.006708) (0.142619,0.006551) (0.143453,0.006510) (0.144287,0.006435) (0.145121,0.006361) (0.145955,0.006238) (0.146789,0.006134) (0.147623,0.006027) (0.148457,0.005991) (0.149291,0.005921) (0.150125,0.005852) (0.150959,0.005852) (0.151793,0.005823) (0.152627,0.005794) (0.153461,0.005787) (0.154295,0.005746) (0.155129,0.005672) (0.155963,0.005619) (0.156797,0.005612) (0.157631,0.005557) (0.158465,0.005495) (0.159299,0.005495) (0.160133,0.005422) (0.160967,0.005324) (0.161802,0.005217) (0.162636,0.005196) (0.163470,0.005167) (0.164304,0.005107) (0.165138,0.005012) (0.165972,0.004999) (0.166806,0.004985) (0.167640,0.004981) (0.168474,0.004936) (0.169308,0.004912) (0.170142,0.004836) (0.170976,0.004822) (0.171810,0.004755) (0.172644,0.004692) (0.173478,0.004687) (0.174312,0.004667) (0.175146,0.004605) (0.175980,0.004546) (0.176814,0.004523) (0.177648,0.004518) (0.178482,0.004512) (0.179316,0.004447) (0.180150,0.004427) (0.180984,0.004408) (0.181818,0.004401) (0.182652,0.004336) (0.183486,0.004326) (0.184320,0.004255) (0.185154,0.004163) (0.185988,0.004152) (0.186822,0.004150) (0.187656,0.004132) (0.188490,0.004125) (0.189324,0.003972) (0.190158,0.003971) (0.190992,0.003942) (0.191827,0.003842) (0.192661,0.003797) (0.193495,0.003710) (0.194329,0.003703) (0.195163,0.003684) (0.195997,0.003626) (0.196831,0.003620) (0.197665,0.003576) (0.198499,0.003526) (0.199333,0.003451) (0.200167,0.003447) (0.201001,0.003402) (0.201835,0.003390) (0.202669,0.003364) (0.203503,0.003361) (0.204337,0.003356) (0.205171,0.003350) (0.206005,0.003341) (0.206839,0.003321) (0.207673,0.003278) (0.208507,0.003246) (0.209341,0.003239) (0.210175,0.003219) (0.211009,0.003208) (0.211843,0.003129) (0.212677,0.003123) (0.213511,0.003073) (0.214345,0.003063) (0.215179,0.003053) (0.216013,0.003053) (0.216847,0.003026) (0.217681,0.003007) (0.218515,0.002989) (0.219349,0.002929) (0.220183,0.002915) (0.221018,0.002913) (0.221852,0.002890) (0.222686,0.002861) (0.223520,0.002845) (0.224354,0.002804) (0.225188,0.002783) (0.226022,0.002781) (0.226856,0.002694) (0.227690,0.002669) (0.228524,0.002631) (0.229358,0.002579) (0.230192,0.002578) (0.231026,0.002573) (0.231860,0.002566) (0.232694,0.002507) (0.233528,0.002487) (0.234362,0.002486) (0.235196,0.002416) (0.236030,0.002367) (0.236864,0.002347) (0.237698,0.002344) (0.238532,0.002338) (0.239366,0.002330) (0.240200,0.002318) (0.241034,0.002315) (0.241868,0.002308) (0.242702,0.002308) (0.243536,0.002292) (0.244370,0.002287) (0.245204,0.002283) (0.246038,0.002264) (0.246872,0.002236) (0.247706,0.002227) (0.248540,0.002185) (0.249374,0.002173) (0.250209,0.002169) (0.251043,0.002135) (0.251877,0.002109) (0.252711,0.002039) (0.253545,0.002031) (0.254379,0.001987) (0.255213,0.001970) (0.256047,0.001966) (0.256881,0.001936) (0.257715,0.001908) (0.258549,0.001908) (0.259383,0.001893) (0.260217,0.001886) (0.261051,0.001882) (0.261885,0.001827) (0.262719,0.001827) (0.263553,0.001817) (0.264387,0.001797) (0.265221,0.001749) (0.266055,0.001742) (0.266889,0.001739) (0.267723,0.001727) (0.268557,0.001704) (0.269391,0.001700) (0.270225,0.001691) (0.271059,0.001690) (0.271893,0.001653) (0.272727,0.001600) (0.273561,0.001595) (0.274395,0.001555) (0.275229,0.001547) (0.276063,0.001546) (0.276897,0.001519) (0.277731,0.001513) (0.278565,0.001510) (0.279399,0.001505) (0.280234,0.001474) (0.281068,0.001468) (0.281902,0.001459) (0.282736,0.001458) (0.283570,0.001432) (0.284404,0.001410) (0.285238,0.001407) (0.286072,0.001401) (0.286906,0.001396) (0.287740,0.001391) (0.288574,0.001376) (0.289408,0.001372) (0.290242,0.001369) (0.291076,0.001345) (0.291910,0.001344) (0.292744,0.001318) (0.293578,0.001299) (0.294412,0.001295) (0.295246,0.001287) (0.296080,0.001285) (0.296914,0.001284) (0.297748,0.001270) (0.298582,0.001265) (0.299416,0.001253) (0.300250,0.001235) (0.301084,0.001233) (0.301918,0.001224) (0.302752,0.001222) (0.303586,0.001219) (0.304420,0.001209) (0.305254,0.001202) (0.306088,0.001191) (0.306922,0.001180) (0.307756,0.001173) (0.308590,0.001170) (0.309425,0.001167) (0.310259,0.001154) (0.311093,0.001147) (0.311927,0.001143) (0.312761,0.001130) (0.313595,0.001126) (0.314429,0.001124) (0.315263,0.001116) (0.316097,0.001115) (0.316931,0.001099) (0.317765,0.001088) (0.318599,0.001088) (0.319433,0.001082) (0.320267,0.001074) (0.321101,0.001071) (0.321935,0.001070) (0.322769,0.001066) (0.323603,0.001062) (0.324437,0.001047) (0.325271,0.001043) (0.326105,0.001041) (0.326939,0.001040) (0.327773,0.001038) (0.328607,0.001027) (0.329441,0.001025) (0.330275,0.001016) (0.331109,0.001016) (0.331943,0.000996) (0.332777,0.000992) (0.333611,0.000985) (0.334445,0.000979) (0.335279,0.000978) (0.336113,0.000978) (0.336947,0.000957) (0.337781,0.000953) (0.338616,0.000951) (0.339450,0.000947) (0.340284,0.000944) (0.341118,0.000939) (0.341952,0.000932) (0.342786,0.000930) (0.343620,0.000930) (0.344454,0.000928) (0.345288,0.000915) (0.346122,0.000914) (0.346956,0.000914) (0.347790,0.000911) (0.348624,0.000910) (0.349458,0.000908) (0.350292,0.000904) (0.351126,0.000895) (0.351960,0.000890) (0.352794,0.000887) (0.353628,0.000884) (0.354462,0.000879) (0.355296,0.000861) (0.356130,0.000861) (0.356964,0.000826) (0.357798,0.000814) (0.358632,0.000808) (0.359466,0.000800) (0.360300,0.000797) (0.361134,0.000796) (0.361968,0.000782) (0.362802,0.000779) (0.363636,0.000778) (0.364470,0.000777) (0.365304,0.000777) (0.366138,0.000775) (0.366972,0.000767) (0.367807,0.000764) (0.368641,0.000761) (0.369475,0.000758) (0.370309,0.000753) (0.371143,0.000753) (0.371977,0.000751) (0.372811,0.000738) (0.373645,0.000718) (0.374479,0.000718) (0.375313,0.000710) (0.376147,0.000709) (0.376981,0.000707) (0.377815,0.000701) (0.378649,0.000699) (0.379483,0.000694) (0.380317,0.000694) (0.381151,0.000688) (0.381985,0.000686) (0.382819,0.000683) (0.383653,0.000681) (0.384487,0.000665) (0.385321,0.000664) (0.386155,0.000660) (0.386989,0.000659) (0.387823,0.000657) (0.388657,0.000657) (0.389491,0.000655) (0.390325,0.000654) (0.391159,0.000647) (0.391993,0.000645) (0.392827,0.000644) (0.393661,0.000643) (0.394495,0.000642) (0.395329,0.000640) (0.396163,0.000639) (0.396997,0.000637) (0.397832,0.000634) (0.398666,0.000630) (0.399500,0.000614) (0.400334,0.000613) (0.401168,0.000607) (0.402002,0.000604) (0.402836,0.000603) (0.403670,0.000602) (0.404504,0.000602) (0.405338,0.000598) (0.406172,0.000597) (0.407006,0.000592) (0.407840,0.000588) (0.408674,0.000576) (0.409508,0.000572) (0.410342,0.000570) (0.411176,0.000570) (0.412010,0.000567) (0.412844,0.000567) (0.413678,0.000566) (0.414512,0.000564) (0.415346,0.000563) (0.416180,0.000554) (0.417014,0.000550) (0.417848,0.000548) (0.418682,0.000547) (0.419516,0.000547) (0.420350,0.000546) (0.421184,0.000542) (0.422018,0.000542) (0.422852,0.000535) (0.423686,0.000529) (0.424520,0.000518) (0.425354,0.000516) (0.426188,0.000515) (0.427023,0.000513) (0.427857,0.000512) (0.428691,0.000511) (0.429525,0.000503) (0.430359,0.000503) (0.431193,0.000503) (0.432027,0.000499) (0.432861,0.000497) (0.433695,0.000497) (0.434529,0.000495) (0.435363,0.000495) (0.436197,0.000494) (0.437031,0.000494) (0.437865,0.000492) (0.438699,0.000491) (0.439533,0.000490) (0.440367,0.000489) (0.441201,0.000488) (0.442035,0.000486) (0.442869,0.000484) (0.443703,0.000480) (0.444537,0.000479) (0.445371,0.000478) (0.446205,0.000471) (0.447039,0.000467) (0.447873,0.000466) (0.448707,0.000464) (0.449541,0.000460) (0.450375,0.000458) (0.451209,0.000456) (0.452043,0.000452) (0.452877,0.000451) (0.453711,0.000448) (0.454545,0.000446) (0.455379,0.000445) (0.456214,0.000444) (0.457048,0.000437) (0.457882,0.000436) (0.458716,0.000435) (0.459550,0.000431) (0.460384,0.000431) (0.461218,0.000430) (0.462052,0.000428) (0.462886,0.000428) (0.463720,0.000428) (0.464554,0.000427) (0.465388,0.000427) (0.466222,0.000422) (0.467056,0.000420) (0.467890,0.000415) (0.468724,0.000409) (0.469558,0.000408) (0.470392,0.000408) (0.471226,0.000406) (0.472060,0.000405) (0.472894,0.000404) (0.473728,0.000404) (0.474562,0.000402) (0.475396,0.000402) (0.476230,0.000402) (0.477064,0.000402) (0.477898,0.000399) (0.478732,0.000399) (0.479566,0.000398) (0.480400,0.000395) (0.481234,0.000395) (0.482068,0.000394) (0.482902,0.000390) (0.483736,0.000389) (0.484570,0.000387) (0.485405,0.000385) (0.486239,0.000383) (0.487073,0.000382) (0.487907,0.000381) (0.488741,0.000380) (0.489575,0.000380) (0.490409,0.000377) (0.491243,0.000375) (0.492077,0.000374) (0.492911,0.000373) (0.493745,0.000371) (0.494579,0.000370) (0.495413,0.000369) (0.496247,0.000368) (0.497081,0.000366) (0.497915,0.000364) (0.498749,0.000362) (0.499583,0.000362) (0.500417,0.000358) (0.501251,0.000354) (0.502085,0.000346) (0.502919,0.000345) (0.503753,0.000344) (0.504587,0.000343) (0.505421,0.000341) (0.506255,0.000340) (0.507089,0.000337) (0.507923,0.000337) (0.508757,0.000331) (0.509591,0.000328) (0.510425,0.000325) (0.511259,0.000323) (0.512093,0.000319) (0.512927,0.000319) (0.513761,0.000317) (0.514595,0.000315) (0.515430,0.000314) (0.516264,0.000313) (0.517098,0.000313) (0.517932,0.000312) (0.518766,0.000312) (0.519600,0.000311) (0.520434,0.000302) (0.521268,0.000300) (0.522102,0.000300) (0.522936,0.000295) (0.523770,0.000295) (0.524604,0.000295) (0.525438,0.000292) (0.526272,0.000290) (0.527106,0.000290) (0.527940,0.000288) (0.528774,0.000287) (0.529608,0.000285) (0.530442,0.000280) (0.531276,0.000278) (0.532110,0.000278) (0.532944,0.000278) (0.533778,0.000277) (0.534612,0.000276) (0.535446,0.000274) (0.536280,0.000273) (0.537114,0.000271) (0.537948,0.000271) (0.538782,0.000270) (0.539616,0.000266) (0.540450,0.000263) (0.541284,0.000260) (0.542118,0.000260) (0.542952,0.000258) (0.543786,0.000258) (0.544621,0.000256) (0.545455,0.000253) (0.546289,0.000252) (0.547123,0.000251) (0.547957,0.000249) (0.548791,0.000248) (0.549625,0.000248) (0.550459,0.000248) (0.551293,0.000246) (0.552127,0.000246) (0.552961,0.000244) (0.553795,0.000244) (0.554629,0.000242) (0.555463,0.000241) (0.556297,0.000240) (0.557131,0.000240) (0.557965,0.000239) (0.558799,0.000236) (0.559633,0.000236) (0.560467,0.000235) (0.561301,0.000234) (0.562135,0.000234) (0.562969,0.000234) (0.563803,0.000233) (0.564637,0.000233) (0.565471,0.000225) (0.566305,0.000223) (0.567139,0.000223) (0.567973,0.000220) (0.568807,0.000219) (0.569641,0.000218) (0.570475,0.000218) (0.571309,0.000217) (0.572143,0.000216) (0.572977,0.000213) (0.573812,0.000211) (0.574646,0.000207) (0.575480,0.000206) (0.576314,0.000206) (0.577148,0.000205) (0.577982,0.000205) (0.578816,0.000203) (0.579650,0.000203) (0.580484,0.000203) (0.581318,0.000203) (0.582152,0.000203) (0.582986,0.000201) (0.583820,0.000200) (0.584654,0.000200) (0.585488,0.000199) (0.586322,0.000199) (0.587156,0.000197) (0.587990,0.000194) (0.588824,0.000193) (0.589658,0.000191) (0.590492,0.000190) (0.591326,0.000190) (0.592160,0.000186) (0.592994,0.000186) (0.593828,0.000181) (0.594662,0.000178) (0.595496,0.000175) (0.596330,0.000174) (0.597164,0.000173) (0.597998,0.000173) (0.598832,0.000172) (0.599666,0.000171) (0.600500,0.000171) (0.601334,0.000170) (0.602168,0.000170) (0.603003,0.000169) (0.603837,0.000166) (0.604671,0.000165) (0.605505,0.000165) (0.606339,0.000165) (0.607173,0.000164) (0.608007,0.000163) (0.608841,0.000162) (0.609675,0.000162) (0.610509,0.000162) (0.611343,0.000162) (0.612177,0.000161) (0.613011,0.000161) (0.613845,0.000159) (0.614679,0.000158) (0.615513,0.000158) (0.616347,0.000157) (0.617181,0.000156) (0.618015,0.000155) (0.618849,0.000155) (0.619683,0.000152) (0.620517,0.000152) (0.621351,0.000151) (0.622185,0.000151) (0.623019,0.000149) (0.623853,0.000149) (0.624687,0.000148) (0.625521,0.000147) (0.626355,0.000147) (0.627189,0.000146) (0.628023,0.000146) (0.628857,0.000146) (0.629691,0.000146) (0.630525,0.000145) (0.631359,0.000145) (0.632193,0.000144) (0.633028,0.000144) (0.633862,0.000144) (0.634696,0.000144) (0.635530,0.000143) (0.636364,0.000142) (0.637198,0.000142) (0.638032,0.000142) (0.638866,0.000142) (0.639700,0.000141) (0.640534,0.000140) (0.641368,0.000139) (0.642202,0.000137) (0.643036,0.000137) (0.643870,0.000133) (0.644704,0.000131) (0.645538,0.000131) (0.646372,0.000129) (0.647206,0.000129) (0.648040,0.000129) (0.648874,0.000128) (0.649708,0.000128) (0.650542,0.000127) (0.651376,0.000124) (0.652210,0.000123) (0.653044,0.000119) (0.653878,0.000117) (0.654712,0.000117) (0.655546,0.000117) (0.656380,0.000115) (0.657214,0.000114) (0.658048,0.000114) (0.658882,0.000114) (0.659716,0.000113) (0.660550,0.000112) (0.661384,0.000111) (0.662219,0.000111) (0.663053,0.000111) (0.663887,0.000111) (0.664721,0.000110) (0.665555,0.000110) (0.666389,0.000109) (0.667223,0.000108) (0.668057,0.000108) (0.668891,0.000107) (0.669725,0.000105) (0.670559,0.000105) (0.671393,0.000105) (0.672227,0.000105) (0.673061,0.000105) (0.673895,0.000105) (0.674729,0.000105) (0.675563,0.000104) (0.676397,0.000104) (0.677231,0.000103) (0.678065,0.000102) (0.678899,0.000101) (0.679733,0.000101) (0.680567,0.000100) (0.681401,0.000100) (0.682235,0.000100) (0.683069,0.000099) (0.683903,0.000099) (0.684737,0.000098) (0.685571,0.000098) (0.686405,0.000098) (0.687239,0.000097) (0.688073,0.000094) (0.688907,0.000094) (0.689741,0.000092) (0.690575,0.000092) (0.691410,0.000091) (0.692244,0.000089) (0.693078,0.000089) (0.693912,0.000087) (0.694746,0.000087) (0.695580,0.000087) (0.696414,0.000086) (0.697248,0.000086) (0.698082,0.000086) (0.698916,0.000085) (0.699750,0.000085) (0.700584,0.000085) (0.701418,0.000085) (0.702252,0.000084) (0.703086,0.000084) (0.703920,0.000083) (0.704754,0.000083) (0.705588,0.000082) (0.706422,0.000081) (0.707256,0.000080) (0.708090,0.000080) (0.708924,0.000080) (0.709758,0.000079) (0.710592,0.000079) (0.711426,0.000078) (0.712260,0.000078) (0.713094,0.000077) (0.713928,0.000076) (0.714762,0.000076) (0.715596,0.000076) (0.716430,0.000075) (0.717264,0.000075) (0.718098,0.000072) (0.718932,0.000071) (0.719766,0.000071) (0.720601,0.000070) (0.721435,0.000070) (0.722269,0.000070) (0.723103,0.000070) (0.723937,0.000070) (0.724771,0.000070) (0.725605,0.000069) (0.726439,0.000068) (0.727273,0.000068) (0.728107,0.000068) (0.728941,0.000067) (0.729775,0.000067) (0.730609,0.000067) (0.731443,0.000067) (0.732277,0.000066) (0.733111,0.000066) (0.733945,0.000065) (0.734779,0.000065) (0.735613,0.000065) (0.736447,0.000065) (0.737281,0.000064) (0.738115,0.000064) (0.738949,0.000063) (0.739783,0.000063) (0.740617,0.000063) (0.741451,0.000062) (0.742285,0.000062) (0.743119,0.000060) (0.743953,0.000060) (0.744787,0.000059) (0.745621,0.000059) (0.746455,0.000059) (0.747289,0.000059) (0.748123,0.000058) (0.748957,0.000058) (0.749791,0.000057) (0.750626,0.000057) (0.751460,0.000057) (0.752294,0.000057) (0.753128,0.000057) (0.753962,0.000057) (0.754796,0.000057) (0.755630,0.000057) (0.756464,0.000057) (0.757298,0.000057) (0.758132,0.000057) (0.758966,0.000057) (0.759800,0.000057) (0.760634,0.000057) (0.761468,0.000057) (0.762302,0.000057) (0.763136,0.000056) (0.763970,0.000056) (0.764804,0.000055) (0.765638,0.000055) (0.766472,0.000055) (0.767306,0.000055) (0.768140,0.000055) (0.768974,0.000055) (0.769808,0.000054) (0.770642,0.000054) (0.771476,0.000054) (0.772310,0.000054) (0.773144,0.000054) (0.773978,0.000053) (0.774812,0.000053) (0.775646,0.000053) (0.776480,0.000053) (0.777314,0.000053) (0.778148,0.000053) (0.778982,0.000053) (0.779817,0.000052) (0.780651,0.000052) (0.781485,0.000052) (0.782319,0.000052) (0.783153,0.000052) (0.783987,0.000052) (0.784821,0.000052) (0.785655,0.000051) (0.786489,0.000051) (0.787323,0.000051) (0.788157,0.000051) (0.788991,0.000050) (0.789825,0.000050) (0.790659,0.000050) (0.791493,0.000049) (0.792327,0.000049) (0.793161,0.000049) (0.793995,0.000049) (0.794829,0.000049) (0.795663,0.000049) (0.796497,0.000049) (0.797331,0.000047) (0.798165,0.000047) (0.798999,0.000047) (0.799833,0.000047) (0.800667,0.000046) (0.801501,0.000046) (0.802335,0.000046) (0.803169,0.000046) (0.804003,0.000045) (0.804837,0.000045) (0.805671,0.000044) (0.806505,0.000044) (0.807339,0.000043) (0.808173,0.000043) (0.809008,0.000043) (0.809842,0.000043) (0.810676,0.000042) (0.811510,0.000042) (0.812344,0.000041) (0.813178,0.000041) (0.814012,0.000041) (0.814846,0.000041) (0.815680,0.000040) (0.816514,0.000040) (0.817348,0.000038) (0.818182,0.000038) (0.819016,0.000038) (0.819850,0.000037) (0.820684,0.000037) (0.821518,0.000037) (0.822352,0.000037) (0.823186,0.000037) (0.824020,0.000036) (0.824854,0.000036) (0.825688,0.000035) (0.826522,0.000035) (0.827356,0.000035) (0.828190,0.000035) (0.829024,0.000034) (0.829858,0.000034) (0.830692,0.000033) (0.831526,0.000033) (0.832360,0.000033) (0.833194,0.000033) (0.834028,0.000032) (0.834862,0.000032) (0.835696,0.000031) (0.836530,0.000031) (0.837364,0.000030) (0.838198,0.000030) (0.839033,0.000030) (0.839867,0.000030) (0.840701,0.000029) (0.841535,0.000029) (0.842369,0.000029) (0.843203,0.000029) (0.844037,0.000029) (0.844871,0.000028) (0.845705,0.000028) (0.846539,0.000028) (0.847373,0.000028) (0.848207,0.000028) (0.849041,0.000028) (0.849875,0.000028) (0.850709,0.000028) (0.851543,0.000028) (0.852377,0.000028) (0.853211,0.000028) (0.854045,0.000028) (0.854879,0.000028) (0.855713,0.000028) (0.856547,0.000028) (0.857381,0.000028) (0.858215,0.000028) (0.859049,0.000027) (0.859883,0.000027) (0.860717,0.000027) (0.861551,0.000027) (0.862385,0.000027) (0.863219,0.000027) (0.864053,0.000027) (0.864887,0.000027) (0.865721,0.000027) (0.866555,0.000027) (0.867389,0.000027) (0.868224,0.000027) (0.869058,0.000027) (0.869892,0.000026) (0.870726,0.000026) (0.871560,0.000026) (0.872394,0.000025) (0.873228,0.000025) (0.874062,0.000025) (0.874896,0.000025) (0.875730,0.000025) (0.876564,0.000025) (0.877398,0.000025) (0.878232,0.000025) (0.879066,0.000025) (0.879900,0.000025) (0.880734,0.000024) (0.881568,0.000024) (0.882402,0.000024) (0.883236,0.000024) (0.884070,0.000024) (0.884904,0.000024) (0.885738,0.000023) (0.886572,0.000023) (0.887406,0.000023) (0.888240,0.000023) (0.889074,0.000023) (0.889908,0.000023) (0.890742,0.000022) (0.891576,0.000022) (0.892410,0.000022) (0.893244,0.000022) (0.894078,0.000022) (0.894912,0.000022) (0.895746,0.000022) (0.896580,0.000022) (0.897415,0.000021) (0.898249,0.000021) (0.899083,0.000021) (0.899917,0.000021) (0.900751,0.000021) (0.901585,0.000021) (0.902419,0.000021) (0.903253,0.000021) (0.904087,0.000021) (0.904921,0.000021) (0.905755,0.000021) (0.906589,0.000021) (0.907423,0.000021) (0.908257,0.000020) (0.909091,0.000020) (0.909925,0.000020) (0.910759,0.000020) (0.911593,0.000020) (0.912427,0.000020) (0.913261,0.000020) (0.914095,0.000019) (0.914929,0.000019) (0.915763,0.000019) (0.916597,0.000018) (0.917431,0.000018) (0.918265,0.000018) (0.919099,0.000017) (0.919933,0.000017) (0.920767,0.000017) (0.921601,0.000017) (0.922435,0.000017) (0.923269,0.000016) (0.924103,0.000016) (0.924937,0.000016) (0.925771,0.000016) (0.926606,0.000016) (0.927440,0.000016) (0.928274,0.000015) (0.929108,0.000015) (0.929942,0.000015) (0.930776,0.000015) (0.931610,0.000015) (0.932444,0.000015) (0.933278,0.000015) (0.934112,0.000015) (0.934946,0.000014) (0.935780,0.000014) (0.936614,0.000014) (0.937448,0.000014) (0.938282,0.000013) (0.939116,0.000013) (0.939950,0.000012) (0.940784,0.000012) (0.941618,0.000012) (0.942452,0.000012) (0.943286,0.000012) (0.944120,0.000012) (0.944954,0.000012) (0.945788,0.000012) (0.946622,0.000011) (0.947456,0.000011) (0.948290,0.000011) (0.949124,0.000011) (0.949958,0.000011) (0.950792,0.000011) (0.951626,0.000010) (0.952460,0.000010) (0.953294,0.000010) (0.954128,0.000010) (0.954962,0.000009) (0.955796,0.000009) (0.956631,0.000009) (0.957465,0.000009) (0.958299,0.000008) (0.959133,0.000008) (0.959967,0.000008) (0.960801,0.000008) (0.961635,0.000008) (0.962469,0.000008) (0.963303,0.000008) (0.964137,0.000008) (0.964971,0.000007) (0.965805,0.000007) (0.966639,0.000007) (0.967473,0.000007) (0.968307,0.000007) (0.969141,0.000007) (0.969975,0.000006) (0.970809,0.000006) (0.971643,0.000006) (0.972477,0.000005) (0.973311,0.000005) (0.974145,0.000004) (0.974979,0.000004) (0.975813,0.000004) (0.976647,0.000004) (0.977481,0.000004) (0.978315,0.000003) (0.979149,0.000003) (0.979983,0.000003) (0.980817,0.000003) (0.981651,0.000002) (0.982485,0.000002) (0.983319,0.000002) (0.984153,0.000002) (0.984987,0.000002) (0.985822,0.000002) (0.986656,0.000001) (0.987490,0.000001) (0.988324,0.000001) (0.989158,0.000001) (0.989992,0.000001) (0.990826,0.000001) (0.991660,0.000001) (0.992494,0.000001) (0.993328,0.000001) (0.994162,0.000001) (0.994996,0.000001) (0.995830,0.000001) (0.996664,0.000001) (0.997498,0.000001) (0.998332,0.000001) (0.999166,0.000001) (1.000000,0.000001) +}; + \ No newline at end of file diff --git a/talk/vmil2012/presentation/figures/go_data.tex b/talk/vmil2012/presentation/figures/go_data.tex new file mode 100644 --- /dev/null +++ b/talk/vmil2012/presentation/figures/go_data.tex @@ -0,0 +1,5 @@ + +\addplot[black] coordinates { +(0.000000,1.000000) (0.000834,0.872400) (0.001668,0.683224) (0.002502,0.608314) (0.003336,0.542330) (0.004170,0.519721) (0.005004,0.447508) (0.005838,0.440065) (0.006672,0.420670) (0.007506,0.418862) (0.008340,0.418009) (0.009174,0.379519) (0.010008,0.357223) (0.010842,0.353534) (0.011676,0.333568) (0.012510,0.319704) (0.013344,0.268160) (0.014178,0.251065) (0.015013,0.226789) (0.015847,0.220089) (0.016681,0.215066) (0.017515,0.213903) (0.018349,0.213091) (0.019183,0.197153) (0.020017,0.187389) (0.020851,0.177430) (0.021685,0.173396) (0.022519,0.170787) (0.023353,0.160834) (0.024187,0.160045) (0.025021,0.157071) (0.025855,0.146612) (0.026689,0.144178) (0.027523,0.137699) (0.028357,0.136683) (0.029191,0.124833) (0.030025,0.121453) (0.030859,0.119189) (0.031693,0.115002) (0.032527,0.114249) (0.033361,0.107546) (0.034195,0.107268) (0.035029,0.104187) (0.035863,0.096624) (0.036697,0.089912) (0.037531,0.089585) (0.038365,0.087446) (0.039199,0.087298) (0.040033,0.084823) (0.040867,0.083414) (0.041701,0.083212) (0.042535,0.082227) (0.043369,0.079913) (0.044204,0.075734) (0.045038,0.073337) (0.045872,0.073039) (0.046706,0.072381) (0.047540,0.069693) (0.048374,0.067325) (0.049208,0.065996) (0.050042,0.057532) (0.050876,0.055707) (0.051710,0.055669) (0.052544,0.049083) (0.053378,0.048652) (0.054212,0.048015) (0.055046,0.045918) (0.055880,0.045234) (0.056714,0.042272) (0.057548,0.041798) (0.058382,0.040969) (0.059216,0.040163) (0.060050,0.040016) (0.060884,0.038778) (0.061718,0.038686) (0.062552,0.038456) (0.063386,0.033439) (0.064220,0.032381) (0.065054,0.031115) (0.065888,0.030103) (0.066722,0.029385) (0.067556,0.026654) (0.068390,0.025877) (0.069224,0.024467) (0.070058,0.024427) (0.070892,0.024134) (0.071726,0.024036) (0.072560,0.021379) (0.073394,0.020813) (0.074229,0.020166) (0.075063,0.020056) (0.075897,0.019981) (0.076731,0.019791) (0.077565,0.019672) (0.078399,0.019356) (0.079233,0.019269) (0.080067,0.019134) (0.080901,0.018119) (0.081735,0.017905) (0.082569,0.017878) (0.083403,0.017865) (0.084237,0.017769) (0.085071,0.017758) (0.085905,0.017065) (0.086739,0.016959) (0.087573,0.016686) (0.088407,0.015666) (0.089241,0.014908) (0.090075,0.014542) (0.090909,0.014518) (0.091743,0.014200) (0.092577,0.013865) (0.093411,0.013736) (0.094245,0.013273) (0.095079,0.013197) (0.095913,0.012997) (0.096747,0.012759) (0.097581,0.012642) (0.098415,0.012344) (0.099249,0.012031) (0.100083,0.011973) (0.100917,0.011805) (0.101751,0.011594) (0.102585,0.011387) (0.103420,0.011332) (0.104254,0.011246) (0.105088,0.010925) (0.105922,0.010566) (0.106756,0.010269) (0.107590,0.010235) (0.108424,0.010220) (0.109258,0.010135) (0.110092,0.010071) (0.110926,0.010048) (0.111760,0.010002) (0.112594,0.009762) (0.113428,0.009756) (0.114262,0.009751) (0.115096,0.009730) (0.115930,0.009551) (0.116764,0.009536) (0.117598,0.009404) (0.118432,0.009399) (0.119266,0.009298) (0.120100,0.009263) (0.120934,0.009245) (0.121768,0.009137) (0.122602,0.009120) (0.123436,0.009097) (0.124270,0.008816) (0.125104,0.008646) (0.125938,0.008484) (0.126772,0.008405) (0.127606,0.008149) (0.128440,0.008032) (0.129274,0.007872) (0.130108,0.007866) (0.130942,0.007823) (0.131776,0.007801) (0.132611,0.007718) (0.133445,0.007481) (0.134279,0.007373) (0.135113,0.007345) (0.135947,0.007296) (0.136781,0.007269) (0.137615,0.007233) (0.138449,0.006991) (0.139283,0.006905) (0.140117,0.006795) (0.140951,0.006738) (0.141785,0.006708) (0.142619,0.006551) (0.143453,0.006510) (0.144287,0.006435) (0.145121,0.006361) (0.145955,0.006238) (0.146789,0.006134) (0.147623,0.006027) (0.148457,0.005991) (0.149291,0.005921) (0.150125,0.005852) (0.150959,0.005852) (0.151793,0.005823) (0.152627,0.005794) (0.153461,0.005787) (0.154295,0.005746) (0.155129,0.005672) (0.155963,0.005619) (0.156797,0.005612) (0.157631,0.005557) (0.158465,0.005495) (0.159299,0.005495) (0.160133,0.005422) (0.160967,0.005324) (0.161802,0.005217) (0.162636,0.005196) (0.163470,0.005167) (0.164304,0.005107) (0.165138,0.005012) (0.165972,0.004999) (0.166806,0.004985) (0.167640,0.004981) (0.168474,0.004936) (0.169308,0.004912) (0.170142,0.004836) (0.170976,0.004822) (0.171810,0.004755) (0.172644,0.004692) (0.173478,0.004687) (0.174312,0.004667) (0.175146,0.004605) (0.175980,0.004546) (0.176814,0.004523) (0.177648,0.004518) (0.178482,0.004512) (0.179316,0.004447) (0.180150,0.004427) (0.180984,0.004408) (0.181818,0.004401) (0.182652,0.004336) (0.183486,0.004326) (0.184320,0.004255) (0.185154,0.004163) (0.185988,0.004152) (0.186822,0.004150) (0.187656,0.004132) (0.188490,0.004125) (0.189324,0.003972) (0.190158,0.003971) (0.190992,0.003942) (0.191827,0.003842) (0.192661,0.003797) (0.193495,0.003710) (0.194329,0.003703) (0.195163,0.003684) (0.195997,0.003626) (0.196831,0.003620) (0.197665,0.003576) (0.198499,0.003526) (0.199333,0.003451) (0.200167,0.003447) (0.201001,0.003402) (0.201835,0.003390) (0.202669,0.003364) (0.203503,0.003361) (0.204337,0.003356) (0.205171,0.003350) (0.206005,0.003341) (0.206839,0.003321) (0.207673,0.003278) (0.208507,0.003246) (0.209341,0.003239) (0.210175,0.003219) (0.211009,0.003208) (0.211843,0.003129) (0.212677,0.003123) (0.213511,0.003073) (0.214345,0.003063) (0.215179,0.003053) (0.216013,0.003053) (0.216847,0.003026) (0.217681,0.003007) (0.218515,0.002989) (0.219349,0.002929) (0.220183,0.002915) (0.221018,0.002913) (0.221852,0.002890) (0.222686,0.002861) (0.223520,0.002845) (0.224354,0.002804) (0.225188,0.002783) (0.226022,0.002781) (0.226856,0.002694) (0.227690,0.002669) (0.228524,0.002631) (0.229358,0.002579) (0.230192,0.002578) (0.231026,0.002573) (0.231860,0.002566) (0.232694,0.002507) (0.233528,0.002487) (0.234362,0.002486) (0.235196,0.002416) (0.236030,0.002367) (0.236864,0.002347) (0.237698,0.002344) (0.238532,0.002338) (0.239366,0.002330) (0.240200,0.002318) (0.241034,0.002315) (0.241868,0.002308) (0.242702,0.002308) (0.243536,0.002292) (0.244370,0.002287) (0.245204,0.002283) (0.246038,0.002264) (0.246872,0.002236) (0.247706,0.002227) (0.248540,0.002185) (0.249374,0.002173) (0.250209,0.002169) (0.251043,0.002135) (0.251877,0.002109) (0.252711,0.002039) (0.253545,0.002031) (0.254379,0.001987) (0.255213,0.001970) (0.256047,0.001966) (0.256881,0.001936) (0.257715,0.001908) (0.258549,0.001908) (0.259383,0.001893) (0.260217,0.001886) (0.261051,0.001882) (0.261885,0.001827) (0.262719,0.001827) (0.263553,0.001817) (0.264387,0.001797) (0.265221,0.001749) (0.266055,0.001742) (0.266889,0.001739) (0.267723,0.001727) (0.268557,0.001704) (0.269391,0.001700) (0.270225,0.001691) (0.271059,0.001690) (0.271893,0.001653) (0.272727,0.001600) (0.273561,0.001595) (0.274395,0.001555) (0.275229,0.001547) (0.276063,0.001546) (0.276897,0.001519) (0.277731,0.001513) (0.278565,0.001510) (0.279399,0.001505) (0.280234,0.001474) (0.281068,0.001468) (0.281902,0.001459) (0.282736,0.001458) (0.283570,0.001432) (0.284404,0.001410) (0.285238,0.001407) (0.286072,0.001401) (0.286906,0.001396) (0.287740,0.001391) (0.288574,0.001376) (0.289408,0.001372) (0.290242,0.001369) (0.291076,0.001345) (0.291910,0.001344) (0.292744,0.001318) (0.293578,0.001299) (0.294412,0.001295) (0.295246,0.001287) (0.296080,0.001285) (0.296914,0.001284) (0.297748,0.001270) (0.298582,0.001265) (0.299416,0.001253) (0.300250,0.001235) (0.301084,0.001233) (0.301918,0.001224) (0.302752,0.001222) (0.303586,0.001219) (0.304420,0.001209) (0.305254,0.001202) (0.306088,0.001191) (0.306922,0.001180) (0.307756,0.001173) (0.308590,0.001170) (0.309425,0.001167) (0.310259,0.001154) (0.311093,0.001147) (0.311927,0.001143) (0.312761,0.001130) (0.313595,0.001126) (0.314429,0.001124) (0.315263,0.001116) (0.316097,0.001115) (0.316931,0.001099) (0.317765,0.001088) (0.318599,0.001088) (0.319433,0.001082) (0.320267,0.001074) (0.321101,0.001071) (0.321935,0.001070) (0.322769,0.001066) (0.323603,0.001062) (0.324437,0.001047) (0.325271,0.001043) (0.326105,0.001041) (0.326939,0.001040) (0.327773,0.001038) (0.328607,0.001027) (0.329441,0.001025) (0.330275,0.001016) (0.331109,0.001016) (0.331943,0.000996) (0.332777,0.000992) (0.333611,0.000985) (0.334445,0.000979) (0.335279,0.000978) (0.336113,0.000978) (0.336947,0.000957) (0.337781,0.000953) (0.338616,0.000951) (0.339450,0.000947) (0.340284,0.000944) (0.341118,0.000939) (0.341952,0.000932) (0.342786,0.000930) (0.343620,0.000930) (0.344454,0.000928) (0.345288,0.000915) (0.346122,0.000914) (0.346956,0.000914) (0.347790,0.000911) (0.348624,0.000910) (0.349458,0.000908) (0.350292,0.000904) (0.351126,0.000895) (0.351960,0.000890) (0.352794,0.000887) (0.353628,0.000884) (0.354462,0.000879) (0.355296,0.000861) (0.356130,0.000861) (0.356964,0.000826) (0.357798,0.000814) (0.358632,0.000808) (0.359466,0.000800) (0.360300,0.000797) (0.361134,0.000796) (0.361968,0.000782) (0.362802,0.000779) (0.363636,0.000778) (0.364470,0.000777) (0.365304,0.000777) (0.366138,0.000775) (0.366972,0.000767) (0.367807,0.000764) (0.368641,0.000761) (0.369475,0.000758) (0.370309,0.000753) (0.371143,0.000753) (0.371977,0.000751) (0.372811,0.000738) (0.373645,0.000718) (0.374479,0.000718) (0.375313,0.000710) (0.376147,0.000709) (0.376981,0.000707) (0.377815,0.000701) (0.378649,0.000699) (0.379483,0.000694) (0.380317,0.000694) (0.381151,0.000688) (0.381985,0.000686) (0.382819,0.000683) (0.383653,0.000681) (0.384487,0.000665) (0.385321,0.000664) (0.386155,0.000660) (0.386989,0.000659) (0.387823,0.000657) (0.388657,0.000657) (0.389491,0.000655) (0.390325,0.000654) (0.391159,0.000647) (0.391993,0.000645) (0.392827,0.000644) (0.393661,0.000643) (0.394495,0.000642) (0.395329,0.000640) (0.396163,0.000639) (0.396997,0.000637) (0.397832,0.000634) (0.398666,0.000630) (0.399500,0.000614) (0.400334,0.000613) (0.401168,0.000607) (0.402002,0.000604) (0.402836,0.000603) (0.403670,0.000602) (0.404504,0.000602) (0.405338,0.000598) (0.406172,0.000597) (0.407006,0.000592) (0.407840,0.000588) (0.408674,0.000576) (0.409508,0.000572) (0.410342,0.000570) (0.411176,0.000570) (0.412010,0.000567) (0.412844,0.000567) (0.413678,0.000566) (0.414512,0.000564) (0.415346,0.000563) (0.416180,0.000554) (0.417014,0.000550) (0.417848,0.000548) (0.418682,0.000547) (0.419516,0.000547) (0.420350,0.000546) (0.421184,0.000542) (0.422018,0.000542) (0.422852,0.000535) (0.423686,0.000529) (0.424520,0.000518) (0.425354,0.000516) (0.426188,0.000515) (0.427023,0.000513) (0.427857,0.000512) (0.428691,0.000511) (0.429525,0.000503) (0.430359,0.000503) (0.431193,0.000503) (0.432027,0.000499) (0.432861,0.000497) (0.433695,0.000497) (0.434529,0.000495) (0.435363,0.000495) (0.436197,0.000494) (0.437031,0.000494) (0.437865,0.000492) (0.438699,0.000491) (0.439533,0.000490) (0.440367,0.000489) (0.441201,0.000488) (0.442035,0.000486) (0.442869,0.000484) (0.443703,0.000480) (0.444537,0.000479) (0.445371,0.000478) (0.446205,0.000471) (0.447039,0.000467) (0.447873,0.000466) (0.448707,0.000464) (0.449541,0.000460) (0.450375,0.000458) (0.451209,0.000456) (0.452043,0.000452) (0.452877,0.000451) (0.453711,0.000448) (0.454545,0.000446) (0.455379,0.000445) (0.456214,0.000444) (0.457048,0.000437) (0.457882,0.000436) (0.458716,0.000435) (0.459550,0.000431) (0.460384,0.000431) (0.461218,0.000430) (0.462052,0.000428) (0.462886,0.000428) (0.463720,0.000428) (0.464554,0.000427) (0.465388,0.000427) (0.466222,0.000422) (0.467056,0.000420) (0.467890,0.000415) (0.468724,0.000409) (0.469558,0.000408) (0.470392,0.000408) (0.471226,0.000406) (0.472060,0.000405) (0.472894,0.000404) (0.473728,0.000404) (0.474562,0.000402) (0.475396,0.000402) (0.476230,0.000402) (0.477064,0.000402) (0.477898,0.000399) (0.478732,0.000399) (0.479566,0.000398) (0.480400,0.000395) (0.481234,0.000395) (0.482068,0.000394) (0.482902,0.000390) (0.483736,0.000389) (0.484570,0.000387) (0.485405,0.000385) (0.486239,0.000383) (0.487073,0.000382) (0.487907,0.000381) (0.488741,0.000380) (0.489575,0.000380) (0.490409,0.000377) (0.491243,0.000375) (0.492077,0.000374) (0.492911,0.000373) (0.493745,0.000371) (0.494579,0.000370) (0.495413,0.000369) (0.496247,0.000368) (0.497081,0.000366) (0.497915,0.000364) (0.498749,0.000362) (0.499583,0.000362) (0.500417,0.000358) (0.501251,0.000354) (0.502085,0.000346) (0.502919,0.000345) (0.503753,0.000344) (0.504587,0.000343) (0.505421,0.000341) (0.506255,0.000340) (0.507089,0.000337) (0.507923,0.000337) (0.508757,0.000331) (0.509591,0.000328) (0.510425,0.000325) (0.511259,0.000323) (0.512093,0.000319) (0.512927,0.000319) (0.513761,0.000317) (0.514595,0.000315) (0.515430,0.000314) (0.516264,0.000313) (0.517098,0.000313) (0.517932,0.000312) (0.518766,0.000312) (0.519600,0.000311) (0.520434,0.000302) (0.521268,0.000300) (0.522102,0.000300) (0.522936,0.000295) (0.523770,0.000295) (0.524604,0.000295) (0.525438,0.000292) (0.526272,0.000290) (0.527106,0.000290) (0.527940,0.000288) (0.528774,0.000287) (0.529608,0.000285) (0.530442,0.000280) (0.531276,0.000278) (0.532110,0.000278) (0.532944,0.000278) (0.533778,0.000277) (0.534612,0.000276) (0.535446,0.000274) (0.536280,0.000273) (0.537114,0.000271) (0.537948,0.000271) (0.538782,0.000270) (0.539616,0.000266) (0.540450,0.000263) (0.541284,0.000260) (0.542118,0.000260) (0.542952,0.000258) (0.543786,0.000258) (0.544621,0.000256) (0.545455,0.000253) (0.546289,0.000252) (0.547123,0.000251) (0.547957,0.000249) (0.548791,0.000248) (0.549625,0.000248) (0.550459,0.000248) (0.551293,0.000246) (0.552127,0.000246) (0.552961,0.000244) (0.553795,0.000244) (0.554629,0.000242) (0.555463,0.000241) (0.556297,0.000240) (0.557131,0.000240) (0.557965,0.000239) (0.558799,0.000236) (0.559633,0.000236) (0.560467,0.000235) (0.561301,0.000234) (0.562135,0.000234) (0.562969,0.000234) (0.563803,0.000233) (0.564637,0.000233) (0.565471,0.000225) (0.566305,0.000223) (0.567139,0.000223) (0.567973,0.000220) (0.568807,0.000219) (0.569641,0.000218) (0.570475,0.000218) (0.571309,0.000217) (0.572143,0.000216) (0.572977,0.000213) (0.573812,0.000211) (0.574646,0.000207) (0.575480,0.000206) (0.576314,0.000206) (0.577148,0.000205) (0.577982,0.000205) (0.578816,0.000203) (0.579650,0.000203) (0.580484,0.000203) (0.581318,0.000203) (0.582152,0.000203) (0.582986,0.000201) (0.583820,0.000200) (0.584654,0.000200) (0.585488,0.000199) (0.586322,0.000199) (0.587156,0.000197) (0.587990,0.000194) (0.588824,0.000193) (0.589658,0.000191) (0.590492,0.000190) (0.591326,0.000190) (0.592160,0.000186) (0.592994,0.000186) (0.593828,0.000181) (0.594662,0.000178) (0.595496,0.000175) (0.596330,0.000174) (0.597164,0.000173) (0.597998,0.000173) (0.598832,0.000172) (0.599666,0.000171) (0.600500,0.000171) (0.601334,0.000170) (0.602168,0.000170) (0.603003,0.000169) (0.603837,0.000166) (0.604671,0.000165) (0.605505,0.000165) (0.606339,0.000165) (0.607173,0.000164) (0.608007,0.000163) (0.608841,0.000162) (0.609675,0.000162) (0.610509,0.000162) (0.611343,0.000162) (0.612177,0.000161) (0.613011,0.000161) (0.613845,0.000159) (0.614679,0.000158) (0.615513,0.000158) (0.616347,0.000157) (0.617181,0.000156) (0.618015,0.000155) (0.618849,0.000155) (0.619683,0.000152) (0.620517,0.000152) (0.621351,0.000151) (0.622185,0.000151) (0.623019,0.000149) (0.623853,0.000149) (0.624687,0.000148) (0.625521,0.000147) (0.626355,0.000147) (0.627189,0.000146) (0.628023,0.000146) (0.628857,0.000146) (0.629691,0.000146) (0.630525,0.000145) (0.631359,0.000145) (0.632193,0.000144) (0.633028,0.000144) (0.633862,0.000144) (0.634696,0.000144) (0.635530,0.000143) (0.636364,0.000142) (0.637198,0.000142) (0.638032,0.000142) (0.638866,0.000142) (0.639700,0.000141) (0.640534,0.000140) (0.641368,0.000139) (0.642202,0.000137) (0.643036,0.000137) (0.643870,0.000133) (0.644704,0.000131) (0.645538,0.000131) (0.646372,0.000129) (0.647206,0.000129) (0.648040,0.000129) (0.648874,0.000128) (0.649708,0.000128) (0.650542,0.000127) (0.651376,0.000124) (0.652210,0.000123) (0.653044,0.000119) (0.653878,0.000117) (0.654712,0.000117) (0.655546,0.000117) (0.656380,0.000115) (0.657214,0.000114) (0.658048,0.000114) (0.658882,0.000114) (0.659716,0.000113) (0.660550,0.000112) (0.661384,0.000111) (0.662219,0.000111) (0.663053,0.000111) (0.663887,0.000111) (0.664721,0.000110) (0.665555,0.000110) (0.666389,0.000109) (0.667223,0.000108) (0.668057,0.000108) (0.668891,0.000107) (0.669725,0.000105) (0.670559,0.000105) (0.671393,0.000105) (0.672227,0.000105) (0.673061,0.000105) (0.673895,0.000105) (0.674729,0.000105) (0.675563,0.000104) (0.676397,0.000104) (0.677231,0.000103) (0.678065,0.000102) (0.678899,0.000101) (0.679733,0.000101) (0.680567,0.000100) (0.681401,0.000100) (0.682235,0.000100) (0.683069,0.000099) (0.683903,0.000099) (0.684737,0.000098) (0.685571,0.000098) (0.686405,0.000098) (0.687239,0.000097) (0.688073,0.000094) (0.688907,0.000094) (0.689741,0.000092) (0.690575,0.000092) (0.691410,0.000091) (0.692244,0.000089) (0.693078,0.000089) (0.693912,0.000087) (0.694746,0.000087) (0.695580,0.000087) (0.696414,0.000086) (0.697248,0.000086) (0.698082,0.000086) (0.698916,0.000085) (0.699750,0.000085) (0.700584,0.000085) (0.701418,0.000085) (0.702252,0.000084) (0.703086,0.000084) (0.703920,0.000083) (0.704754,0.000083) (0.705588,0.000082) (0.706422,0.000081) (0.707256,0.000080) (0.708090,0.000080) (0.708924,0.000080) (0.709758,0.000079) (0.710592,0.000079) (0.711426,0.000078) (0.712260,0.000078) (0.713094,0.000077) (0.713928,0.000076) (0.714762,0.000076) (0.715596,0.000076) (0.716430,0.000075) (0.717264,0.000075) (0.718098,0.000072) (0.718932,0.000071) (0.719766,0.000071) (0.720601,0.000070) (0.721435,0.000070) (0.722269,0.000070) (0.723103,0.000070) (0.723937,0.000070) (0.724771,0.000070) (0.725605,0.000069) (0.726439,0.000068) (0.727273,0.000068) (0.728107,0.000068) (0.728941,0.000067) (0.729775,0.000067) (0.730609,0.000067) (0.731443,0.000067) (0.732277,0.000066) (0.733111,0.000066) (0.733945,0.000065) (0.734779,0.000065) (0.735613,0.000065) (0.736447,0.000065) (0.737281,0.000064) (0.738115,0.000064) (0.738949,0.000063) (0.739783,0.000063) (0.740617,0.000063) (0.741451,0.000062) (0.742285,0.000062) (0.743119,0.000060) (0.743953,0.000060) (0.744787,0.000059) (0.745621,0.000059) (0.746455,0.000059) (0.747289,0.000059) (0.748123,0.000058) (0.748957,0.000058) (0.749791,0.000057) (0.750626,0.000057) (0.751460,0.000057) (0.752294,0.000057) (0.753128,0.000057) (0.753962,0.000057) (0.754796,0.000057) (0.755630,0.000057) (0.756464,0.000057) (0.757298,0.000057) (0.758132,0.000057) (0.758966,0.000057) (0.759800,0.000057) (0.760634,0.000057) (0.761468,0.000057) (0.762302,0.000057) (0.763136,0.000056) (0.763970,0.000056) (0.764804,0.000055) (0.765638,0.000055) (0.766472,0.000055) (0.767306,0.000055) (0.768140,0.000055) (0.768974,0.000055) (0.769808,0.000054) (0.770642,0.000054) (0.771476,0.000054) (0.772310,0.000054) (0.773144,0.000054) (0.773978,0.000053) (0.774812,0.000053) (0.775646,0.000053) (0.776480,0.000053) (0.777314,0.000053) (0.778148,0.000053) (0.778982,0.000053) (0.779817,0.000052) (0.780651,0.000052) (0.781485,0.000052) (0.782319,0.000052) (0.783153,0.000052) (0.783987,0.000052) (0.784821,0.000052) (0.785655,0.000051) (0.786489,0.000051) (0.787323,0.000051) (0.788157,0.000051) (0.788991,0.000050) (0.789825,0.000050) (0.790659,0.000050) (0.791493,0.000049) (0.792327,0.000049) (0.793161,0.000049) (0.793995,0.000049) (0.794829,0.000049) (0.795663,0.000049) (0.796497,0.000049) (0.797331,0.000047) (0.798165,0.000047) (0.798999,0.000047) (0.799833,0.000047) (0.800667,0.000046) (0.801501,0.000046) (0.802335,0.000046) (0.803169,0.000046) (0.804003,0.000045) (0.804837,0.000045) (0.805671,0.000044) (0.806505,0.000044) (0.807339,0.000043) (0.808173,0.000043) (0.809008,0.000043) (0.809842,0.000043) (0.810676,0.000042) (0.811510,0.000042) (0.812344,0.000041) (0.813178,0.000041) (0.814012,0.000041) (0.814846,0.000041) (0.815680,0.000040) (0.816514,0.000040) (0.817348,0.000038) (0.818182,0.000038) (0.819016,0.000038) (0.819850,0.000037) (0.820684,0.000037) (0.821518,0.000037) (0.822352,0.000037) (0.823186,0.000037) (0.824020,0.000036) (0.824854,0.000036) (0.825688,0.000035) (0.826522,0.000035) (0.827356,0.000035) (0.828190,0.000035) (0.829024,0.000034) (0.829858,0.000034) (0.830692,0.000033) (0.831526,0.000033) (0.832360,0.000033) (0.833194,0.000033) (0.834028,0.000032) (0.834862,0.000032) (0.835696,0.000031) (0.836530,0.000031) (0.837364,0.000030) (0.838198,0.000030) (0.839033,0.000030) (0.839867,0.000030) (0.840701,0.000029) (0.841535,0.000029) (0.842369,0.000029) (0.843203,0.000029) (0.844037,0.000029) (0.844871,0.000028) (0.845705,0.000028) (0.846539,0.000028) (0.847373,0.000028) (0.848207,0.000028) (0.849041,0.000028) (0.849875,0.000028) (0.850709,0.000028) (0.851543,0.000028) (0.852377,0.000028) (0.853211,0.000028) (0.854045,0.000028) (0.854879,0.000028) (0.855713,0.000028) (0.856547,0.000028) (0.857381,0.000028) (0.858215,0.000028) (0.859049,0.000027) (0.859883,0.000027) (0.860717,0.000027) (0.861551,0.000027) (0.862385,0.000027) (0.863219,0.000027) (0.864053,0.000027) (0.864887,0.000027) (0.865721,0.000027) (0.866555,0.000027) (0.867389,0.000027) (0.868224,0.000027) (0.869058,0.000027) (0.869892,0.000026) (0.870726,0.000026) (0.871560,0.000026) (0.872394,0.000025) (0.873228,0.000025) (0.874062,0.000025) (0.874896,0.000025) (0.875730,0.000025) (0.876564,0.000025) (0.877398,0.000025) (0.878232,0.000025) (0.879066,0.000025) (0.879900,0.000025) (0.880734,0.000024) (0.881568,0.000024) (0.882402,0.000024) (0.883236,0.000024) (0.884070,0.000024) (0.884904,0.000024) (0.885738,0.000023) (0.886572,0.000023) (0.887406,0.000023) (0.888240,0.000023) (0.889074,0.000023) (0.889908,0.000023) (0.890742,0.000022) (0.891576,0.000022) (0.892410,0.000022) (0.893244,0.000022) (0.894078,0.000022) (0.894912,0.000022) (0.895746,0.000022) (0.896580,0.000022) (0.897415,0.000021) (0.898249,0.000021) (0.899083,0.000021) (0.899917,0.000021) (0.900751,0.000021) (0.901585,0.000021) (0.902419,0.000021) (0.903253,0.000021) (0.904087,0.000021) (0.904921,0.000021) (0.905755,0.000021) (0.906589,0.000021) (0.907423,0.000021) (0.908257,0.000020) (0.909091,0.000020) (0.909925,0.000020) (0.910759,0.000020) (0.911593,0.000020) (0.912427,0.000020) (0.913261,0.000020) (0.914095,0.000019) (0.914929,0.000019) (0.915763,0.000019) (0.916597,0.000018) (0.917431,0.000018) (0.918265,0.000018) (0.919099,0.000017) (0.919933,0.000017) (0.920767,0.000017) (0.921601,0.000017) (0.922435,0.000017) (0.923269,0.000016) (0.924103,0.000016) (0.924937,0.000016) (0.925771,0.000016) (0.926606,0.000016) (0.927440,0.000016) (0.928274,0.000015) (0.929108,0.000015) (0.929942,0.000015) (0.930776,0.000015) (0.931610,0.000015) (0.932444,0.000015) (0.933278,0.000015) (0.934112,0.000015) (0.934946,0.000014) (0.935780,0.000014) (0.936614,0.000014) (0.937448,0.000014) (0.938282,0.000013) (0.939116,0.000013) (0.939950,0.000012) (0.940784,0.000012) (0.941618,0.000012) (0.942452,0.000012) (0.943286,0.000012) (0.944120,0.000012) (0.944954,0.000012) (0.945788,0.000012) (0.946622,0.000011) (0.947456,0.000011) (0.948290,0.000011) (0.949124,0.000011) (0.949958,0.000011) (0.950792,0.000011) (0.951626,0.000010) (0.952460,0.000010) (0.953294,0.000010) (0.954128,0.000010) (0.954962,0.000009) (0.955796,0.000009) (0.956631,0.000009) (0.957465,0.000009) (0.958299,0.000008) (0.959133,0.000008) (0.959967,0.000008) (0.960801,0.000008) (0.961635,0.000008) (0.962469,0.000008) (0.963303,0.000008) (0.964137,0.000008) (0.964971,0.000007) (0.965805,0.000007) (0.966639,0.000007) (0.967473,0.000007) (0.968307,0.000007) (0.969141,0.000007) (0.969975,0.000006) (0.970809,0.000006) (0.971643,0.000006) (0.972477,0.000005) (0.973311,0.000005) (0.974145,0.000004) (0.974979,0.000004) (0.975813,0.000004) (0.976647,0.000004) (0.977481,0.000004) (0.978315,0.000003) (0.979149,0.000003) (0.979983,0.000003) (0.980817,0.000003) (0.981651,0.000002) (0.982485,0.000002) (0.983319,0.000002) (0.984153,0.000002) (0.984987,0.000002) (0.985822,0.000002) (0.986656,0.000001) (0.987490,0.000001) (0.988324,0.000001) (0.989158,0.000001) (0.989992,0.000001) (0.990826,0.000001) (0.991660,0.000001) (0.992494,0.000001) (0.993328,0.000001) (0.994162,0.000001) (0.994996,0.000001) (0.995830,0.000001) (0.996664,0.000001) (0.997498,0.000001) (0.998332,0.000001) (0.999166,0.000001) (1.000000,0.000001) +}; + \ No newline at end of file diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -21,6 +21,8 @@ \usepackage{ulem} \usepackage{color} \usepackage{alltt} +\usepackage{tikz} +\usepackage{pgfplots} \usepackage[utf8x]{inputenc} @@ -197,7 +199,6 @@ \begin{figure} \centering \includegraphics[width=1\textwidth]{figures/loop.pdf} - \label{fig:trampoline} \end{figure} \end{frame} @@ -205,20 +206,58 @@ \begin{figure} \centering \includegraphics[width=1\textwidth]{figures/bridge_compiled.pdf} - \label{fig:trampoline} \end{figure} \end{frame} \begin{frame} \begin{figure} \centering \includegraphics[width=1\textwidth]{figures/bridge_patched.pdf} - \label{fig:trampoline} \end{figure} \end{frame} \begin{frame} \frametitle{Patching Guards for Bridges} \end{frame} +\begin{frame}[t,fragile] +\pgfplotsset{tick label style={font=\tiny\bfseries}, +label style={font=\small}, +legend style={font=\tiny} +} + \frametitle{Guard Failure Rates} + \begin{figure} + \centering + \begin{tikzpicture} + \begin{axis}[ + xlabel= Guards by failures, + ylabel=Relative \# of failures, + xtick=\empty, + ytick=\empty, + ] + \input{figures/data} + \end{axis} + \end{tikzpicture} + \end{figure} +\end{frame} +\begin{frame}[t,fragile] +\pgfplotsset{tick label style={font=\tiny\bfseries}, +label style={font=\small}, +legend style={font=\tiny} +} + \frametitle{Guard Failure Rates / Go Benchmark} + \begin{figure} + \centering + \begin{tikzpicture} + \begin{axis}[ + xlabel= Guards by failures, + ylabel=Relative \# of failures, + xtick=\empty, + ytick=\empty, + ] + \input{figures/go_data} + \end{axis} + \end{tikzpicture} + \end{figure} +\end{frame} %\section{Evaluation} diff --git a/talk/vmil2012/presentation/tool/data.py b/talk/vmil2012/presentation/tool/data.py new file mode 100644 --- /dev/null +++ b/talk/vmil2012/presentation/tool/data.py @@ -0,0 +1,77 @@ +from __future__ import division +import csv +import json +import os + + +COLORS = ["red", "green", "blue", + "cyan", "magenta", "yellow", + "black", "gray", # "white", + "darkgray", "lightgray", "brown", + "lime", "olive", "orange", + "pink", "purple", "teal", + "violet" + ] +def getlines(csvfile): + with open(csvfile, 'rb') as f: + reader = csv.DictReader(f, delimiter=',') + return [l for l in reader] + + +def we_are_n_percent(info, n): + failure_counts = info['results'].values() + print failure_counts + failure_counts.sort() + print failure_counts + failure_counts.reverse() + print failure_counts + + total_failures = sum(failure_counts) + current_sum = 0 + for i, f in enumerate(failure_counts): + current_sum += f + if current_sum > total_failures * n / 100.0: + return (i + 1) + return -1 + + +def build_plot_data(files): + assert len(files) == 2 + with open(files[1]) as f: + failures = json.load(f) + for l in getlines(files[0]): + failures[l['bench']]['nguards'] = float(l['number of guards']) + + output = [] + plot = """ +\\addplot[%(color)s] coordinates { +%(data)s +}; + """ + for j, (bench, info) in enumerate(failures.iteritems()): + data = [] + results = info['results'].values() + results.sort() + results.reverse() + for i, result in enumerate(results): + data.append("(%04f,%04f)" % (float(i) / (len(results) - 1), + float(result) / max(results))) + + if bench == 'go': + with open('figures/go_data.tex', 'w') as f: + f.write(plot % {'color': 'black', 'name': bench, 'data': " ".join(data)}) + output.append(plot % {'color':COLORS[j], 'name': bench, 'data': " ".join(data)}) + + with open('figures/data.tex', 'w') as f: + for l in output: + f.write(l) + + +def main(): + files = [os.path.realpath('../logs/'+ f) for f in ['resume_summary.csv', + 'guard_summary.json']] + build_plot_data(files) + + +if __name__ == '__main__': + main() From noreply at buildbot.pypy.org Tue Oct 16 21:10:09 2012 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 16 Oct 2012 21:10:09 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: tweaks Message-ID: <20121016191009.0D2EF1C027A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4863:d4a87bd8a954 Date: 2012-10-16 16:06 -0300 http://bitbucket.org/pypy/extradoc/changeset/d4a87bd8a954/ Log: tweaks diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -196,28 +196,28 @@ \end{frame} \begin{frame} + \frametitle{Compiling a Trace} \begin{figure} \centering \includegraphics[width=1\textwidth]{figures/loop.pdf} \end{figure} \end{frame} + \begin{frame} + \frametitle{Compiling a Bridge} \begin{figure} \centering \includegraphics[width=1\textwidth]{figures/bridge_compiled.pdf} \end{figure} \end{frame} \begin{frame} + \frametitle{Patching Guards for Bridges} \begin{figure} \centering \includegraphics[width=1\textwidth]{figures/bridge_patched.pdf} \end{figure} \end{frame} - -\begin{frame} - \frametitle{Patching Guards for Bridges} -\end{frame} \begin{frame}[t,fragile] \pgfplotsset{tick label style={font=\tiny\bfseries}, label style={font=\small}, From noreply at buildbot.pypy.org Tue Oct 16 21:20:00 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 16 Oct 2012 21:20:00 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: Start rewriting the llgraph backend. Enough Message-ID: <20121016192000.CB9A91C027A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58146:71b0d3849c20 Date: 2012-10-16 21:01 +0200 http://bitbucket.org/pypy/pypy/changeset/71b0d3849c20/ Log: Start rewriting the llgraph backend. Enough diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/+runner.py copy from pypy/jit/backend/llgraph/runner.py copy to pypy/jit/backend/llgraph/+runner.py diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -1,912 +1,153 @@ -""" -Minimal-API wrapper around the llinterpreter to run operations. -""" -from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.jit_hooks import LOOP_RUN_CONTAINER -from pypy.rpython.lltypesystem import lltype, llmemory, rclass -from pypy.rpython.ootypesystem import ootype +from weakref import WeakKeyDictionary + +from pypy.jit.backend import model +from pypy.jit.metainterp.history import Const +from pypy.jit.metainterp.resoperation import rop from pypy.rpython.llinterp import LLInterpreter -from pypy.jit.metainterp import history -from pypy.jit.metainterp.history import REF, INT, FLOAT, STRUCT -from pypy.jit.metainterp.warmstate import unwrap -from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend import model -from pypy.jit.backend.llgraph import llimpl, symbolic -from pypy.jit.metainterp.typesystem import llhelper, oohelper -from pypy.jit.codewriter import heaptracker, longlong -class MiniStats: - pass +class LLLoop(object): + def __init__(self, inputargs, operations): + self.inputargs = inputargs + self.operations = operations +class GuardFailed(Exception): + def __init__(self, failargs, descr): + self.failargs = failargs + self.descr = descr -class Descr(history.AbstractDescr): +class ExecutionFinished(Exception): + def __init__(self, descr, arg): + self.descr = descr + self.arg = arg - def __init__(self, ofs, typeinfo, extrainfo=None, name=None, - arg_types=None, count_fields_if_immut=-1, ffi_flags=0, width=-1): +class Jump(Exception): + def __init__(self, descr, args): + self.descr = descr + self.args = args - self.ofs = ofs - self.width = width - self.typeinfo = typeinfo - self.extrainfo = extrainfo - self.name = name - self.arg_types = arg_types - self.count_fields_if_immut = count_fields_if_immut - self.ffi_flags = ffi_flags - self._debug = False +class LLGraphCPU(model.AbstractCPU): + def __init__(self, rtyper): + self.rtyper = rtyper + self.llinterp = LLInterpreter(rtyper) + self.known_labels = WeakKeyDictionary() - def set_debug(self, v): - self._debug = True - - def get_arg_types(self): - return self.arg_types - - def get_result_type(self): - return self.typeinfo - - def get_extra_info(self): - return self.extrainfo - - def sort_key(self): - """Returns an integer that can be used as a key when sorting the - field descrs of a single structure. The property that this - number has is simply that two different field descrs of the same - structure give different numbers.""" - return self.ofs - - def is_pointer_field(self): - return self.typeinfo == REF - - def is_float_field(self): - return self.typeinfo == FLOAT - - def is_array_of_pointers(self): - return self.typeinfo == REF - - def is_array_of_floats(self): - return self.typeinfo == FLOAT - - def is_array_of_structs(self): - return self.typeinfo == STRUCT - - def as_vtable_size_descr(self): - return self - - def count_fields_if_immutable(self): - return self.count_fields_if_immut - - def get_ffi_flags(self): - return self.ffi_flags - - def __lt__(self, other): - raise TypeError("cannot use comparison on Descrs") - def __le__(self, other): - raise TypeError("cannot use comparison on Descrs") - def __gt__(self, other): - raise TypeError("cannot use comparison on Descrs") - def __ge__(self, other): - raise TypeError("cannot use comparison on Descrs") - - def __repr__(self): - args = [repr(self.ofs), repr(self.typeinfo)] - if self.name is not None: - args.append(repr(self.name)) - if self.extrainfo is not None: - args.append('E') - return '' % (', '.join(args),) - - -history.TreeLoop._compiled_version = lltype.nullptr(llimpl.COMPILEDLOOP.TO) - - -class BaseCPU(model.AbstractCPU): - supports_floats = True - supports_longlong = llimpl.IS_32_BIT - supports_singlefloats = True - - def __init__(self, rtyper, stats=None, opts=None, - translate_support_code=False, - annmixlevel=None, gcdescr=None): - assert type(opts) is not bool - model.AbstractCPU.__init__(self) - self.rtyper = rtyper - self.translate_support_code = translate_support_code - self.stats = stats or MiniStats() - self.stats.exec_counters = {} - self.stats.exec_jumps = 0 - self.stats.exec_conditional_jumps = 0 - llimpl._stats = self.stats - llimpl._llinterp = LLInterpreter(self.rtyper) - self._future_values = [] - self._descrs = {} - - def _cleanup_(self): - assert self.translate_support_code - - def getdescr(self, ofs, typeinfo='?', extrainfo=None, name=None, - arg_types=None, count_fields_if_immut=-1, ffi_flags=0, width=-1): - key = (ofs, typeinfo, extrainfo, name, arg_types, - count_fields_if_immut, ffi_flags, width) - try: - return self._descrs[key] - except KeyError: - descr = Descr(ofs, typeinfo, extrainfo, name, arg_types, - count_fields_if_immut, ffi_flags, width) - self._descrs[key] = descr - return descr - - def compile_bridge(self, faildescr, inputargs, operations, - original_loop_token, log=True): - c = llimpl.compile_start() - clt = original_loop_token.compiled_loop_token - clt.loop_and_bridges.append(c) - clt.compiling_a_bridge() - self._compile_loop_or_bridge(c, inputargs, operations, clt) - old, oldindex = faildescr._compiled_fail - llimpl.compile_redirect_fail(old, oldindex, c) - - def compile_loop(self, inputargs, operations, jitcell_token, - log=True, name=''): - """In a real assembler backend, this should assemble the given - list of operations. Here we just generate a similar CompiledLoop - instance. The code here is RPython, whereas the code in llimpl - is not. - """ - c = llimpl.compile_start() - clt = model.CompiledLoopToken(self, jitcell_token.number) - clt.loop_and_bridges = [c] - clt.compiled_version = c - jitcell_token.compiled_loop_token = clt - self._compile_loop_or_bridge(c, inputargs, operations, clt) - - def free_loop_and_bridges(self, compiled_loop_token): - for c in compiled_loop_token.loop_and_bridges: - llimpl.mark_as_free(c) - model.AbstractCPU.free_loop_and_bridges(self, compiled_loop_token) - - def _compile_loop_or_bridge(self, c, inputargs, operations, clt): - var2index = {} - for box in inputargs: - if isinstance(box, history.BoxInt): - var2index[box] = llimpl.compile_start_int_var(c) - elif isinstance(box, self.ts.BoxRef): - TYPE = self.ts.BASETYPE - var2index[box] = llimpl.compile_start_ref_var(c, TYPE) - elif isinstance(box, history.BoxFloat): - var2index[box] = llimpl.compile_start_float_var(c) - else: - raise Exception("box is: %r" % (box,)) - llimpl.compile_started_vars(clt) - self._compile_operations(c, operations, var2index, clt) - return c - - def _compile_operations(self, c, operations, var2index, clt): - for op in operations: - if op.getopnum() == -124: # force_spill - continue - llimpl.compile_add(c, op.getopnum()) - descr = op.getdescr() - if isinstance(descr, Descr): - llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo, - descr.arg_types, descr.extrainfo, - descr.width) - if isinstance(descr, history.JitCellToken): - assert op.getopnum() != rop.JUMP - llimpl.compile_add_loop_token(c, descr) - if isinstance(descr, history.TargetToken) and op.getopnum() == rop.LABEL: - llimpl.compile_add_target_token(c, descr, clt) - if self.is_oo and isinstance(descr, (OODescr, MethDescr)): - # hack hack, not rpython - c._obj.externalobj.operations[-1].setdescr(descr) - for i in range(op.numargs()): - x = op.getarg(i) - if isinstance(x, history.Box): - llimpl.compile_add_var(c, var2index[x]) - elif isinstance(x, history.ConstInt): - llimpl.compile_add_int_const(c, x.value) - elif isinstance(x, self.ts.ConstRef): - llimpl.compile_add_ref_const(c, x.value, self.ts.BASETYPE) - elif isinstance(x, history.ConstFloat): - llimpl.compile_add_float_const(c, x.value) - elif isinstance(x, Descr): - llimpl.compile_add_descr_arg(c, x.ofs, x.typeinfo, - x.arg_types) - else: - raise Exception("'%s' args contain: %r" % (op.getopname(), - x)) - if op.is_guard(): - faildescr = op.getdescr() - assert isinstance(faildescr, history.AbstractFailDescr) - faildescr._fail_args_types = [] - for box in op.getfailargs(): - if box is None: - type = history.HOLE - else: - type = box.type - faildescr._fail_args_types.append(type) - fail_index = self.get_fail_descr_number(faildescr) - index = llimpl.compile_add_fail(c, fail_index) - faildescr._compiled_fail = c, index - for box in op.getfailargs(): - if box is not None: - llimpl.compile_add_fail_arg(c, var2index[box]) - else: - llimpl.compile_add_fail_arg(c, -1) - - x = op.result - if x is not None: - if isinstance(x, history.BoxInt): - var2index[x] = llimpl.compile_add_int_result(c) - elif isinstance(x, self.ts.BoxRef): - var2index[x] = llimpl.compile_add_ref_result(c, self.ts.BASETYPE) - elif isinstance(x, history.BoxFloat): - var2index[x] = llimpl.compile_add_float_result(c) - else: - raise Exception("%s.result contain: %r" % (op.getopname(), - x)) - op = operations[-1] - assert op.is_final() - if op.getopnum() == rop.JUMP: - targettoken = op.getdescr() - llimpl.compile_add_jump_target(c, targettoken, clt) - elif op.getopnum() == rop.FINISH: - faildescr = op.getdescr() - index = self.get_fail_descr_number(faildescr) - llimpl.compile_add_fail(c, index) - else: - assert False, "unknown operation" - - def _execute_token(self, loop_token): - compiled_version = loop_token.compiled_loop_token.compiled_version - frame = llimpl.new_frame(self.is_oo, self) - # setup the frame - llimpl.frame_clear(frame, compiled_version) - # run the loop - fail_index = llimpl.frame_execute(frame) - # we hit a FAIL operation. - self.latest_frame = frame - return fail_index + def compile_loop(self, inputargs, operations, looptoken, log=True, name=''): + for i, op in enumerate(operations): + if op.getopnum() == rop.LABEL: + self.known_labels[op.getdescr()] = (operations, i) + looptoken._llgraph_loop = LLLoop(inputargs, operations) def make_execute_token(self, *argtypes): - nb_args = len(argtypes) - unroll_argtypes = unrolling_iterable(list(enumerate(argtypes))) - # - def execute_token(loop_token, *args): - assert len(args) == nb_args - for index, TYPE in unroll_argtypes: - x = args[index] - assert TYPE == lltype.typeOf(x) - if TYPE == lltype.Signed: - llimpl.set_future_value_int(index, x) - elif TYPE == llmemory.GCREF: - llimpl.set_future_value_ref(index, x) - elif TYPE == longlong.FLOATSTORAGE: - llimpl.set_future_value_float(index, x) - else: - assert 0 - # - fail_index = self._execute_token(loop_token) - return self.get_fail_descr_from_number(fail_index) - # - return execute_token + return self._execute_token + + def _execute_token(self, loop_token, *args): + loop = loop_token._llgraph_loop + frame = LLFrame(self, loop.inputargs, args) + try: + frame.execute(loop.operations) + assert False + except ExecutionFinished, e: + self.latest_values = [e.arg] + return e.descr + except GuardFailed, e: + self.latest_values = e.failargs + return e.descr def get_latest_value_int(self, index): - return llimpl.frame_int_getvalue(self.latest_frame, index) + return self.latest_values[index] + get_latest_value_float = get_latest_value_int - def get_latest_value_ref(self, index): - return llimpl.frame_ptr_getvalue(self.latest_frame, index) +class LLFrame(object): + def __init__(self, cpu, argboxes, args): + self.env = {} + self.cpu = cpu + assert len(argboxes) == len(args) + for box, arg in zip(argboxes, args): + self.env[box] = arg - def get_latest_value_float(self, index): - return llimpl.frame_float_getvalue(self.latest_frame, index) + def lookup(self, arg): + if isinstance(arg, Const): + return arg.value + return self.env[arg] - def get_latest_value_count(self): - return llimpl.frame_get_value_count(self.latest_frame) + def execute(self, operations): + i = 0 + while True: + op = operations[i] + args = [self.lookup(arg) for arg in op.getarglist()] + self.current_op = op # for label + try: + resval = getattr(self, 'execute_' + op.getopname())(op.getdescr(), + *args) + except Jump, j: + operations, i = self.cpu.known_labels[j.descr] + label_op = operations[i] + self.do_renaming(label_op.getarglist(), j.args) + i += 1 + continue + if op.result is not None: + assert resval is not None + self.env[op.result] = resval + else: + assert resval is None + i += 1 - def get_latest_force_token(self): - token = llimpl.get_frame_forced_token(self.latest_frame) - return heaptracker.adr2int(token) + def _getfailargs(self): + r = [] + for arg in self.current_op.getfailargs(): + if arg is None: + r.append(None) + else: + r.append(self.env[arg]) + return r - def clear_latest_values(self, count): - llimpl.frame_clear_latest_values(self.latest_frame, count) + def do_renaming(self, newargs, oldargs): + assert len(newargs) == len(oldargs) + newenv = {} + for new, old in zip(newargs, oldargs): + newenv[new] = old + self.env = newenv - def redirect_call_assembler(self, oldlooptoken, newlooptoken): - if we_are_translated(): - raise ValueError("CALL_ASSEMBLER not supported") - llimpl.redirect_call_assembler(self, oldlooptoken, newlooptoken) + # ----------------------------------------------------- - def invalidate_loop(self, looptoken): - for loop in looptoken.compiled_loop_token.loop_and_bridges: - loop._obj.externalobj.invalid = True + def execute_finish(self, descr, arg=None): + raise ExecutionFinished(descr, arg) - # ---------- + def execute_label(self, descr, *args): + argboxes = self.current_op.getarglist() + self.do_renaming(argboxes, args) - def sizeof(self, S): - assert not isinstance(S, lltype.Ptr) - count = heaptracker.count_fields_if_immutable(S) - return self.getdescr(symbolic.get_size(S), count_fields_if_immut=count) + def execute_guard_true(self, descr, arg): + if not arg: + raise GuardFailed(self._getfailargs(), descr) + def execute_jump(self, descr, *args): + raise Jump(descr, args) -class LLtypeCPU(BaseCPU): - is_oo = False - ts = llhelper +def _setup(): + def _make_impl_from_blackhole_interp(opname): + from pypy.jit.metainterp.blackhole import BlackholeInterpreter + name = 'bhimpl_' + opname.lower() + try: + func = BlackholeInterpreter.__dict__[name] + except KeyError: + return + for argtype in func.argtypes: + if argtype not in ('i', 'r', 'f'): + return + # + def _op_default_implementation(self, descr, *args): + # for all operations implemented in the blackhole interpreter + return func(*args) + # + _op_default_implementation.func_name = 'execute_' + opname + return _op_default_implementation - def __init__(self, *args, **kwds): - BaseCPU.__init__(self, *args, **kwds) - self.fielddescrof_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr') + for k, v in rop.__dict__.iteritems(): + if not k.startswith("_"): + func = _make_impl_from_blackhole_interp(k) + if func is not None: + setattr(LLFrame, 'execute_' + k.lower(), func) - def fielddescrof(self, S, fieldname): - ofs, size = symbolic.get_field_token(S, fieldname) - token = history.getkind(getattr(S, fieldname)) - return self.getdescr(ofs, token[0], name=fieldname) - - def interiorfielddescrof(self, A, fieldname): - S = A.OF - width = symbolic.get_size(A) - ofs, size = symbolic.get_field_token(S, fieldname) - token = history.getkind(getattr(S, fieldname)) - return self.getdescr(ofs, token[0], name=fieldname, width=width) - - def calldescrof(self, FUNC, ARGS, RESULT, extrainfo): - arg_types = [] - for ARG in ARGS: - token = history.getkind(ARG) - if token != 'void': - if token == 'float' and longlong.is_longlong(ARG): - token = 'L' - arg_types.append(token[0]) - token = history.getkind(RESULT) - if token == 'float' and longlong.is_longlong(RESULT): - token = 'L' - return self.getdescr(0, token[0], extrainfo=extrainfo, - arg_types=''.join(arg_types)) - - def calldescrof_dynamic(self, cif_description, extrainfo): - from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind - from pypy.jit.backend.llsupport.ffisupport import UnsupportedKind - arg_types = [] - try: - for itp in range(cif_description.nargs): - arg = cif_description.atypes[itp] - kind = get_ffi_type_kind(self, arg) - if kind != history.VOID: - arg_types.append(kind) - reskind = get_ffi_type_kind(self, cif_description.rtype) - except UnsupportedKind: - return None - return self.getdescr(0, reskind, extrainfo=extrainfo, - arg_types=''.join(arg_types), - ffi_flags=cif_description.abi) - - def _calldescr_dynamic_for_tests(self, atypes, rtype, - abiname='FFI_DEFAULT_ABI'): - from pypy.jit.backend.llsupport import ffisupport - return ffisupport.calldescr_dynamic_for_tests(self, atypes, rtype, - abiname) - - def grab_exc_value(self): - return llimpl.grab_exc_value() - - def arraydescrof(self, A): - assert A.OF != lltype.Void - assert isinstance(A, lltype.GcArray) or A._hints.get('nolength', False) - size = symbolic.get_size(A) - if isinstance(A.OF, lltype.Ptr) or isinstance(A.OF, lltype.Primitive): - token = history.getkind(A.OF)[0] - elif isinstance(A.OF, lltype.Struct): - token = 's' - else: - token = '?' - return self.getdescr(size, token) - - # ---------- the backend-dependent operations ---------- - - def bh_strlen(self, string): - return llimpl.do_strlen(string) - - def bh_strgetitem(self, string, index): - return llimpl.do_strgetitem(string, index) - - def bh_unicodelen(self, string): - return llimpl.do_unicodelen(string) - - def bh_unicodegetitem(self, string, index): - return llimpl.do_unicodegetitem(string, index) - - def bh_getarrayitem_gc_i(self, arraydescr, array, index): - assert isinstance(arraydescr, Descr) - return llimpl.do_getarrayitem_gc_int(array, index) - def bh_getarrayitem_raw_i(self, arraydescr, array, index): - assert isinstance(arraydescr, Descr) - return llimpl.do_getarrayitem_raw_int(array, index, arraydescr.ofs) - def bh_getarrayitem_gc_r(self, arraydescr, array, index): - assert isinstance(arraydescr, Descr) - return llimpl.do_getarrayitem_gc_ptr(array, index) - def bh_getarrayitem_gc_f(self, arraydescr, array, index): - assert isinstance(arraydescr, Descr) - return llimpl.do_getarrayitem_gc_float(array, index) - def bh_getarrayitem_raw_f(self, arraydescr, array, index): - assert isinstance(arraydescr, Descr) - return llimpl.do_getarrayitem_raw_float(array, index) - - def bh_getfield_gc_i(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_gc_int(struct, fielddescr.ofs) - def bh_getfield_gc_r(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs) - def bh_getfield_gc_f(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_gc_float(struct, fielddescr.ofs) - - def bh_getfield_raw_i(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_raw_int(struct, fielddescr.ofs) - def bh_getfield_raw_r(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_raw_ptr(struct, fielddescr.ofs) - def bh_getfield_raw_f(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_raw_float(struct, fielddescr.ofs) - - def bh_getinteriorfield_gc_i(self, array, index, descr): - assert isinstance(descr, Descr) - return llimpl.do_getinteriorfield_gc_int(array, index, descr.ofs) - def bh_getinteriorfield_gc_r(self, array, index, descr): - assert isinstance(descr, Descr) - return llimpl.do_getinteriorfield_gc_ptr(array, index, descr.ofs) - def bh_getinteriorfield_gc_f(self, array, index, descr): - assert isinstance(descr, Descr) - return llimpl.do_getinteriorfield_gc_float(array, index, descr.ofs) - - def bh_setinteriorfield_gc_i(self, array, index, descr, value): - assert isinstance(descr, Descr) - return llimpl.do_setinteriorfield_gc_int(array, index, descr.ofs, - value) - def bh_setinteriorfield_gc_r(self, array, index, descr, value): - assert isinstance(descr, Descr) - return llimpl.do_setinteriorfield_gc_ptr(array, index, descr.ofs, - value) - def bh_setinteriorfield_gc_f(self, array, index, descr, value): - assert isinstance(descr, Descr) - return llimpl.do_setinteriorfield_gc_float(array, index, descr.ofs, - value) - - def bh_raw_store_i(self, struct, offset, descr, newvalue): - assert isinstance(descr, Descr) - return llimpl.do_raw_store_int(struct, offset, descr.ofs, newvalue) - def bh_raw_store_f(self, struct, offset, descr, newvalue): - assert isinstance(descr, Descr) - return llimpl.do_raw_store_float(struct, offset, newvalue) - def bh_raw_load_i(self, struct, offset, descr): - assert isinstance(descr, Descr) - return llimpl.do_raw_load_int(struct, offset, descr.ofs) - def bh_raw_load_f(self, struct, offset, descr): - assert isinstance(descr, Descr) - return llimpl.do_raw_load_float(struct, offset) - - def bh_new(self, sizedescr): - assert isinstance(sizedescr, Descr) - return llimpl.do_new(sizedescr.ofs) - - def bh_new_with_vtable(self, sizedescr, vtable): - assert isinstance(sizedescr, Descr) - result = llimpl.do_new(sizedescr.ofs) - llimpl.do_setfield_gc_int(result, self.fielddescrof_vtable.ofs, vtable) - return result - - def bh_classof(self, struct): - struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) - result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) - return heaptracker.adr2int(result_adr) - - def bh_new_array(self, arraydescr, length): - assert isinstance(arraydescr, Descr) - return llimpl.do_new_array(arraydescr.ofs, length) - - def bh_arraylen_gc(self, arraydescr, array): - assert isinstance(arraydescr, Descr) - return llimpl.do_arraylen_gc(arraydescr, array) - - def bh_setarrayitem_gc_i(self, arraydescr, array, index, newvalue): - assert isinstance(arraydescr, Descr) - llimpl.do_setarrayitem_gc_int(array, index, newvalue) - - def bh_setarrayitem_raw_i(self, arraydescr, array, index, newvalue): - assert isinstance(arraydescr, Descr) - llimpl.do_setarrayitem_raw_int(array, index, newvalue, arraydescr.ofs) - - def bh_setarrayitem_gc_r(self, arraydescr, array, index, newvalue): - assert isinstance(arraydescr, Descr) - llimpl.do_setarrayitem_gc_ptr(array, index, newvalue) - - def bh_setarrayitem_gc_f(self, arraydescr, array, index, newvalue): - assert isinstance(arraydescr, Descr) - llimpl.do_setarrayitem_gc_float(array, index, newvalue) - - def bh_setarrayitem_raw_f(self, arraydescr, array, index, newvalue): - assert isinstance(arraydescr, Descr) - llimpl.do_setarrayitem_raw_float(array, index, newvalue) - - def bh_setfield_gc_i(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_gc_int(struct, fielddescr.ofs, newvalue) - def bh_setfield_gc_r(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) - def bh_setfield_gc_f(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_gc_float(struct, fielddescr.ofs, newvalue) - - def bh_setfield_raw_i(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_raw_int(struct, fielddescr.ofs, newvalue) - def bh_setfield_raw_r(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue) - def bh_setfield_raw_f(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_raw_float(struct, fielddescr.ofs, newvalue) - - def bh_newstr(self, length): - return llimpl.do_newstr(length) - - def bh_newunicode(self, length): - return llimpl.do_newunicode(length) - - def bh_strsetitem(self, string, index, newvalue): - llimpl.do_strsetitem(string, index, newvalue) - - def bh_unicodesetitem(self, string, index, newvalue): - llimpl.do_unicodesetitem(string, index, newvalue) - - def bh_call_i(self, func, calldescr, args_i, args_r, args_f): - self._prepare_call(INT, calldescr, args_i, args_r, args_f) - return llimpl.do_call_int(func) - def bh_call_r(self, func, calldescr, args_i, args_r, args_f): - self._prepare_call(REF, calldescr, args_i, args_r, args_f) - return llimpl.do_call_ptr(func) - def bh_call_f(self, func, calldescr, args_i, args_r, args_f): - self._prepare_call(FLOAT + 'L', calldescr, args_i, args_r, args_f) - return llimpl.do_call_float(func) - def bh_call_v(self, func, calldescr, args_i, args_r, args_f): - self._prepare_call('v', calldescr, args_i, args_r, args_f) - llimpl.do_call_void(func) - - def _prepare_call(self, resulttypeinfo, calldescr, args_i, args_r, args_f): - assert isinstance(calldescr, Descr) - assert calldescr.typeinfo in resulttypeinfo - if args_i is not None: - for x in args_i: - llimpl.do_call_pushint(x) - if args_r is not None: - for x in args_r: - llimpl.do_call_pushptr(x) - if args_f is not None: - for x in args_f: - llimpl.do_call_pushfloat(x) - - def get_all_loop_runs(self): - return lltype.malloc(LOOP_RUN_CONTAINER, 0) - - def force(self, force_token): - token = llmemory.cast_int_to_adr(force_token) - frame = llimpl.get_forced_token_frame(token) - fail_index = llimpl.force(frame) - self.latest_frame = frame - return self.get_fail_descr_from_number(fail_index) - - -class OOtypeCPU_xxx_disabled(BaseCPU): - is_oo = True - ts = oohelper - - @staticmethod - def fielddescrof(T, fieldname): - # use class where the field is really defined as a key - T1, _ = T._lookup_field(fieldname) - return FieldDescr.new(T1, fieldname) - - @staticmethod - def calldescrof(FUNC, ARGS, RESULT, extrainfo): - return StaticMethDescr.new(FUNC, ARGS, RESULT, extrainfo) - - @staticmethod - def methdescrof(SELFTYPE, methname): - return MethDescr.new(SELFTYPE, methname) - - @staticmethod - def typedescrof(TYPE): - return TypeDescr.new(TYPE) - - @staticmethod - def arraydescrof(A): - assert isinstance(A, ootype.Array) - TYPE = A.ITEM - return TypeDescr.new(TYPE) - - def typedescr2classbox(self, descr): - assert isinstance(descr, TypeDescr) - return history.ConstObj(ootype.cast_to_object( - ootype.runtimeClass(descr.TYPE))) - - def get_exception(self): - if llimpl._last_exception: - e = llimpl._last_exception.args[0] - return ootype.cast_to_object(e) - else: - return ootype.NULL - - def get_exc_value(self): - if llimpl._last_exception: - earg = llimpl._last_exception.args[1] - return ootype.cast_to_object(earg) - else: - return ootype.NULL - - def get_overflow_error(self): - ll_err = llimpl._get_error(OverflowError) - return (ootype.cast_to_object(ll_err.args[0]), - ootype.cast_to_object(ll_err.args[1])) - - def get_zero_division_error(self): - ll_err = llimpl._get_error(ZeroDivisionError) - return (ootype.cast_to_object(ll_err.args[0]), - ootype.cast_to_object(ll_err.args[1])) - - def do_new_with_vtable(self, clsbox): - cls = clsbox.getref_base() - typedescr = self.class_sizes[cls] - return typedescr.create() - - def do_new_array(self, lengthbox, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.create_array(lengthbox) - - def do_new(self, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.create() - - def do_runtimenew(self, classbox): - "NOT_RPYTHON" - classobj = classbox.getref(ootype.Class) - res = ootype.runtimenew(classobj) - return history.BoxObj(ootype.cast_to_object(res)) - - def do_instanceof(self, box1, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.instanceof(box1) - - def do_getfield_gc(self, box1, fielddescr): - assert isinstance(fielddescr, FieldDescr) - return fielddescr.getfield(box1) - - def do_setfield_gc(self, box1, box2, fielddescr): - assert isinstance(fielddescr, FieldDescr) - return fielddescr.setfield(box1, box2) - - def do_getarrayitem_gc(self, box1, box2, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.getarrayitem(box1, box2) - - def do_setarrayitem_gc(self, box1, box2, box3, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.setarrayitem(box1, box2, box3) - - def do_arraylen_gc(self, box1, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.getarraylength(box1) - - def do_call_XXX(self, args, descr): - assert isinstance(descr, StaticMethDescr) - funcbox = args[0] - argboxes = args[1:] - x = descr.callfunc(funcbox, argboxes) - # XXX: return None if RESULT is Void - return x - - def do_oosend(self, args, descr): - assert isinstance(descr, MethDescr) - selfbox = args[0] - argboxes = args[1:] - x = descr.callmeth(selfbox, argboxes) - # XXX: return None if METH.RESULT is Void - return x - - -def make_getargs(ARGS): - argsiter = unrolling_iterable(ARGS) - args_n = len([ARG for ARG in ARGS if ARG is not ootype.Void]) - def getargs(argboxes): - funcargs = () - assert len(argboxes) == args_n - i = 0 - for ARG in argsiter: - if ARG is ootype.Void: - funcargs += (None,) - else: - box = argboxes[i] - i+=1 - funcargs += (unwrap(ARG, box),) - return funcargs - return getargs - -def boxresult(RESULT, result): - if isinstance(RESULT, ootype.OOType): - return history.BoxObj(ootype.cast_to_object(result)) - elif RESULT is lltype.Float: - return history.BoxFloat(result) - else: - return history.BoxInt(lltype.cast_primitive(ootype.Signed, result)) -boxresult._annspecialcase_ = 'specialize:arg(0)' - - -class KeyManager(object): - """ - Helper class to convert arbitrary dictionary keys to integers. - """ - - def __init__(self): - self.keys = {} - - def getkey(self, key): - try: - return self.keys[key] - except KeyError: - n = len(self.keys) - self.keys[key] = n - return n - - def _freeze_(self): - raise Exception("KeyManager is not supposed to be turned into a pbc") - - -descr_cache = {} -class OODescr(history.AbstractDescr): - - @classmethod - def new(cls, *args): - 'NOT_RPYTHON' - key = (cls, args) - try: - return descr_cache[key] - except KeyError: - res = cls(*args) - descr_cache[key] = res - return res - -class StaticMethDescr(OODescr): - - def __init__(self, FUNC, ARGS, RESULT, extrainfo=None): - self.FUNC = FUNC - getargs = make_getargs(FUNC.ARGS) - def callfunc(funcbox, argboxes): - funcobj = funcbox.getref(FUNC) - funcargs = getargs(argboxes) - res = llimpl.call_maybe_on_top_of_llinterp(funcobj, funcargs) - if RESULT is not ootype.Void: - return boxresult(RESULT, res) - self.callfunc = callfunc - self.extrainfo = extrainfo - - def get_extra_info(self): - return self.extrainfo - -class MethDescr(history.AbstractMethDescr): - - callmeth = None - - new = classmethod(OODescr.new.im_func) - - def __init__(self, SELFTYPE, methname): - _, meth = SELFTYPE._lookup(methname) - METH = ootype.typeOf(meth) - self.SELFTYPE = SELFTYPE - self.METH = METH - self.methname = methname - RESULT = METH.RESULT - getargs = make_getargs(METH.ARGS) - def callmeth(selfbox, argboxes): - selfobj = selfbox.getref(SELFTYPE) - meth = getattr(selfobj, methname) - methargs = getargs(argboxes) - res = llimpl.call_maybe_on_top_of_llinterp(meth, methargs) - if RESULT is not ootype.Void: - return boxresult(RESULT, res) - self.callmeth = callmeth - - def __repr__(self): - return '' % self.methname - -class TypeDescr(OODescr): - - create = None - - def __init__(self, TYPE): - self.TYPE = TYPE - self.ARRAY = ARRAY = ootype.Array(TYPE) - def create(): - return boxresult(TYPE, ootype.new(TYPE)) - - def create_array(lengthbox): - n = lengthbox.getint() - return boxresult(ARRAY, ootype.oonewarray(ARRAY, n)) - - def getarrayitem(arraybox, ibox): - array = arraybox.getref(ARRAY) - i = ibox.getint() - return boxresult(TYPE, array.ll_getitem_fast(i)) - - def setarrayitem(arraybox, ibox, valuebox): - array = arraybox.getref(ARRAY) - i = ibox.getint() - value = unwrap(TYPE, valuebox) - array.ll_setitem_fast(i, value) - - def getarraylength(arraybox): - array = arraybox.getref(ARRAY) - return boxresult(ootype.Signed, array.ll_length()) - - def instanceof(box): - obj = box.getref(ootype.ROOT) - return history.BoxInt(ootype.instanceof(obj, TYPE)) - - self.create = create - self.create_array = create_array - self.getarrayitem = getarrayitem - self.setarrayitem = setarrayitem - self.getarraylength = getarraylength - self.instanceof = instanceof - self._is_array_of_pointers = (history.getkind(TYPE) == 'ref') - self._is_array_of_floats = (history.getkind(TYPE) == 'float') - - def is_array_of_pointers(self): - # for arrays, TYPE is the type of the array item. - return self._is_array_of_pointers - - def is_array_of_floats(self): - # for arrays, TYPE is the type of the array item. - return self._is_array_of_floats - - def __repr__(self): - return '' % self.TYPE._short_name() - -class FieldDescr(OODescr): - - getfield = None - _keys = KeyManager() - - def __init__(self, TYPE, fieldname): - self.TYPE = TYPE - self.fieldname = fieldname - - _, T = TYPE._lookup_field(fieldname) - def getfield(objbox): - obj = objbox.getref(TYPE) - value = getattr(obj, fieldname) - return boxresult(T, value) - def setfield(objbox, valuebox): - obj = objbox.getref(TYPE) - value = unwrap(T, valuebox) - setattr(obj, fieldname, value) - - self.getfield = getfield - self.setfield = setfield - self._is_pointer_field = (history.getkind(T) == 'ref') - self._is_float_field = (history.getkind(T) == 'float') - - def sort_key(self): - return self._keys.getkey((self.TYPE, self.fieldname)) - - def is_pointer_field(self): - return self._is_pointer_field - - def is_float_field(self): - return self._is_float_field - - def equals(self, other): - return self.TYPE == other.TYPE and \ - self.fieldname == other.fieldname - - def __repr__(self): - return '' % self.fieldname +_setup() diff --git a/pypy/jit/backend/llgraph/test/test_llgraph.py b/pypy/jit/backend/llgraph/test/test_llgraph.py --- a/pypy/jit/backend/llgraph/test/test_llgraph.py +++ b/pypy/jit/backend/llgraph/test/test_llgraph.py @@ -14,7 +14,7 @@ # for individual tests see: # ====> ../../test/runner_test.py - from pypy.jit.backend.llgraph.runner import LLtypeCPU as cpu_type + from pypy.jit.backend.llgraph.runner import LLGraphCPU as cpu_type def setup_method(self, _): self.cpu = self.cpu_type(None) From noreply at buildbot.pypy.org Tue Oct 16 21:31:52 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 16 Oct 2012 21:31:52 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: progress Message-ID: <20121016193152.3472D1C027A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58147:038b7419f1b2 Date: 2012-10-16 21:31 +0200 http://bitbucket.org/pypy/pypy/changeset/038b7419f1b2/ Log: progress diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -33,11 +33,17 @@ self.known_labels = WeakKeyDictionary() def compile_loop(self, inputargs, operations, looptoken, log=True, name=''): + self.total_compiled_loops += 1 for i, op in enumerate(operations): if op.getopnum() == rop.LABEL: self.known_labels[op.getdescr()] = (operations, i) looptoken._llgraph_loop = LLLoop(inputargs, operations) + def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token): + faildescr._llgraph_bridge = LLLoop(inputargs, operations) + self.total_compiled_bridges += 1 + def make_execute_token(self, *argtypes): return self._execute_token @@ -58,6 +64,12 @@ return self.latest_values[index] get_latest_value_float = get_latest_value_int + def get_latest_value_count(self): + return len(self.latest_values) + + def clear_latest_values(self, count): + del self.latest_values + class LLFrame(object): def __init__(self, cpu, argboxes, args): self.env = {} @@ -86,6 +98,16 @@ self.do_renaming(label_op.getarglist(), j.args) i += 1 continue + except GuardFailed, gf: + if hasattr(gf.descr, '_llgraph_bridge'): + i = 0 + bridge = gf.descr._llgraph_bridge + operations = bridge.operations + newargs = [self.env[arg] for arg in + self.current_op.getfailargs() if arg is not None] + self.do_renaming(bridge.inputargs, newargs) + continue + raise if op.result is not None: assert resval is not None self.env[op.result] = resval @@ -111,6 +133,9 @@ # ----------------------------------------------------- + def fail_guard(self, descr): + raise GuardFailed(self._getfailargs(), descr) + def execute_finish(self, descr, arg=None): raise ExecutionFinished(descr, arg) @@ -120,7 +145,11 @@ def execute_guard_true(self, descr, arg): if not arg: - raise GuardFailed(self._getfailargs(), descr) + self.fail_guard(descr) + + def execute_guard_false(self, descr, arg): + if arg: + self.fail_guard(descr) def execute_jump(self, descr, *args): raise Jump(descr, args) diff --git a/pypy/jit/backend/llgraph/test/test_llgraph.py b/pypy/jit/backend/llgraph/test/test_llgraph.py --- a/pypy/jit/backend/llgraph/test/test_llgraph.py +++ b/pypy/jit/backend/llgraph/test/test_llgraph.py @@ -1,12 +1,6 @@ import py -from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rclass -from pypy.rpython.test.test_llinterp import interpret -from pypy.rlib.unroll import unrolling_iterable +from pypy.rpython.lltypesystem import lltype, llmemory -from pypy.jit.metainterp.history import BoxInt, BoxPtr, Const, ConstInt,\ - TreeLoop -from pypy.jit.metainterp.resoperation import ResOperation, rop -from pypy.jit.metainterp.executor import execute from pypy.jit.codewriter import heaptracker from pypy.jit.backend.test.runner_test import LLtypeBackendTest @@ -19,6 +13,9 @@ def setup_method(self, _): self.cpu = self.cpu_type(None) + def test_backends_dont_keep_loops_alive(self): + py.test.skip("does not make much sense on the llgraph backend") + def test_memoryerror(self): py.test.skip("does not make much sense on the llgraph backend") @@ -34,18 +31,3 @@ assert llmemory.cast_adr_to_ptr(a2, lltype.Ptr(X)) == x assert heaptracker.adr2int(llmemory.NULL) == 0 assert heaptracker.int2adr(0) == llmemory.NULL - -## these tests never worked -## class TestOOTypeLLGraph(LLGraphTest): -## from pypy.jit.backend.llgraph.runner import OOtypeCPU as cpu_type - -def test_fielddescr_ootype(): - py.test.skip("ootype tests skipped") - from pypy.rpython.ootypesystem import ootype - from pypy.jit.backend.llgraph.runner import OOtypeCPU - A = ootype.Instance("A", ootype.ROOT, {"foo": ootype.Signed}) - B = ootype.Instance("B", A) - cpu = OOtypeCPU(None) - descr1 = cpu.fielddescrof(A, "foo") - descr2 = cpu.fielddescrof(B, "foo") - assert descr1 is descr2 From noreply at buildbot.pypy.org Tue Oct 16 21:46:01 2012 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 16 Oct 2012 21:46:01 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: add marks for 50%, 99% and 99.9% of failures Message-ID: <20121016194601.0B0A11C027A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4864:acad1ee1094e Date: 2012-10-16 16:44 -0300 http://bitbucket.org/pypy/extradoc/changeset/acad1ee1094e/ Log: add marks for 50%, 99% and 99.9% of failures diff --git a/talk/vmil2012/presentation/figures/data.tex b/talk/vmil2012/presentation/figures/data.tex --- a/talk/vmil2012/presentation/figures/data.tex +++ b/talk/vmil2012/presentation/figures/data.tex @@ -1,45 +1,56 @@ -\addplot[red] coordinates { +\addplot[red,mark=none] coordinates { (0.000000,1.000000) (0.006494,0.148545) (0.012987,0.143156) (0.019481,0.074262) (0.025974,0.070332) (0.032468,0.047160) (0.038961,0.046744) (0.045455,0.041526) (0.051948,0.032187) (0.058442,0.027040) (0.064935,0.020597) (0.071429,0.018534) (0.077922,0.017118) (0.084416,0.016888) (0.090909,0.011212) (0.097403,0.009493) (0.103896,0.007359) (0.110390,0.007268) (0.116883,0.006596) (0.123377,0.005563) (0.129870,0.005529) (0.136364,0.005470) (0.142857,0.003591) (0.149351,0.002948) (0.155844,0.002945) (0.162338,0.002749) (0.168831,0.002558) (0.175325,0.001651) (0.181818,0.001644) (0.188312,0.001592) (0.194805,0.001582) (0.201299,0.001365) (0.207792,0.001362) (0.214286,0.000933) (0.220779,0.000887) (0.227273,0.000871) (0.233766,0.000863) (0.240260,0.000843) (0.246753,0.000726) (0.253247,0.000695) (0.259740,0.000594) (0.266234,0.000558) (0.272727,0.000534) (0.279221,0.000498) (0.285714,0.000389) (0.292208,0.000389) (0.298701,0.000382) (0.305195,0.000381) (0.311688,0.000376) (0.318182,0.000364) (0.324675,0.000340) (0.331169,0.000312) (0.337662,0.000237) (0.344156,0.000219) (0.350649,0.000204) (0.357143,0.000202) (0.363636,0.000202) (0.370130,0.000193) (0.376623,0.000174) (0.383117,0.000162) (0.389610,0.000139) (0.396104,0.000137) (0.402597,0.000135) (0.409091,0.000130) (0.415584,0.000130) (0.422078,0.000122) (0.428571,0.000119) (0.435065,0.000104) (0.441558,0.000101) (0.448052,0.000097) (0.454545,0.000087) (0.461039,0.000079) (0.467532,0.000069) (0.474026,0.000058) (0.480519,0.000051) (0.487013,0.000041) (0.493506,0.000040) (0.500000,0.000035) (0.506494,0.000029) (0.512987,0.000028) (0.519481,0.000028) (0.525974,0.000027) (0.532468,0.000026) (0.538961,0.000026) (0.545455,0.000024) (0.551948,0.000021) (0.558442,0.000018) (0.564935,0.000018) (0.571429,0.000017) (0.577922,0.000016) (0.584416,0.000015) (0.590909,0.000015) (0.597403,0.000014) (0.603896,0.000014) (0.610390,0.000011) (0.616883,0.000011) (0.623377,0.000011) (0.629870,0.000011) (0.636364,0.000011) (0.642857,0.000011) (0.649351,0.000011) (0.655844,0.000011) (0.662338,0.000010) (0.668831,0.000009) (0.675325,0.000007) (0.681818,0.000007) (0.688312,0.000007) (0.694805,0.000007) (0.701299,0.000007) (0.707792,0.000006) (0.714286,0.000006) (0.720779,0.000005) (0.727273,0.000005) (0.733766,0.000005) (0.740260,0.000005) (0.746753,0.000004) (0.753247,0.000004) (0.759740,0.000003) (0.766234,0.000003) (0.772727,0.000003) (0.779221,0.000003) (0.785714,0.000002) (0.792208,0.000002) (0.798701,0.000002) (0.805195,0.000002) (0.811688,0.000002) (0.818182,0.000002) (0.824675,0.000002) (0.831169,0.000002) (0.837662,0.000002) (0.844156,0.000002) (0.850649,0.000002) (0.857143,0.000002) (0.863636,0.000002) (0.870130,0.000001) (0.876623,0.000001) (0.883117,0.000001) (0.889610,0.000001) (0.896104,0.000001) (0.902597,0.000001) (0.909091,0.000001) (0.915584,0.000001) (0.922078,0.000001) (0.928571,0.000001) (0.935065,0.000001) (0.941558,0.000001) (0.948052,0.000000) (0.954545,0.000000) (0.961039,0.000000) (0.967532,0.000000) (0.974026,0.000000) (0.980519,0.000000) (0.987013,0.000000) (0.993506,0.000000) (1.000000,0.000000) }; +\addplot[red,only marks,mark=*] coordinates {(0.006494,0.148545) (0.201299,0.001365) (0.415584,0.000130)}; +\addplot[green,only marks,mark=*] coordinates {(0.060976,0.459611) (0.524390,0.006634) (0.756098,0.001243)}; -\addplot[green] coordinates { +\addplot[green,mark=none] coordinates { (0.000000,1.000000) (0.012195,0.997326) (0.024390,0.701335) (0.036585,0.503352) (0.048780,0.496172) (0.060976,0.459611) (0.073171,0.381570) (0.085366,0.349645) (0.097561,0.315892) (0.109756,0.312117) (0.121951,0.242322) (0.134146,0.213275) (0.146341,0.186336) (0.158537,0.114441) (0.170732,0.077514) (0.182927,0.054374) (0.195122,0.047764) (0.207317,0.043576) (0.219512,0.039644) (0.231707,0.029204) (0.243902,0.029145) (0.256098,0.027214) (0.268293,0.023030) (0.280488,0.016877) (0.292683,0.016283) (0.304878,0.015489) (0.317073,0.014624) (0.329268,0.014572) (0.341463,0.014451) (0.353659,0.009960) (0.365854,0.009811) (0.378049,0.009299) (0.390244,0.009197) (0.402439,0.009182) (0.414634,0.009178) (0.426829,0.007813) (0.439024,0.007797) (0.451220,0.007786) (0.463415,0.007715) (0.475610,0.007381) (0.487805,0.007172) (0.500000,0.006791) (0.512195,0.006783) (0.524390,0.006634) (0.536585,0.006366) (0.548780,0.005879) (0.560976,0.004203) (0.573171,0.004074) (0.585366,0.003983) (0.597561,0.003260) (0.609756,0.003252) (0.621951,0.003181) (0.634146,0.002945) (0.646341,0.002670) (0.658537,0.002399) (0.670732,0.002159) (0.682927,0.002143) (0.695122,0.001817) (0.707317,0.001793) (0.719512,0.001785) (0.731707,0.001577) (0.743902,0.001573) (0.756098,0.001243) (0.768293,0.001073) (0.780488,0.000598) (0.792683,0.000590) (0.804878,0.000492) (0.817073,0.000440) (0.829268,0.000240) (0.841463,0.000201) (0.853659,0.000201) (0.865854,0.000197) (0.878049,0.000177) (0.890244,0.000079) (0.902439,0.000079) (0.914634,0.000067) (0.926829,0.000031) (0.939024,0.000028) (0.951220,0.000024) (0.963415,0.000012) (0.975610,0.000008) (0.987805,0.000004) (1.000000,0.000004) }; +\addplot[blue,only marks,mark=*] coordinates {(0.045045,0.253942) (0.378378,0.003324) (0.585586,0.000480)}; -\addplot[blue] coordinates { +\addplot[blue,mark=none] coordinates { (0.000000,1.000000) (0.009009,0.274799) (0.018018,0.254401) (0.027027,0.254401) (0.036036,0.254400) (0.045045,0.253942) (0.054054,0.176493) (0.063063,0.170575) (0.072072,0.170575) (0.081081,0.166477) (0.090090,0.103439) (0.099099,0.087880) (0.108108,0.085545) (0.117117,0.085441) (0.126126,0.077913) (0.135135,0.075639) (0.144144,0.059419) (0.153153,0.052926) (0.162162,0.051446) (0.171171,0.040551) (0.180180,0.036356) (0.189189,0.031443) (0.198198,0.026162) (0.207207,0.023960) (0.216216,0.020391) (0.225225,0.018926) (0.234234,0.018265) (0.243243,0.018091) (0.252252,0.018011) (0.261261,0.015999) (0.270270,0.011937) (0.279279,0.010101) (0.288288,0.010101) (0.297297,0.009964) (0.306306,0.009956) (0.315315,0.009498) (0.324324,0.006923) (0.333333,0.006919) (0.342342,0.005088) (0.351351,0.004699) (0.360360,0.004400) (0.369369,0.004132) (0.378378,0.003324) (0.387387,0.003266) (0.396396,0.003017) (0.405405,0.002900) (0.414414,0.002389) (0.423423,0.001747) (0.432432,0.001717) (0.441441,0.001660) (0.450450,0.001634) (0.459459,0.001542) (0.468468,0.001353) (0.477477,0.001264) (0.486486,0.001263) (0.495495,0.001131) (0.504505,0.001046) (0.513514,0.000934) (0.522523,0.000928) (0.531532,0.000856) (0.540541,0.000850) (0.549550,0.000821) (0.558559,0.000745) (0.567568,0.000679) (0.576577,0.000581) (0.585586,0.000480) (0.594595,0.000316) (0.603604,0.000260) (0.612613,0.000256) (0.621622,0.000209) (0.630631,0.000195) (0.639640,0.000163) (0.648649,0.000161) (0.657658,0.000145) (0.666667,0.000136) (0.675676,0.000134) (0.684685,0.000128) (0.693694,0.000123) (0.702703,0.000117) (0.711712,0.000100) (0.720721,0.000099) (0.729730,0.000095) (0.738739,0.000088) (0.747748,0.000087) (0.756757,0.000065) (0.765766,0.000058) (0.774775,0.000052) (0.783784,0.000051) (0.792793,0.000045) (0.801802,0.000043) (0.810811,0.000033) (0.819820,0.000031) (0.828829,0.000028) (0.837838,0.000023) (0.846847,0.000019) (0.855856,0.000018) (0.864865,0.000017) (0.873874,0.000017) (0.882883,0.000016) (0.891892,0.000016) (0.900901,0.000016) (0.909910,0.000016) (0.918919,0.000015) (0.927928,0.000015) (0.936937,0.000012) (0.945946,0.000011) (0.954955,0.000009) (0.963964,0.000006) (0.972973,0.000005) (0.981982,0.000003) (0.990991,0.000001) (1.000000,0.000000) }; +\addplot[cyan,only marks,mark=*] coordinates {(0.040541,0.223088) (0.328829,0.004749) (0.563063,0.000352)}; -\addplot[cyan] coordinates { +\addplot[cyan,mark=none] coordinates { (0.000000,1.000000) (0.004505,0.536162) (0.009009,0.533859) (0.013514,0.483711) (0.018018,0.468958) (0.022523,0.385926) (0.027027,0.368855) (0.031532,0.330881) (0.036036,0.273385) (0.040541,0.223088) (0.045045,0.201529) (0.049550,0.188300) (0.054054,0.184877) (0.058559,0.165360) (0.063063,0.160965) (0.067568,0.151293) (0.072072,0.125402) (0.076577,0.121903) (0.081081,0.121395) (0.085586,0.117212) (0.090090,0.117117) (0.094595,0.099425) (0.099099,0.096936) (0.103604,0.096847) (0.108108,0.096552) (0.112613,0.096421) (0.117117,0.083108) (0.121622,0.076876) (0.126126,0.068604) (0.130631,0.064969) (0.135135,0.056385) (0.139640,0.056383) (0.144144,0.049812) (0.148649,0.049576) (0.153153,0.042719) (0.157658,0.042151) (0.162162,0.038817) (0.166667,0.038467) (0.171171,0.038437) (0.175676,0.038161) (0.180180,0.037712) (0.184685,0.037469) (0.189189,0.037434) (0.193694,0.037419) (0.198198,0.037035) (0.202703,0.037000) (0.207207,0.036987) (0.211712,0.035969) (0.216216,0.034370) (0.220721,0.033375) (0.225225,0.031819) (0.229730,0.031613) (0.234234,0.029056) (0.238739,0.028685) (0.243243,0.026102) (0.247748,0.023276) (0.252252,0.018629) (0.256757,0.018545) (0.261261,0.015560) (0.265766,0.013442) (0.270270,0.013322) (0.274775,0.011983) (0.279279,0.011599) (0.283784,0.008508) (0.288288,0.008463) (0.292793,0.008461) (0.297297,0.008456) (0.301802,0.007547) (0.306306,0.007021) (0.310811,0.006568) (0.315315,0.006344) (0.319820,0.005826) (0.324324,0.004751) (0.328829,0.004749) (0.333333,0.004749) (0.337838,0.003794) (0.342342,0.003082) (0.346847,0.002806) (0.351351,0.002767) (0.355856,0.002535) (0.360360,0.002472) (0.364865,0.002390) (0.369369,0.002320) (0.373874,0.002290) (0.378378,0.002275) (0.382883,0.002210) (0.387387,0.002049) (0.391892,0.001854) (0.396396,0.001647) (0.400901,0.001502) (0.405405,0.001322) (0.409910,0.001200) (0.414414,0.001161) (0.418919,0.001159) (0.423423,0.001146) (0.427928,0.001144) (0.432432,0.001116) (0.436937,0.001066) (0.441441,0.001059) (0.445946,0.001018) (0.450450,0.000873) (0.454955,0.000864) (0.459459,0.000840) (0.463964,0.000777) (0.468468,0.000766) (0.472973,0.000747) (0.477477,0.000729) (0.481982,0.000729) (0.486486,0.000621) (0.490991,0.000597) (0.495495,0.000590) (0.500000,0.000582) (0.504505,0.000577) (0.509009,0.000562) (0.513514,0.000558) (0.518018,0.000523) (0.522523,0.000478) (0.527027,0.000469) (0.531532,0.000456) (0.536036,0.000434) (0.540541,0.000432) (0.545045,0.000425) (0.549550,0.000425) (0.554054,0.000417) (0.558559,0.000412) (0.563063,0.000352) (0.567568,0.000332) (0.572072,0.000330) (0.576577,0.000326) (0.581081,0.000313) (0.585586,0.000289) (0.590090,0.000267) (0.594595,0.000247) (0.599099,0.000247) (0.603604,0.000217) (0.608108,0.000204) (0.612613,0.000195) (0.617117,0.000182) (0.621622,0.000165) (0.626126,0.000165) (0.630631,0.000163) (0.635135,0.000137) (0.639640,0.000137) (0.644144,0.000132) (0.648649,0.000130) (0.653153,0.000130) (0.657658,0.000122) (0.662162,0.000122) (0.666667,0.000122) (0.671171,0.000119) (0.675676,0.000115) (0.680180,0.000104) (0.684685,0.000104) (0.689189,0.000100) (0.693694,0.000096) (0.698198,0.000093) (0.702703,0.000087) (0.707207,0.000087) (0.711712,0.000087) (0.716216,0.000085) (0.720721,0.000085) (0.725225,0.000078) (0.729730,0.000074) (0.734234,0.000063) (0.738739,0.000059) (0.743243,0.000059) (0.747748,0.000059) (0.752252,0.000056) (0.756757,0.000056) (0.761261,0.000056) (0.765766,0.000054) (0.770270,0.000052) (0.774775,0.000052) (0.779279,0.000048) (0.783784,0.000046) (0.788288,0.000043) (0.792793,0.000041) (0.797297,0.000039) (0.801802,0.000039) (0.806306,0.000037) (0.810811,0.000037) (0.815315,0.000035) (0.819820,0.000035) (0.824324,0.000035) (0.828829,0.000033) (0.833333,0.000030) (0.837838,0.000030) (0.842342,0.000028) (0.846847,0.000028) (0.851351,0.000026) (0.855856,0.000026) (0.860360,0.000026) (0.864865,0.000024) (0.869369,0.000022) (0.873874,0.000020) (0.878378,0.000020) (0.882883,0.000017) (0.887387,0.000017) (0.891892,0.000017) (0.896396,0.000013) (0.900901,0.000013) (0.905405,0.000013) (0.909910,0.000011) (0.914414,0.000011) (0.918919,0.000011) (0.923423,0.000011) (0.927928,0.000011) (0.932432,0.000009) (0.936937,0.000009) (0.941441,0.000009) (0.945946,0.000009) (0.950450,0.000007) (0.954955,0.000007) (0.959459,0.000007) (0.963964,0.000004) (0.968468,0.000004) (0.972973,0.000004) (0.977477,0.000002) (0.981982,0.000002) (0.986486,0.000002) (0.990991,0.000002) (0.995495,0.000002) (1.000000,0.000002) }; +\addplot[magenta,only marks,mark=*] coordinates {(0.066667,0.333230) (0.300000,0.003317) (0.366667,0.000795)}; -\addplot[magenta] coordinates { +\addplot[magenta,mark=none] coordinates { (0.000000,1.000000) (0.033333,0.333289) (0.066667,0.333230) (0.100000,0.330941) (0.133333,0.089999) (0.166667,0.087891) (0.200000,0.074485) (0.233333,0.074414) (0.266667,0.074281) (0.300000,0.003317) (0.333333,0.002204) (0.366667,0.000795) (0.400000,0.000294) (0.433333,0.000133) (0.466667,0.000099) (0.500000,0.000099) (0.533333,0.000067) (0.566667,0.000033) (0.600000,0.000032) (0.633333,0.000031) (0.666667,0.000025) (0.700000,0.000019) (0.733333,0.000010) (0.766667,0.000005) (0.800000,0.000003) (0.833333,0.000003) (0.866667,0.000003) (0.900000,0.000001) (0.933333,0.000001) (0.966667,0.000001) (1.000000,0.000001) }; +\addplot[yellow,only marks,mark=*] coordinates {(0.035088,0.506431) (0.070175,0.003334) (0.192982,0.000768)}; -\addplot[yellow] coordinates { +\addplot[yellow,mark=none] coordinates { (0.000000,1.000000) (0.017544,0.993592) (0.035088,0.506431) (0.052632,0.496860) (0.070175,0.003334) (0.087719,0.003334) (0.105263,0.003290) (0.122807,0.003290) (0.140351,0.003290) (0.157895,0.003289) (0.175439,0.003250) (0.192982,0.000768) (0.210526,0.000464) (0.228070,0.000216) (0.245614,0.000205) (0.263158,0.000137) (0.280702,0.000133) (0.298246,0.000121) (0.315789,0.000105) (0.333333,0.000081) (0.350877,0.000067) (0.368421,0.000058) (0.385965,0.000055) (0.403509,0.000053) (0.421053,0.000052) (0.438596,0.000043) (0.456140,0.000034) (0.473684,0.000030) (0.491228,0.000029) (0.508772,0.000023) (0.526316,0.000022) (0.543860,0.000022) (0.561404,0.000022) (0.578947,0.000020) (0.596491,0.000019) (0.614035,0.000018) (0.631579,0.000014) (0.649123,0.000012) (0.666667,0.000011) (0.684211,0.000010) (0.701754,0.000006) (0.719298,0.000006) (0.736842,0.000005) (0.754386,0.000004) (0.771930,0.000004) (0.789474,0.000004) (0.807018,0.000003) (0.824561,0.000003) (0.842105,0.000002) (0.859649,0.000002) (0.877193,0.000001) (0.894737,0.000001) (0.912281,0.000001) (0.929825,0.000001) (0.947368,0.000000) (0.964912,0.000000) (0.982456,0.000000) (1.000000,0.000000) }; +\addplot[black,only marks,mark=*] coordinates {(0.001953,0.247783) (0.214844,0.000248) (0.519531,0.000021)}; -\addplot[black] coordinates { +\addplot[black,mark=none] coordinates { (0.000000,1.000000) (0.001953,0.247783) (0.003906,0.056979) (0.005859,0.026968) (0.007812,0.019062) (0.009766,0.014136) (0.011719,0.011763) (0.013672,0.009968) (0.015625,0.009263) (0.017578,0.007132) (0.019531,0.006664) (0.021484,0.006547) (0.023438,0.006214) (0.025391,0.006190) (0.027344,0.005569) (0.029297,0.004773) (0.031250,0.004590) (0.033203,0.004576) (0.035156,0.004534) (0.037109,0.004497) (0.039062,0.004348) (0.041016,0.004135) (0.042969,0.003889) (0.044922,0.003631) (0.046875,0.003618) (0.048828,0.003285) (0.050781,0.003143) (0.052734,0.003024) (0.054688,0.003020) (0.056641,0.002903) (0.058594,0.002661) (0.060547,0.002589) (0.062500,0.002268) (0.064453,0.002194) (0.066406,0.002187) (0.068359,0.001941) (0.070312,0.001798) (0.072266,0.001740) (0.074219,0.001716) (0.076172,0.001704) (0.078125,0.001658) (0.080078,0.001649) (0.082031,0.001550) (0.083984,0.001484) (0.085938,0.001468) (0.087891,0.001432) (0.089844,0.001429) (0.091797,0.001423) (0.093750,0.001376) (0.095703,0.001359) (0.097656,0.001281) (0.099609,0.001224) (0.101562,0.001212) (0.103516,0.001182) (0.105469,0.001181) (0.107422,0.001174) (0.109375,0.001089) (0.111328,0.001037) (0.113281,0.001024) (0.115234,0.000993) (0.117188,0.000955) (0.119141,0.000955) (0.121094,0.000954) (0.123047,0.000954) (0.125000,0.000902) (0.126953,0.000889) (0.128906,0.000887) (0.130859,0.000881) (0.132812,0.000856) (0.134766,0.000823) (0.136719,0.000694) (0.138672,0.000676) (0.140625,0.000675) (0.142578,0.000675) (0.144531,0.000625) (0.146484,0.000616) (0.148438,0.000603) (0.150391,0.000591) (0.152344,0.000575) (0.154297,0.000573) (0.156250,0.000553) (0.158203,0.000514) (0.160156,0.000491) (0.162109,0.000467) (0.164062,0.000429) (0.166016,0.000426) (0.167969,0.000426) (0.169922,0.000421) (0.171875,0.000419) (0.173828,0.000418) (0.175781,0.000413) (0.177734,0.000408) (0.179688,0.000408) (0.181641,0.000388) (0.183594,0.000385) (0.185547,0.000355) (0.187500,0.000336) (0.189453,0.000334) (0.191406,0.000324) (0.193359,0.000303) (0.195312,0.000296) (0.197266,0.000291) (0.199219,0.000267) (0.201172,0.000265) (0.203125,0.000264) (0.205078,0.000261) (0.207031,0.000260) (0.208984,0.000259) (0.210938,0.000259) (0.212891,0.000251) (0.214844,0.000248) (0.216797,0.000245) (0.218750,0.000237) (0.220703,0.000215) (0.222656,0.000209) (0.224609,0.000208) (0.226562,0.000204) (0.228516,0.000201) (0.230469,0.000199) (0.232422,0.000197) (0.234375,0.000195) (0.236328,0.000179) (0.238281,0.000178) (0.240234,0.000178) (0.242188,0.000178) (0.244141,0.000178) (0.246094,0.000178) (0.248047,0.000178) (0.250000,0.000178) (0.251953,0.000171) (0.253906,0.000171) (0.255859,0.000170) (0.257812,0.000169) (0.259766,0.000166) (0.261719,0.000164) (0.263672,0.000163) (0.265625,0.000161) (0.267578,0.000160) (0.269531,0.000158) (0.271484,0.000155) (0.273438,0.000152) (0.275391,0.000148) (0.277344,0.000148) (0.279297,0.000148) (0.281250,0.000147) (0.283203,0.000147) (0.285156,0.000147) (0.287109,0.000146) (0.289062,0.000146) (0.291016,0.000145) (0.292969,0.000138) (0.294922,0.000136) (0.296875,0.000135) (0.298828,0.000134) (0.300781,0.000133) (0.302734,0.000132) (0.304688,0.000127) (0.306641,0.000125) (0.308594,0.000125) (0.310547,0.000124) (0.312500,0.000122) (0.314453,0.000121) (0.316406,0.000120) (0.318359,0.000119) (0.320312,0.000118) (0.322266,0.000118) (0.324219,0.000113) (0.326172,0.000110) (0.328125,0.000109) (0.330078,0.000107) (0.332031,0.000106) (0.333984,0.000104) (0.335938,0.000102) (0.337891,0.000097) (0.339844,0.000095) (0.341797,0.000092) (0.343750,0.000091) (0.345703,0.000089) (0.347656,0.000088) (0.349609,0.000086) (0.351562,0.000086) (0.353516,0.000086) (0.355469,0.000085) (0.357422,0.000085) (0.359375,0.000084) (0.361328,0.000083) (0.363281,0.000081) (0.365234,0.000081) (0.367188,0.000081) (0.369141,0.000077) (0.371094,0.000076) (0.373047,0.000076) (0.375000,0.000075) (0.376953,0.000074) (0.378906,0.000074) (0.380859,0.000067) (0.382812,0.000066) (0.384766,0.000065) (0.386719,0.000065) (0.388672,0.000062) (0.390625,0.000060) (0.392578,0.000055) (0.394531,0.000055) (0.396484,0.000051) (0.398438,0.000049) (0.400391,0.000049) (0.402344,0.000048) (0.404297,0.000046) (0.406250,0.000045) (0.408203,0.000044) (0.410156,0.000044) (0.412109,0.000044) (0.414062,0.000043) (0.416016,0.000042) (0.417969,0.000042) (0.419922,0.000041) (0.421875,0.000040) (0.423828,0.000040) (0.425781,0.000040) (0.427734,0.000038) (0.429688,0.000038) (0.431641,0.000037) (0.433594,0.000036) (0.435547,0.000035) (0.437500,0.000035) (0.439453,0.000034) (0.441406,0.000034) (0.443359,0.000034) (0.445312,0.000033) (0.447266,0.000032) (0.449219,0.000031) (0.451172,0.000031) (0.453125,0.000031) (0.455078,0.000029) (0.457031,0.000028) (0.458984,0.000027) (0.460938,0.000027) (0.462891,0.000027) (0.464844,0.000027) (0.466797,0.000026) (0.468750,0.000025) (0.470703,0.000025) (0.472656,0.000025) (0.474609,0.000024) (0.476562,0.000024) (0.478516,0.000023) (0.480469,0.000023) (0.482422,0.000023) (0.484375,0.000023) (0.486328,0.000023) (0.488281,0.000023) (0.490234,0.000023) (0.492188,0.000023) (0.494141,0.000023) (0.496094,0.000023) (0.498047,0.000023) (0.500000,0.000023) (0.501953,0.000023) (0.503906,0.000022) (0.505859,0.000022) (0.507812,0.000022) (0.509766,0.000022) (0.511719,0.000022) (0.513672,0.000021) (0.515625,0.000021) (0.517578,0.000021) (0.519531,0.000021) (0.521484,0.000021) (0.523438,0.000021) (0.525391,0.000021) (0.527344,0.000020) (0.529297,0.000020) (0.531250,0.000019) (0.533203,0.000019) (0.535156,0.000019) (0.537109,0.000019) (0.539062,0.000018) (0.541016,0.000018) (0.542969,0.000018) (0.544922,0.000018) (0.546875,0.000018) (0.548828,0.000018) (0.550781,0.000017) (0.552734,0.000017) (0.554688,0.000017) (0.556641,0.000017) (0.558594,0.000017) (0.560547,0.000016) (0.562500,0.000016) (0.564453,0.000016) (0.566406,0.000015) (0.568359,0.000015) (0.570312,0.000015) (0.572266,0.000015) (0.574219,0.000014) (0.576172,0.000014) (0.578125,0.000014) (0.580078,0.000014) (0.582031,0.000013) (0.583984,0.000013) (0.585938,0.000013) (0.587891,0.000013) (0.589844,0.000013) (0.591797,0.000012) (0.593750,0.000012) (0.595703,0.000012) (0.597656,0.000012) (0.599609,0.000012) (0.601562,0.000012) (0.603516,0.000012) (0.605469,0.000012) (0.607422,0.000011) (0.609375,0.000011) (0.611328,0.000011) (0.613281,0.000011) (0.615234,0.000011) (0.617188,0.000011) (0.619141,0.000011) (0.621094,0.000010) (0.623047,0.000010) (0.625000,0.000009) (0.626953,0.000009) (0.628906,0.000009) (0.630859,0.000009) (0.632812,0.000009) (0.634766,0.000009) (0.636719,0.000009) (0.638672,0.000009) (0.640625,0.000009) (0.642578,0.000009) (0.644531,0.000009) (0.646484,0.000009) (0.648438,0.000009) (0.650391,0.000009) (0.652344,0.000009) (0.654297,0.000009) (0.656250,0.000009) (0.658203,0.000009) (0.660156,0.000009) (0.662109,0.000009) (0.664062,0.000009) (0.666016,0.000009) (0.667969,0.000009) (0.669922,0.000008) (0.671875,0.000008) (0.673828,0.000008) (0.675781,0.000008) (0.677734,0.000008) (0.679688,0.000008) (0.681641,0.000008) (0.683594,0.000008) (0.685547,0.000008) (0.687500,0.000008) (0.689453,0.000008) (0.691406,0.000008) (0.693359,0.000008) (0.695312,0.000008) (0.697266,0.000008) (0.699219,0.000007) (0.701172,0.000007) (0.703125,0.000007) (0.705078,0.000007) (0.707031,0.000007) (0.708984,0.000007) (0.710938,0.000007) (0.712891,0.000007) (0.714844,0.000006) (0.716797,0.000006) (0.718750,0.000006) (0.720703,0.000006) (0.722656,0.000006) (0.724609,0.000006) (0.726562,0.000006) (0.728516,0.000006) (0.730469,0.000006) (0.732422,0.000005) (0.734375,0.000005) (0.736328,0.000005) (0.738281,0.000005) (0.740234,0.000005) (0.742188,0.000005) (0.744141,0.000005) (0.746094,0.000005) (0.748047,0.000005) (0.750000,0.000005) (0.751953,0.000005) (0.753906,0.000005) (0.755859,0.000004) (0.757812,0.000004) (0.759766,0.000004) (0.761719,0.000004) (0.763672,0.000004) (0.765625,0.000004) (0.767578,0.000004) (0.769531,0.000004) (0.771484,0.000004) (0.773438,0.000004) (0.775391,0.000004) (0.777344,0.000004) (0.779297,0.000004) (0.781250,0.000004) (0.783203,0.000004) (0.785156,0.000004) (0.787109,0.000004) (0.789062,0.000004) (0.791016,0.000004) (0.792969,0.000004) (0.794922,0.000004) (0.796875,0.000004) (0.798828,0.000004) (0.800781,0.000004) (0.802734,0.000003) (0.804688,0.000003) (0.806641,0.000003) (0.808594,0.000003) (0.810547,0.000003) (0.812500,0.000003) (0.814453,0.000003) (0.816406,0.000003) (0.818359,0.000003) (0.820312,0.000003) (0.822266,0.000003) (0.824219,0.000003) (0.826172,0.000003) (0.828125,0.000003) (0.830078,0.000003) (0.832031,0.000003) (0.833984,0.000003) (0.835938,0.000003) (0.837891,0.000003) (0.839844,0.000003) (0.841797,0.000003) (0.843750,0.000003) (0.845703,0.000003) (0.847656,0.000003) (0.849609,0.000003) (0.851562,0.000003) (0.853516,0.000002) (0.855469,0.000002) (0.857422,0.000002) (0.859375,0.000002) (0.861328,0.000002) (0.863281,0.000002) (0.865234,0.000002) (0.867188,0.000002) (0.869141,0.000002) (0.871094,0.000002) (0.873047,0.000002) (0.875000,0.000002) (0.876953,0.000002) (0.878906,0.000002) (0.880859,0.000002) (0.882812,0.000002) (0.884766,0.000002) (0.886719,0.000002) (0.888672,0.000002) (0.890625,0.000002) (0.892578,0.000002) (0.894531,0.000002) (0.896484,0.000002) (0.898438,0.000002) (0.900391,0.000001) (0.902344,0.000001) (0.904297,0.000001) (0.906250,0.000001) (0.908203,0.000001) (0.910156,0.000001) (0.912109,0.000001) (0.914062,0.000001) (0.916016,0.000001) (0.917969,0.000001) (0.919922,0.000001) (0.921875,0.000001) (0.923828,0.000001) (0.925781,0.000001) (0.927734,0.000001) (0.929688,0.000001) (0.931641,0.000001) (0.933594,0.000001) (0.935547,0.000001) (0.937500,0.000001) (0.939453,0.000001) (0.941406,0.000001) (0.943359,0.000001) (0.945312,0.000001) (0.947266,0.000001) (0.949219,0.000001) (0.951172,0.000001) (0.953125,0.000001) (0.955078,0.000001) (0.957031,0.000001) (0.958984,0.000001) (0.960938,0.000000) (0.962891,0.000000) (0.964844,0.000000) (0.966797,0.000000) (0.968750,0.000000) (0.970703,0.000000) (0.972656,0.000000) (0.974609,0.000000) (0.976562,0.000000) (0.978516,0.000000) (0.980469,0.000000) (0.982422,0.000000) (0.984375,0.000000) (0.986328,0.000000) (0.988281,0.000000) (0.990234,0.000000) (0.992188,0.000000) (0.994141,0.000000) (0.996094,0.000000) (0.998047,0.000000) (1.000000,0.000000) }; +\addplot[gray,only marks,mark=*] coordinates {(0.034483,0.386091) (0.396552,0.006830) (0.517241,0.000962)}; -\addplot[gray] coordinates { +\addplot[gray,mark=none] coordinates { (0.000000,1.000000) (0.017241,0.487558) (0.034483,0.386091) (0.051724,0.126229) (0.068966,0.108863) (0.086207,0.100941) (0.103448,0.097250) (0.120690,0.060934) (0.137931,0.054349) (0.155172,0.025283) (0.172414,0.025270) (0.189655,0.025262) (0.206897,0.025238) (0.224138,0.025208) (0.241379,0.022267) (0.258621,0.016262) (0.275862,0.016261) (0.293103,0.012610) (0.310345,0.009401) (0.327586,0.008822) (0.344828,0.008804) (0.362069,0.008801) (0.379310,0.007326) (0.396552,0.006830) (0.413793,0.003673) (0.431034,0.003672) (0.448276,0.003642) (0.465517,0.001939) (0.482759,0.001709) (0.500000,0.000965) (0.517241,0.000962) (0.534483,0.000277) (0.551724,0.000119) (0.568966,0.000093) (0.586207,0.000088) (0.603448,0.000050) (0.620690,0.000048) (0.637931,0.000043) (0.655172,0.000042) (0.672414,0.000025) (0.689655,0.000021) (0.706897,0.000011) (0.724138,0.000011) (0.741379,0.000011) (0.758621,0.000011) (0.775862,0.000011) (0.793103,0.000010) (0.810345,0.000009) (0.827586,0.000008) (0.844828,0.000006) (0.862069,0.000005) (0.879310,0.000004) (0.896552,0.000003) (0.913793,0.000002) (0.931034,0.000002) (0.948276,0.000001) (0.965517,0.000001) (0.982759,0.000001) (1.000000,0.000000) }; +\addplot[darkgray,only marks,mark=*] coordinates {(0.071429,0.409043) (0.285714,0.001856) (0.285714,0.001856)}; -\addplot[darkgray] coordinates { +\addplot[darkgray,mark=none] coordinates { (0.000000,1.000000) (0.035714,0.909090) (0.071429,0.409043) (0.107143,0.409043) (0.142857,0.045445) (0.178571,0.045445) (0.214286,0.045437) (0.250000,0.045437) (0.285714,0.001856) (0.321429,0.000157) (0.357143,0.000150) (0.392857,0.000148) (0.428571,0.000138) (0.464286,0.000116) (0.500000,0.000070) (0.535714,0.000048) (0.571429,0.000032) (0.607143,0.000032) (0.642857,0.000032) (0.678571,0.000016) (0.714286,0.000009) (0.750000,0.000008) (0.785714,0.000008) (0.821429,0.000008) (0.857143,0.000006) (0.892857,0.000005) (0.928571,0.000002) (0.964286,0.000001) (1.000000,0.000001) }; +\addplot[lightgray,only marks,mark=*] coordinates {(0.038627,0.153140) (0.197425,0.002447) (0.433476,0.000174)}; -\addplot[lightgray] coordinates { +\addplot[lightgray,mark=none] coordinates { (0.000000,1.000000) (0.004292,0.333547) (0.008584,0.333312) (0.012876,0.166857) (0.017167,0.166758) (0.021459,0.166551) (0.025751,0.166414) (0.030043,0.166294) (0.034335,0.165678) (0.038627,0.153140) (0.042918,0.084910) (0.047210,0.084877) (0.051502,0.083928) (0.055794,0.083394) (0.060086,0.083329) (0.064378,0.083328) (0.068670,0.083313) (0.072961,0.083313) (0.077253,0.083302) (0.081545,0.083301) (0.085837,0.083292) (0.090129,0.083239) (0.094421,0.083209) (0.098712,0.083176) (0.103004,0.083169) (0.107296,0.083125) (0.111588,0.083071) (0.115880,0.083067) (0.120172,0.083054) (0.124464,0.082872) (0.128755,0.082758) (0.133047,0.082151) (0.137339,0.081810) (0.141631,0.081809) (0.145923,0.081721) (0.150215,0.081378) (0.154506,0.081001) (0.158798,0.063929) (0.163090,0.041639) (0.167382,0.017348) (0.171674,0.012510) (0.175966,0.011755) (0.180258,0.004971) (0.184549,0.004140) (0.188841,0.003972) (0.193133,0.002505) (0.197425,0.002447) (0.201717,0.002335) (0.206009,0.002075) (0.210300,0.001713) (0.214592,0.001685) (0.218884,0.001622) (0.223176,0.001588) (0.227468,0.001512) (0.231760,0.001506) (0.236052,0.001486) (0.240343,0.001475) (0.244635,0.001291) (0.248927,0.001284) (0.253219,0.001203) (0.257511,0.001158) (0.261803,0.001088) (0.266094,0.001087) (0.270386,0.001028) (0.274678,0.001019) (0.278970,0.001010) (0.283262,0.000943) (0.287554,0.000860) (0.291845,0.000808) (0.296137,0.000797) (0.300429,0.000788) (0.304721,0.000773) (0.309013,0.000769) (0.313305,0.000686) (0.317597,0.000640) (0.321888,0.000621) (0.326180,0.000604) (0.330472,0.000548) (0.334764,0.000478) (0.339056,0.000468) (0.343348,0.000444) (0.347639,0.000424) (0.351931,0.000419) (0.356223,0.000404) (0.360515,0.000388) (0.364807,0.000384) (0.369099,0.000381) (0.373391,0.000333) (0.377682,0.000327) (0.381974,0.000318) (0.386266,0.000301) (0.390558,0.000271) (0.394850,0.000262) (0.399142,0.000255) (0.403433,0.000243) (0.407725,0.000238) (0.412017,0.000237) (0.416309,0.000235) (0.420601,0.000230) (0.424893,0.000209) (0.429185,0.000189) (0.433476,0.000174) (0.437768,0.000165) (0.442060,0.000164) (0.446352,0.000153) (0.450644,0.000151) (0.454936,0.000150) (0.459227,0.000140) (0.463519,0.000136) (0.467811,0.000136) (0.472103,0.000118) (0.476395,0.000117) (0.480687,0.000112) (0.484979,0.000111) (0.489270,0.000106) (0.493562,0.000106) (0.497854,0.000106) (0.502146,0.000106) (0.506438,0.000106) (0.510730,0.000102) (0.515021,0.000092) (0.519313,0.000087) (0.523605,0.000082) (0.527897,0.000079) (0.532189,0.000077) (0.536481,0.000076) (0.540773,0.000075) (0.545064,0.000074) (0.549356,0.000073) (0.553648,0.000068) (0.557940,0.000068) (0.562232,0.000066) (0.566524,0.000063) (0.570815,0.000063) (0.575107,0.000062) (0.579399,0.000061) (0.583691,0.000061) (0.587983,0.000060) (0.592275,0.000059) (0.596567,0.000053) (0.600858,0.000050) (0.605150,0.000047) (0.609442,0.000046) (0.613734,0.000042) (0.618026,0.000042) (0.622318,0.000041) (0.626609,0.000040) (0.630901,0.000035) (0.635193,0.000035) (0.639485,0.000033) (0.643777,0.000033) (0.648069,0.000032) (0.652361,0.000032) (0.656652,0.000031) (0.660944,0.000031) (0.665236,0.000031) (0.669528,0.000031) (0.673820,0.000030) (0.678112,0.000029) (0.682403,0.000028) (0.686695,0.000027) (0.690987,0.000026) (0.695279,0.000025) (0.699571,0.000023) (0.703863,0.000022) (0.708155,0.000022) (0.712446,0.000021) (0.716738,0.000019) (0.721030,0.000018) (0.725322,0.000017) (0.729614,0.000016) (0.733906,0.000013) (0.738197,0.000012) (0.742489,0.000011) (0.746781,0.000011) (0.751073,0.000011) (0.755365,0.000011) (0.759657,0.000011) (0.763948,0.000011) (0.768240,0.000011) (0.772532,0.000011) (0.776824,0.000011) (0.781116,0.000011) (0.785408,0.000010) (0.789700,0.000010) (0.793991,0.000009) (0.798283,0.000009) (0.802575,0.000009) (0.806867,0.000009) (0.811159,0.000008) (0.815451,0.000007) (0.819742,0.000005) (0.824034,0.000005) (0.828326,0.000005) (0.832618,0.000005) (0.836910,0.000005) (0.841202,0.000004) (0.845494,0.000004) (0.849785,0.000004) (0.854077,0.000004) (0.858369,0.000004) (0.862661,0.000004) (0.866953,0.000004) (0.871245,0.000003) (0.875536,0.000003) (0.879828,0.000003) (0.884120,0.000003) (0.888412,0.000003) (0.892704,0.000002) (0.896996,0.000002) (0.901288,0.000002) (0.905579,0.000002) (0.909871,0.000002) (0.914163,0.000002) (0.918455,0.000001) (0.922747,0.000001) (0.927039,0.000001) (0.931330,0.000001) (0.935622,0.000001) (0.939914,0.000001) (0.944206,0.000001) (0.948498,0.000001) (0.952790,0.000001) (0.957082,0.000001) (0.961373,0.000001) (0.965665,0.000001) (0.969957,0.000001) (0.974249,0.000001) (0.978541,0.000001) (0.982833,0.000001) (0.987124,0.000001) (0.991416,0.000001) (0.995708,0.000001) (1.000000,0.000001) }; -\addplot[brown] coordinates { +\addplot[brown,mark=none] coordinates { (0.000000,1.000000) (0.000834,0.872400) (0.001668,0.683224) (0.002502,0.608314) (0.003336,0.542330) (0.004170,0.519721) (0.005004,0.447508) (0.005838,0.440065) (0.006672,0.420670) (0.007506,0.418862) (0.008340,0.418009) (0.009174,0.379519) (0.010008,0.357223) (0.010842,0.353534) (0.011676,0.333568) (0.012510,0.319704) (0.013344,0.268160) (0.014178,0.251065) (0.015013,0.226789) (0.015847,0.220089) (0.016681,0.215066) (0.017515,0.213903) (0.018349,0.213091) (0.019183,0.197153) (0.020017,0.187389) (0.020851,0.177430) (0.021685,0.173396) (0.022519,0.170787) (0.023353,0.160834) (0.024187,0.160045) (0.025021,0.157071) (0.025855,0.146612) (0.026689,0.144178) (0.027523,0.137699) (0.028357,0.136683) (0.029191,0.124833) (0.030025,0.121453) (0.030859,0.119189) (0.031693,0.115002) (0.032527,0.114249) (0.033361,0.107546) (0.034195,0.107268) (0.035029,0.104187) (0.035863,0.096624) (0.036697,0.089912) (0.037531,0.089585) (0.038365,0.087446) (0.039199,0.087298) (0.040033,0.084823) (0.040867,0.083414) (0.041701,0.083212) (0.042535,0.082227) (0.043369,0.079913) (0.044204,0.075734) (0.045038,0.073337) (0.045872,0.073039) (0.046706,0.072381) (0.047540,0.069693) (0.048374,0.067325) (0.049208,0.065996) (0.050042,0.057532) (0.050876,0.055707) (0.051710,0.055669) (0.052544,0.049083) (0.053378,0.048652) (0.054212,0.048015) (0.055046,0.045918) (0.055880,0.045234) (0.056714,0.042272) (0.057548,0.041798) (0.058382,0.040969) (0.059216,0.040163) (0.060050,0.040016) (0.060884,0.038778) (0.061718,0.038686) (0.062552,0.038456) (0.063386,0.033439) (0.064220,0.032381) (0.065054,0.031115) (0.065888,0.030103) (0.066722,0.029385) (0.067556,0.026654) (0.068390,0.025877) (0.069224,0.024467) (0.070058,0.024427) (0.070892,0.024134) (0.071726,0.024036) (0.072560,0.021379) (0.073394,0.020813) (0.074229,0.020166) (0.075063,0.020056) (0.075897,0.019981) (0.076731,0.019791) (0.077565,0.019672) (0.078399,0.019356) (0.079233,0.019269) (0.080067,0.019134) (0.080901,0.018119) (0.081735,0.017905) (0.082569,0.017878) (0.083403,0.017865) (0.084237,0.017769) (0.085071,0.017758) (0.085905,0.017065) (0.086739,0.016959) (0.087573,0.016686) (0.088407,0.015666) (0.089241,0.014908) (0.090075,0.014542) (0.090909,0.014518) (0.091743,0.014200) (0.092577,0.013865) (0.093411,0.013736) (0.094245,0.013273) (0.095079,0.013197) (0.095913,0.012997) (0.096747,0.012759) (0.097581,0.012642) (0.098415,0.012344) (0.099249,0.012031) (0.100083,0.011973) (0.100917,0.011805) (0.101751,0.011594) (0.102585,0.011387) (0.103420,0.011332) (0.104254,0.011246) (0.105088,0.010925) (0.105922,0.010566) (0.106756,0.010269) (0.107590,0.010235) (0.108424,0.010220) (0.109258,0.010135) (0.110092,0.010071) (0.110926,0.010048) (0.111760,0.010002) (0.112594,0.009762) (0.113428,0.009756) (0.114262,0.009751) (0.115096,0.009730) (0.115930,0.009551) (0.116764,0.009536) (0.117598,0.009404) (0.118432,0.009399) (0.119266,0.009298) (0.120100,0.009263) (0.120934,0.009245) (0.121768,0.009137) (0.122602,0.009120) (0.123436,0.009097) (0.124270,0.008816) (0.125104,0.008646) (0.125938,0.008484) (0.126772,0.008405) (0.127606,0.008149) (0.128440,0.008032) (0.129274,0.007872) (0.130108,0.007866) (0.130942,0.007823) (0.131776,0.007801) (0.132611,0.007718) (0.133445,0.007481) (0.134279,0.007373) (0.135113,0.007345) (0.135947,0.007296) (0.136781,0.007269) (0.137615,0.007233) (0.138449,0.006991) (0.139283,0.006905) (0.140117,0.006795) (0.140951,0.006738) (0.141785,0.006708) (0.142619,0.006551) (0.143453,0.006510) (0.144287,0.006435) (0.145121,0.006361) (0.145955,0.006238) (0.146789,0.006134) (0.147623,0.006027) (0.148457,0.005991) (0.149291,0.005921) (0.150125,0.005852) (0.150959,0.005852) (0.151793,0.005823) (0.152627,0.005794) (0.153461,0.005787) (0.154295,0.005746) (0.155129,0.005672) (0.155963,0.005619) (0.156797,0.005612) (0.157631,0.005557) (0.158465,0.005495) (0.159299,0.005495) (0.160133,0.005422) (0.160967,0.005324) (0.161802,0.005217) (0.162636,0.005196) (0.163470,0.005167) (0.164304,0.005107) (0.165138,0.005012) (0.165972,0.004999) (0.166806,0.004985) (0.167640,0.004981) (0.168474,0.004936) (0.169308,0.004912) (0.170142,0.004836) (0.170976,0.004822) (0.171810,0.004755) (0.172644,0.004692) (0.173478,0.004687) (0.174312,0.004667) (0.175146,0.004605) (0.175980,0.004546) (0.176814,0.004523) (0.177648,0.004518) (0.178482,0.004512) (0.179316,0.004447) (0.180150,0.004427) (0.180984,0.004408) (0.181818,0.004401) (0.182652,0.004336) (0.183486,0.004326) (0.184320,0.004255) (0.185154,0.004163) (0.185988,0.004152) (0.186822,0.004150) (0.187656,0.004132) (0.188490,0.004125) (0.189324,0.003972) (0.190158,0.003971) (0.190992,0.003942) (0.191827,0.003842) (0.192661,0.003797) (0.193495,0.003710) (0.194329,0.003703) (0.195163,0.003684) (0.195997,0.003626) (0.196831,0.003620) (0.197665,0.003576) (0.198499,0.003526) (0.199333,0.003451) (0.200167,0.003447) (0.201001,0.003402) (0.201835,0.003390) (0.202669,0.003364) (0.203503,0.003361) (0.204337,0.003356) (0.205171,0.003350) (0.206005,0.003341) (0.206839,0.003321) (0.207673,0.003278) (0.208507,0.003246) (0.209341,0.003239) (0.210175,0.003219) (0.211009,0.003208) (0.211843,0.003129) (0.212677,0.003123) (0.213511,0.003073) (0.214345,0.003063) (0.215179,0.003053) (0.216013,0.003053) (0.216847,0.003026) (0.217681,0.003007) (0.218515,0.002989) (0.219349,0.002929) (0.220183,0.002915) (0.221018,0.002913) (0.221852,0.002890) (0.222686,0.002861) (0.223520,0.002845) (0.224354,0.002804) (0.225188,0.002783) (0.226022,0.002781) (0.226856,0.002694) (0.227690,0.002669) (0.228524,0.002631) (0.229358,0.002579) (0.230192,0.002578) (0.231026,0.002573) (0.231860,0.002566) (0.232694,0.002507) (0.233528,0.002487) (0.234362,0.002486) (0.235196,0.002416) (0.236030,0.002367) (0.236864,0.002347) (0.237698,0.002344) (0.238532,0.002338) (0.239366,0.002330) (0.240200,0.002318) (0.241034,0.002315) (0.241868,0.002308) (0.242702,0.002308) (0.243536,0.002292) (0.244370,0.002287) (0.245204,0.002283) (0.246038,0.002264) (0.246872,0.002236) (0.247706,0.002227) (0.248540,0.002185) (0.249374,0.002173) (0.250209,0.002169) (0.251043,0.002135) (0.251877,0.002109) (0.252711,0.002039) (0.253545,0.002031) (0.254379,0.001987) (0.255213,0.001970) (0.256047,0.001966) (0.256881,0.001936) (0.257715,0.001908) (0.258549,0.001908) (0.259383,0.001893) (0.260217,0.001886) (0.261051,0.001882) (0.261885,0.001827) (0.262719,0.001827) (0.263553,0.001817) (0.264387,0.001797) (0.265221,0.001749) (0.266055,0.001742) (0.266889,0.001739) (0.267723,0.001727) (0.268557,0.001704) (0.269391,0.001700) (0.270225,0.001691) (0.271059,0.001690) (0.271893,0.001653) (0.272727,0.001600) (0.273561,0.001595) (0.274395,0.001555) (0.275229,0.001547) (0.276063,0.001546) (0.276897,0.001519) (0.277731,0.001513) (0.278565,0.001510) (0.279399,0.001505) (0.280234,0.001474) (0.281068,0.001468) (0.281902,0.001459) (0.282736,0.001458) (0.283570,0.001432) (0.284404,0.001410) (0.285238,0.001407) (0.286072,0.001401) (0.286906,0.001396) (0.287740,0.001391) (0.288574,0.001376) (0.289408,0.001372) (0.290242,0.001369) (0.291076,0.001345) (0.291910,0.001344) (0.292744,0.001318) (0.293578,0.001299) (0.294412,0.001295) (0.295246,0.001287) (0.296080,0.001285) (0.296914,0.001284) (0.297748,0.001270) (0.298582,0.001265) (0.299416,0.001253) (0.300250,0.001235) (0.301084,0.001233) (0.301918,0.001224) (0.302752,0.001222) (0.303586,0.001219) (0.304420,0.001209) (0.305254,0.001202) (0.306088,0.001191) (0.306922,0.001180) (0.307756,0.001173) (0.308590,0.001170) (0.309425,0.001167) (0.310259,0.001154) (0.311093,0.001147) (0.311927,0.001143) (0.312761,0.001130) (0.313595,0.001126) (0.314429,0.001124) (0.315263,0.001116) (0.316097,0.001115) (0.316931,0.001099) (0.317765,0.001088) (0.318599,0.001088) (0.319433,0.001082) (0.320267,0.001074) (0.321101,0.001071) (0.321935,0.001070) (0.322769,0.001066) (0.323603,0.001062) (0.324437,0.001047) (0.325271,0.001043) (0.326105,0.001041) (0.326939,0.001040) (0.327773,0.001038) (0.328607,0.001027) (0.329441,0.001025) (0.330275,0.001016) (0.331109,0.001016) (0.331943,0.000996) (0.332777,0.000992) (0.333611,0.000985) (0.334445,0.000979) (0.335279,0.000978) (0.336113,0.000978) (0.336947,0.000957) (0.337781,0.000953) (0.338616,0.000951) (0.339450,0.000947) (0.340284,0.000944) (0.341118,0.000939) (0.341952,0.000932) (0.342786,0.000930) (0.343620,0.000930) (0.344454,0.000928) (0.345288,0.000915) (0.346122,0.000914) (0.346956,0.000914) (0.347790,0.000911) (0.348624,0.000910) (0.349458,0.000908) (0.350292,0.000904) (0.351126,0.000895) (0.351960,0.000890) (0.352794,0.000887) (0.353628,0.000884) (0.354462,0.000879) (0.355296,0.000861) (0.356130,0.000861) (0.356964,0.000826) (0.357798,0.000814) (0.358632,0.000808) (0.359466,0.000800) (0.360300,0.000797) (0.361134,0.000796) (0.361968,0.000782) (0.362802,0.000779) (0.363636,0.000778) (0.364470,0.000777) (0.365304,0.000777) (0.366138,0.000775) (0.366972,0.000767) (0.367807,0.000764) (0.368641,0.000761) (0.369475,0.000758) (0.370309,0.000753) (0.371143,0.000753) (0.371977,0.000751) (0.372811,0.000738) (0.373645,0.000718) (0.374479,0.000718) (0.375313,0.000710) (0.376147,0.000709) (0.376981,0.000707) (0.377815,0.000701) (0.378649,0.000699) (0.379483,0.000694) (0.380317,0.000694) (0.381151,0.000688) (0.381985,0.000686) (0.382819,0.000683) (0.383653,0.000681) (0.384487,0.000665) (0.385321,0.000664) (0.386155,0.000660) (0.386989,0.000659) (0.387823,0.000657) (0.388657,0.000657) (0.389491,0.000655) (0.390325,0.000654) (0.391159,0.000647) (0.391993,0.000645) (0.392827,0.000644) (0.393661,0.000643) (0.394495,0.000642) (0.395329,0.000640) (0.396163,0.000639) (0.396997,0.000637) (0.397832,0.000634) (0.398666,0.000630) (0.399500,0.000614) (0.400334,0.000613) (0.401168,0.000607) (0.402002,0.000604) (0.402836,0.000603) (0.403670,0.000602) (0.404504,0.000602) (0.405338,0.000598) (0.406172,0.000597) (0.407006,0.000592) (0.407840,0.000588) (0.408674,0.000576) (0.409508,0.000572) (0.410342,0.000570) (0.411176,0.000570) (0.412010,0.000567) (0.412844,0.000567) (0.413678,0.000566) (0.414512,0.000564) (0.415346,0.000563) (0.416180,0.000554) (0.417014,0.000550) (0.417848,0.000548) (0.418682,0.000547) (0.419516,0.000547) (0.420350,0.000546) (0.421184,0.000542) (0.422018,0.000542) (0.422852,0.000535) (0.423686,0.000529) (0.424520,0.000518) (0.425354,0.000516) (0.426188,0.000515) (0.427023,0.000513) (0.427857,0.000512) (0.428691,0.000511) (0.429525,0.000503) (0.430359,0.000503) (0.431193,0.000503) (0.432027,0.000499) (0.432861,0.000497) (0.433695,0.000497) (0.434529,0.000495) (0.435363,0.000495) (0.436197,0.000494) (0.437031,0.000494) (0.437865,0.000492) (0.438699,0.000491) (0.439533,0.000490) (0.440367,0.000489) (0.441201,0.000488) (0.442035,0.000486) (0.442869,0.000484) (0.443703,0.000480) (0.444537,0.000479) (0.445371,0.000478) (0.446205,0.000471) (0.447039,0.000467) (0.447873,0.000466) (0.448707,0.000464) (0.449541,0.000460) (0.450375,0.000458) (0.451209,0.000456) (0.452043,0.000452) (0.452877,0.000451) (0.453711,0.000448) (0.454545,0.000446) (0.455379,0.000445) (0.456214,0.000444) (0.457048,0.000437) (0.457882,0.000436) (0.458716,0.000435) (0.459550,0.000431) (0.460384,0.000431) (0.461218,0.000430) (0.462052,0.000428) (0.462886,0.000428) (0.463720,0.000428) (0.464554,0.000427) (0.465388,0.000427) (0.466222,0.000422) (0.467056,0.000420) (0.467890,0.000415) (0.468724,0.000409) (0.469558,0.000408) (0.470392,0.000408) (0.471226,0.000406) (0.472060,0.000405) (0.472894,0.000404) (0.473728,0.000404) (0.474562,0.000402) (0.475396,0.000402) (0.476230,0.000402) (0.477064,0.000402) (0.477898,0.000399) (0.478732,0.000399) (0.479566,0.000398) (0.480400,0.000395) (0.481234,0.000395) (0.482068,0.000394) (0.482902,0.000390) (0.483736,0.000389) (0.484570,0.000387) (0.485405,0.000385) (0.486239,0.000383) (0.487073,0.000382) (0.487907,0.000381) (0.488741,0.000380) (0.489575,0.000380) (0.490409,0.000377) (0.491243,0.000375) (0.492077,0.000374) (0.492911,0.000373) (0.493745,0.000371) (0.494579,0.000370) (0.495413,0.000369) (0.496247,0.000368) (0.497081,0.000366) (0.497915,0.000364) (0.498749,0.000362) (0.499583,0.000362) (0.500417,0.000358) (0.501251,0.000354) (0.502085,0.000346) (0.502919,0.000345) (0.503753,0.000344) (0.504587,0.000343) (0.505421,0.000341) (0.506255,0.000340) (0.507089,0.000337) (0.507923,0.000337) (0.508757,0.000331) (0.509591,0.000328) (0.510425,0.000325) (0.511259,0.000323) (0.512093,0.000319) (0.512927,0.000319) (0.513761,0.000317) (0.514595,0.000315) (0.515430,0.000314) (0.516264,0.000313) (0.517098,0.000313) (0.517932,0.000312) (0.518766,0.000312) (0.519600,0.000311) (0.520434,0.000302) (0.521268,0.000300) (0.522102,0.000300) (0.522936,0.000295) (0.523770,0.000295) (0.524604,0.000295) (0.525438,0.000292) (0.526272,0.000290) (0.527106,0.000290) (0.527940,0.000288) (0.528774,0.000287) (0.529608,0.000285) (0.530442,0.000280) (0.531276,0.000278) (0.532110,0.000278) (0.532944,0.000278) (0.533778,0.000277) (0.534612,0.000276) (0.535446,0.000274) (0.536280,0.000273) (0.537114,0.000271) (0.537948,0.000271) (0.538782,0.000270) (0.539616,0.000266) (0.540450,0.000263) (0.541284,0.000260) (0.542118,0.000260) (0.542952,0.000258) (0.543786,0.000258) (0.544621,0.000256) (0.545455,0.000253) (0.546289,0.000252) (0.547123,0.000251) (0.547957,0.000249) (0.548791,0.000248) (0.549625,0.000248) (0.550459,0.000248) (0.551293,0.000246) (0.552127,0.000246) (0.552961,0.000244) (0.553795,0.000244) (0.554629,0.000242) (0.555463,0.000241) (0.556297,0.000240) (0.557131,0.000240) (0.557965,0.000239) (0.558799,0.000236) (0.559633,0.000236) (0.560467,0.000235) (0.561301,0.000234) (0.562135,0.000234) (0.562969,0.000234) (0.563803,0.000233) (0.564637,0.000233) (0.565471,0.000225) (0.566305,0.000223) (0.567139,0.000223) (0.567973,0.000220) (0.568807,0.000219) (0.569641,0.000218) (0.570475,0.000218) (0.571309,0.000217) (0.572143,0.000216) (0.572977,0.000213) (0.573812,0.000211) (0.574646,0.000207) (0.575480,0.000206) (0.576314,0.000206) (0.577148,0.000205) (0.577982,0.000205) (0.578816,0.000203) (0.579650,0.000203) (0.580484,0.000203) (0.581318,0.000203) (0.582152,0.000203) (0.582986,0.000201) (0.583820,0.000200) (0.584654,0.000200) (0.585488,0.000199) (0.586322,0.000199) (0.587156,0.000197) (0.587990,0.000194) (0.588824,0.000193) (0.589658,0.000191) (0.590492,0.000190) (0.591326,0.000190) (0.592160,0.000186) (0.592994,0.000186) (0.593828,0.000181) (0.594662,0.000178) (0.595496,0.000175) (0.596330,0.000174) (0.597164,0.000173) (0.597998,0.000173) (0.598832,0.000172) (0.599666,0.000171) (0.600500,0.000171) (0.601334,0.000170) (0.602168,0.000170) (0.603003,0.000169) (0.603837,0.000166) (0.604671,0.000165) (0.605505,0.000165) (0.606339,0.000165) (0.607173,0.000164) (0.608007,0.000163) (0.608841,0.000162) (0.609675,0.000162) (0.610509,0.000162) (0.611343,0.000162) (0.612177,0.000161) (0.613011,0.000161) (0.613845,0.000159) (0.614679,0.000158) (0.615513,0.000158) (0.616347,0.000157) (0.617181,0.000156) (0.618015,0.000155) (0.618849,0.000155) (0.619683,0.000152) (0.620517,0.000152) (0.621351,0.000151) (0.622185,0.000151) (0.623019,0.000149) (0.623853,0.000149) (0.624687,0.000148) (0.625521,0.000147) (0.626355,0.000147) (0.627189,0.000146) (0.628023,0.000146) (0.628857,0.000146) (0.629691,0.000146) (0.630525,0.000145) (0.631359,0.000145) (0.632193,0.000144) (0.633028,0.000144) (0.633862,0.000144) (0.634696,0.000144) (0.635530,0.000143) (0.636364,0.000142) (0.637198,0.000142) (0.638032,0.000142) (0.638866,0.000142) (0.639700,0.000141) (0.640534,0.000140) (0.641368,0.000139) (0.642202,0.000137) (0.643036,0.000137) (0.643870,0.000133) (0.644704,0.000131) (0.645538,0.000131) (0.646372,0.000129) (0.647206,0.000129) (0.648040,0.000129) (0.648874,0.000128) (0.649708,0.000128) (0.650542,0.000127) (0.651376,0.000124) (0.652210,0.000123) (0.653044,0.000119) (0.653878,0.000117) (0.654712,0.000117) (0.655546,0.000117) (0.656380,0.000115) (0.657214,0.000114) (0.658048,0.000114) (0.658882,0.000114) (0.659716,0.000113) (0.660550,0.000112) (0.661384,0.000111) (0.662219,0.000111) (0.663053,0.000111) (0.663887,0.000111) (0.664721,0.000110) (0.665555,0.000110) (0.666389,0.000109) (0.667223,0.000108) (0.668057,0.000108) (0.668891,0.000107) (0.669725,0.000105) (0.670559,0.000105) (0.671393,0.000105) (0.672227,0.000105) (0.673061,0.000105) (0.673895,0.000105) (0.674729,0.000105) (0.675563,0.000104) (0.676397,0.000104) (0.677231,0.000103) (0.678065,0.000102) (0.678899,0.000101) (0.679733,0.000101) (0.680567,0.000100) (0.681401,0.000100) (0.682235,0.000100) (0.683069,0.000099) (0.683903,0.000099) (0.684737,0.000098) (0.685571,0.000098) (0.686405,0.000098) (0.687239,0.000097) (0.688073,0.000094) (0.688907,0.000094) (0.689741,0.000092) (0.690575,0.000092) (0.691410,0.000091) (0.692244,0.000089) (0.693078,0.000089) (0.693912,0.000087) (0.694746,0.000087) (0.695580,0.000087) (0.696414,0.000086) (0.697248,0.000086) (0.698082,0.000086) (0.698916,0.000085) (0.699750,0.000085) (0.700584,0.000085) (0.701418,0.000085) (0.702252,0.000084) (0.703086,0.000084) (0.703920,0.000083) (0.704754,0.000083) (0.705588,0.000082) (0.706422,0.000081) (0.707256,0.000080) (0.708090,0.000080) (0.708924,0.000080) (0.709758,0.000079) (0.710592,0.000079) (0.711426,0.000078) (0.712260,0.000078) (0.713094,0.000077) (0.713928,0.000076) (0.714762,0.000076) (0.715596,0.000076) (0.716430,0.000075) (0.717264,0.000075) (0.718098,0.000072) (0.718932,0.000071) (0.719766,0.000071) (0.720601,0.000070) (0.721435,0.000070) (0.722269,0.000070) (0.723103,0.000070) (0.723937,0.000070) (0.724771,0.000070) (0.725605,0.000069) (0.726439,0.000068) (0.727273,0.000068) (0.728107,0.000068) (0.728941,0.000067) (0.729775,0.000067) (0.730609,0.000067) (0.731443,0.000067) (0.732277,0.000066) (0.733111,0.000066) (0.733945,0.000065) (0.734779,0.000065) (0.735613,0.000065) (0.736447,0.000065) (0.737281,0.000064) (0.738115,0.000064) (0.738949,0.000063) (0.739783,0.000063) (0.740617,0.000063) (0.741451,0.000062) (0.742285,0.000062) (0.743119,0.000060) (0.743953,0.000060) (0.744787,0.000059) (0.745621,0.000059) (0.746455,0.000059) (0.747289,0.000059) (0.748123,0.000058) (0.748957,0.000058) (0.749791,0.000057) (0.750626,0.000057) (0.751460,0.000057) (0.752294,0.000057) (0.753128,0.000057) (0.753962,0.000057) (0.754796,0.000057) (0.755630,0.000057) (0.756464,0.000057) (0.757298,0.000057) (0.758132,0.000057) (0.758966,0.000057) (0.759800,0.000057) (0.760634,0.000057) (0.761468,0.000057) (0.762302,0.000057) (0.763136,0.000056) (0.763970,0.000056) (0.764804,0.000055) (0.765638,0.000055) (0.766472,0.000055) (0.767306,0.000055) (0.768140,0.000055) (0.768974,0.000055) (0.769808,0.000054) (0.770642,0.000054) (0.771476,0.000054) (0.772310,0.000054) (0.773144,0.000054) (0.773978,0.000053) (0.774812,0.000053) (0.775646,0.000053) (0.776480,0.000053) (0.777314,0.000053) (0.778148,0.000053) (0.778982,0.000053) (0.779817,0.000052) (0.780651,0.000052) (0.781485,0.000052) (0.782319,0.000052) (0.783153,0.000052) (0.783987,0.000052) (0.784821,0.000052) (0.785655,0.000051) (0.786489,0.000051) (0.787323,0.000051) (0.788157,0.000051) (0.788991,0.000050) (0.789825,0.000050) (0.790659,0.000050) (0.791493,0.000049) (0.792327,0.000049) (0.793161,0.000049) (0.793995,0.000049) (0.794829,0.000049) (0.795663,0.000049) (0.796497,0.000049) (0.797331,0.000047) (0.798165,0.000047) (0.798999,0.000047) (0.799833,0.000047) (0.800667,0.000046) (0.801501,0.000046) (0.802335,0.000046) (0.803169,0.000046) (0.804003,0.000045) (0.804837,0.000045) (0.805671,0.000044) (0.806505,0.000044) (0.807339,0.000043) (0.808173,0.000043) (0.809008,0.000043) (0.809842,0.000043) (0.810676,0.000042) (0.811510,0.000042) (0.812344,0.000041) (0.813178,0.000041) (0.814012,0.000041) (0.814846,0.000041) (0.815680,0.000040) (0.816514,0.000040) (0.817348,0.000038) (0.818182,0.000038) (0.819016,0.000038) (0.819850,0.000037) (0.820684,0.000037) (0.821518,0.000037) (0.822352,0.000037) (0.823186,0.000037) (0.824020,0.000036) (0.824854,0.000036) (0.825688,0.000035) (0.826522,0.000035) (0.827356,0.000035) (0.828190,0.000035) (0.829024,0.000034) (0.829858,0.000034) (0.830692,0.000033) (0.831526,0.000033) (0.832360,0.000033) (0.833194,0.000033) (0.834028,0.000032) (0.834862,0.000032) (0.835696,0.000031) (0.836530,0.000031) (0.837364,0.000030) (0.838198,0.000030) (0.839033,0.000030) (0.839867,0.000030) (0.840701,0.000029) (0.841535,0.000029) (0.842369,0.000029) (0.843203,0.000029) (0.844037,0.000029) (0.844871,0.000028) (0.845705,0.000028) (0.846539,0.000028) (0.847373,0.000028) (0.848207,0.000028) (0.849041,0.000028) (0.849875,0.000028) (0.850709,0.000028) (0.851543,0.000028) (0.852377,0.000028) (0.853211,0.000028) (0.854045,0.000028) (0.854879,0.000028) (0.855713,0.000028) (0.856547,0.000028) (0.857381,0.000028) (0.858215,0.000028) (0.859049,0.000027) (0.859883,0.000027) (0.860717,0.000027) (0.861551,0.000027) (0.862385,0.000027) (0.863219,0.000027) (0.864053,0.000027) (0.864887,0.000027) (0.865721,0.000027) (0.866555,0.000027) (0.867389,0.000027) (0.868224,0.000027) (0.869058,0.000027) (0.869892,0.000026) (0.870726,0.000026) (0.871560,0.000026) (0.872394,0.000025) (0.873228,0.000025) (0.874062,0.000025) (0.874896,0.000025) (0.875730,0.000025) (0.876564,0.000025) (0.877398,0.000025) (0.878232,0.000025) (0.879066,0.000025) (0.879900,0.000025) (0.880734,0.000024) (0.881568,0.000024) (0.882402,0.000024) (0.883236,0.000024) (0.884070,0.000024) (0.884904,0.000024) (0.885738,0.000023) (0.886572,0.000023) (0.887406,0.000023) (0.888240,0.000023) (0.889074,0.000023) (0.889908,0.000023) (0.890742,0.000022) (0.891576,0.000022) (0.892410,0.000022) (0.893244,0.000022) (0.894078,0.000022) (0.894912,0.000022) (0.895746,0.000022) (0.896580,0.000022) (0.897415,0.000021) (0.898249,0.000021) (0.899083,0.000021) (0.899917,0.000021) (0.900751,0.000021) (0.901585,0.000021) (0.902419,0.000021) (0.903253,0.000021) (0.904087,0.000021) (0.904921,0.000021) (0.905755,0.000021) (0.906589,0.000021) (0.907423,0.000021) (0.908257,0.000020) (0.909091,0.000020) (0.909925,0.000020) (0.910759,0.000020) (0.911593,0.000020) (0.912427,0.000020) (0.913261,0.000020) (0.914095,0.000019) (0.914929,0.000019) (0.915763,0.000019) (0.916597,0.000018) (0.917431,0.000018) (0.918265,0.000018) (0.919099,0.000017) (0.919933,0.000017) (0.920767,0.000017) (0.921601,0.000017) (0.922435,0.000017) (0.923269,0.000016) (0.924103,0.000016) (0.924937,0.000016) (0.925771,0.000016) (0.926606,0.000016) (0.927440,0.000016) (0.928274,0.000015) (0.929108,0.000015) (0.929942,0.000015) (0.930776,0.000015) (0.931610,0.000015) (0.932444,0.000015) (0.933278,0.000015) (0.934112,0.000015) (0.934946,0.000014) (0.935780,0.000014) (0.936614,0.000014) (0.937448,0.000014) (0.938282,0.000013) (0.939116,0.000013) (0.939950,0.000012) (0.940784,0.000012) (0.941618,0.000012) (0.942452,0.000012) (0.943286,0.000012) (0.944120,0.000012) (0.944954,0.000012) (0.945788,0.000012) (0.946622,0.000011) (0.947456,0.000011) (0.948290,0.000011) (0.949124,0.000011) (0.949958,0.000011) (0.950792,0.000011) (0.951626,0.000010) (0.952460,0.000010) (0.953294,0.000010) (0.954128,0.000010) (0.954962,0.000009) (0.955796,0.000009) (0.956631,0.000009) (0.957465,0.000009) (0.958299,0.000008) (0.959133,0.000008) (0.959967,0.000008) (0.960801,0.000008) (0.961635,0.000008) (0.962469,0.000008) (0.963303,0.000008) (0.964137,0.000008) (0.964971,0.000007) (0.965805,0.000007) (0.966639,0.000007) (0.967473,0.000007) (0.968307,0.000007) (0.969141,0.000007) (0.969975,0.000006) (0.970809,0.000006) (0.971643,0.000006) (0.972477,0.000005) (0.973311,0.000005) (0.974145,0.000004) (0.974979,0.000004) (0.975813,0.000004) (0.976647,0.000004) (0.977481,0.000004) (0.978315,0.000003) (0.979149,0.000003) (0.979983,0.000003) (0.980817,0.000003) (0.981651,0.000002) (0.982485,0.000002) (0.983319,0.000002) (0.984153,0.000002) (0.984987,0.000002) (0.985822,0.000002) (0.986656,0.000001) (0.987490,0.000001) (0.988324,0.000001) (0.989158,0.000001) (0.989992,0.000001) (0.990826,0.000001) (0.991660,0.000001) (0.992494,0.000001) (0.993328,0.000001) (0.994162,0.000001) (0.994996,0.000001) (0.995830,0.000001) (0.996664,0.000001) (0.997498,0.000001) (0.998332,0.000001) (0.999166,0.000001) (1.000000,0.000001) }; +\addplot[brown,only marks,mark=*] coordinates {(0.015013,0.226789) (0.341952,0.000932) (0.663053,0.000111)}; \ No newline at end of file diff --git a/talk/vmil2012/presentation/figures/go_data.tex b/talk/vmil2012/presentation/figures/go_data.tex --- a/talk/vmil2012/presentation/figures/go_data.tex +++ b/talk/vmil2012/presentation/figures/go_data.tex @@ -1,5 +1,6 @@ -\addplot[black] coordinates { +\addplot[green,mark=none] coordinates { (0.000000,1.000000) (0.000834,0.872400) (0.001668,0.683224) (0.002502,0.608314) (0.003336,0.542330) (0.004170,0.519721) (0.005004,0.447508) (0.005838,0.440065) (0.006672,0.420670) (0.007506,0.418862) (0.008340,0.418009) (0.009174,0.379519) (0.010008,0.357223) (0.010842,0.353534) (0.011676,0.333568) (0.012510,0.319704) (0.013344,0.268160) (0.014178,0.251065) (0.015013,0.226789) (0.015847,0.220089) (0.016681,0.215066) (0.017515,0.213903) (0.018349,0.213091) (0.019183,0.197153) (0.020017,0.187389) (0.020851,0.177430) (0.021685,0.173396) (0.022519,0.170787) (0.023353,0.160834) (0.024187,0.160045) (0.025021,0.157071) (0.025855,0.146612) (0.026689,0.144178) (0.027523,0.137699) (0.028357,0.136683) (0.029191,0.124833) (0.030025,0.121453) (0.030859,0.119189) (0.031693,0.115002) (0.032527,0.114249) (0.033361,0.107546) (0.034195,0.107268) (0.035029,0.104187) (0.035863,0.096624) (0.036697,0.089912) (0.037531,0.089585) (0.038365,0.087446) (0.039199,0.087298) (0.040033,0.084823) (0.040867,0.083414) (0.041701,0.083212) (0.042535,0.082227) (0.043369,0.079913) (0.044204,0.075734) (0.045038,0.073337) (0.045872,0.073039) (0.046706,0.072381) (0.047540,0.069693) (0.048374,0.067325) (0.049208,0.065996) (0.050042,0.057532) (0.050876,0.055707) (0.051710,0.055669) (0.052544,0.049083) (0.053378,0.048652) (0.054212,0.048015) (0.055046,0.045918) (0.055880,0.045234) (0.056714,0.042272) (0.057548,0.041798) (0.058382,0.040969) (0.059216,0.040163) (0.060050,0.040016) (0.060884,0.038778) (0.061718,0.038686) (0.062552,0.038456) (0.063386,0.033439) (0.064220,0.032381) (0.065054,0.031115) (0.065888,0.030103) (0.066722,0.029385) (0.067556,0.026654) (0.068390,0.025877) (0.069224,0.024467) (0.070058,0.024427) (0.070892,0.024134) (0.071726,0.024036) (0.072560,0.021379) (0.073394,0.020813) (0.074229,0.020166) (0.075063,0.020056) (0.075897,0.019981) (0.076731,0.019791) (0.077565,0.019672) (0.078399,0.019356) (0.079233,0.019269) (0.080067,0.019134) (0.080901,0.018119) (0.081735,0.017905) (0.082569,0.017878) (0.083403,0.017865) (0.084237,0.017769) (0.085071,0.017758) (0.085905,0.017065) (0.086739,0.016959) (0.087573,0.016686) (0.088407,0.015666) (0.089241,0.014908) (0.090075,0.014542) (0.090909,0.014518) (0.091743,0.014200) (0.092577,0.013865) (0.093411,0.013736) (0.094245,0.013273) (0.095079,0.013197) (0.095913,0.012997) (0.096747,0.012759) (0.097581,0.012642) (0.098415,0.012344) (0.099249,0.012031) (0.100083,0.011973) (0.100917,0.011805) (0.101751,0.011594) (0.102585,0.011387) (0.103420,0.011332) (0.104254,0.011246) (0.105088,0.010925) (0.105922,0.010566) (0.106756,0.010269) (0.107590,0.010235) (0.108424,0.010220) (0.109258,0.010135) (0.110092,0.010071) (0.110926,0.010048) (0.111760,0.010002) (0.112594,0.009762) (0.113428,0.009756) (0.114262,0.009751) (0.115096,0.009730) (0.115930,0.009551) (0.116764,0.009536) (0.117598,0.009404) (0.118432,0.009399) (0.119266,0.009298) (0.120100,0.009263) (0.120934,0.009245) (0.121768,0.009137) (0.122602,0.009120) (0.123436,0.009097) (0.124270,0.008816) (0.125104,0.008646) (0.125938,0.008484) (0.126772,0.008405) (0.127606,0.008149) (0.128440,0.008032) (0.129274,0.007872) (0.130108,0.007866) (0.130942,0.007823) (0.131776,0.007801) (0.132611,0.007718) (0.133445,0.007481) (0.134279,0.007373) (0.135113,0.007345) (0.135947,0.007296) (0.136781,0.007269) (0.137615,0.007233) (0.138449,0.006991) (0.139283,0.006905) (0.140117,0.006795) (0.140951,0.006738) (0.141785,0.006708) (0.142619,0.006551) (0.143453,0.006510) (0.144287,0.006435) (0.145121,0.006361) (0.145955,0.006238) (0.146789,0.006134) (0.147623,0.006027) (0.148457,0.005991) (0.149291,0.005921) (0.150125,0.005852) (0.150959,0.005852) (0.151793,0.005823) (0.152627,0.005794) (0.153461,0.005787) (0.154295,0.005746) (0.155129,0.005672) (0.155963,0.005619) (0.156797,0.005612) (0.157631,0.005557) (0.158465,0.005495) (0.159299,0.005495) (0.160133,0.005422) (0.160967,0.005324) (0.161802,0.005217) (0.162636,0.005196) (0.163470,0.005167) (0.164304,0.005107) (0.165138,0.005012) (0.165972,0.004999) (0.166806,0.004985) (0.167640,0.004981) (0.168474,0.004936) (0.169308,0.004912) (0.170142,0.004836) (0.170976,0.004822) (0.171810,0.004755) (0.172644,0.004692) (0.173478,0.004687) (0.174312,0.004667) (0.175146,0.004605) (0.175980,0.004546) (0.176814,0.004523) (0.177648,0.004518) (0.178482,0.004512) (0.179316,0.004447) (0.180150,0.004427) (0.180984,0.004408) (0.181818,0.004401) (0.182652,0.004336) (0.183486,0.004326) (0.184320,0.004255) (0.185154,0.004163) (0.185988,0.004152) (0.186822,0.004150) (0.187656,0.004132) (0.188490,0.004125) (0.189324,0.003972) (0.190158,0.003971) (0.190992,0.003942) (0.191827,0.003842) (0.192661,0.003797) (0.193495,0.003710) (0.194329,0.003703) (0.195163,0.003684) (0.195997,0.003626) (0.196831,0.003620) (0.197665,0.003576) (0.198499,0.003526) (0.199333,0.003451) (0.200167,0.003447) (0.201001,0.003402) (0.201835,0.003390) (0.202669,0.003364) (0.203503,0.003361) (0.204337,0.003356) (0.205171,0.003350) (0.206005,0.003341) (0.206839,0.003321) (0.207673,0.003278) (0.208507,0.003246) (0.209341,0.003239) (0.210175,0.003219) (0.211009,0.003208) (0.211843,0.003129) (0.212677,0.003123) (0.213511,0.003073) (0.214345,0.003063) (0.215179,0.003053) (0.216013,0.003053) (0.216847,0.003026) (0.217681,0.003007) (0.218515,0.002989) (0.219349,0.002929) (0.220183,0.002915) (0.221018,0.002913) (0.221852,0.002890) (0.222686,0.002861) (0.223520,0.002845) (0.224354,0.002804) (0.225188,0.002783) (0.226022,0.002781) (0.226856,0.002694) (0.227690,0.002669) (0.228524,0.002631) (0.229358,0.002579) (0.230192,0.002578) (0.231026,0.002573) (0.231860,0.002566) (0.232694,0.002507) (0.233528,0.002487) (0.234362,0.002486) (0.235196,0.002416) (0.236030,0.002367) (0.236864,0.002347) (0.237698,0.002344) (0.238532,0.002338) (0.239366,0.002330) (0.240200,0.002318) (0.241034,0.002315) (0.241868,0.002308) (0.242702,0.002308) (0.243536,0.002292) (0.244370,0.002287) (0.245204,0.002283) (0.246038,0.002264) (0.246872,0.002236) (0.247706,0.002227) (0.248540,0.002185) (0.249374,0.002173) (0.250209,0.002169) (0.251043,0.002135) (0.251877,0.002109) (0.252711,0.002039) (0.253545,0.002031) (0.254379,0.001987) (0.255213,0.001970) (0.256047,0.001966) (0.256881,0.001936) (0.257715,0.001908) (0.258549,0.001908) (0.259383,0.001893) (0.260217,0.001886) (0.261051,0.001882) (0.261885,0.001827) (0.262719,0.001827) (0.263553,0.001817) (0.264387,0.001797) (0.265221,0.001749) (0.266055,0.001742) (0.266889,0.001739) (0.267723,0.001727) (0.268557,0.001704) (0.269391,0.001700) (0.270225,0.001691) (0.271059,0.001690) (0.271893,0.001653) (0.272727,0.001600) (0.273561,0.001595) (0.274395,0.001555) (0.275229,0.001547) (0.276063,0.001546) (0.276897,0.001519) (0.277731,0.001513) (0.278565,0.001510) (0.279399,0.001505) (0.280234,0.001474) (0.281068,0.001468) (0.281902,0.001459) (0.282736,0.001458) (0.283570,0.001432) (0.284404,0.001410) (0.285238,0.001407) (0.286072,0.001401) (0.286906,0.001396) (0.287740,0.001391) (0.288574,0.001376) (0.289408,0.001372) (0.290242,0.001369) (0.291076,0.001345) (0.291910,0.001344) (0.292744,0.001318) (0.293578,0.001299) (0.294412,0.001295) (0.295246,0.001287) (0.296080,0.001285) (0.296914,0.001284) (0.297748,0.001270) (0.298582,0.001265) (0.299416,0.001253) (0.300250,0.001235) (0.301084,0.001233) (0.301918,0.001224) (0.302752,0.001222) (0.303586,0.001219) (0.304420,0.001209) (0.305254,0.001202) (0.306088,0.001191) (0.306922,0.001180) (0.307756,0.001173) (0.308590,0.001170) (0.309425,0.001167) (0.310259,0.001154) (0.311093,0.001147) (0.311927,0.001143) (0.312761,0.001130) (0.313595,0.001126) (0.314429,0.001124) (0.315263,0.001116) (0.316097,0.001115) (0.316931,0.001099) (0.317765,0.001088) (0.318599,0.001088) (0.319433,0.001082) (0.320267,0.001074) (0.321101,0.001071) (0.321935,0.001070) (0.322769,0.001066) (0.323603,0.001062) (0.324437,0.001047) (0.325271,0.001043) (0.326105,0.001041) (0.326939,0.001040) (0.327773,0.001038) (0.328607,0.001027) (0.329441,0.001025) (0.330275,0.001016) (0.331109,0.001016) (0.331943,0.000996) (0.332777,0.000992) (0.333611,0.000985) (0.334445,0.000979) (0.335279,0.000978) (0.336113,0.000978) (0.336947,0.000957) (0.337781,0.000953) (0.338616,0.000951) (0.339450,0.000947) (0.340284,0.000944) (0.341118,0.000939) (0.341952,0.000932) (0.342786,0.000930) (0.343620,0.000930) (0.344454,0.000928) (0.345288,0.000915) (0.346122,0.000914) (0.346956,0.000914) (0.347790,0.000911) (0.348624,0.000910) (0.349458,0.000908) (0.350292,0.000904) (0.351126,0.000895) (0.351960,0.000890) (0.352794,0.000887) (0.353628,0.000884) (0.354462,0.000879) (0.355296,0.000861) (0.356130,0.000861) (0.356964,0.000826) (0.357798,0.000814) (0.358632,0.000808) (0.359466,0.000800) (0.360300,0.000797) (0.361134,0.000796) (0.361968,0.000782) (0.362802,0.000779) (0.363636,0.000778) (0.364470,0.000777) (0.365304,0.000777) (0.366138,0.000775) (0.366972,0.000767) (0.367807,0.000764) (0.368641,0.000761) (0.369475,0.000758) (0.370309,0.000753) (0.371143,0.000753) (0.371977,0.000751) (0.372811,0.000738) (0.373645,0.000718) (0.374479,0.000718) (0.375313,0.000710) (0.376147,0.000709) (0.376981,0.000707) (0.377815,0.000701) (0.378649,0.000699) (0.379483,0.000694) (0.380317,0.000694) (0.381151,0.000688) (0.381985,0.000686) (0.382819,0.000683) (0.383653,0.000681) (0.384487,0.000665) (0.385321,0.000664) (0.386155,0.000660) (0.386989,0.000659) (0.387823,0.000657) (0.388657,0.000657) (0.389491,0.000655) (0.390325,0.000654) (0.391159,0.000647) (0.391993,0.000645) (0.392827,0.000644) (0.393661,0.000643) (0.394495,0.000642) (0.395329,0.000640) (0.396163,0.000639) (0.396997,0.000637) (0.397832,0.000634) (0.398666,0.000630) (0.399500,0.000614) (0.400334,0.000613) (0.401168,0.000607) (0.402002,0.000604) (0.402836,0.000603) (0.403670,0.000602) (0.404504,0.000602) (0.405338,0.000598) (0.406172,0.000597) (0.407006,0.000592) (0.407840,0.000588) (0.408674,0.000576) (0.409508,0.000572) (0.410342,0.000570) (0.411176,0.000570) (0.412010,0.000567) (0.412844,0.000567) (0.413678,0.000566) (0.414512,0.000564) (0.415346,0.000563) (0.416180,0.000554) (0.417014,0.000550) (0.417848,0.000548) (0.418682,0.000547) (0.419516,0.000547) (0.420350,0.000546) (0.421184,0.000542) (0.422018,0.000542) (0.422852,0.000535) (0.423686,0.000529) (0.424520,0.000518) (0.425354,0.000516) (0.426188,0.000515) (0.427023,0.000513) (0.427857,0.000512) (0.428691,0.000511) (0.429525,0.000503) (0.430359,0.000503) (0.431193,0.000503) (0.432027,0.000499) (0.432861,0.000497) (0.433695,0.000497) (0.434529,0.000495) (0.435363,0.000495) (0.436197,0.000494) (0.437031,0.000494) (0.437865,0.000492) (0.438699,0.000491) (0.439533,0.000490) (0.440367,0.000489) (0.441201,0.000488) (0.442035,0.000486) (0.442869,0.000484) (0.443703,0.000480) (0.444537,0.000479) (0.445371,0.000478) (0.446205,0.000471) (0.447039,0.000467) (0.447873,0.000466) (0.448707,0.000464) (0.449541,0.000460) (0.450375,0.000458) (0.451209,0.000456) (0.452043,0.000452) (0.452877,0.000451) (0.453711,0.000448) (0.454545,0.000446) (0.455379,0.000445) (0.456214,0.000444) (0.457048,0.000437) (0.457882,0.000436) (0.458716,0.000435) (0.459550,0.000431) (0.460384,0.000431) (0.461218,0.000430) (0.462052,0.000428) (0.462886,0.000428) (0.463720,0.000428) (0.464554,0.000427) (0.465388,0.000427) (0.466222,0.000422) (0.467056,0.000420) (0.467890,0.000415) (0.468724,0.000409) (0.469558,0.000408) (0.470392,0.000408) (0.471226,0.000406) (0.472060,0.000405) (0.472894,0.000404) (0.473728,0.000404) (0.474562,0.000402) (0.475396,0.000402) (0.476230,0.000402) (0.477064,0.000402) (0.477898,0.000399) (0.478732,0.000399) (0.479566,0.000398) (0.480400,0.000395) (0.481234,0.000395) (0.482068,0.000394) (0.482902,0.000390) (0.483736,0.000389) (0.484570,0.000387) (0.485405,0.000385) (0.486239,0.000383) (0.487073,0.000382) (0.487907,0.000381) (0.488741,0.000380) (0.489575,0.000380) (0.490409,0.000377) (0.491243,0.000375) (0.492077,0.000374) (0.492911,0.000373) (0.493745,0.000371) (0.494579,0.000370) (0.495413,0.000369) (0.496247,0.000368) (0.497081,0.000366) (0.497915,0.000364) (0.498749,0.000362) (0.499583,0.000362) (0.500417,0.000358) (0.501251,0.000354) (0.502085,0.000346) (0.502919,0.000345) (0.503753,0.000344) (0.504587,0.000343) (0.505421,0.000341) (0.506255,0.000340) (0.507089,0.000337) (0.507923,0.000337) (0.508757,0.000331) (0.509591,0.000328) (0.510425,0.000325) (0.511259,0.000323) (0.512093,0.000319) (0.512927,0.000319) (0.513761,0.000317) (0.514595,0.000315) (0.515430,0.000314) (0.516264,0.000313) (0.517098,0.000313) (0.517932,0.000312) (0.518766,0.000312) (0.519600,0.000311) (0.520434,0.000302) (0.521268,0.000300) (0.522102,0.000300) (0.522936,0.000295) (0.523770,0.000295) (0.524604,0.000295) (0.525438,0.000292) (0.526272,0.000290) (0.527106,0.000290) (0.527940,0.000288) (0.528774,0.000287) (0.529608,0.000285) (0.530442,0.000280) (0.531276,0.000278) (0.532110,0.000278) (0.532944,0.000278) (0.533778,0.000277) (0.534612,0.000276) (0.535446,0.000274) (0.536280,0.000273) (0.537114,0.000271) (0.537948,0.000271) (0.538782,0.000270) (0.539616,0.000266) (0.540450,0.000263) (0.541284,0.000260) (0.542118,0.000260) (0.542952,0.000258) (0.543786,0.000258) (0.544621,0.000256) (0.545455,0.000253) (0.546289,0.000252) (0.547123,0.000251) (0.547957,0.000249) (0.548791,0.000248) (0.549625,0.000248) (0.550459,0.000248) (0.551293,0.000246) (0.552127,0.000246) (0.552961,0.000244) (0.553795,0.000244) (0.554629,0.000242) (0.555463,0.000241) (0.556297,0.000240) (0.557131,0.000240) (0.557965,0.000239) (0.558799,0.000236) (0.559633,0.000236) (0.560467,0.000235) (0.561301,0.000234) (0.562135,0.000234) (0.562969,0.000234) (0.563803,0.000233) (0.564637,0.000233) (0.565471,0.000225) (0.566305,0.000223) (0.567139,0.000223) (0.567973,0.000220) (0.568807,0.000219) (0.569641,0.000218) (0.570475,0.000218) (0.571309,0.000217) (0.572143,0.000216) (0.572977,0.000213) (0.573812,0.000211) (0.574646,0.000207) (0.575480,0.000206) (0.576314,0.000206) (0.577148,0.000205) (0.577982,0.000205) (0.578816,0.000203) (0.579650,0.000203) (0.580484,0.000203) (0.581318,0.000203) (0.582152,0.000203) (0.582986,0.000201) (0.583820,0.000200) (0.584654,0.000200) (0.585488,0.000199) (0.586322,0.000199) (0.587156,0.000197) (0.587990,0.000194) (0.588824,0.000193) (0.589658,0.000191) (0.590492,0.000190) (0.591326,0.000190) (0.592160,0.000186) (0.592994,0.000186) (0.593828,0.000181) (0.594662,0.000178) (0.595496,0.000175) (0.596330,0.000174) (0.597164,0.000173) (0.597998,0.000173) (0.598832,0.000172) (0.599666,0.000171) (0.600500,0.000171) (0.601334,0.000170) (0.602168,0.000170) (0.603003,0.000169) (0.603837,0.000166) (0.604671,0.000165) (0.605505,0.000165) (0.606339,0.000165) (0.607173,0.000164) (0.608007,0.000163) (0.608841,0.000162) (0.609675,0.000162) (0.610509,0.000162) (0.611343,0.000162) (0.612177,0.000161) (0.613011,0.000161) (0.613845,0.000159) (0.614679,0.000158) (0.615513,0.000158) (0.616347,0.000157) (0.617181,0.000156) (0.618015,0.000155) (0.618849,0.000155) (0.619683,0.000152) (0.620517,0.000152) (0.621351,0.000151) (0.622185,0.000151) (0.623019,0.000149) (0.623853,0.000149) (0.624687,0.000148) (0.625521,0.000147) (0.626355,0.000147) (0.627189,0.000146) (0.628023,0.000146) (0.628857,0.000146) (0.629691,0.000146) (0.630525,0.000145) (0.631359,0.000145) (0.632193,0.000144) (0.633028,0.000144) (0.633862,0.000144) (0.634696,0.000144) (0.635530,0.000143) (0.636364,0.000142) (0.637198,0.000142) (0.638032,0.000142) (0.638866,0.000142) (0.639700,0.000141) (0.640534,0.000140) (0.641368,0.000139) (0.642202,0.000137) (0.643036,0.000137) (0.643870,0.000133) (0.644704,0.000131) (0.645538,0.000131) (0.646372,0.000129) (0.647206,0.000129) (0.648040,0.000129) (0.648874,0.000128) (0.649708,0.000128) (0.650542,0.000127) (0.651376,0.000124) (0.652210,0.000123) (0.653044,0.000119) (0.653878,0.000117) (0.654712,0.000117) (0.655546,0.000117) (0.656380,0.000115) (0.657214,0.000114) (0.658048,0.000114) (0.658882,0.000114) (0.659716,0.000113) (0.660550,0.000112) (0.661384,0.000111) (0.662219,0.000111) (0.663053,0.000111) (0.663887,0.000111) (0.664721,0.000110) (0.665555,0.000110) (0.666389,0.000109) (0.667223,0.000108) (0.668057,0.000108) (0.668891,0.000107) (0.669725,0.000105) (0.670559,0.000105) (0.671393,0.000105) (0.672227,0.000105) (0.673061,0.000105) (0.673895,0.000105) (0.674729,0.000105) (0.675563,0.000104) (0.676397,0.000104) (0.677231,0.000103) (0.678065,0.000102) (0.678899,0.000101) (0.679733,0.000101) (0.680567,0.000100) (0.681401,0.000100) (0.682235,0.000100) (0.683069,0.000099) (0.683903,0.000099) (0.684737,0.000098) (0.685571,0.000098) (0.686405,0.000098) (0.687239,0.000097) (0.688073,0.000094) (0.688907,0.000094) (0.689741,0.000092) (0.690575,0.000092) (0.691410,0.000091) (0.692244,0.000089) (0.693078,0.000089) (0.693912,0.000087) (0.694746,0.000087) (0.695580,0.000087) (0.696414,0.000086) (0.697248,0.000086) (0.698082,0.000086) (0.698916,0.000085) (0.699750,0.000085) (0.700584,0.000085) (0.701418,0.000085) (0.702252,0.000084) (0.703086,0.000084) (0.703920,0.000083) (0.704754,0.000083) (0.705588,0.000082) (0.706422,0.000081) (0.707256,0.000080) (0.708090,0.000080) (0.708924,0.000080) (0.709758,0.000079) (0.710592,0.000079) (0.711426,0.000078) (0.712260,0.000078) (0.713094,0.000077) (0.713928,0.000076) (0.714762,0.000076) (0.715596,0.000076) (0.716430,0.000075) (0.717264,0.000075) (0.718098,0.000072) (0.718932,0.000071) (0.719766,0.000071) (0.720601,0.000070) (0.721435,0.000070) (0.722269,0.000070) (0.723103,0.000070) (0.723937,0.000070) (0.724771,0.000070) (0.725605,0.000069) (0.726439,0.000068) (0.727273,0.000068) (0.728107,0.000068) (0.728941,0.000067) (0.729775,0.000067) (0.730609,0.000067) (0.731443,0.000067) (0.732277,0.000066) (0.733111,0.000066) (0.733945,0.000065) (0.734779,0.000065) (0.735613,0.000065) (0.736447,0.000065) (0.737281,0.000064) (0.738115,0.000064) (0.738949,0.000063) (0.739783,0.000063) (0.740617,0.000063) (0.741451,0.000062) (0.742285,0.000062) (0.743119,0.000060) (0.743953,0.000060) (0.744787,0.000059) (0.745621,0.000059) (0.746455,0.000059) (0.747289,0.000059) (0.748123,0.000058) (0.748957,0.000058) (0.749791,0.000057) (0.750626,0.000057) (0.751460,0.000057) (0.752294,0.000057) (0.753128,0.000057) (0.753962,0.000057) (0.754796,0.000057) (0.755630,0.000057) (0.756464,0.000057) (0.757298,0.000057) (0.758132,0.000057) (0.758966,0.000057) (0.759800,0.000057) (0.760634,0.000057) (0.761468,0.000057) (0.762302,0.000057) (0.763136,0.000056) (0.763970,0.000056) (0.764804,0.000055) (0.765638,0.000055) (0.766472,0.000055) (0.767306,0.000055) (0.768140,0.000055) (0.768974,0.000055) (0.769808,0.000054) (0.770642,0.000054) (0.771476,0.000054) (0.772310,0.000054) (0.773144,0.000054) (0.773978,0.000053) (0.774812,0.000053) (0.775646,0.000053) (0.776480,0.000053) (0.777314,0.000053) (0.778148,0.000053) (0.778982,0.000053) (0.779817,0.000052) (0.780651,0.000052) (0.781485,0.000052) (0.782319,0.000052) (0.783153,0.000052) (0.783987,0.000052) (0.784821,0.000052) (0.785655,0.000051) (0.786489,0.000051) (0.787323,0.000051) (0.788157,0.000051) (0.788991,0.000050) (0.789825,0.000050) (0.790659,0.000050) (0.791493,0.000049) (0.792327,0.000049) (0.793161,0.000049) (0.793995,0.000049) (0.794829,0.000049) (0.795663,0.000049) (0.796497,0.000049) (0.797331,0.000047) (0.798165,0.000047) (0.798999,0.000047) (0.799833,0.000047) (0.800667,0.000046) (0.801501,0.000046) (0.802335,0.000046) (0.803169,0.000046) (0.804003,0.000045) (0.804837,0.000045) (0.805671,0.000044) (0.806505,0.000044) (0.807339,0.000043) (0.808173,0.000043) (0.809008,0.000043) (0.809842,0.000043) (0.810676,0.000042) (0.811510,0.000042) (0.812344,0.000041) (0.813178,0.000041) (0.814012,0.000041) (0.814846,0.000041) (0.815680,0.000040) (0.816514,0.000040) (0.817348,0.000038) (0.818182,0.000038) (0.819016,0.000038) (0.819850,0.000037) (0.820684,0.000037) (0.821518,0.000037) (0.822352,0.000037) (0.823186,0.000037) (0.824020,0.000036) (0.824854,0.000036) (0.825688,0.000035) (0.826522,0.000035) (0.827356,0.000035) (0.828190,0.000035) (0.829024,0.000034) (0.829858,0.000034) (0.830692,0.000033) (0.831526,0.000033) (0.832360,0.000033) (0.833194,0.000033) (0.834028,0.000032) (0.834862,0.000032) (0.835696,0.000031) (0.836530,0.000031) (0.837364,0.000030) (0.838198,0.000030) (0.839033,0.000030) (0.839867,0.000030) (0.840701,0.000029) (0.841535,0.000029) (0.842369,0.000029) (0.843203,0.000029) (0.844037,0.000029) (0.844871,0.000028) (0.845705,0.000028) (0.846539,0.000028) (0.847373,0.000028) (0.848207,0.000028) (0.849041,0.000028) (0.849875,0.000028) (0.850709,0.000028) (0.851543,0.000028) (0.852377,0.000028) (0.853211,0.000028) (0.854045,0.000028) (0.854879,0.000028) (0.855713,0.000028) (0.856547,0.000028) (0.857381,0.000028) (0.858215,0.000028) (0.859049,0.000027) (0.859883,0.000027) (0.860717,0.000027) (0.861551,0.000027) (0.862385,0.000027) (0.863219,0.000027) (0.864053,0.000027) (0.864887,0.000027) (0.865721,0.000027) (0.866555,0.000027) (0.867389,0.000027) (0.868224,0.000027) (0.869058,0.000027) (0.869892,0.000026) (0.870726,0.000026) (0.871560,0.000026) (0.872394,0.000025) (0.873228,0.000025) (0.874062,0.000025) (0.874896,0.000025) (0.875730,0.000025) (0.876564,0.000025) (0.877398,0.000025) (0.878232,0.000025) (0.879066,0.000025) (0.879900,0.000025) (0.880734,0.000024) (0.881568,0.000024) (0.882402,0.000024) (0.883236,0.000024) (0.884070,0.000024) (0.884904,0.000024) (0.885738,0.000023) (0.886572,0.000023) (0.887406,0.000023) (0.888240,0.000023) (0.889074,0.000023) (0.889908,0.000023) (0.890742,0.000022) (0.891576,0.000022) (0.892410,0.000022) (0.893244,0.000022) (0.894078,0.000022) (0.894912,0.000022) (0.895746,0.000022) (0.896580,0.000022) (0.897415,0.000021) (0.898249,0.000021) (0.899083,0.000021) (0.899917,0.000021) (0.900751,0.000021) (0.901585,0.000021) (0.902419,0.000021) (0.903253,0.000021) (0.904087,0.000021) (0.904921,0.000021) (0.905755,0.000021) (0.906589,0.000021) (0.907423,0.000021) (0.908257,0.000020) (0.909091,0.000020) (0.909925,0.000020) (0.910759,0.000020) (0.911593,0.000020) (0.912427,0.000020) (0.913261,0.000020) (0.914095,0.000019) (0.914929,0.000019) (0.915763,0.000019) (0.916597,0.000018) (0.917431,0.000018) (0.918265,0.000018) (0.919099,0.000017) (0.919933,0.000017) (0.920767,0.000017) (0.921601,0.000017) (0.922435,0.000017) (0.923269,0.000016) (0.924103,0.000016) (0.924937,0.000016) (0.925771,0.000016) (0.926606,0.000016) (0.927440,0.000016) (0.928274,0.000015) (0.929108,0.000015) (0.929942,0.000015) (0.930776,0.000015) (0.931610,0.000015) (0.932444,0.000015) (0.933278,0.000015) (0.934112,0.000015) (0.934946,0.000014) (0.935780,0.000014) (0.936614,0.000014) (0.937448,0.000014) (0.938282,0.000013) (0.939116,0.000013) (0.939950,0.000012) (0.940784,0.000012) (0.941618,0.000012) (0.942452,0.000012) (0.943286,0.000012) (0.944120,0.000012) (0.944954,0.000012) (0.945788,0.000012) (0.946622,0.000011) (0.947456,0.000011) (0.948290,0.000011) (0.949124,0.000011) (0.949958,0.000011) (0.950792,0.000011) (0.951626,0.000010) (0.952460,0.000010) (0.953294,0.000010) (0.954128,0.000010) (0.954962,0.000009) (0.955796,0.000009) (0.956631,0.000009) (0.957465,0.000009) (0.958299,0.000008) (0.959133,0.000008) (0.959967,0.000008) (0.960801,0.000008) (0.961635,0.000008) (0.962469,0.000008) (0.963303,0.000008) (0.964137,0.000008) (0.964971,0.000007) (0.965805,0.000007) (0.966639,0.000007) (0.967473,0.000007) (0.968307,0.000007) (0.969141,0.000007) (0.969975,0.000006) (0.970809,0.000006) (0.971643,0.000006) (0.972477,0.000005) (0.973311,0.000005) (0.974145,0.000004) (0.974979,0.000004) (0.975813,0.000004) (0.976647,0.000004) (0.977481,0.000004) (0.978315,0.000003) (0.979149,0.000003) (0.979983,0.000003) (0.980817,0.000003) (0.981651,0.000002) (0.982485,0.000002) (0.983319,0.000002) (0.984153,0.000002) (0.984987,0.000002) (0.985822,0.000002) (0.986656,0.000001) (0.987490,0.000001) (0.988324,0.000001) (0.989158,0.000001) (0.989992,0.000001) (0.990826,0.000001) (0.991660,0.000001) (0.992494,0.000001) (0.993328,0.000001) (0.994162,0.000001) (0.994996,0.000001) (0.995830,0.000001) (0.996664,0.000001) (0.997498,0.000001) (0.998332,0.000001) (0.999166,0.000001) (1.000000,0.000001) }; +\addplot[green,only marks,mark=*] coordinates {(0.015013,0.226789) (0.341952,0.000932) (0.663053,0.000111)}; \ No newline at end of file diff --git a/talk/vmil2012/presentation/tool/data.py b/talk/vmil2012/presentation/tool/data.py --- a/talk/vmil2012/presentation/tool/data.py +++ b/talk/vmil2012/presentation/tool/data.py @@ -20,11 +20,8 @@ def we_are_n_percent(info, n): failure_counts = info['results'].values() - print failure_counts failure_counts.sort() - print failure_counts failure_counts.reverse() - print failure_counts total_failures = sum(failure_counts) current_sum = 0 @@ -44,23 +41,42 @@ output = [] plot = """ -\\addplot[%(color)s] coordinates { +\\addplot[%(color)s,mark=none] coordinates { %(data)s }; +\\addplot[%(color)s,only marks,mark=*] coordinates {%(marks)s}; """ for j, (bench, info) in enumerate(failures.iteritems()): data = [] + marks = [] results = info['results'].values() results.sort() results.reverse() + + num_50 = we_are_n_percent(info, 50) + num_99 = we_are_n_percent(info, 99) + num_99_dot_9 = we_are_n_percent(info, 99.9) + + marks.append("(%04f,%04f)" % (float(num_50) / (len(results) - 1), + float(results[num_50]) / max(results))) + marks.append("(%04f,%04f)" % (float(num_99) / (len(results) - 1), + float(results[num_99]) / max(results))) + marks.append("(%04f,%04f)" % (float(num_99_dot_9) / (len(results) - 1), + float(results[num_99_dot_9]) / max(results))) for i, result in enumerate(results): data.append("(%04f,%04f)" % (float(i) / (len(results) - 1), float(result) / max(results))) if bench == 'go': with open('figures/go_data.tex', 'w') as f: - f.write(plot % {'color': 'black', 'name': bench, 'data': " ".join(data)}) - output.append(plot % {'color':COLORS[j], 'name': bench, 'data': " ".join(data)}) + f.write(plot % {'color': 'green', + 'name': bench, + 'marks': " ".join(marks), + 'data': " ".join(data)}) + output.append(plot % {'color': COLORS[j], + 'name': bench, + 'marks': " ".join(marks), + 'data': " ".join(data)}) with open('figures/data.tex', 'w') as f: for l in output: From noreply at buildbot.pypy.org Tue Oct 16 22:14:55 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 16 Oct 2012 22:14:55 +0200 (CEST) Subject: [pypy-commit] pypy default: kill things that are done Message-ID: <20121016201455.E8BB01C1C7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58148:298a247fd496 Date: 2012-10-16 22:14 +0200 http://bitbucket.org/pypy/pypy/changeset/298a247fd496/ Log: kill things that are done diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -17,12 +17,6 @@ projects, or anything else in PyPy, pop up on IRC or write to us on the `mailing list`_. -Make big integers faster -------------------------- - -PyPy's implementation of the Python ``long`` type is slower than CPython's. -Find out why and optimize them. **UPDATE:** this was done (thanks stian). - Make bytearray type fast ------------------------ @@ -81,14 +75,6 @@ * Allow separate compilation of extension modules. -Work on some of other languages -------------------------------- - -There are various languages implemented using the RPython translation toolchain. -One of the most interesting is the `JavaScript implementation`_, but there -are others like scheme or prolog. An interesting project would be to improve -the jittability of those or to experiment with various optimizations. - Various GCs ----------- @@ -144,8 +130,6 @@ * `hg` -* `sympy` - Experiment (again) with LLVM backend for RPython compilation ------------------------------------------------------------ From noreply at buildbot.pypy.org Tue Oct 16 22:33:11 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 16 Oct 2012 22:33:11 +0200 (CEST) Subject: [pypy-commit] pypy default: kill unused link Message-ID: <20121016203311.3A58C1C1C7A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58149:1418da034d1a Date: 2012-10-16 22:31 +0200 http://bitbucket.org/pypy/pypy/changeset/1418da034d1a/ Log: kill unused link diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -175,4 +175,3 @@ .. _`issue tracker`: http://bugs.pypy.org .. _`mailing list`: http://mail.python.org/mailman/listinfo/pypy-dev .. _`jitviewer`: http://bitbucket.org/pypy/jitviewer -.. _`JavaScript implementation`: https://bitbucket.org/pypy/lang-js/overview From noreply at buildbot.pypy.org Wed Oct 17 09:37:16 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 09:37:16 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: test_field_basic Message-ID: <20121017073716.5EE571C0732@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58151:6370f32ec6b9 Date: 2012-10-17 09:36 +0200 http://bitbucket.org/pypy/pypy/changeset/6370f32ec6b9/ Log: test_field_basic diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -37,6 +37,16 @@ self.RESULT = RESULT self.ARGS = ARGS +class FieldDescr(AbstractDescr): + def __init__(self, S, fieldname): + self.S = S + self.fieldname = fieldname + self.FIELD = getattr(S, fieldname) + + def is_pointer_field(self): + return getkind(self.FIELD) == 'ref' + + class LLGraphCPU(model.AbstractCPU): def __init__(self, rtyper): self.rtyper = rtyper @@ -76,6 +86,7 @@ def get_latest_value_int(self, index): return self.latest_values[index] get_latest_value_float = get_latest_value_int + get_latest_value_ref = get_latest_value_int def get_latest_value_count(self): return len(self.latest_values) @@ -87,7 +98,7 @@ return self.exc_value def calldescrof(self, FUNC, ARGS, RESULT, effect_info): - key = (getkind(RESULT), + key = ('call', getkind(RESULT), tuple([getkind(A) for A in ARGS]), effect_info) try: @@ -97,7 +108,14 @@ self.descrs[key] = descr return descr - + def fielddescrof(self, S, fieldname): + key = ('field', S, fieldname) + try: + return self.descrs[key] + except KeyError: + descr = FieldDescr(S, fieldname) + self.descrs[key] = descr + return descr def _calldescr_dynamic_for_tests(self, atypes, rtype, abiname='FFI_DEFAULT_ABI'): @@ -248,6 +266,14 @@ def execute_call(self, descr, *args): return self.cpu.call(args[0], descr, args[1:]) + def execute_getfield_gc(self, descr, p): + p = lltype.cast_opaque_ptr(lltype.Ptr(descr.S), p) + return support.cast_result(descr.FIELD, getattr(p, descr.fieldname)) + + def execute_setfield_gc(self, descr, p, newvalue): + p = lltype.cast_opaque_ptr(lltype.Ptr(descr.S), p) + setattr(p, descr.fieldname, support.cast_arg(descr.FIELD, newvalue)) + def _setup(): def _make_impl_from_blackhole_interp(opname): from pypy.jit.metainterp.blackhole import BlackholeInterpreter diff --git a/pypy/jit/backend/llgraph/support.py b/pypy/jit/backend/llgraph/support.py --- a/pypy/jit/backend/llgraph/support.py +++ b/pypy/jit/backend/llgraph/support.py @@ -75,6 +75,19 @@ x = heaptracker.adr2int(x) return lltype.cast_primitive(TYPE, x) +def cast_from_ptr(TYPE, x): + return lltype.cast_opaque_ptr(TYPE, x) + +def cast_arg(TP, x): + kind = getkind(TP) + if kind == 'int': + return cast_from_int(TP, x) + elif kind == 'ref': + return cast_from_ptr(TP, x) + else: + assert kind == 'float' + return cast_from_floatstorage(TP, x) + def cast_call_args(ARGS, args_i, args_r, args_f, args_in_order=None): argsiter_i = iter(args_i or []) argsiter_r = iter(args_r or []) @@ -91,7 +104,7 @@ n = orderiter.next() assert n == 'r' x = argsiter_r.next() - x = lltype.cast_opaque_ptr(TYPE, x) + x = cast_from_ptr(TYPE, x) elif TYPE is lltype.Float or longlong.is_longlong(TYPE): if args_in_order is not None: n = orderiter.next() From noreply at buildbot.pypy.org Wed Oct 17 09:53:11 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 17 Oct 2012 09:53:11 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: add an abstract Message-ID: <20121017075311.1C7021C0FB8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4865:a56d8976330b Date: 2012-10-17 09:49 +0200 http://bitbucket.org/pypy/extradoc/changeset/a56d8976330b/ Log: add an abstract diff --git a/talk/rupy2012/abstract.rst b/talk/rupy2012/abstract.rst new file mode 100644 --- /dev/null +++ b/talk/rupy2012/abstract.rst @@ -0,0 +1,13 @@ +In this talk I would like to present the dominant implementation of Python +(CPython) performance characteristics and explain why, in case the performance +is an issue for your application, it's characteristics are bad for +abstractions. + +In the next part I'll explain the mission statement of the PyPy Python +implementation, brief description of it's performance characteristics and +where the project is going. I'll also explain the basics of Just in Time +compilation and what it changes on the observed performance. +In summary, the goal is to explain how +"if you want performance, don't write things in Python" is a bad attitude +and how we're trying to battle it with a high performance Python +virtual machine. From noreply at buildbot.pypy.org Wed Oct 17 09:53:12 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 17 Oct 2012 09:53:12 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: merge Message-ID: <20121017075312.6B8C71C0FB8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4866:85b726d79ae2 Date: 2012-10-17 09:51 +0200 http://bitbucket.org/pypy/extradoc/changeset/85b726d79ae2/ Log: merge diff --git a/talk/dls2012/benchmarks/image/sobel.py b/talk/dls2012/benchmarks/image/sobel.py --- a/talk/dls2012/benchmarks/image/sobel.py +++ b/talk/dls2012/benchmarks/image/sobel.py @@ -27,7 +27,7 @@ -1.0 * img[p + (-1, 1)] + 1.0 * img[p + (1, 1)] dy = -1.0*img[p + (-1,-1)] -2.0*img[p + (0,-1)] -1.0*img[p + (1,-1)] + \ 1.0*img[p + (-1, 1)] +2.0*img[p + (0, 1)] +1.0*img[p + (1, 1)] - res[p] = sqrt(dx*dx + dy*dy) / 4.0 + res[p] = sqrt(dx*dx + dy*dy) / 1.5 return res def uint8(img): diff --git a/talk/rupy2012/abstract.rst b/talk/rupy2012/abstract.rst --- a/talk/rupy2012/abstract.rst +++ b/talk/rupy2012/abstract.rst @@ -1,10 +1,10 @@ In this talk I would like to present the dominant implementation of Python (CPython) performance characteristics and explain why, in case the performance -is an issue for your application, it's characteristics are bad for +is an issue for your application, its characteristics are bad for abstractions. In the next part I'll explain the mission statement of the PyPy Python -implementation, brief description of it's performance characteristics and +implementation, brief description of its performance characteristics and where the project is going. I'll also explain the basics of Just in Time compilation and what it changes on the observed performance. In summary, the goal is to explain how From noreply at buildbot.pypy.org Wed Oct 17 09:53:13 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 17 Oct 2012 09:53:13 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Ups Message-ID: <20121017075313.89F7A1C0FB8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4867:8b79fd6c918d Date: 2012-10-17 09:52 +0200 http://bitbucket.org/pypy/extradoc/changeset/8b79fd6c918d/ Log: Ups diff --git a/talk/dls2012/benchmarks/image/sobel.py b/talk/dls2012/benchmarks/image/sobel.py --- a/talk/dls2012/benchmarks/image/sobel.py +++ b/talk/dls2012/benchmarks/image/sobel.py @@ -27,7 +27,7 @@ -1.0 * img[p + (-1, 1)] + 1.0 * img[p + (1, 1)] dy = -1.0*img[p + (-1,-1)] -2.0*img[p + (0,-1)] -1.0*img[p + (1,-1)] + \ 1.0*img[p + (-1, 1)] +2.0*img[p + (0, 1)] +1.0*img[p + (1, 1)] - res[p] = sqrt(dx*dx + dy*dy) / 1.5 + res[p] = sqrt(dx*dx + dy*dy) / 4.0 return res def uint8(img): From noreply at buildbot.pypy.org Wed Oct 17 09:53:15 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 17 Oct 2012 09:53:15 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: merge Message-ID: <20121017075315.C80531C0FB8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4868:53b9c87e31e9 Date: 2012-10-17 09:52 +0200 http://bitbucket.org/pypy/extradoc/changeset/53b9c87e31e9/ Log: merge diff too long, truncating to 2000 out of 11558 lines diff --git a/blog/draft/py3k-status-update-6.rst b/blog/draft/py3k-status-update-6.rst --- a/blog/draft/py3k-status-update-6.rst +++ b/blog/draft/py3k-status-update-6.rst @@ -58,7 +58,7 @@ Finally, I would like to thank Amaury Forgeot d'Arc and Ariel Ben-Yehuda for their work on the branch; among other things, Amaury recently worked on ``cpyext`` and on the PyPy ``_cffi_backend``, while Ariel submitted a patch to -implement `PEP 3138`. +implement `PEP 3138`_. .. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html .. _`py3k proposal`: http://pypy.org/py3donate.html diff --git a/planning/2.0/todo.txt b/planning/2.0/todo.txt new file mode 100644 --- /dev/null +++ b/planning/2.0/todo.txt @@ -0,0 +1,10 @@ +Things to do +============ + +* Fix ctypes performnace for 2.0 beta +* result-in-resop (maybe) +* NumPy speed for 2.0 final +* cffi on pypy on windows +* raw malloc virtuals +* bug tracker gardening +* all green buildbots diff --git a/planning/todo.txt b/planning/todo.txt deleted file mode 100644 --- a/planning/todo.txt +++ /dev/null @@ -1,13 +0,0 @@ -PyPy todo areas -================== - -This is a todo list that lists various areas of PyPy that should be cleaned up -(for whatever reason: less mess, less code duplication, etc). - -translation toolchain ---------------------- - - - clean up the tangle of including headers in the C backend - - make approach for loading modules more sane, mixedmodule capture - too many platform dependencies especially for pypy-cli - diff --git a/talk/dls2012/presentation/talk.tex b/talk/dls2012/presentation/talk.tex new file mode 100644 --- /dev/null +++ b/talk/dls2012/presentation/talk.tex @@ -0,0 +1,144 @@ +\documentclass[utf8x]{beamer} + +% This file is a solution template for: + +% - Talk at a conference/colloquium. +% - Talk length is about 20min. +% - Style is ornate. + +\mode +{ + \usetheme{Warsaw} + % or ... + + %\setbeamercovered{transparent} + % or whatever (possibly just delete it) +} + + +\usepackage[english]{babel} +\usepackage{listings} +\usepackage{ulem} +\usepackage{color} +\usepackage{alltt} + +\usepackage[utf8x]{inputenc} + + +\newcommand\redsout[1]{{\color{red}\sout{\hbox{\color{black}{#1}}}}} + +% or whatever + +% Or whatever. Note that the encoding and the font should match. If T1 +% does not look nice, try deleting the line with the fontenc. + + +\title{Loop-Aware Optimizations in PyPy’s Tracing JIT} + +\author[Ardö, Bolz, Fijałkowski]{Håkan Ardö$^1$ \and \emph{Carl Friedrich Bolz}$^2$ \and Maciej Fijałkowski} +% - Give the names in the same order as the appear in the paper. +% - Use the \inst{?} command only if the authors have different +% affiliation. + +\institute[Lund, Düsseldorf]{ +$^1$Centre for Mathematical Sciences, Lund University \and +$^2$Heinrich-Heine-Universität Düsseldorf, STUPS Group, Germany +} + +\date{2012 DLS, 22nd of October, 2012} +% - Either use conference name or its abbreviation. +% - Not really informative to the audience, more for people (including +% yourself) who are reading the slides online + + +% If you have a file called "university-logo-filename.xxx", where xxx +% is a graphic format that can be processed by latex or pdflatex, +% resp., then you can add a logo as follows: + + + + +% Delete this, if you do not want the table of contents to pop up at +% the beginning of each subsection: +%\AtBeginSubsection[] +%{ +% \begin{frame} +% \frametitle{Outline} +% \tableofcontents[currentsection,currentsubsection] +% \end{frame} +%} + + +% If you wish to uncover everything in a step-wise fashion, uncomment +% the following command: + +%\beamerdefaultoverlayspecification{<+->} + + +\begin{document} + +\begin{frame} + \titlepage +\end{frame} + +\begin{frame} + \frametitle{Why do tracing JITs work?} + \begin{itemize} + \item They are good at selecting interesting and common code paths + \item both through user program and through the runtime + \item the latter is particularly important for dynamic languages + \pause + \item traces are trivial to optimize + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Optimizing traces} + \begin{itemize} + \item Traces trivial to optimize, because there's no control flow + \item most optimizations are one forward pass + \item optimizers are often like symbolic executors + \item can do optimizations that are untractable with full control flow + \item XXX example + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Problems with this approach} + \begin{itemize} + \item most traces actually are loops + \item naive foward passes ignore this bit of control flow optimization available + \item how to fix that without sacrifing simplicity? + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Idea for solution} + \begin{itemize} + \item idea first proposed and implemented in LuaJIT by Mike Pall + \item this talk presents the implementation of the same approach in RPython's tracing JIT + \end{itemize} + \pause + \begin{block}{Approach} + \begin{itemize} + \item do a pre-processing step on the traces + \item apply the unchanged forward-pass optimizations + \item do some post-processing + \item pre-processing is done in such a way that the normal optimizations become loop-aware + \item intuition: give the optimizations a second iteration of context to work with + \end{itemize} + \end{block} +\end{frame} + +\begin{frame} + \frametitle{Pre-processing the loops} + \begin{itemize} + \item pre-processing does loop unrolling + \item peels off one iteration of the loop, duplicating the trace + \item the optimizations optimize both iterations together + \item this yields loop-invariant code motion and related optimizations + \end{itemize} +\end{frame} + + +\end{document} diff --git a/talk/ep2012/jit/abstract.rst b/talk/pycon-uk-2012/abstract.rst copy from talk/ep2012/jit/abstract.rst copy to talk/pycon-uk-2012/abstract.rst diff --git a/talk/ep2012/jit/talk/Makefile b/talk/pycon-uk-2012/talk/Makefile copy from talk/ep2012/jit/talk/Makefile copy to talk/pycon-uk-2012/talk/Makefile diff --git a/talk/pycon-uk-2012/talk/author.latex b/talk/pycon-uk-2012/talk/author.latex new file mode 100644 --- /dev/null +++ b/talk/pycon-uk-2012/talk/author.latex @@ -0,0 +1,8 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[PyPy JIT under the hood]{PyPy JIT under the hood} +\author[antocuni] +{Antonio Cuni} + +\institute{PyCon UK 2012} +\date{September 28, 2012} diff --git a/talk/ep2012/jit/talk/beamerdefs.txt b/talk/pycon-uk-2012/talk/beamerdefs.txt copy from talk/ep2012/jit/talk/beamerdefs.txt copy to talk/pycon-uk-2012/talk/beamerdefs.txt diff --git a/talk/ep2012/jit/talk/diagrams/architecture.svg b/talk/pycon-uk-2012/talk/diagrams/architecture.svg copy from talk/ep2012/jit/talk/diagrams/architecture.svg copy to talk/pycon-uk-2012/talk/diagrams/architecture.svg diff --git a/talk/ep2012/jit/talk/diagrams/pypytrace.svg b/talk/pycon-uk-2012/talk/diagrams/pypytrace.svg copy from talk/ep2012/jit/talk/diagrams/pypytrace.svg copy to talk/pycon-uk-2012/talk/diagrams/pypytrace.svg diff --git a/talk/ep2012/jit/talk/diagrams/trace.svg b/talk/pycon-uk-2012/talk/diagrams/trace.svg copy from talk/ep2012/jit/talk/diagrams/trace.svg copy to talk/pycon-uk-2012/talk/diagrams/trace.svg diff --git a/talk/ep2012/jit/talk/diagrams/tracetree.svg b/talk/pycon-uk-2012/talk/diagrams/tracetree.svg copy from talk/ep2012/jit/talk/diagrams/tracetree.svg copy to talk/pycon-uk-2012/talk/diagrams/tracetree.svg diff --git a/talk/ep2012/jit/talk/diagrams/tracing-phases.svg b/talk/pycon-uk-2012/talk/diagrams/tracing-phases.svg copy from talk/ep2012/jit/talk/diagrams/tracing-phases.svg copy to talk/pycon-uk-2012/talk/diagrams/tracing-phases.svg diff --git a/talk/ep2012/jit/talk/stylesheet.latex b/talk/pycon-uk-2012/talk/stylesheet.latex copy from talk/ep2012/jit/talk/stylesheet.latex copy to talk/pycon-uk-2012/talk/stylesheet.latex diff --git a/talk/pycon-uk-2012/talk/talk.pdf.info b/talk/pycon-uk-2012/talk/talk.pdf.info new file mode 100644 --- /dev/null +++ b/talk/pycon-uk-2012/talk/talk.pdf.info @@ -0,0 +1,11 @@ +AvailableTransitions=[Crossfade] +TransitionDuration = 100 +EstimatedDuration = 60*60 # in seconds +MinutesOnly = True + +PageProps = { + 1: { + 'reset': FirstTimeOnly, + 'progress': False, + }, +} diff --git a/talk/pycon-uk-2012/talk/talk.rst b/talk/pycon-uk-2012/talk/talk.rst new file mode 100644 --- /dev/null +++ b/talk/pycon-uk-2012/talk/talk.rst @@ -0,0 +1,587 @@ +.. include:: beamerdefs.txt + +================================ +PyPy JIT under the hood +================================ + +About me +--------- + +- PyPy core dev + +- PyPy py3k tech leader + +- ``pdb++``, ``fancycompleter``, ... + +- Consultant, trainer + +- You can hire me :-) + +- http://antocuni.eu + + +About this talk +---------------- + +* What is PyPy? (in 30 seconds) + +* Overview of tracing JITs + +* The PyPy JIT generator + + +Part 0: What is PyPy? +---------------------- + +* RPython toolchain + + - subset of Python + + - ideal for writing VMs + + - JIT & GC for free + +* Python interpreter + + - written in RPython + +* Whatever (dynamic) language you want + + - smalltalk, prolog, javascript, ... + + +Part 1 +------ + +**Overview of tracing JITs** + +Compilers +--------- + +* When? + + - Batch or Ahead Of Time + + - Just In Time + +|pause| + +* How? + + - Static + + - Dynamic or Adaptive + +|pause| + +* What? + + - Method-based compiler + + - Tracing compiler + +|pause| + +* PyPy: JIT, Dynamic, Tracing + + +Assumptions +----------- + +* Pareto Principle (80-20 rule) + + - the 20% of the program accounts for the 80% of the runtime + + - **hot-spots** + +* Fast Path principle + + - optimize only what is necessary + + - fall back for uncommon cases + +|pause| + +* Most of runtime spent in **loops** + +* Always the same code paths (likely) + + +Tracing JIT +----------- + +* Interpret the program as usual + +* Detect **hot** loops + +* Tracing phase + + - **linear** trace + +* Compiling + +* Execute + + - guards to ensure correctness + +* Profit :-) + + +Tracing JIT phases +------------------- + +.. animage:: diagrams/tracing-phases-p*.pdf + :align: center + :scale: 100% + + +Tracing Example (1) +-------------------- + +.. we use java instead of RPython to avoid confusion with applevel Python + + +|scriptsize| +|example<| |small| java |end_small| |>| + +.. sourcecode:: java + + interface Operation { + int DoSomething(int x); + } + class IncrOrDecr implements Operation { + public int DoSomething(int x) { + if (x < 0) return x-1; + else return x+1; + } + } + class tracing { + public static void main(String argv[]) { + int N = 100; + int i = 0; + Operation op = new IncrOrDecr(); + while (i < N) { + i = op.DoSomething(i); + } + System.out.println(i); + } + } + +|end_example| +|end_scriptsize| + + +Tracing Example (2) +-------------------- + +|scriptsize| +|column1| +|example<| |small| Java bytecode |end_small| |>| + +.. sourcecode:: java + + class IncrOrDecr { + ... + public DoSomething(I)I + ILOAD 1 + IFGE LABEL_0 + ILOAD 1 + ICONST_1 + ISUB + IRETURN + LABEL_0 + ILOAD 1 + ICONST_1 + IADD + IRETURN + } + +|end_example| + +|pause| + +|column2| +|example<| |small| Java bytecode |end_small| |>| + +.. sourcecode:: java + + class tracing { + ... + public static main( + [Ljava/lang/String;)V + ... + LABEL_0 + ILOAD 2 + ILOAD 1 + IF_ICMPGE LABEL_1 + ALOAD 3 + ILOAD 2 + INVOKEINTERFACE + Operation.DoSomething (I)I + ISTORE 2 + GOTO LABEL_0 + LABEL_1 + ... + } + +|end_example| +|end_columns| +|end_scriptsize| + + +Tracing example (3) +------------------- + +.. animage:: diagrams/trace-p*.pdf + :align: center + :scale: 80% + + +Trace trees (1) +--------------- + +|scriptsize| +|example<| |small| tracetree.java |end_small| |>| + +.. sourcecode:: java + + public static void trace_trees() { + int a = 0; + int i = 0; + int N = 100; + + while(i < N) { + if (i%2 == 0) + a++; + else + a*=2; + i++; + } + } + +|end_example| +|end_scriptsize| + +Trace trees (2) +--------------- + +.. animage:: diagrams/tracetree-p*.pdf + :align: center + :scale: 34% + + +Part 2 +------ + +**The PyPy JIT generator** + +General architecture +--------------------- + +.. animage:: diagrams/architecture-p*.pdf + :align: center + :scale: 24% + + +PyPy trace example +------------------- + +.. animage:: diagrams/pypytrace-p*.pdf + :align: center + :scale: 40% + + +PyPy optimizer +--------------- + +- intbounds + +- constant folding / pure operations + +- virtuals + +- string optimizations + +- heap (multiple get/setfield, etc) + +- ffi + +- unroll + + +Intbound optimization (1) +------------------------- + +|example<| |small| intbound.py |end_small| |>| + +.. sourcecode:: python + + def fn(): + i = 0 + while i < 5000: + i += 2 + return i + +|end_example| + +Intbound optimization (2) +-------------------------- + +|scriptsize| +|column1| +|example<| |small| unoptimized |end_small| |>| + +.. sourcecode:: python + + ... + i17 = int_lt(i15, 5000) + guard_true(i17) + i19 = int_add_ovf(i15, 2) + guard_no_overflow() + ... + +|end_example| + +|pause| + +|column2| +|example<| |small| optimized |end_small| |>| + +.. sourcecode:: python + + ... + i17 = int_lt(i15, 5000) + guard_true(i17) + i19 = int_add(i15, 2) + ... + +|end_example| +|end_columns| +|end_scriptsize| + +|pause| + +* It works **often** + +* array bound checking + +* intbound info propagates all over the trace + + +Virtuals (1) +------------- + +|example<| |small| virtuals.py |end_small| |>| + +.. sourcecode:: python + + def fn(): + i = 0 + while i < 5000: + i += 2 + return i + +|end_example| + + +Virtuals (2) +------------ + +|scriptsize| +|column1| +|example<| |small| unoptimized |end_small| |>| + +.. sourcecode:: python + + ... + guard_class(p0, W_IntObject) + i1 = getfield_pure(p0, 'intval') + i2 = int_add(i1, 2) + p3 = new(W_IntObject) + setfield_gc(p3, i2, 'intval') + ... + +|end_example| + +|pause| + +|column2| +|example<| |small| optimized |end_small| |>| + +.. sourcecode:: python + + ... + i2 = int_add(i1, 2) + ... + +|end_example| +|end_columns| +|end_scriptsize| + +|pause| + +* The most important optimization (TM) + +* It works both inside the trace and across the loop + +* It works for tons of cases + + - e.g. function frames + + +Constant folding (1) +--------------------- + +|example<| |small| constfold.py |end_small| |>| + +.. sourcecode:: python + + def fn(): + i = 0 + while i < 5000: + i += 2 + return i + +|end_example| + + +Constant folding (2) +-------------------- + +|scriptsize| +|column1| +|example<| |small| unoptimized |end_small| |>| + +.. sourcecode:: python + + ... + i1 = getfield_pure(p0, 'intval') + i2 = getfield_pure(, + 'intval') + i3 = int_add(i1, i2) + ... + +|end_example| + +|pause| + +|column2| +|example<| |small| optimized |end_small| |>| + +.. sourcecode:: python + + ... + i1 = getfield_pure(p0, 'intval') + i3 = int_add(i1, 2) + ... + +|end_example| +|end_columns| +|end_scriptsize| + +|pause| + +* It "finishes the job" + +* Works well together with other optimizations (e.g. virtuals) + +* It also does "normal, boring, static" constant-folding + + +Out of line guards (1) +----------------------- + +|example<| |small| outoflineguards.py |end_small| |>| + +.. sourcecode:: python + + N = 2 + def fn(): + i = 0 + while i < 5000: + i += N + return i + +|end_example| + + +Out of line guards (2) +---------------------- + +|scriptsize| +|column1| +|example<| |small| unoptimized |end_small| |>| + +.. sourcecode:: python + + ... + quasiimmut_field(, 'val') + guard_not_invalidated() + p0 = getfield_gc(, 'val') + ... + i2 = getfield_pure(p0, 'intval') + i3 = int_add(i1, i2) + +|end_example| + +|pause| + +|column2| +|example<| |small| optimized |end_small| |>| + +.. sourcecode:: python + + ... + guard_not_invalidated() + ... + i3 = int_add(i1, 2) + ... + +|end_example| +|end_columns| +|end_scriptsize| + +|pause| + +* Python is too dynamic, but we don't care :-) + +* No overhead in assembler code + +* Used a bit "everywhere" + +* Credits to Mark Shannon + + - for the name :-) + +Guards +------- + +- guard_true + +- guard_false + +- guard_class + +- guard_no_overflow + +- **guard_value** + +Promotion +--------- + +- guard_value + +- specialize code + +- make sure not to **overspecialize** + +- example: type of objects + +- example: function code objects, ... + +Conclusion +----------- + +- PyPy is cool :-) + +- Any question? diff --git a/talk/ep2012/jit/talk/title.latex b/talk/pycon-uk-2012/talk/title.latex copy from talk/ep2012/jit/talk/title.latex copy to talk/pycon-uk-2012/talk/title.latex diff --git a/talk/googlezurich2012/Makefile b/talk/pyconza2012/stm-talk/Makefile copy from talk/googlezurich2012/Makefile copy to talk/pyconza2012/stm-talk/Makefile diff --git a/talk/pyconza2012/stm-talk/author.latex b/talk/pyconza2012/stm-talk/author.latex new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stm-talk/author.latex @@ -0,0 +1,8 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[PyPy in Production]{PyPy} +\author[Armin Rigo] +{Armin Rigo} + +\institute{PyCon ZA 2012} +\date{October 4, 2012} diff --git a/talk/googlezurich2012/beamerdefs.txt b/talk/pyconza2012/stm-talk/beamerdefs.txt copy from talk/googlezurich2012/beamerdefs.txt copy to talk/pyconza2012/stm-talk/beamerdefs.txt --- a/talk/googlezurich2012/beamerdefs.txt +++ b/talk/pyconza2012/stm-talk/beamerdefs.txt @@ -89,7 +89,7 @@ -.. |snake| image:: ../img/py-web-new.png +.. |snake| image:: ../../img/py-web-new.png :scale: 15% diff --git a/talk/pyconza2012/stm-talk/demo1.py b/talk/pyconza2012/stm-talk/demo1.py new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stm-talk/demo1.py @@ -0,0 +1,19 @@ + +class Number(object): + + def __init__(self, num): + self.num = num + + def __add__(self, other): + return Number(self.num + other.num) + + def __invert__(self): + return Number(~self.num) + +def foo(n): + total = Number(0) + for i in range(n): + total += Number(i) + total += ~ Number(i) + return total.num + diff --git a/talk/googlezurich2012/standards.png b/talk/pyconza2012/stm-talk/standards.png copy from talk/googlezurich2012/standards.png copy to talk/pyconza2012/stm-talk/standards.png diff --git a/talk/googlezurich2012/stylesheet.latex b/talk/pyconza2012/stm-talk/stylesheet.latex copy from talk/googlezurich2012/stylesheet.latex copy to talk/pyconza2012/stm-talk/stylesheet.latex diff --git a/talk/pyconza2012/stm-talk/talk.rst b/talk/pyconza2012/stm-talk/talk.rst new file mode 100644 --- /dev/null +++ b/talk/pyconza2012/stm-talk/talk.rst @@ -0,0 +1,205 @@ +.. include:: beamerdefs.txt + +============================================================ +PyPy +============================================================ + + +PyPy is... +-------------------------- + +* Another Python interpreter + +* with a JIT compiler + + +PyPy was... +------------------- + +* Around since 2003 + +* (advertised as) production ready since December 2010 + + - release 1.4 + +* Funding + + - EU FP6 programme + + - Eurostars programme + + - donations + + - ... + + +PyPy 1.9: current status +------------------------ + +* Faster + + - **1.7x** than 1.5 (Summer 2011) + + - **2.2x** than 1.4 (December 2010) + + - **5.5x** than CPython + +* Implements Python 2.7.3 + +* Many more "PyPy-friendly" programs than before + +* Packaging + + - |scriptsize| Debian, Ubuntu, Fedora, Homebrew, Gentoo, ArchLinux, ... |end_scriptsize| + + - |scriptsize| Windows (32bit only), OS X |end_scriptsize| + +* C extension compatibility + + - runs (big part of) **PyOpenSSL** and **lxml** + + +PyPy organization +----------------- + +* Part of SFC -- Software Freedom Conservancy + + - Bradley successfully fighting U.S. bureaucracy + + - we are happy about it + + +* Funding model + + - py3k, numpy, STM + + - more than 100'000$ in donations + + - from individuals, large companies and the PSF + + +PyPy's JIT compiler +------------------- + +* Removes abstraction + +* Almost never gives up + +* x86-32, x86-64, ARMv7, (POWER64) + +* (Works with other languages) + + +Real world applications +----------------------- + +* Positive feedback + +* http://speed.pypy.org/ + + + +py3k +------------------------ + +* ``py3k`` branch in mercurial + + - developed in parallel + + - Python 3 written in Python 2 + +* Focus on correctness + +* Dropped some interpreter optimizations for now + +* First 90% done, remaining 90% not done + +* Majority of the funds by Google + + +NumPy +----- + +* progress going slowly + +* multi dimensional arrays, broadcasting, fancy indexing + +* all dtypes, except complex, strings and objects + +* good results for performance + + +STM +--------------------------- + +* Software Transactional Memory + +* "Remove the GIL" + +* But also, new models (better than threads) + + + +Calling C +--------- + +.. image:: standards.png + :scale: 60% + :align: center + +Calling C landscape +------------------- + +* CPython C extensions + +* SWIG, SIP, wrapper generators + +* ctypes + +* Cython + +* CFFI (our new thing) + +CFFI +---------- + +|scriptsize| +|example<| Example |>| + + .. sourcecode:: pycon + + >>> from cffi import FFI + >>> ffi = FFI() + >>> ffi.cdef(""" + ... int printf(const char *format, ...); + ... """) + >>> C = ffi.dlopen(None) + >>> arg = ffi.new("char[]", "world") + >>> C.printf("hi there, %s!\n", arg) + hi there, world! + +|end_example| +|end_scriptsize| + +CFFI +---- + +* Many more examples + +* Including macro calls and most subtleties of C + +* http://cffi.readthedocs.org + + +STM +--- + + +Conclusion +---------- + +* Try out PyPy on real code + +* http://pypy.org/ + +* Thank you! diff --git a/talk/googlezurich2012/title.latex b/talk/pyconza2012/stm-talk/title.latex copy from talk/googlezurich2012/title.latex copy to talk/pyconza2012/stm-talk/title.latex --- a/talk/googlezurich2012/title.latex +++ b/talk/pyconza2012/stm-talk/title.latex @@ -1,5 +1,5 @@ \begin{titlepage} \begin{figure}[h] -\includegraphics[width=60px]{../img/py-web-new.png} +\includegraphics[width=60px]{../../img/py-web-new.png} \end{figure} \end{titlepage} diff --git a/talk/vmil2012/Makefile b/talk/vmil2012/Makefile --- a/talk/vmil2012/Makefile +++ b/talk/vmil2012/Makefile @@ -42,6 +42,9 @@ logs:: tool/run_benchmarks.sh +slides: + $(MAKE) -C presentation + clean: rm -f *.aux *.bbl *.blg *.log *.tdo rm -f *.pdf diff --git a/talk/vmil2012/presentation/Makefile b/talk/vmil2012/presentation/Makefile new file mode 100644 --- /dev/null +++ b/talk/vmil2012/presentation/Makefile @@ -0,0 +1,16 @@ +talk.pdf: talk.tex figures/data.tex figures/go_data.tex tool/data.py + pdflatex talk.tex &> /dev/null + +UNAME := $(shell "uname") +view: talk.pdf +ifeq ($(UNAME), Linux) + evince talk.pdf & +endif +ifeq ($(UNAME), Darwin) + open talk.pdf & +endif + + +figures/go_data.tex: tool/data.py +figures/data.tex: tool/data.py + python tool/data.py diff --git a/talk/vmil2012/presentation/charts.ods b/talk/vmil2012/presentation/charts.ods new file mode 100644 index 0000000000000000000000000000000000000000..94300512c367f6ea2553953adde39281e950b27c GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/bridge_compiled.graffle b/talk/vmil2012/presentation/figures/bridge_compiled.graffle new file mode 100644 --- /dev/null +++ b/talk/vmil2012/presentation/figures/bridge_compiled.graffle @@ -0,0 +1,1457 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGrafflePro + 139.16.0.171715 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {1118, 783}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2012-07-24 10:50:56 +0000 + Creator + David Schneider + DisplayScale + 1.000 cm = 1.000 cm + GraphDocumentVersion + 8 + GraphicsList + + + Class + LineGraphic + Head + + ID + 16 + Info + 1 + + ID + 63 + Points + + {427, 250} + {328, 162} + {188, 113} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 36 + + + + Class + LineGraphic + Head + + ID + 16 + Info + 1 + + ID + 62 + Points + + {188, 250} + {206, 184} + {188, 113} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 27 + + + + Class + LineGraphic + Head + + ID + 42 + + ID + 61 + Points + + {83, 205} + {42, 264.875} + {83, 334.75} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 24 + + + + Class + Group + Graphics + + + Bounds + {{232.00001379686913, 294.74999999999989}, {150.99998620313085, 93.5}} + Class + ShapedGraphic + ID + 59 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs20 \cf0 read backend map\ +decode resume data\ +retrieve stack and register values\ +...\ +return to interpreter} + + + + Bounds + {{232, 261.25}, {151, 33.5}} + Class + ShapedGraphic + ID + 60 + Magnets + + {0, 1} + {0, -1} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 compensation code} + + + + ID + 58 + + + Class + LineGraphic + Head + + ID + 40 + + ID + 56 + Points + + {531, 333.75} + {555, 351} + {580.89735689328165, 373.74999618530273} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 44 + + + + Class + LineGraphic + Head + + ID + 41 + + ID + 55 + Points + + {531, 301.25} + {580, 278} + {580.415709839653, 277.88418648722006} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 43 + + + + Class + LineGraphic + Head + + ID + 39 + + ID + 54 + Points + + {82.536736108577472, 339.10023442863826} + {52, 351.5} + {34.428503435249759, 361.50264298468693} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 42 + Info + 2 + + + + Class + LineGraphic + Head + + ID + 38 + + ID + 53 + Points + + {83, 301.25} + {60, 286} + {33.993974985969523, 268.75} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 37 + + + + Class + LineGraphic + Head + + ID + 44 + + ID + 52 + Points + + {532, 205} + {566, 277} + {531, 333.75} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 34 + + + + Class + LineGraphic + Head + + ID + 43 + + ID + 51 + Points + + {532, 159} + {569, 211} + {531, 301.25} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 32 + + + + Class + LineGraphic + Head + + ID + 59 + + ID + 50 + Points + + {428, 301.25} + {404, 330} + {383, 341.49999999999989} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 43 + + + + Class + LineGraphic + Head + + ID + 59 + + ID + 49 + Points + + {479.5, 350.5} + {427, 385.25} + {383, 341.49999999999989} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 44 + Info + 1 + + + + Class + LineGraphic + Head + + ID + 59 + + ID + 48 + Points + + {134.5, 351.5} + {186, 384} + {232.0000137968691, 341.49999999999989} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 42 + + + + Class + LineGraphic + Head + + ID + 59 + + ID + 47 + Points + + {186, 301.25} + {211, 307} + {232.0000137968691, 341.49999999999989} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 37 + + + + Class + LineGraphic + Head + + ID + 37 + + ID + 45 + Points + + {83, 159} + {42, 222} + {83, 301.25} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 18 + + + + Bounds + {{428, 317}, {103, 33.5}} + Class + ShapedGraphic + ID + 44 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Trampoline #4} + + + + Bounds + {{428, 284.5}, {103, 33.5}} + Class + ShapedGraphic + ID + 43 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Trampoline #3} + + + + Bounds + {{83, 318}, {103, 33.5}} + Class + ShapedGraphic + ID + 42 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Trampoline #2} + + + + Bounds + {{575.00001069962946, 254.25000040105692}, {85, 47}} + Class + ShapedGraphic + ID + 41 + Magnets + + {1, 0} + {-1, 0} + + Shape + Cloud + Style + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 backend map #3} + + + + Bounds + {{575, 350.24999618530273}, {85, 47}} + Class + ShapedGraphic + ID + 40 + Magnets + + {1, 0} + {-1, 0} + + Shape + Cloud + Style + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 backend map #4} + + + + Bounds + {{-46, 338.25}, {85, 47}} + Class + ShapedGraphic + ID + 39 + Magnets + + {1, 0} + {-1, 0} + + Shape + Cloud + Style + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 backend map #2} + + + + Bounds + {{-46, 245.25}, {85, 47}} + Class + ShapedGraphic + ID + 38 + Magnets + + {1, 0} + {-1, 0} + + Shape + Cloud + Style + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 backend map #1} + + + + Bounds + {{83, 284.5}, {103, 33.5}} + Class + ShapedGraphic From noreply at buildbot.pypy.org Wed Oct 17 10:50:17 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 17 Oct 2012 10:50:17 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: pass dynamic call tests Message-ID: <20121017085017.899261C02D5@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58152:43443eb2153b Date: 2012-10-17 10:22 +0200 http://bitbucket.org/pypy/pypy/changeset/43443eb2153b/ Log: pass dynamic call tests diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -3,8 +3,7 @@ from pypy.jit.backend import model from pypy.jit.backend.llgraph import support -from pypy.jit.metainterp.history import Const, getkind, AbstractDescr, INT,\ - REF, FLOAT +from pypy.jit.metainterp.history import Const, getkind, AbstractDescr, VOID from pypy.jit.metainterp.resoperation import rop from pypy.rpython.llinterp import LLInterpreter @@ -124,15 +123,41 @@ return ffisupport.calldescr_dynamic_for_tests(self, atypes, rtype, abiname) + def calldescrof_dynamic(self, cif_description, extrainfo): + # XXX WTF, this is happy nonsense + from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind + from pypy.jit.backend.llsupport.ffisupport import UnsupportedKind + ARGS = [] + try: + for itp in range(cif_description.nargs): + arg = cif_description.atypes[itp] + kind = get_ffi_type_kind(self, arg) + if kind != VOID: + ARGS.append(support.kind2TYPE[kind[0]]) + RESULT = support.kind2TYPE[get_ffi_type_kind(self, cif_description.rtype)[0]] + except UnsupportedKind: + return None + key = ('call_dynamic', RESULT, tuple(ARGS), + extrainfo, cif_description.abi) + try: + return self.descrs[key] + except KeyError: + descr = CallDescr(RESULT, ARGS) + self.descrs[key] = descr + return descr + # ------------------------------------------------------------ def call(self, func, calldescr, args): + TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE + RESULT = TP.RESULT func = llmemory.cast_int_to_adr(func).ptr._obj._callable res = func(*args) - return support.cast_result(calldescr.RESULT, res) + return support.cast_result(RESULT, res) def do_call(self, func, calldescr, args_i, args_r, args_f): - args = support.cast_call_args(calldescr.ARGS, args_i, args_r, args_f) + TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE + args = support.cast_call_args(TP.ARGS, args_i, args_r, args_f) return self.call(func, calldescr, args) bh_call_i = do_call @@ -264,7 +289,8 @@ raise Jump(descr, args) def execute_call(self, descr, *args): - return self.cpu.call(args[0], descr, args[1:]) + call_args = support.cast_call_args_in_order(args[0], args[1:]) + return self.cpu.call(args[0], descr, call_args) def execute_getfield_gc(self, descr, p): p = lltype.cast_opaque_ptr(lltype.Ptr(descr.S), p) diff --git a/pypy/jit/backend/llgraph/support.py b/pypy/jit/backend/llgraph/support.py --- a/pypy/jit/backend/llgraph/support.py +++ b/pypy/jit/backend/llgraph/support.py @@ -9,6 +9,14 @@ IS_32_BIT = r_ulonglong is not r_uint +kind2TYPE = { + 'i': lltype.Signed, + 'f': lltype.Float, + 'L': lltype.SignedLongLong, + 'S': lltype.SingleFloat, + 'v': lltype.Void, + } + def cast_to_int(x): TP = lltype.typeOf(x) if isinstance(TP, lltype.Ptr): @@ -122,3 +130,17 @@ assert list(argsiter_r) == [] assert list(argsiter_f) == [] return args + +def cast_call_args_in_order(func, args): + ARGS = llmemory.cast_int_to_adr(func).ptr._obj._TYPE.ARGS + call_args = [] + for ARG, arg in zip(ARGS, args): + kind = getkind(ARG) + if kind == 'int': + n = cast_from_int(ARG, arg) + elif kind == 'ref': + n = cast_from_ptr(ARG, arg) + else: + n = cast_from_floatstorage(ARG, arg) + call_args.append(n) + return call_args From noreply at buildbot.pypy.org Wed Oct 17 10:50:18 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 17 Oct 2012 10:50:18 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal, arigo) array support Message-ID: <20121017085018.D0F9A1C02D5@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58153:b8a017f07707 Date: 2012-10-17 10:29 +0200 http://bitbucket.org/pypy/pypy/changeset/b8a017f07707/ Log: (fijal, arigo) array support diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -7,7 +7,7 @@ from pypy.jit.metainterp.resoperation import rop from pypy.rpython.llinterp import LLInterpreter -from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.lltypesystem import lltype, llmemory, rclass from pypy.rlib.rarithmetic import ovfcheck @@ -45,6 +45,12 @@ def is_pointer_field(self): return getkind(self.FIELD) == 'ref' +class ArrayDescr(AbstractDescr): + def __init__(self, A): + self.A = A + + def is_array_of_pointers(self): + return getkind(self.A.OF) == 'ref' class LLGraphCPU(model.AbstractCPU): def __init__(self, rtyper): @@ -116,6 +122,15 @@ self.descrs[key] = descr return descr + def arraydescrof(self, A): + key = ('array', A) + try: + return self.descrs[key] + except KeyError: + descr = ArrayDescr(A) + self.descrs[key] = descr + return descr + def _calldescr_dynamic_for_tests(self, atypes, rtype, abiname='FFI_DEFAULT_ABI'): # XXX WTF is that and why it breaks all abstractions? @@ -244,6 +259,30 @@ if arg: self.fail_guard(descr) + def execute_guard_value(self, descr, arg1, arg2): + if arg1 != arg2: + self.fail_guard(descr) + + def execute_guard_nonnull(self, descr, arg): + if not arg: + self.fail_guard(descr) + + def execute_guard_isnull(self, descr, arg): + if arg: + self.fail_guard(descr) + + def execute_guard_class(self, descr, arg, klass): + value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, arg) + expected_class = llmemory.cast_adr_to_ptr( + llmemory.cast_int_to_adr(klass), + rclass.CLASSTYPE) + if value.typeptr != expected_class: + self.fail_guard(descr) + + def execute_guard_nonnull_class(self, descr, arg, klass): + self.execute_guard_nonnull(descr, arg) + self.execute_guard_class(descr, arg, klass) + def execute_int_add_ovf(self, _, x, y): try: z = ovfcheck(x + y) @@ -300,6 +339,18 @@ p = lltype.cast_opaque_ptr(lltype.Ptr(descr.S), p) setattr(p, descr.fieldname, support.cast_arg(descr.FIELD, newvalue)) + def execute_arraylen_gc(self, descr, a): + array = a._obj.container + return array.getlength() + + def execute_setarrayitem_gc(self, descr, a, index, item): + array = a._obj.container + array.setitem(index, support.cast_arg(descr.A.OF, item)) + + def execute_getarrayitem_gc(self, descr, a, index): + array = a._obj.container + return support.cast_result(descr.A.OF, array.getitem(index)) + def _setup(): def _make_impl_from_blackhole_interp(opname): from pypy.jit.metainterp.blackhole import BlackholeInterpreter From noreply at buildbot.pypy.org Wed Oct 17 10:50:19 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 17 Oct 2012 10:50:19 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal, arigo) progress Message-ID: <20121017085019.F22881C02D5@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58154:716b88c56d65 Date: 2012-10-17 10:50 +0200 http://bitbucket.org/pypy/pypy/changeset/716b88c56d65/ Log: (fijal, arigo) progress diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -7,7 +7,7 @@ from pypy.jit.metainterp.resoperation import rop from pypy.rpython.llinterp import LLInterpreter -from pypy.rpython.lltypesystem import lltype, llmemory, rclass +from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr from pypy.rlib.rarithmetic import ovfcheck @@ -52,6 +52,12 @@ def is_array_of_pointers(self): return getkind(self.A.OF) == 'ref' +class InteriorFieldDescr(AbstractDescr): + def __init__(self, A, fieldname): + self.A = A + self.fieldname = fieldname + self.FIELD = getattr(A.OF, fieldname) + class LLGraphCPU(model.AbstractCPU): def __init__(self, rtyper): self.rtyper = rtyper @@ -131,6 +137,15 @@ self.descrs[key] = descr return descr + def interiorfielddescrof(self, A, fieldname): + key = ('interiorfield', A, fieldname) + try: + return self.descrs[key] + except KeyError: + descr = InteriorFieldDescr(A, fieldname) + self.descrs[key] = descr + return descr + def _calldescr_dynamic_for_tests(self, atypes, rtype, abiname='FFI_DEFAULT_ABI'): # XXX WTF is that and why it breaks all abstractions? @@ -170,12 +185,36 @@ res = func(*args) return support.cast_result(RESULT, res) - def do_call(self, func, calldescr, args_i, args_r, args_f): + def _do_call(self, func, calldescr, args_i, args_r, args_f): TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE args = support.cast_call_args(TP.ARGS, args_i, args_r, args_f) return self.call(func, calldescr, args) - bh_call_i = do_call + bh_call_i = _do_call + + def do_getinteriorfield_gc(self, a, index, descr): + array = a._obj.container + return support.cast_result(descr.FIELD, + getattr(array.getitem(index), descr.fieldname)) + + bh_getinteriorfield_gc_f = do_getinteriorfield_gc + bh_getinteriorfield_gc_i = do_getinteriorfield_gc + bh_getinteriorfield_gc_r = do_getinteriorfield_gc + + def do_setinteriorfield_gc(self, a, index, item, descr): + array = a._obj.container + setattr(array.getitem(index), descr.fieldname, + support.cast_arg(descr.FIELD, item)) + + bh_setinteriorfield_gc_f = do_setinteriorfield_gc + bh_setinteriorfield_gc_r = do_setinteriorfield_gc + bh_setinteriorfield_gc_i = do_setinteriorfield_gc + + def do_newunicode(self, length): + return lltype.cast_opaque_ptr(llmemory.GCREF, + lltype.malloc(rstr.UNICODE, length)) + + bh_newunicode = do_newunicode class LLFrame(object): def __init__(self, cpu, argboxes, args): @@ -351,6 +390,29 @@ array = a._obj.container return support.cast_result(descr.A.OF, array.getitem(index)) + def execute_strlen(self, descr, s): + return s._obj.container.chars.getlength() + + def execute_strgetitem(self, descr, s, item): + return ord(s._obj.container.chars.getitem(item)) + + def execute_strsetitem(self, descr, s, item, v): + s._obj.container.chars.setitem(item, chr(v)) + + def execute_copystrcontent(self, _, src, dst, srcstart, dststart, length): + src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), src) + dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), dst) + assert 0 <= srcstart <= srcstart + length <= len(src.chars) + assert 0 <= dststart <= dststart + length <= len(dst.chars) + rstr.copy_string_contents(src, dst, srcstart, dststart, length) + + def execute_copyunicodecontent(self, _, src, dst, srcstart, dststart, length): + src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), src) + dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst) + assert 0 <= srcstart <= srcstart + length <= len(src.chars) + assert 0 <= dststart <= dststart + length <= len(dst.chars) + rstr.copy_unicode_contents(src, dst, srcstart, dststart, length) + def _setup(): def _make_impl_from_blackhole_interp(opname): from pypy.jit.metainterp.blackhole import BlackholeInterpreter @@ -370,11 +432,20 @@ _op_default_implementation.func_name = 'execute_' + opname return _op_default_implementation + def _new_execute(opname): + def execute(self, descr, *args): + new_args = args + (descr,) + return getattr(self.cpu, 'do_' + opname)(*new_args) + execute.func_name = 'execute_' + opname + return execute + for k, v in rop.__dict__.iteritems(): if not k.startswith("_"): func = _make_impl_from_blackhole_interp(k) fname = 'execute_' + k.lower() if func is not None and not hasattr(LLFrame, fname): setattr(LLFrame, fname, func) + elif hasattr(LLGraphCPU, 'do_' + k.lower()): + setattr(LLFrame, fname, _new_execute(k.lower())) _setup() diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -1002,7 +1002,7 @@ 'void', descr=kdescr) f = self.cpu.bh_getinteriorfield_gc_f(a_box.getref_base(), 3, kdescr) assert longlong.getrealfloat(f) == 1.5 - self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, kdescr, longlong.getfloatstorage(2.5)) + self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, longlong.getfloatstorage(2.5), kdescr) r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], 'float', descr=kdescr) assert r.getfloat() == 2.5 @@ -1028,7 +1028,7 @@ for name, TYPE in NUMBER_FIELDS[::-1]: vdescr = self.cpu.interiorfielddescrof(A, name) self.cpu.bh_setinteriorfield_gc_i(a_box.getref_base(), 3, - vdescr, -25) + -25, vdescr) for name, TYPE in NUMBER_FIELDS: vdescr = self.cpu.interiorfielddescrof(A, name) r = self.execute_operation(rop.GETINTERIORFIELD_GC, @@ -1041,8 +1041,8 @@ 'void', descr=pdescr) r = self.cpu.bh_getinteriorfield_gc_r(a_box.getref_base(), 4, pdescr) assert r == s_box.getref_base() - self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, pdescr, - s_box.getref_base()) + self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, + s_box.getref_base(), pdescr) r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], 'ref', descr=pdescr) assert r.getref_base() == s_box.getref_base() diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -1208,13 +1208,13 @@ @arguments("cpu", "r", "i", "i", "d") def bhimpl_setinteriorfield_gc_i(cpu, array, index, value, descr): - cpu.bh_setinteriorfield_gc_i(array, index, descr, value) + cpu.bh_setinteriorfield_gc_i(array, index, value, descr) @arguments("cpu", "r", "i", "r", "d") def bhimpl_setinteriorfield_gc_r(cpu, array, index, value, descr): - cpu.bh_setinteriorfield_gc_r(array, index, descr, value) + cpu.bh_setinteriorfield_gc_r(array, index, value, descr) @arguments("cpu", "r", "i", "f", "d") def bhimpl_setinteriorfield_gc_f(cpu, array, index, value, descr): - cpu.bh_setinteriorfield_gc_f(array, index, descr, value) + cpu.bh_setinteriorfield_gc_f(array, index, value, descr) @arguments("cpu", "r", "d", returns="i") def bhimpl_getfield_gc_i(cpu, struct, fielddescr): From noreply at buildbot.pypy.org Wed Oct 17 11:27:17 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 11:27:17 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: work in progress, notably changing the argument order of bh_*() to Message-ID: <20121017092717.3330E1C02D5@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58155:1379a0ac0c19 Date: 2012-10-17 11:26 +0200 http://bitbucket.org/pypy/pypy/changeset/1379a0ac0c19/ Log: work in progress, notably changing the argument order of bh_*() to always pass the descr last. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -5,6 +5,7 @@ from pypy.jit.backend.llgraph import support from pypy.jit.metainterp.history import Const, getkind, AbstractDescr, VOID from pypy.jit.metainterp.resoperation import rop +from pypy.jit.codewriter import heaptracker from pypy.rpython.llinterp import LLInterpreter from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr @@ -22,9 +23,9 @@ self.descr = descr class ExecutionFinished(Exception): - def __init__(self, descr, arg): + def __init__(self, descr, args): self.descr = descr - self.arg = arg + self.args = args class Jump(Exception): def __init__(self, descr, args): @@ -36,6 +37,12 @@ self.RESULT = RESULT self.ARGS = ARGS +class SizeDescr(AbstractDescr): + def __init__(self, S): + self.S = S + def as_vtable_size_descr(self): + return self + class FieldDescr(AbstractDescr): def __init__(self, S, fieldname): self.S = S @@ -88,7 +95,7 @@ frame.execute(loop.operations) assert False except ExecutionFinished, e: - self.latest_values = [e.arg] + self.latest_values = e.args return e.descr except GuardFailed, e: self.latest_values = e.failargs @@ -119,6 +126,15 @@ self.descrs[key] = descr return descr + def sizeof(self, S): + key = ('size', S) + try: + return self.descrs[key] + except KeyError: + descr = SizeDescr(S) + self.descrs[key] = descr + return descr + def fielddescrof(self, S, fieldname): key = ('field', S, fieldname) try: @@ -185,36 +201,109 @@ res = func(*args) return support.cast_result(RESULT, res) - def _do_call(self, func, calldescr, args_i, args_r, args_f): + def _do_call(self, func, args_i, args_r, args_f, calldescr): TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE args = support.cast_call_args(TP.ARGS, args_i, args_r, args_f) return self.call(func, calldescr, args) bh_call_i = _do_call + bh_call_r = _do_call + bh_call_f = _do_call + bh_call_v = _do_call - def do_getinteriorfield_gc(self, a, index, descr): + def bh_getfield_gc(self, p, descr): + p = lltype.cast_opaque_ptr(lltype.Ptr(descr.S), p) + return support.cast_result(descr.FIELD, getattr(p, descr.fieldname)) + + bh_getfield_gc_i = bh_getfield_gc + bh_getfield_gc_r = bh_getfield_gc + bh_getfield_gc_f = bh_getfield_gc + + def bh_setfield_gc(self, p, newvalue, descr): + p = lltype.cast_opaque_ptr(lltype.Ptr(descr.S), p) + setattr(p, descr.fieldname, support.cast_arg(descr.FIELD, newvalue)) + + bh_setfield_gc_i = bh_setfield_gc + bh_setfield_gc_r = bh_setfield_gc + bh_setfield_gc_f = bh_setfield_gc + + def bh_arraylen_gc(self, a, descr): + array = a._obj.container + return array.getlength() + + def bh_setarrayitem_gc(self, a, index, item, descr): + array = a._obj.container + array.setitem(index, support.cast_arg(descr.A.OF, item)) + + def bh_getarrayitem_gc(self, a, index, descr): + array = a._obj.container + return support.cast_result(descr.A.OF, array.getitem(index)) + + def bh_strlen(self, s): + return s._obj.container.chars.getlength() + + def bh_strgetitem(self, s, item): + return ord(s._obj.container.chars.getitem(item)) + + def bh_strsetitem(self, s, item, v): + s._obj.container.chars.setitem(item, chr(v)) + + def bh_copystrcontent(self, src, dst, srcstart, dststart, length): + src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), src) + dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), dst) + assert 0 <= srcstart <= srcstart + length <= len(src.chars) + assert 0 <= dststart <= dststart + length <= len(dst.chars) + rstr.copy_string_contents(src, dst, srcstart, dststart, length) + + def bh_copyunicodecontent(self, src, dst, srcstart, dststart, length): + src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), src) + dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst) + assert 0 <= srcstart <= srcstart + length <= len(src.chars) + assert 0 <= dststart <= dststart + length <= len(dst.chars) + rstr.copy_unicode_contents(src, dst, srcstart, dststart, length) + + def bh_getinteriorfield_gc(self, a, index, descr): array = a._obj.container return support.cast_result(descr.FIELD, getattr(array.getitem(index), descr.fieldname)) - bh_getinteriorfield_gc_f = do_getinteriorfield_gc - bh_getinteriorfield_gc_i = do_getinteriorfield_gc - bh_getinteriorfield_gc_r = do_getinteriorfield_gc + bh_getinteriorfield_gc_f = bh_getinteriorfield_gc + bh_getinteriorfield_gc_i = bh_getinteriorfield_gc + bh_getinteriorfield_gc_r = bh_getinteriorfield_gc - def do_setinteriorfield_gc(self, a, index, item, descr): + def bh_setinteriorfield_gc(self, a, index, item, descr): array = a._obj.container setattr(array.getitem(index), descr.fieldname, support.cast_arg(descr.FIELD, item)) - bh_setinteriorfield_gc_f = do_setinteriorfield_gc - bh_setinteriorfield_gc_r = do_setinteriorfield_gc - bh_setinteriorfield_gc_i = do_setinteriorfield_gc + bh_setinteriorfield_gc_f = bh_setinteriorfield_gc + bh_setinteriorfield_gc_r = bh_setinteriorfield_gc + bh_setinteriorfield_gc_i = bh_setinteriorfield_gc - def do_newunicode(self, length): + def bh_newunicode(self, length): return lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.UNICODE, length)) - bh_newunicode = do_newunicode + def bh_unicodelen(self, string): + return string._obj.container.chars.getlength() + + def bh_unicodegetitem(self, string, index): + return ord(string._obj.container.chars.getitem(index)) + + def bh_unicodesetitem(self, string, index, newvalue): + string._obj.container.chars.setitem(index, unichr(newvalue)) + + def bh_new(self, sizedescr): + return lltype.cast_opaque_ptr(llmemory.GCREF, + lltype.malloc(sizedescr.S)) + + def bh_new_with_vtable(self, descr, vtable): + result = lltype.malloc(descr.S) + result_as_objptr = lltype.cast_pointer(rclass.OBJECTPTR, result) + result_as_objptr.typeptr = support.cast_from_int(rclass.CLASSTYPE, + vtable) + return lltype.cast_opaque_ptr(llmemory.GCREF, result) + class LLFrame(object): def __init__(self, cpu, argboxes, args): @@ -283,8 +372,8 @@ def fail_guard(self, descr): raise GuardFailed(self._getfailargs(), descr) - def execute_finish(self, descr, arg=None): - raise ExecutionFinished(descr, arg) + def execute_finish(self, descr, *args): + raise ExecutionFinished(descr, args) def execute_label(self, descr, *args): argboxes = self.current_op.getarglist() @@ -370,48 +459,16 @@ call_args = support.cast_call_args_in_order(args[0], args[1:]) return self.cpu.call(args[0], descr, call_args) - def execute_getfield_gc(self, descr, p): - p = lltype.cast_opaque_ptr(lltype.Ptr(descr.S), p) - return support.cast_result(descr.FIELD, getattr(p, descr.fieldname)) + def execute_same_as(self, _, x): + return x - def execute_setfield_gc(self, descr, p, newvalue): - p = lltype.cast_opaque_ptr(lltype.Ptr(descr.S), p) - setattr(p, descr.fieldname, support.cast_arg(descr.FIELD, newvalue)) + def execute_debug_merge_point(self, descr, *args): + pass - def execute_arraylen_gc(self, descr, a): - array = a._obj.container - return array.getlength() + def execute_new_with_vtable(self, _, vtable): + descr = heaptracker.vtable2descr(self.cpu, vtable) + return self.cpu.bh_new_with_vtable(descr, vtable) - def execute_setarrayitem_gc(self, descr, a, index, item): - array = a._obj.container - array.setitem(index, support.cast_arg(descr.A.OF, item)) - - def execute_getarrayitem_gc(self, descr, a, index): - array = a._obj.container - return support.cast_result(descr.A.OF, array.getitem(index)) - - def execute_strlen(self, descr, s): - return s._obj.container.chars.getlength() - - def execute_strgetitem(self, descr, s, item): - return ord(s._obj.container.chars.getitem(item)) - - def execute_strsetitem(self, descr, s, item, v): - s._obj.container.chars.setitem(item, chr(v)) - - def execute_copystrcontent(self, _, src, dst, srcstart, dststart, length): - src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), src) - dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), dst) - assert 0 <= srcstart <= srcstart + length <= len(src.chars) - assert 0 <= dststart <= dststart + length <= len(dst.chars) - rstr.copy_string_contents(src, dst, srcstart, dststart, length) - - def execute_copyunicodecontent(self, _, src, dst, srcstart, dststart, length): - src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), src) - dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst) - assert 0 <= srcstart <= srcstart + length <= len(src.chars) - assert 0 <= dststart <= dststart + length <= len(dst.chars) - rstr.copy_unicode_contents(src, dst, srcstart, dststart, length) def _setup(): def _make_impl_from_blackhole_interp(opname): @@ -434,18 +491,21 @@ def _new_execute(opname): def execute(self, descr, *args): - new_args = args + (descr,) - return getattr(self.cpu, 'do_' + opname)(*new_args) + if descr is not None: + new_args = args + (descr,) + else: + new_args = args + return getattr(self.cpu, 'bh_' + opname)(*new_args) execute.func_name = 'execute_' + opname return execute for k, v in rop.__dict__.iteritems(): if not k.startswith("_"): - func = _make_impl_from_blackhole_interp(k) fname = 'execute_' + k.lower() - if func is not None and not hasattr(LLFrame, fname): + if not hasattr(LLFrame, fname): + func = _make_impl_from_blackhole_interp(k) + if func is None: + func = _new_execute(k.lower()) setattr(LLFrame, fname, func) - elif hasattr(LLGraphCPU, 'do_' + k.lower()): - setattr(LLFrame, fname, _new_execute(k.lower())) _setup() diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py --- a/pypy/jit/backend/llsupport/llmodel.py +++ b/pypy/jit/backend/llsupport/llmodel.py @@ -440,7 +440,7 @@ # --- end of GC unsafe code --- return fval - def bh_setinteriorfield_gc_i(self, gcref, itemindex, descr, value): + def bh_setinteriorfield_gc_i(self, gcref, itemindex, value, descr): assert isinstance(descr, InteriorFieldDescr) arraydescr = descr.arraydescr ofs, size, _ = self.unpack_arraydescr_size(arraydescr) @@ -458,7 +458,7 @@ else: raise NotImplementedError("size = %d" % fieldsize) - def bh_setinteriorfield_gc_r(self, gcref, itemindex, descr, 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) @@ -471,7 +471,7 @@ items[0] = self.cast_gcref_to_int(newvalue) # --- end of GC unsafe code --- - def bh_setinteriorfield_gc_f(self, gcref, itemindex, descr, 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) @@ -588,7 +588,7 @@ bh_setfield_raw_r = _base_do_setfield_r bh_setfield_raw_f = _base_do_setfield_f - def bh_raw_store_i(self, addr, offset, descr, newvalue): + 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: @@ -597,7 +597,7 @@ items[0] = rffi.cast(TYPE, newvalue) break - def bh_raw_store_f(self, addr, offset, descr, newvalue): + def bh_raw_store_f(self, addr, offset, newvalue, descr): items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset) items[0] = newvalue diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -233,11 +233,11 @@ # lltype specific operations # -------------------------- - def bh_getarrayitem_gc_i(self, arraydescr, array, index): + def bh_getarrayitem_gc_i(self, array, index, arraydescr): raise NotImplementedError - def bh_getarrayitem_gc_r(self, arraydescr, array, index): + def bh_getarrayitem_gc_r(self, array, index, arraydescr): raise NotImplementedError - def bh_getarrayitem_gc_f(self, arraydescr, array, index): + def bh_getarrayitem_gc_f(self, array, index, arraydescr): raise NotImplementedError def bh_getfield_gc_i(self, struct, fielddescr): @@ -256,49 +256,63 @@ def bh_new(self, sizedescr): raise NotImplementedError - def bh_new_with_vtable(self, sizedescr, vtable): + def bh_new_with_vtable(self, vtable, sizedescr): raise NotImplementedError - def bh_new_array(self, arraydescr, length): + def bh_new_array(self, length, arraydescr): raise NotImplementedError def bh_newstr(self, length): raise NotImplementedError def bh_newunicode(self, length): raise NotImplementedError - def bh_arraylen_gc(self, arraydescr, array): + def bh_arraylen_gc(self, array, arraydescr): raise NotImplementedError def bh_classof(self, struct): raise NotImplementedError - def bh_setarrayitem_gc_i(self, arraydescr, array, index, newvalue): + def bh_setarrayitem_gc_i(self, array, index, newvalue, arraydescr): raise NotImplementedError - def bh_setarrayitem_gc_r(self, arraydescr, array, index, newvalue): + def bh_setarrayitem_gc_r(self, array, index, newvalue, arraydescr): raise NotImplementedError - def bh_setarrayitem_gc_f(self, arraydescr, array, index, newvalue): + def bh_setarrayitem_gc_f(self, array, index, newvalue, arraydescr): raise NotImplementedError - def bh_setfield_gc_i(self, struct, fielddescr, newvalue): + def bh_setfield_gc_i(self, struct, newvalue, fielddescr): raise NotImplementedError - def bh_setfield_gc_r(self, struct, fielddescr, newvalue): + def bh_setfield_gc_r(self, struct, newvalue, fielddescr): raise NotImplementedError - def bh_setfield_gc_f(self, struct, fielddescr, newvalue): + def bh_setfield_gc_f(self, struct, newvalue, fielddescr): raise NotImplementedError - def bh_setfield_raw_i(self, struct, fielddescr, newvalue): + def bh_setfield_raw_i(self, struct, newvalue, fielddescr): raise NotImplementedError - def bh_setfield_raw_r(self, struct, fielddescr, newvalue): + def bh_setfield_raw_r(self, struct, newvalue, fielddescr): raise NotImplementedError - def bh_setfield_raw_f(self, struct, fielddescr, newvalue): + def bh_setfield_raw_f(self, struct, newvalue, fielddescr): raise NotImplementedError - def bh_call_i(self, func, calldescr, args_i, args_r, args_f): + def bh_getinteriorfield_gc_i(self, array, index, descr): raise NotImplementedError - def bh_call_r(self, func, calldescr, args_i, args_r, args_f): + def bh_getinteriorfield_gc_r(self, array, index, descr): raise NotImplementedError - def bh_call_f(self, func, calldescr, args_i, args_r, args_f): + def bh_getinteriorfield_gc_f(self, array, index, descr): raise NotImplementedError - def bh_call_v(self, func, calldescr, args_i, args_r, args_f): + + def bh_setinteriorfield_gc_i(self, array, index, item, descr): + raise NotImplementedError + def bh_setinteriorfield_gc_r(self, array, index, item, descr): + raise NotImplementedError + def bh_setinteriorfield_gc_f(self, array, index, item, descr): + raise NotImplementedError + + def bh_call_i(self, func, args_i, args_r, args_f, calldescr): + raise NotImplementedError + def bh_call_r(self, func, args_i, args_r, args_f, calldescr): + raise NotImplementedError + def bh_call_f(self, func, args_i, args_r, args_f, calldescr): + raise NotImplementedError + def bh_call_v(self, func, args_i, args_r, args_f, calldescr): raise NotImplementedError def bh_strlen(self, string): diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -511,7 +511,7 @@ calldescr = cpu.calldescrof(deref(FPTR), (lltype.Char,), lltype.Char, EffectInfo.MOST_GENERAL) x = cpu.bh_call_i(self.get_funcbox(cpu, func_ptr).value, - calldescr, [ord('A')], None, None) + [ord('A')], None, None, calldescr) assert x == ord('B') if cpu.supports_floats: def func(f, i): @@ -525,8 +525,8 @@ calldescr = cpu.calldescrof(FTP, FTP.ARGS, FTP.RESULT, EffectInfo.MOST_GENERAL) x = cpu.bh_call_f(self.get_funcbox(cpu, func_ptr).value, - calldescr, - [42], None, [longlong.getfloatstorage(3.5)]) + [42], None, [longlong.getfloatstorage(3.5)], + calldescr) assert longlong.getrealfloat(x) == 3.5 - 42 def test_call(self): @@ -1926,7 +1926,7 @@ assert s.parent.chr2 == chr(150) r = self.cpu.bh_getfield_gc_i(r1.value, descrshort) assert r == 1313 - self.cpu.bh_setfield_gc_i(r1.value, descrshort, 1333) + self.cpu.bh_setfield_gc_i(r1.value, 1333, descrshort) r = self.cpu.bh_getfield_gc_i(r1.value, descrshort) assert r == 1333 r = self.execute_operation(rop.GETFIELD_GC, [r1], 'int', @@ -2681,7 +2681,7 @@ #assert x.getref(rclass.OBJECTPTR).typeptr == vtable2 # arraydescr = cpu.arraydescrof(A) - x = cpu.bh_new_array(arraydescr, 7) + x = cpu.bh_new_array(7, arraydescr) array = lltype.cast_opaque_ptr(lltype.Ptr(A), x) assert len(array) == 7 # @@ -3129,7 +3129,7 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) x = self.cpu.bh_call_i(self.get_funcbox(self.cpu, f).value, - calldescr, [value], None, None) + [value], None, None, calldescr) assert x == expected, ( "%r: got %r, expected %r" % (RESTYPE, x, expected)) @@ -3198,7 +3198,7 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) x = self.cpu.bh_call_f(self.get_funcbox(self.cpu, f).value, - calldescr, None, None, [value]) + None, None, [value], calldescr) assert x == expected def test_longlong_result_of_call_compiled(self): @@ -3257,7 +3257,7 @@ ivalue = longlong.singlefloat2int(value) iexpected = longlong.singlefloat2int(expected) x = self.cpu.bh_call_i(self.get_funcbox(self.cpu, f).value, - calldescr, [ivalue], None, None) + [ivalue], None, None, calldescr) assert x == iexpected def test_singlefloat_result_of_call_compiled(self): diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -936,34 +936,34 @@ def bhimpl_recursive_call_i(self, jdindex, greens_i, greens_r, greens_f, reds_i, reds_r, reds_f): fnptr, calldescr = self.get_portal_runner(jdindex) - return self.cpu.bh_call_i(fnptr, calldescr, + return self.cpu.bh_call_i(fnptr, greens_i + reds_i, greens_r + reds_r, - greens_f + reds_f) + greens_f + reds_f, calldescr) @arguments("self", "i", "I", "R", "F", "I", "R", "F", returns="r") def bhimpl_recursive_call_r(self, jdindex, greens_i, greens_r, greens_f, reds_i, reds_r, reds_f): fnptr, calldescr = self.get_portal_runner(jdindex) - return self.cpu.bh_call_r(fnptr, calldescr, + return self.cpu.bh_call_r(fnptr, greens_i + reds_i, greens_r + reds_r, - greens_f + reds_f) + greens_f + reds_f, calldescr) @arguments("self", "i", "I", "R", "F", "I", "R", "F", returns="f") def bhimpl_recursive_call_f(self, jdindex, greens_i, greens_r, greens_f, reds_i, reds_r, reds_f): fnptr, calldescr = self.get_portal_runner(jdindex) - return self.cpu.bh_call_f(fnptr, calldescr, + return self.cpu.bh_call_f(fnptr, greens_i + reds_i, greens_r + reds_r, - greens_f + reds_f) + greens_f + reds_f, calldescr) @arguments("self", "i", "I", "R", "F", "I", "R", "F") def bhimpl_recursive_call_v(self, jdindex, greens_i, greens_r, greens_f, reds_i, reds_r, reds_f): fnptr, calldescr = self.get_portal_runner(jdindex) - return self.cpu.bh_call_v(fnptr, calldescr, + return self.cpu.bh_call_v(fnptr, greens_i + reds_i, greens_r + reds_r, - greens_f + reds_f) + greens_f + reds_f, calldescr) # ---------- # virtual refs @@ -982,7 +982,7 @@ @arguments("cpu", "r", "d", "i", returns="i") def bhimpl_check_neg_index(cpu, array, arraydescr, index): if index < 0: - index += cpu.bh_arraylen_gc(arraydescr, array) + index += cpu.bh_arraylen_gc(array, arraydescr) return index @arguments("cpu", "r", "d", "i", returns="i") @@ -995,138 +995,138 @@ def bhimpl_newlist(cpu, structdescr, lengthdescr, itemsdescr, arraydescr, length): result = cpu.bh_new(structdescr) - cpu.bh_setfield_gc_i(result, lengthdescr, length) - items = cpu.bh_new_array(arraydescr, length) - cpu.bh_setfield_gc_r(result, itemsdescr, items) + cpu.bh_setfield_gc_i(result, length, lengthdescr) + items = cpu.bh_new_array(length, arraydescr) + cpu.bh_setfield_gc_r(result, items, itemsdescr) return result @arguments("cpu", "d", "d", "d", "d", "i", returns="r") def bhimpl_newlist_hint(cpu, structdescr, lengthdescr, itemsdescr, arraydescr, lengthhint): result = cpu.bh_new(structdescr) - cpu.bh_setfield_gc_i(result, lengthdescr, 0) - items = cpu.bh_new_array(arraydescr, lengthhint) - cpu.bh_setfield_gc_r(result, itemsdescr, items) + cpu.bh_setfield_gc_i(result, 0, lengthdescr) + items = cpu.bh_new_array(lengthhint, arraydescr) + cpu.bh_setfield_gc_r(result, items, itemsdescr) return result @arguments("cpu", "r", "d", "d", "i", returns="i") def bhimpl_getlistitem_gc_i(cpu, lst, itemsdescr, arraydescr, index): items = cpu.bh_getfield_gc_r(lst, itemsdescr) - return cpu.bh_getarrayitem_gc_i(arraydescr, items, index) + return cpu.bh_getarrayitem_gc_i(items, index, arraydescr) @arguments("cpu", "r", "d", "d", "i", returns="r") def bhimpl_getlistitem_gc_r(cpu, lst, itemsdescr, arraydescr, index): items = cpu.bh_getfield_gc_r(lst, itemsdescr) - return cpu.bh_getarrayitem_gc_r(arraydescr, items, index) + return cpu.bh_getarrayitem_gc_r(items, index, arraydescr) @arguments("cpu", "r", "d", "d", "i", returns="f") def bhimpl_getlistitem_gc_f(cpu, lst, itemsdescr, arraydescr, index): items = cpu.bh_getfield_gc_r(lst, itemsdescr) - return cpu.bh_getarrayitem_gc_f(arraydescr, items, index) + return cpu.bh_getarrayitem_gc_f(items, index, arraydescr) @arguments("cpu", "r", "d", "d", "i", "i") def bhimpl_setlistitem_gc_i(cpu, lst, itemsdescr, arraydescr, index, nval): items = cpu.bh_getfield_gc_r(lst, itemsdescr) - cpu.bh_setarrayitem_gc_i(arraydescr, items, index, nval) + cpu.bh_setarrayitem_gc_i(items, index, nval, arraydescr) @arguments("cpu", "r", "d", "d", "i", "r") def bhimpl_setlistitem_gc_r(cpu, lst, itemsdescr, arraydescr, index, nval): items = cpu.bh_getfield_gc_r(lst, itemsdescr) - cpu.bh_setarrayitem_gc_r(arraydescr, items, index, nval) + cpu.bh_setarrayitem_gc_r(items, index, nval, arraydescr) @arguments("cpu", "r", "d", "d", "i", "f") def bhimpl_setlistitem_gc_f(cpu, lst, itemsdescr, arraydescr, index, nval): items = cpu.bh_getfield_gc_r(lst, itemsdescr) - cpu.bh_setarrayitem_gc_f(arraydescr, items, index, nval) + cpu.bh_setarrayitem_gc_f(items, index, nval, arraydescr) # ---------- # the following operations are directly implemented by the backend @arguments("cpu", "i", "d", "R", returns="i") def bhimpl_residual_call_r_i(cpu, func, calldescr, args_r): - return cpu.bh_call_i(func, calldescr, None, args_r, None) + return cpu.bh_call_i(func, None, args_r, None, calldescr) @arguments("cpu", "i", "d", "R", returns="r") def bhimpl_residual_call_r_r(cpu, func, calldescr, args_r): - return cpu.bh_call_r(func, calldescr, None, args_r, None) + return cpu.bh_call_r(func, None, args_r, None, calldescr) @arguments("cpu", "i", "d", "R") def bhimpl_residual_call_r_v(cpu, func, calldescr, args_r): - return cpu.bh_call_v(func, calldescr, None, args_r, None) + return cpu.bh_call_v(func, None, args_r, None, calldescr) @arguments("cpu", "i", "d", "I", "R", returns="i") def bhimpl_residual_call_ir_i(cpu, func, calldescr, args_i, args_r): - return cpu.bh_call_i(func, calldescr, args_i, args_r, None) + return cpu.bh_call_i(func, args_i, args_r, None, calldescr) @arguments("cpu", "i", "d", "I", "R", returns="r") def bhimpl_residual_call_ir_r(cpu, func, calldescr, args_i, args_r): - return cpu.bh_call_r(func, calldescr, args_i, args_r, None) + return cpu.bh_call_r(func, args_i, args_r, None, calldescr) @arguments("cpu", "i", "d", "I", "R") def bhimpl_residual_call_ir_v(cpu, func, calldescr, args_i, args_r): - return cpu.bh_call_v(func, calldescr, args_i, args_r, None) + return cpu.bh_call_v(func, args_i, args_r, None, calldescr) @arguments("cpu", "i", "d", "I", "R", "F", returns="i") def bhimpl_residual_call_irf_i(cpu, func, calldescr,args_i,args_r,args_f): - return cpu.bh_call_i(func, calldescr, args_i, args_r, args_f) + return cpu.bh_call_i(func, args_i, args_r, args_f, calldescr) @arguments("cpu", "i", "d", "I", "R", "F", returns="r") def bhimpl_residual_call_irf_r(cpu, func, calldescr,args_i,args_r,args_f): - return cpu.bh_call_r(func, calldescr, args_i, args_r, args_f) + return cpu.bh_call_r(func, args_i, args_r, args_f, calldescr) @arguments("cpu", "i", "d", "I", "R", "F", returns="f") def bhimpl_residual_call_irf_f(cpu, func, calldescr,args_i,args_r,args_f): - return cpu.bh_call_f(func, calldescr, args_i, args_r, args_f) + return cpu.bh_call_f(func, args_i, args_r, args_f, calldescr) @arguments("cpu", "i", "d", "I", "R", "F") def bhimpl_residual_call_irf_v(cpu, func, calldescr,args_i,args_r,args_f): - return cpu.bh_call_v(func, calldescr, args_i, args_r, args_f) + return cpu.bh_call_v(func, args_i, args_r, args_f, calldescr) @arguments("cpu", "j", "R", returns="i") def bhimpl_inline_call_r_i(cpu, jitcode, args_r): - return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), jitcode.calldescr, - None, args_r, None) + return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), + None, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "R", returns="r") def bhimpl_inline_call_r_r(cpu, jitcode, args_r): - return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), jitcode.calldescr, - None, args_r, None) + return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), + None, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "R") def bhimpl_inline_call_r_v(cpu, jitcode, args_r): - return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), jitcode.calldescr, - None, args_r, None) + return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), + None, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R", returns="i") def bhimpl_inline_call_ir_i(cpu, jitcode, args_i, args_r): - return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), jitcode.calldescr, - args_i, args_r, None) + return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), + args_i, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R", returns="r") def bhimpl_inline_call_ir_r(cpu, jitcode, args_i, args_r): - return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), jitcode.calldescr, - args_i, args_r, None) + return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), + args_i, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R") def bhimpl_inline_call_ir_v(cpu, jitcode, args_i, args_r): - return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), jitcode.calldescr, - args_i, args_r, None) + return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), + args_i, args_r, None, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F", returns="i") def bhimpl_inline_call_irf_i(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), jitcode.calldescr, - args_i, args_r, args_f) + return cpu.bh_call_i(jitcode.get_fnaddr_as_int(), + args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F", returns="r") def bhimpl_inline_call_irf_r(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), jitcode.calldescr, - args_i, args_r, args_f) + return cpu.bh_call_r(jitcode.get_fnaddr_as_int(), + args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F", returns="f") def bhimpl_inline_call_irf_f(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_f(jitcode.get_fnaddr_as_int(), jitcode.calldescr, - args_i, args_r, args_f) + return cpu.bh_call_f(jitcode.get_fnaddr_as_int(), + args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "j", "I", "R", "F") def bhimpl_inline_call_irf_v(cpu, jitcode, args_i, args_r, args_f): - return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), jitcode.calldescr, - args_i, args_r, args_f) + return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), + args_i, args_r, args_f, jitcode.calldescr) @arguments("cpu", "d", "i", returns="r") def bhimpl_new_array(cpu, arraydescr, length): - return cpu.bh_new_array(arraydescr, length) + return cpu.bh_new_array(length, arraydescr) @arguments("cpu", "r", "d", "i", returns="i") def bhimpl_getarrayitem_gc_i(cpu, array, arraydescr, index): - return cpu.bh_getarrayitem_gc_i(arraydescr, array, index) + return cpu.bh_getarrayitem_gc_i(array, index, arraydescr) @arguments("cpu", "r", "d", "i", returns="r") def bhimpl_getarrayitem_gc_r(cpu, array, arraydescr, index): - return cpu.bh_getarrayitem_gc_r(arraydescr, array, index) + return cpu.bh_getarrayitem_gc_r(array, index, arraydescr) @arguments("cpu", "r", "d", "i", returns="f") def bhimpl_getarrayitem_gc_f(cpu, array, arraydescr, index): - return cpu.bh_getarrayitem_gc_f(arraydescr, array, index) + return cpu.bh_getarrayitem_gc_f(array, index, arraydescr) bhimpl_getarrayitem_gc_i_pure = bhimpl_getarrayitem_gc_i bhimpl_getarrayitem_gc_r_pure = bhimpl_getarrayitem_gc_r @@ -1134,67 +1134,67 @@ @arguments("cpu", "i", "d", "i", returns="i") def bhimpl_getarrayitem_raw_i(cpu, array, arraydescr, index): - return cpu.bh_getarrayitem_raw_i(arraydescr, array, index) + return cpu.bh_getarrayitem_raw_i(array, index, arraydescr) @arguments("cpu", "i", "d", "i", returns="f") def bhimpl_getarrayitem_raw_f(cpu, array, arraydescr, index): - return cpu.bh_getarrayitem_raw_f(arraydescr, array, index) + return cpu.bh_getarrayitem_raw_f(array, index, arraydescr) bhimpl_getarrayitem_raw_i_pure = bhimpl_getarrayitem_raw_i bhimpl_getarrayitem_raw_f_pure = bhimpl_getarrayitem_raw_f @arguments("cpu", "r", "d", "i", "i") def bhimpl_setarrayitem_gc_i(cpu, array, arraydescr, index, newvalue): - cpu.bh_setarrayitem_gc_i(arraydescr, array, index, newvalue) + cpu.bh_setarrayitem_gc_i(array, index, newvalue, arraydescr) @arguments("cpu", "r", "d", "i", "r") def bhimpl_setarrayitem_gc_r(cpu, array, arraydescr, index, newvalue): - cpu.bh_setarrayitem_gc_r(arraydescr, array, index, newvalue) + cpu.bh_setarrayitem_gc_r(array, index, newvalue, arraydescr) @arguments("cpu", "r", "d", "i", "f") def bhimpl_setarrayitem_gc_f(cpu, array, arraydescr, index, newvalue): - cpu.bh_setarrayitem_gc_f(arraydescr, array, index, newvalue) + cpu.bh_setarrayitem_gc_f(array, index, newvalue, arraydescr) @arguments("cpu", "i", "d", "i", "i") def bhimpl_setarrayitem_raw_i(cpu, array, arraydescr, index, newvalue): - cpu.bh_setarrayitem_raw_i(arraydescr, array, index, newvalue) + cpu.bh_setarrayitem_raw_i(array, index, newvalue, arraydescr) @arguments("cpu", "i", "d", "i", "f") def bhimpl_setarrayitem_raw_f(cpu, array, arraydescr, index, newvalue): - cpu.bh_setarrayitem_raw_f(arraydescr, array, index, newvalue) + cpu.bh_setarrayitem_raw_f(array, index, newvalue, arraydescr) # note, there is no 'r' here, since it can't happen @arguments("cpu", "r", "d", returns="i") def bhimpl_arraylen_gc(cpu, array, arraydescr): - return cpu.bh_arraylen_gc(arraydescr, array) + return cpu.bh_arraylen_gc(array, arraydescr) @arguments("cpu", "r", "d", "d", "i", returns="i") def bhimpl_getarrayitem_vable_i(cpu, vable, fielddescr, arraydescr, index): array = cpu.bh_getfield_gc_r(vable, fielddescr) - return cpu.bh_getarrayitem_gc_i(arraydescr, array, index) + return cpu.bh_getarrayitem_gc_i(array, index, arraydescr) @arguments("cpu", "r", "d", "d", "i", returns="r") def bhimpl_getarrayitem_vable_r(cpu, vable, fielddescr, arraydescr, index): array = cpu.bh_getfield_gc_r(vable, fielddescr) - return cpu.bh_getarrayitem_gc_r(arraydescr, array, index) + return cpu.bh_getarrayitem_gc_r(array, index, arraydescr) @arguments("cpu", "r", "d", "d", "i", returns="f") def bhimpl_getarrayitem_vable_f(cpu, vable, fielddescr, arraydescr, index): array = cpu.bh_getfield_gc_r(vable, fielddescr) - return cpu.bh_getarrayitem_gc_f(arraydescr, array, index) + return cpu.bh_getarrayitem_gc_f(array, index, arraydescr) @arguments("cpu", "r", "d", "d", "i", "i") def bhimpl_setarrayitem_vable_i(cpu, vable, fdescr, adescr, index, newval): array = cpu.bh_getfield_gc_r(vable, fdescr) - cpu.bh_setarrayitem_gc_i(adescr, array, index, newval) + cpu.bh_setarrayitem_gc_i(array, index, newval, adescr) @arguments("cpu", "r", "d", "d", "i", "r") def bhimpl_setarrayitem_vable_r(cpu, vable, fdescr, adescr, index, newval): array = cpu.bh_getfield_gc_r(vable, fdescr) - cpu.bh_setarrayitem_gc_r(adescr, array, index, newval) + cpu.bh_setarrayitem_gc_r(array, index, newval, adescr) @arguments("cpu", "r", "d", "d", "i", "f") def bhimpl_setarrayitem_vable_f(cpu, vable, fdescr, adescr, index, newval): array = cpu.bh_getfield_gc_r(vable, fdescr) - cpu.bh_setarrayitem_gc_f(adescr, array, index, newval) + cpu.bh_setarrayitem_gc_f(array, index, newval, adescr) @arguments("cpu", "r", "d", "d", returns="i") def bhimpl_arraylen_vable(cpu, vable, fdescr, adescr): array = cpu.bh_getfield_gc_r(vable, fdescr) - return cpu.bh_arraylen_gc(adescr, array) + return cpu.bh_arraylen_gc(array, adescr) @arguments("cpu", "r", "i", "d", returns="i") def bhimpl_getinteriorfield_gc_i(cpu, array, index, descr): @@ -1254,13 +1254,13 @@ @arguments("cpu", "r", "d", "i") def bhimpl_setfield_gc_i(cpu, struct, fielddescr, newvalue): - cpu.bh_setfield_gc_i(struct, fielddescr, newvalue) + cpu.bh_setfield_gc_i(struct, newvalue, fielddescr) @arguments("cpu", "r", "d", "r") def bhimpl_setfield_gc_r(cpu, struct, fielddescr, newvalue): - cpu.bh_setfield_gc_r(struct, fielddescr, newvalue) + cpu.bh_setfield_gc_r(struct, newvalue, fielddescr) @arguments("cpu", "r", "d", "f") def bhimpl_setfield_gc_f(cpu, struct, fielddescr, newvalue): - cpu.bh_setfield_gc_f(struct, fielddescr, newvalue) + cpu.bh_setfield_gc_f(struct, newvalue, fielddescr) bhimpl_setfield_vable_i = bhimpl_setfield_gc_i bhimpl_setfield_vable_r = bhimpl_setfield_gc_r @@ -1268,20 +1268,20 @@ @arguments("cpu", "i", "d", "i") def bhimpl_setfield_raw_i(cpu, struct, fielddescr, newvalue): - cpu.bh_setfield_raw_i(struct, fielddescr, newvalue) + cpu.bh_setfield_raw_i(struct, newvalue, fielddescr) @arguments("cpu", "i", "d", "r") def bhimpl_setfield_raw_r(cpu, struct, fielddescr, newvalue): - cpu.bh_setfield_raw_r(struct, fielddescr, newvalue) + cpu.bh_setfield_raw_r(struct, newvalue, fielddescr) @arguments("cpu", "i", "d", "f") def bhimpl_setfield_raw_f(cpu, struct, fielddescr, newvalue): - cpu.bh_setfield_raw_f(struct, fielddescr, newvalue) + cpu.bh_setfield_raw_f(struct, newvalue, fielddescr) @arguments("cpu", "i", "i", "d", "i") def bhimpl_raw_store_i(cpu, addr, offset, arraydescr, newvalue): - cpu.bh_raw_store_i(addr, offset, arraydescr, newvalue) + cpu.bh_raw_store_i(addr, offset, newvalue, arraydescr) @arguments("cpu", "i", "i", "d", "f") def bhimpl_raw_store_f(cpu, addr, offset, arraydescr, newvalue): - cpu.bh_raw_store_f(addr, offset, arraydescr, newvalue) + cpu.bh_raw_store_f(addr, offset, newvalue, arraydescr) @arguments("cpu", "i", "i", "d", returns="i") def bhimpl_raw_load_i(cpu, addr, offset, arraydescr): @@ -1306,7 +1306,7 @@ @arguments("cpu", "d", returns="r") def bhimpl_new_with_vtable(cpu, descr): vtable = heaptracker.descr2vtable(cpu, descr) - return cpu.bh_new_with_vtable(descr, vtable) + return cpu.bh_new_with_vtable(vtable, descr) @arguments("cpu", "r", returns="i") def bhimpl_guard_class(cpu, struct): From noreply at buildbot.pypy.org Wed Oct 17 11:33:22 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 11:33:22 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal, arigo) More of the same kind. Message-ID: <20121017093322.983201C02D5@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58156:7235b5827eec Date: 2012-10-17 11:32 +0200 http://bitbucket.org/pypy/pypy/changeset/7235b5827eec/ Log: (fijal, arigo) More of the same kind. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -239,29 +239,6 @@ array = a._obj.container return support.cast_result(descr.A.OF, array.getitem(index)) - def bh_strlen(self, s): - return s._obj.container.chars.getlength() - - def bh_strgetitem(self, s, item): - return ord(s._obj.container.chars.getitem(item)) - - def bh_strsetitem(self, s, item, v): - s._obj.container.chars.setitem(item, chr(v)) - - def bh_copystrcontent(self, src, dst, srcstart, dststart, length): - src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), src) - dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), dst) - assert 0 <= srcstart <= srcstart + length <= len(src.chars) - assert 0 <= dststart <= dststart + length <= len(dst.chars) - rstr.copy_string_contents(src, dst, srcstart, dststart, length) - - def bh_copyunicodecontent(self, src, dst, srcstart, dststart, length): - src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), src) - dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst) - assert 0 <= srcstart <= srcstart + length <= len(src.chars) - assert 0 <= dststart <= dststart + length <= len(dst.chars) - rstr.copy_unicode_contents(src, dst, srcstart, dststart, length) - def bh_getinteriorfield_gc(self, a, index, descr): array = a._obj.container return support.cast_result(descr.FIELD, @@ -280,6 +257,26 @@ bh_setinteriorfield_gc_r = bh_setinteriorfield_gc bh_setinteriorfield_gc_i = bh_setinteriorfield_gc + def bh_newstr(self, length): + return lltype.cast_opaque_ptr(llmemory.GCREF, + lltype.malloc(rstr.STR, length)) + + def bh_strlen(self, s): + return s._obj.container.chars.getlength() + + def bh_strgetitem(self, s, item): + return ord(s._obj.container.chars.getitem(item)) + + def bh_strsetitem(self, s, item, v): + s._obj.container.chars.setitem(item, chr(v)) + + def bh_copystrcontent(self, src, dst, srcstart, dststart, length): + src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), src) + dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), dst) + assert 0 <= srcstart <= srcstart + length <= len(src.chars) + assert 0 <= dststart <= dststart + length <= len(dst.chars) + rstr.copy_string_contents(src, dst, srcstart, dststart, length) + def bh_newunicode(self, length): return lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.UNICODE, length)) @@ -293,17 +290,28 @@ def bh_unicodesetitem(self, string, index, newvalue): string._obj.container.chars.setitem(index, unichr(newvalue)) + def bh_copyunicodecontent(self, src, dst, srcstart, dststart, length): + src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), src) + dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst) + assert 0 <= srcstart <= srcstart + length <= len(src.chars) + assert 0 <= dststart <= dststart + length <= len(dst.chars) + rstr.copy_unicode_contents(src, dst, srcstart, dststart, length) + def bh_new(self, sizedescr): return lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(sizedescr.S)) - def bh_new_with_vtable(self, descr, vtable): + def bh_new_with_vtable(self, vtable, descr): result = lltype.malloc(descr.S) result_as_objptr = lltype.cast_pointer(rclass.OBJECTPTR, result) result_as_objptr.typeptr = support.cast_from_int(rclass.CLASSTYPE, vtable) return lltype.cast_opaque_ptr(llmemory.GCREF, result) + def bh_new_array(self, length, arraydescr): + array = lltype.malloc(arraydescr.A, length, zero=True) + return lltype.cast_opaque_ptr(llmemory.GCREF, array) + class LLFrame(object): def __init__(self, cpu, argboxes, args): @@ -467,7 +475,7 @@ def execute_new_with_vtable(self, _, vtable): descr = heaptracker.vtable2descr(self.cpu, vtable) - return self.cpu.bh_new_with_vtable(descr, vtable) + return self.cpu.bh_new_with_vtable(vtable, descr) def _setup(): diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py --- a/pypy/jit/backend/llsupport/gc.py +++ b/pypy/jit/backend/llsupport/gc.py @@ -83,15 +83,15 @@ assert isinstance(sizedescr, SizeDescr) return self._bh_malloc(sizedescr) - def gc_malloc_array(self, arraydescr, num_elem): + def gc_malloc_array(self, num_elem, arraydescr): assert isinstance(arraydescr, ArrayDescr) - return self._bh_malloc_array(arraydescr, num_elem) + return self._bh_malloc_array(num_elem, arraydescr) def gc_malloc_str(self, num_elem): - return self._bh_malloc_array(self.str_descr, num_elem) + return self._bh_malloc_array(num_elem, self.str_descr) def gc_malloc_unicode(self, num_elem): - return self._bh_malloc_array(self.unicode_descr, num_elem) + return self._bh_malloc_array(num_elem, self.unicode_descr) def _record_constptrs(self, op, gcrefs_output_list): for i in range(op.numargs()): @@ -193,7 +193,7 @@ def _bh_malloc(self, sizedescr): return self.malloc_fixedsize(sizedescr.size) - def _bh_malloc_array(self, arraydescr, num_elem): + def _bh_malloc_array(self, num_elem, arraydescr): return self.malloc_array(arraydescr.basesize, num_elem, arraydescr.itemsize, arraydescr.lendescr.offset) @@ -802,7 +802,7 @@ type_id, sizedescr.size, False, False, False) - def _bh_malloc_array(self, arraydescr, num_elem): + def _bh_malloc_array(self, num_elem, arraydescr): from pypy.rpython.memory.gctypelayout import check_typeid llop1 = self.llop1 type_id = llop.extract_ushort(llgroup.HALFWORD, arraydescr.tid) diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py --- a/pypy/jit/backend/llsupport/llmodel.py +++ b/pypy/jit/backend/llsupport/llmodel.py @@ -307,13 +307,13 @@ # ____________________________________________________________ - def bh_arraylen_gc(self, arraydescr, array): + 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] @specialize.argtype(2) - def bh_getarrayitem_gc_i(self, arraydescr, gcref, itemindex): + def bh_getarrayitem_gc_i(self, gcref, itemindex, arraydescr): ofs, size, sign = self.unpack_arraydescr_size(arraydescr) # --- start of GC unsafe code (no GC operation!) --- items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) @@ -332,7 +332,7 @@ else: raise NotImplementedError("size = %d" % size) - def bh_getarrayitem_gc_r(self, arraydescr, gcref, itemindex): + def bh_getarrayitem_gc_r(self, gcref, itemindex, arraydescr): ofs = self.unpack_arraydescr(arraydescr) # --- start of GC unsafe code (no GC operation!) --- items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) @@ -342,7 +342,7 @@ return pval @specialize.argtype(2) - def bh_getarrayitem_gc_f(self, arraydescr, gcref, itemindex): + def bh_getarrayitem_gc_f(self, gcref, itemindex, arraydescr): ofs = self.unpack_arraydescr(arraydescr) # --- start of GC unsafe code (no GC operation!) --- items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) @@ -352,7 +352,7 @@ return fval @specialize.argtype(2) - def bh_setarrayitem_gc_i(self, arraydescr, gcref, itemindex, newvalue): + def bh_setarrayitem_gc_i(self, gcref, itemindex, newvalue, arraydescr): ofs, size, sign = self.unpack_arraydescr_size(arraydescr) # --- start of GC unsafe code (no GC operation!) --- items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) @@ -365,7 +365,7 @@ else: raise NotImplementedError("size = %d" % size) - def bh_setarrayitem_gc_r(self, arraydescr, gcref, itemindex, newvalue): + def bh_setarrayitem_gc_r(self, gcref, itemindex, newvalue, arraydescr): ofs = self.unpack_arraydescr(arraydescr) self.gc_ll_descr.do_write_barrier(gcref, newvalue) # --- start of GC unsafe code (no GC operation!) --- @@ -375,7 +375,7 @@ # --- end of GC unsafe code --- @specialize.argtype(2) - def bh_setarrayitem_gc_f(self, arraydescr, gcref, itemindex, newvalue): + def bh_setarrayitem_gc_f(self, gcref, itemindex, newvalue, arraydescr): ofs = self.unpack_arraydescr(arraydescr) # --- start of GC unsafe code (no GC operation!) --- items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) @@ -547,7 +547,7 @@ bh_getfield_raw_f = _base_do_getfield_f @specialize.argtype(1) - def _base_do_setfield_i(self, struct, fielddescr, newvalue): + 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) @@ -561,7 +561,7 @@ raise NotImplementedError("size = %d" % size) @specialize.argtype(1) - def _base_do_setfield_r(self, struct, fielddescr, newvalue): + 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") @@ -573,7 +573,7 @@ # --- end of GC unsafe code --- @specialize.argtype(1) - def _base_do_setfield_f(self, struct, fielddescr, newvalue): + 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) @@ -617,7 +617,7 @@ def bh_new(self, sizedescr): return self.gc_ll_descr.gc_malloc(sizedescr) - def bh_new_with_vtable(self, sizedescr, vtable): + 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) @@ -629,8 +629,8 @@ result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) return heaptracker.adr2int(result_adr) - def bh_new_array(self, arraydescr, length): - return self.gc_ll_descr.gc_malloc_array(arraydescr, length) + def bh_new_array(self, length, arraydescr): + return self.gc_ll_descr.gc_malloc_array(length, arraydescr) def bh_newstr(self, length): return self.gc_ll_descr.gc_malloc_str(length) @@ -656,25 +656,25 @@ dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst) rstr.copy_unicode_contents(src, dst, srcstart, dststart, length) - def bh_call_i(self, func, calldescr, args_i, args_r, args_f): + def bh_call_i(self, func, args_i, args_r, args_f, calldescr): assert isinstance(calldescr, CallDescr) if not we_are_translated(): calldescr.verify_types(args_i, args_r, args_f, history.INT + 'S') return calldescr.call_stub_i(func, args_i, args_r, args_f) - def bh_call_r(self, func, calldescr, args_i, args_r, args_f): + def bh_call_r(self, func, args_i, args_r, args_f, calldescr): assert isinstance(calldescr, CallDescr) if not we_are_translated(): calldescr.verify_types(args_i, args_r, args_f, history.REF) return calldescr.call_stub_r(func, args_i, args_r, args_f) - def bh_call_f(self, func, calldescr, args_i, args_r, args_f): + def bh_call_f(self, func, args_i, args_r, args_f, calldescr): assert isinstance(calldescr, CallDescr) if not we_are_translated(): calldescr.verify_types(args_i, args_r, args_f, history.FLOAT + 'L') return calldescr.call_stub_f(func, args_i, args_r, args_f) - def bh_call_v(self, func, calldescr, args_i, args_r, args_f): + def bh_call_v(self, func, args_i, args_r, args_f, calldescr): assert isinstance(calldescr, CallDescr) if not we_are_translated(): calldescr.verify_types(args_i, args_r, args_f, history.VOID) From noreply at buildbot.pypy.org Wed Oct 17 11:48:25 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 11:48:25 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal around, arigo) guard_{no}_exception Message-ID: <20121017094825.8648A1C00BF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58157:919e6ca88df7 Date: 2012-10-17 11:45 +0200 http://bitbucket.org/pypy/pypy/changeset/919e6ca88df7/ Log: (fijal around, arigo) guard_{no}_exception diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -7,7 +7,7 @@ from pypy.jit.metainterp.resoperation import rop from pypy.jit.codewriter import heaptracker -from pypy.rpython.llinterp import LLInterpreter +from pypy.rpython.llinterp import LLInterpreter, LLException from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr from pypy.rlib.rarithmetic import ovfcheck @@ -70,7 +70,7 @@ self.rtyper = rtyper self.llinterp = LLInterpreter(rtyper) self.known_labels = WeakKeyDictionary() - self.exc_value = lltype.nullptr(llmemory.GCREF.TO) + self.last_exception = None self.descrs = {} def compile_loop(self, inputargs, operations, looptoken, log=True, name=''): @@ -113,7 +113,12 @@ del self.latest_values def grab_exc_value(self): - return self.exc_value + if self.last_exception is not None: + result = self.last_exception.args[1] + self.last_exception = None + return lltype.cast_opaque_ptr(llmemory.GCREF, result) + else: + return lltype.nullptr(llmemory.GCREF.TO) def calldescrof(self, FUNC, ARGS, RESULT, effect_info): key = ('call', getkind(RESULT), @@ -194,17 +199,26 @@ # ------------------------------------------------------------ - def call(self, func, calldescr, args): + def call(self, func, args, calldescr): TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE RESULT = TP.RESULT func = llmemory.cast_int_to_adr(func).ptr._obj._callable - res = func(*args) + try: + res = func(*args) + self.last_exception = None + except LLException, lle: + self.last_exception = lle + d = {'void': None, + 'ref': lltype.nullptr(llmemory.GCREF.TO), + 'int': 0, + 'float': 0.0} + res = d[getkind(RESULT)] return support.cast_result(RESULT, res) def _do_call(self, func, args_i, args_r, args_f, calldescr): TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE args = support.cast_call_args(TP.ARGS, args_i, args_r, args_f) - return self.call(func, calldescr, args) + return self.call(func, args, calldescr) bh_call_i = _do_call bh_call_r = _do_call @@ -419,6 +433,26 @@ self.execute_guard_nonnull(descr, arg) self.execute_guard_class(descr, arg, klass) + def execute_guard_no_exception(self, descr): + if self.cpu.last_exception is not None: + self.fail_guard(descr) + + def execute_guard_exception(self, descr, excklass): + lle = self.cpu.last_exception + if lle is None: + gotklass = lltype.nullptr(rclass.CLASSTYPE.TO) + else: + gotklass = lle.args[0] + excklass = llmemory.cast_adr_to_ptr( + llmemory.cast_int_to_adr(excklass), + rclass.CLASSTYPE) + if gotklass != excklass: + self.fail_guard(descr) + # + res = lle.args[1] + self.cpu.last_exception = None + return support.cast_to_ptr(res) + def execute_int_add_ovf(self, _, x, y): try: z = ovfcheck(x + y) @@ -465,7 +499,7 @@ def execute_call(self, descr, *args): call_args = support.cast_call_args_in_order(args[0], args[1:]) - return self.cpu.call(args[0], descr, call_args) + return self.cpu.call(args[0], call_args, descr) def execute_same_as(self, _, x): return x diff --git a/pypy/jit/backend/llgraph/support.py b/pypy/jit/backend/llgraph/support.py --- a/pypy/jit/backend/llgraph/support.py +++ b/pypy/jit/backend/llgraph/support.py @@ -48,9 +48,12 @@ return cast_to_int(x) elif kind == 'ref': return cast_to_ptr(x) + elif kind == 'float': + return cast_to_floatstorage(x) else: - assert kind == 'float' - return cast_to_floatstorage(x) + assert kind == 'void' + assert x is None + return None def cast_from_floatstorage(TYPE, x): assert isinstance(x, longlong.r_float_storage) From noreply at buildbot.pypy.org Wed Oct 17 11:48:26 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 11:48:26 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: Skip the wb tests Message-ID: <20121017094826.A424C1C00BF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58158:85a19069a150 Date: 2012-10-17 11:47 +0200 http://bitbucket.org/pypy/pypy/changeset/85a19069a150/ Log: Skip the wb tests diff --git a/pypy/jit/backend/llgraph/test/test_llgraph.py b/pypy/jit/backend/llgraph/test/test_llgraph.py --- a/pypy/jit/backend/llgraph/test/test_llgraph.py +++ b/pypy/jit/backend/llgraph/test/test_llgraph.py @@ -13,6 +13,12 @@ def setup_method(self, _): self.cpu = self.cpu_type(None) + def test_cond_call_gc_wb(self): + py.test.skip("does not make much sense on the llgraph backend") + + test_cond_call_gc_wb_array = test_cond_call_gc_wb + test_cond_call_gc_wb_array_card_marking_fast_path = test_cond_call_gc_wb + def test_backends_dont_keep_loops_alive(self): py.test.skip("does not make much sense on the llgraph backend") From noreply at buildbot.pypy.org Wed Oct 17 12:08:11 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 12:08:11 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal, arigo) in-progress Message-ID: <20121017100811.BE0C81C02D5@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58159:d25105a3ad76 Date: 2012-10-17 12:07 +0200 http://bitbucket.org/pypy/pypy/changeset/d25105a3ad76/ Log: (fijal, arigo) in-progress diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -8,7 +8,7 @@ from pypy.jit.codewriter import heaptracker from pypy.rpython.llinterp import LLInterpreter, LLException -from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr from pypy.rlib.rarithmetic import ovfcheck @@ -199,10 +199,7 @@ # ------------------------------------------------------------ - def call(self, func, args, calldescr): - TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE - RESULT = TP.RESULT - func = llmemory.cast_int_to_adr(func).ptr._obj._callable + def call(self, func, args, RESULT, calldescr): try: res = func(*args) self.last_exception = None @@ -218,7 +215,8 @@ def _do_call(self, func, args_i, args_r, args_f, calldescr): TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE args = support.cast_call_args(TP.ARGS, args_i, args_r, args_f) - return self.call(func, args, calldescr) + func = llmemory.cast_int_to_adr(func).ptr._obj._callable + return self.call(func, args, TP.RESULT, calldescr) bh_call_i = _do_call bh_call_r = _do_call @@ -453,6 +451,13 @@ self.cpu.last_exception = None return support.cast_to_ptr(res) + def execute_guard_not_forced(self, descr): + pass # XXX + + def execute_guard_not_invalidated(self, descr): + if self.loop.invalid: + raise GuardFailed + def execute_int_add_ovf(self, _, x, y): try: z = ovfcheck(x + y) @@ -497,9 +502,18 @@ def execute_jump(self, descr, *args): raise Jump(descr, args) - def execute_call(self, descr, *args): - call_args = support.cast_call_args_in_order(args[0], args[1:]) - return self.cpu.call(args[0], call_args, descr) + def execute_call(self, descr, func, *args): + TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE + ARGS = TP.ARGS + call_args = support.cast_call_args_in_order(ARGS, args) + func = llmemory.cast_int_to_adr(func).ptr._obj._callable + return self.cpu.call(func, call_args, TP.RESULT, descr) + + def execute_call_release_gil(self, descr, func, *args): + call_args = support.cast_call_args_in_order(descr.ARGS, args) + FUNC = lltype.FuncType(descr.ARGS, descr.RESULT) + func_to_call = rffi.cast(lltype.Ptr(FUNC), func) + return self.cpu.call(func_to_call, call_args, descr.RESULT, descr) def execute_same_as(self, _, x): return x @@ -511,6 +525,9 @@ descr = heaptracker.vtable2descr(self.cpu, vtable) return self.cpu.bh_new_with_vtable(vtable, descr) + def execute_force_token(self, _): + import py; py.test.skip("XXX") + def _setup(): def _make_impl_from_blackhole_interp(opname): diff --git a/pypy/jit/backend/llgraph/support.py b/pypy/jit/backend/llgraph/support.py --- a/pypy/jit/backend/llgraph/support.py +++ b/pypy/jit/backend/llgraph/support.py @@ -134,8 +134,7 @@ assert list(argsiter_f) == [] return args -def cast_call_args_in_order(func, args): - ARGS = llmemory.cast_int_to_adr(func).ptr._obj._TYPE.ARGS +def cast_call_args_in_order(ARGS, args): call_args = [] for ARG, arg in zip(ARGS, args): kind = getkind(ARG) From noreply at buildbot.pypy.org Wed Oct 17 12:27:52 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 12:27:52 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal, arigo) Progress Message-ID: <20121017102752.8EB471C0FB8@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58160:6357106a6341 Date: 2012-10-17 12:24 +0200 http://bitbucket.org/pypy/pypy/changeset/6357106a6341/ Log: (fijal, arigo) Progress diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -12,10 +12,14 @@ from pypy.rlib.rarithmetic import ovfcheck -class LLLoop(object): - def __init__(self, inputargs, operations): +class LLTrace(object): + has_been_freed = False + invalid = False + + def __init__(self, inputargs, operations, looptoken): self.inputargs = inputargs self.operations = operations + self.looptoken = looptoken class GuardFailed(Exception): def __init__(self, failargs, descr): @@ -74,25 +78,37 @@ self.descrs = {} def compile_loop(self, inputargs, operations, looptoken, log=True, name=''): + lltrace = LLTrace(inputargs, operations, looptoken) + looptoken._llgraph_loop = lltrace + looptoken._llgraph_alltraces = [lltrace] + self._record_labels(lltrace) self.total_compiled_loops += 1 - for i, op in enumerate(operations): - if op.getopnum() == rop.LABEL: - self.known_labels[op.getdescr()] = (operations, i) - looptoken._llgraph_loop = LLLoop(inputargs, operations) def compile_bridge(self, faildescr, inputargs, operations, original_loop_token): - faildescr._llgraph_bridge = LLLoop(inputargs, operations) + lltrace = LLTrace(inputargs, operations, original_loop_token) + faildescr._llgraph_bridge = lltrace + original_loop_token._llgraph_alltraces.append(lltrace) + self._record_labels(lltrace) self.total_compiled_bridges += 1 + def _record_labels(self, lltrace): + for i, op in enumerate(lltrace.operations): + if op.getopnum() == rop.LABEL: + self.known_labels[op.getdescr()] = (lltrace, i) + + def invalidate_loop(self, looptoken): + for trace in looptoken._llgraph_alltraces: + trace.invalid = True + def make_execute_token(self, *argtypes): return self._execute_token def _execute_token(self, loop_token, *args): - loop = loop_token._llgraph_loop - frame = LLFrame(self, loop.inputargs, args) + lltrace = loop_token._llgraph_loop + frame = LLFrame(self, lltrace.inputargs, args) try: - frame.execute(loop.operations) + frame.execute(lltrace) assert False except ExecutionFinished, e: self.latest_values = e.args @@ -339,29 +355,30 @@ return arg.value return self.env[arg] - def execute(self, operations): + def execute(self, lltrace): + self.lltrace = lltrace + del lltrace i = 0 while True: - op = operations[i] + op = self.lltrace.operations[i] args = [self.lookup(arg) for arg in op.getarglist()] self.current_op = op # for label try: resval = getattr(self, 'execute_' + op.getopname())(op.getdescr(), *args) except Jump, j: - operations, i = self.cpu.known_labels[j.descr] - label_op = operations[i] + self.lltrace, i = self.cpu.known_labels[j.descr] + label_op = self.lltrace.operations[i] self.do_renaming(label_op.getarglist(), j.args) i += 1 continue except GuardFailed, gf: if hasattr(gf.descr, '_llgraph_bridge'): i = 0 - bridge = gf.descr._llgraph_bridge - operations = bridge.operations + self.lltrace = gf.descr._llgraph_bridge newargs = [self.env[arg] for arg in self.current_op.getfailargs() if arg is not None] - self.do_renaming(bridge.inputargs, newargs) + self.do_renaming(self.lltrace.inputargs, newargs) continue raise if op.result is not None: @@ -455,8 +472,8 @@ pass # XXX def execute_guard_not_invalidated(self, descr): - if self.loop.invalid: - raise GuardFailed + if self.lltrace.invalid: + self.fail_guard(descr) def execute_int_add_ovf(self, _, x, y): try: From noreply at buildbot.pypy.org Wed Oct 17 12:27:54 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 12:27:54 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal, arigo) completely random progress Message-ID: <20121017102754.1132E1C0FB8@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58161:80b606bc9e83 Date: 2012-10-17 12:27 +0200 http://bitbucket.org/pypy/pypy/changeset/80b606bc9e83/ Log: (fijal, arigo) completely random progress diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -259,31 +259,39 @@ array = a._obj.container return array.getlength() + def bh_getarrayitem_gc(self, a, index, descr): + array = a._obj.container + return support.cast_result(descr.A.OF, array.getitem(index)) + + bh_getarrayitem_gc_i = bh_getarrayitem_gc + bh_getarrayitem_gc_r = bh_getarrayitem_gc + bh_getarrayitem_gc_f = bh_getarrayitem_gc + def bh_setarrayitem_gc(self, a, index, item, descr): array = a._obj.container array.setitem(index, support.cast_arg(descr.A.OF, item)) - def bh_getarrayitem_gc(self, a, index, descr): - array = a._obj.container - return support.cast_result(descr.A.OF, array.getitem(index)) + bh_setarrayitem_gc_i = bh_setarrayitem_gc + bh_setarrayitem_gc_r = bh_setarrayitem_gc + bh_setarrayitem_gc_f = bh_setarrayitem_gc def bh_getinteriorfield_gc(self, a, index, descr): array = a._obj.container return support.cast_result(descr.FIELD, getattr(array.getitem(index), descr.fieldname)) - bh_getinteriorfield_gc_f = bh_getinteriorfield_gc bh_getinteriorfield_gc_i = bh_getinteriorfield_gc bh_getinteriorfield_gc_r = bh_getinteriorfield_gc + bh_getinteriorfield_gc_f = bh_getinteriorfield_gc def bh_setinteriorfield_gc(self, a, index, item, descr): array = a._obj.container setattr(array.getitem(index), descr.fieldname, support.cast_arg(descr.FIELD, item)) + bh_setinteriorfield_gc_i = bh_setinteriorfield_gc + bh_setinteriorfield_gc_r = bh_setinteriorfield_gc bh_setinteriorfield_gc_f = bh_setinteriorfield_gc - bh_setinteriorfield_gc_r = bh_setinteriorfield_gc - bh_setinteriorfield_gc_i = bh_setinteriorfield_gc def bh_newstr(self, length): return lltype.cast_opaque_ptr(llmemory.GCREF, diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2564,13 +2564,13 @@ A = lltype.GcArray(lltype.Char) descr_A = cpu.arraydescrof(A) a = lltype.malloc(A, 5) - x = cpu.bh_arraylen_gc(descr_A, - lltype.cast_opaque_ptr(llmemory.GCREF, a)) + x = cpu.bh_arraylen_gc(lltype.cast_opaque_ptr(llmemory.GCREF, a), + descr_A) assert x == 5 # a[2] = 'Y' x = cpu.bh_getarrayitem_gc_i( - descr_A, lltype.cast_opaque_ptr(llmemory.GCREF, a), 2) + lltype.cast_opaque_ptr(llmemory.GCREF, a), 2, descr_A) assert x == ord('Y') # B = lltype.GcArray(lltype.Ptr(A)) @@ -2578,7 +2578,7 @@ b = lltype.malloc(B, 4) b[3] = a x = cpu.bh_getarrayitem_gc_r( - descr_B, lltype.cast_opaque_ptr(llmemory.GCREF, b), 3) + lltype.cast_opaque_ptr(llmemory.GCREF, b), 3, descr_B) assert lltype.cast_opaque_ptr(lltype.Ptr(A), x) == a if self.cpu.supports_floats: C = lltype.GcArray(lltype.Float) @@ -2610,8 +2610,7 @@ assert x == ord('Z') # cpu.bh_setfield_gc_i(lltype.cast_opaque_ptr(llmemory.GCREF, s), - descrfld_x, - ord('4')) + ord('4'), descrfld_x) assert s.x == '4' # descrfld_y = cpu.fielddescrof(S, 'y') @@ -2622,7 +2621,7 @@ # s.y = lltype.nullptr(A) cpu.bh_setfield_gc_r(lltype.cast_opaque_ptr(llmemory.GCREF, s), - descrfld_y, x) + x, descrfld_y) assert s.y == a # RS = lltype.Struct('S', ('x', lltype.Char)) #, ('y', lltype.Ptr(A))) @@ -2685,11 +2684,11 @@ array = lltype.cast_opaque_ptr(lltype.Ptr(A), x) assert len(array) == 7 # - cpu.bh_setarrayitem_gc_i(descr_A, x, 5, ord('*')) + cpu.bh_setarrayitem_gc_i(x, 5, ord('*'), descr_A) assert array[5] == '*' # cpu.bh_setarrayitem_gc_r( - descr_B, lltype.cast_opaque_ptr(llmemory.GCREF, b), 1, x) + lltype.cast_opaque_ptr(llmemory.GCREF, b), 1, x, descr_B) assert b[1] == array # x = cpu.bh_newstr(5) From noreply at buildbot.pypy.org Wed Oct 17 12:37:46 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 12:37:46 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal, arigo) pass few more tests, really Message-ID: <20121017103746.A5E621C0FB8@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58162:39517f9580e2 Date: 2012-10-17 12:37 +0200 http://bitbucket.org/pypy/pypy/changeset/39517f9580e2/ Log: (fijal, arigo) pass few more tests, really diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -11,6 +11,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr from pypy.rlib.rarithmetic import ovfcheck +from pypy.rlib.rtimer import read_timestamp class LLTrace(object): has_been_freed = False @@ -53,6 +54,9 @@ self.fieldname = fieldname self.FIELD = getattr(S, fieldname) + def sort_key(self): + return self.fieldname + def is_pointer_field(self): return getkind(self.FIELD) == 'ref' @@ -70,7 +74,12 @@ self.FIELD = getattr(A.OF, fieldname) class LLGraphCPU(model.AbstractCPU): + supports_floats = True + supports_longlong = True + supports_singlefloats = True + def __init__(self, rtyper): + model.AbstractCPU.__init__(self) self.rtyper = rtyper self.llinterp = LLInterpreter(rtyper) self.known_labels = WeakKeyDictionary() @@ -240,21 +249,31 @@ bh_call_v = _do_call def bh_getfield_gc(self, p, descr): - p = lltype.cast_opaque_ptr(lltype.Ptr(descr.S), p) + p = support.cast_arg(lltype.Ptr(descr.S), p) return support.cast_result(descr.FIELD, getattr(p, descr.fieldname)) bh_getfield_gc_i = bh_getfield_gc bh_getfield_gc_r = bh_getfield_gc bh_getfield_gc_f = bh_getfield_gc + bh_getfield_raw = bh_getfield_gc + bh_getfield_raw_i = bh_getfield_raw + bh_getfield_raw_r = bh_getfield_raw + bh_getfield_raw_f = bh_getfield_raw + def bh_setfield_gc(self, p, newvalue, descr): - p = lltype.cast_opaque_ptr(lltype.Ptr(descr.S), p) + p = support.cast_arg(lltype.Ptr(descr.S), p) setattr(p, descr.fieldname, support.cast_arg(descr.FIELD, newvalue)) bh_setfield_gc_i = bh_setfield_gc bh_setfield_gc_r = bh_setfield_gc bh_setfield_gc_f = bh_setfield_gc + 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): array = a._obj.container return array.getlength() @@ -348,6 +367,9 @@ array = lltype.malloc(arraydescr.A, length, zero=True) return lltype.cast_opaque_ptr(llmemory.GCREF, array) + def bh_read_timestamp(self): + return read_timestamp() + class LLFrame(object): def __init__(self, cpu, argboxes, args): @@ -369,6 +391,9 @@ i = 0 while True: op = self.lltrace.operations[i] + if op.getopnum() == -124: # force_spill, for tests + i += 1 + continue args = [self.lookup(arg) for arg in op.getarglist()] self.current_op = op # for label try: diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2586,11 +2586,11 @@ c[3] = 3.5 descr_C = cpu.arraydescrof(C) x = cpu.bh_getarrayitem_gc_f( - descr_C, lltype.cast_opaque_ptr(llmemory.GCREF, c), 3) + lltype.cast_opaque_ptr(llmemory.GCREF, c), 3, descr_C) assert longlong.getrealfloat(x) == 3.5 cpu.bh_setarrayitem_gc_f( - descr_C, lltype.cast_opaque_ptr(llmemory.GCREF, c), 4, - longlong.getfloatstorage(4.5)) + lltype.cast_opaque_ptr(llmemory.GCREF, c), 4, + longlong.getfloatstorage(4.5), descr_C) assert c[4] == 4.5 s = rstr.mallocstr(6) x = cpu.bh_strlen(lltype.cast_opaque_ptr(llmemory.GCREF, s)) @@ -2635,15 +2635,14 @@ # cpu.bh_setfield_raw_i( heaptracker.adr2int(llmemory.cast_ptr_to_adr(rs)), - descrfld_rx, ord('!')) + ord('!'), descrfld_rx) assert rs.x == '!' # - if self.cpu.supports_floats: descrfld_z = cpu.fielddescrof(S, 'z') cpu.bh_setfield_gc_f( lltype.cast_opaque_ptr(llmemory.GCREF, s), - descrfld_z, longlong.getfloatstorage(3.5)) + longlong.getfloatstorage(3.5), descrfld_z) assert s.z == 3.5 s.z = 3.2 x = cpu.bh_getfield_gc_f( @@ -2674,7 +2673,7 @@ vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) vtable2_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(vtable2)) heaptracker.register_known_gctype(cpu, vtable2, rclass.OBJECT) - x = cpu.bh_new_with_vtable(descrsize2, vtable2_int) + x = cpu.bh_new_with_vtable(vtable2_int, descrsize2) lltype.cast_opaque_ptr(lltype.Ptr(rclass.OBJECT), x) # type check # well... #assert x.getref(rclass.OBJECTPTR).typeptr == vtable2 From noreply at buildbot.pypy.org Wed Oct 17 14:14:00 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 14:14:00 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: call_assembler support, initial version Message-ID: <20121017121400.3D9AD1C1C84@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58163:55132b711d27 Date: 2012-10-17 14:13 +0200 http://bitbucket.org/pypy/pypy/changeset/55132b711d27/ Log: call_assembler support, initial version diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -3,9 +3,10 @@ from pypy.jit.backend import model from pypy.jit.backend.llgraph import support -from pypy.jit.metainterp.history import Const, getkind, AbstractDescr, VOID +from pypy.jit.metainterp.history import Const, getkind, AbstractDescr +from pypy.jit.metainterp.history import INT, REF, FLOAT, VOID from pypy.jit.metainterp.resoperation import rop -from pypy.jit.codewriter import heaptracker +from pypy.jit.codewriter import longlong, heaptracker from pypy.rpython.llinterp import LLInterpreter, LLException from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr @@ -415,7 +416,16 @@ continue raise if op.result is not None: - assert resval is not None + # typecheck the result + if op.result.type == INT: + assert lltype.typeOf(resval) == lltype.Signed + elif op.result.type == REF: + assert lltype.typeOf(resval) == llmemory.GCREF + elif op.result.type == FLOAT: + assert lltype.typeOf(resval) == longlong.FLOATSTORAGE + else: + raise AssertionError(op.result.type) + # self.env[op.result] = resval else: assert resval is None @@ -565,6 +575,48 @@ func_to_call = rffi.cast(lltype.Ptr(FUNC), func) return self.cpu.call(func_to_call, call_args, descr.RESULT, descr) + def execute_call_assembler(self, descr, *args): + faildescr = self.cpu._execute_token(descr, *args) + jd = descr.outermost_jitdriver_sd + if jd.index_of_virtualizable != -1: + vable = args[jd.index_of_virtualizable] + else: + vable = lltype.nullptr(llmemory.GCREF.TO) + # + # Emulate the fast path + failindex = self.cpu.get_fail_descr_number(faildescr) + if failindex == self.cpu.done_with_this_frame_int_v: + self._reset_vable(jd, vable) + return self.cpu.get_latest_value_int(0) + if failindex == self.cpu.done_with_this_frame_ref_v: + self._reset_vable(jd, vable) + return self.cpu.get_latest_value_ref(0) + if failindex == self.cpu.done_with_this_frame_float_v: + self._reset_vable(jd, vable) + return self.cpu.get_latest_value_float(0) + if failindex == self.cpu.done_with_this_frame_void_v: + self._reset_vable(jd, vable) + return None + # + assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish + try: + result = assembler_helper_ptr(failindex, vable) + except LLException, lle: + xxxxxxxxxx + assert _last_exception is None, "exception left behind" + _last_exception = lle + # fish op + op = self.loop.operations[self.opindex] + if op.result is not None: + yyyyyyyyyyyyy + return 0 + return support.cast_result(lltype.typeOf(result), result) + + def _reset_vable(self, jd, vable): + if jd.index_of_virtualizable != -1: + fielddescr = jd.vable_token_descr + self.cpu.bh_setfield_gc_i(vable, 0, fielddescr) + def execute_same_as(self, _, x): return x From noreply at buildbot.pypy.org Wed Oct 17 14:26:21 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 14:26:21 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: {get, set}arrayitem_raw Message-ID: <20121017122621.533531C1C84@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58164:b458ff289b23 Date: 2012-10-17 14:26 +0200 http://bitbucket.org/pypy/pypy/changeset/b458ff289b23/ Log: {get,set}arrayitem_raw diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -280,21 +280,33 @@ return array.getlength() def bh_getarrayitem_gc(self, a, index, descr): - array = a._obj.container + a = support.cast_arg(lltype.Ptr(descr.A), a) + array = a._obj return support.cast_result(descr.A.OF, array.getitem(index)) bh_getarrayitem_gc_i = bh_getarrayitem_gc bh_getarrayitem_gc_r = bh_getarrayitem_gc bh_getarrayitem_gc_f = bh_getarrayitem_gc + bh_getarrayitem_raw = bh_getarrayitem_gc + bh_getarrayitem_raw_i = bh_getarrayitem_raw + bh_getarrayitem_raw_r = bh_getarrayitem_raw + bh_getarrayitem_raw_f = bh_getarrayitem_raw + def bh_setarrayitem_gc(self, a, index, item, descr): - array = a._obj.container + a = support.cast_arg(lltype.Ptr(descr.A), a) + array = a._obj array.setitem(index, support.cast_arg(descr.A.OF, item)) bh_setarrayitem_gc_i = bh_setarrayitem_gc bh_setarrayitem_gc_r = bh_setarrayitem_gc bh_setarrayitem_gc_f = bh_setarrayitem_gc + bh_setarrayitem_raw = bh_setarrayitem_gc + bh_setarrayitem_raw_i = bh_setarrayitem_raw + bh_setarrayitem_raw_r = bh_setarrayitem_raw + bh_setarrayitem_raw_f = bh_setarrayitem_raw + def bh_getinteriorfield_gc(self, a, index, descr): array = a._obj.container return support.cast_result(descr.FIELD, From noreply at buildbot.pypy.org Wed Oct 17 14:38:04 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 14:38:04 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: redirect_call_assembler Message-ID: <20121017123804.386051C1C84@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58165:d591e13a1084 Date: 2012-10-17 14:31 +0200 http://bitbucket.org/pypy/pypy/changeset/d591e13a1084/ Log: redirect_call_assembler diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -111,6 +111,16 @@ for trace in looptoken._llgraph_alltraces: trace.invalid = True + def redirect_call_assembler(self, oldlooptoken, newlooptoken): + oldtrace = oldlooptoken._llgraph_loop + newtrace = newlooptoken._llgraph_loop + OLD = [box.type for box in oldtrace.inputargs] + NEW = [box.type for box in newtrace.inputargs] + assert OLD == NEW + assert not hasattr(oldlooptoken, '_llgraph_redirected') + oldlooptoken._llgraph_redirected = True + oldlooptoken._llgraph_loop = newtrace + def make_execute_token(self, *argtypes): return self._execute_token From noreply at buildbot.pypy.org Wed Oct 17 14:38:05 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 14:38:05 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: fixes Message-ID: <20121017123805.727B71C1C84@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58166:3286418ab00f Date: 2012-10-17 14:32 +0200 http://bitbucket.org/pypy/pypy/changeset/3286418ab00f/ Log: fixes diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -3027,7 +3027,7 @@ expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value)) a[3] = rffi.cast(RESTYPE, value) x = cpu.bh_getarrayitem_gc_i( - descrarray, lltype.cast_opaque_ptr(llmemory.GCREF, a), 3) + lltype.cast_opaque_ptr(llmemory.GCREF, a), 3, descrarray) assert x == expected, ( "%r: got %r, expected %r" % (RESTYPE, x, expected)) @@ -3069,7 +3069,7 @@ expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value)) a[3] = rffi.cast(RESTYPE, value) a_rawint = heaptracker.adr2int(llmemory.cast_ptr_to_adr(a)) - x = cpu.bh_getarrayitem_raw_i(descrarray, a_rawint, 3) + x = cpu.bh_getarrayitem_raw_i(a_rawint, 3, descrarray) assert x == expected, ( "%r: got %r, expected %r" % (RESTYPE, x, expected)) lltype.free(a, flavor='raw') From noreply at buildbot.pypy.org Wed Oct 17 14:38:06 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 14:38:06 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: call to sqrt(). details Message-ID: <20121017123806.9BC6F1C1C84@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58167:1941bfe12a4d Date: 2012-10-17 14:37 +0200 http://bitbucket.org/pypy/pypy/changeset/1941bfe12a4d/ Log: call to sqrt(). details diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -7,6 +7,7 @@ from pypy.jit.metainterp.history import INT, REF, FLOAT, VOID from pypy.jit.metainterp.resoperation import rop from pypy.jit.codewriter import longlong, heaptracker +from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.rpython.llinterp import LLInterpreter, LLException from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr @@ -39,9 +40,12 @@ self.args = args class CallDescr(AbstractDescr): - def __init__(self, RESULT, ARGS): + def __init__(self, RESULT, ARGS, extrainfo=None): self.RESULT = RESULT self.ARGS = ARGS + self.extrainfo = extrainfo + def get_extra_info(self): + return self.extrainfo class SizeDescr(AbstractDescr): def __init__(self, S): @@ -163,7 +167,7 @@ try: return self.descrs[key] except KeyError: - descr = CallDescr(RESULT, ARGS) + descr = CallDescr(RESULT, ARGS, effect_info) self.descrs[key] = descr return descr @@ -440,7 +444,8 @@ if op.result is not None: # typecheck the result if op.result.type == INT: - assert lltype.typeOf(resval) == lltype.Signed + resval = int(resval) + assert isinstance(resval, int) elif op.result.type == REF: assert lltype.typeOf(resval) == llmemory.GCREF elif op.result.type == FLOAT: @@ -584,12 +589,23 @@ def execute_jump(self, descr, *args): raise Jump(descr, args) - def execute_call(self, descr, func, *args): + def _do_math_sqrt(self, value): + import math + y = support.cast_from_floatstorage(lltype.Float, value) + x = math.sqrt(y) + return support.cast_to_floatstorage(x) + + def execute_call(self, calldescr, func, *args): + effectinfo = calldescr.get_extra_info() + if effectinfo is not None and hasattr(effectinfo, 'oopspecindex'): + oopspecindex = effectinfo.oopspecindex + if oopspecindex == EffectInfo.OS_MATH_SQRT: + return self._do_math_sqrt(args[0]) TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE ARGS = TP.ARGS call_args = support.cast_call_args_in_order(ARGS, args) func = llmemory.cast_int_to_adr(func).ptr._obj._callable - return self.cpu.call(func, call_args, TP.RESULT, descr) + return self.cpu.call(func, call_args, TP.RESULT, calldescr) def execute_call_release_gil(self, descr, func, *args): call_args = support.cast_call_args_in_order(descr.ARGS, args) From noreply at buildbot.pypy.org Wed Oct 17 14:38:49 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 17 Oct 2012 14:38:49 +0200 (CEST) Subject: [pypy-commit] pypy default: manually revert f1c048beb436: this has never been true on CPython, no clue why it was introduced Message-ID: <20121017123849.91FD91C1C92@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r58168:6d1ad31ec914 Date: 2012-10-17 14:38 +0200 http://bitbucket.org/pypy/pypy/changeset/6d1ad31ec914/ Log: manually revert f1c048beb436: this has never been true on CPython, no clue why it was introduced diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py --- a/pypy/objspace/std/complextype.py +++ b/pypy/objspace/std/complextype.py @@ -190,13 +190,18 @@ w_z = space.get_and_call_function(w_method, w_complex) # if w_z is not None: - # __complex__() must return a complex object + # __complex__() must return a complex or (float,int,long) object # (XXX should not use isinstance here) - if not isinstance(w_z, W_ComplexObject): - raise OperationError(space.w_TypeError, - space.wrap("__complex__() must return" - " a complex number")) - return (w_z.realval, w_z.imagval) + if (space.isinstance_w(w_z, space.w_int) or + space.isinstance_w(w_z, space.w_long) or + space.isinstance_w(w_z, space.w_float)): + return (space.float_w(w_z), 0.0) + elif isinstance(w_z, W_ComplexObject): + return (w_z.realval, w_z.imagval) + raise OperationError(space.w_TypeError, + space.wrap("__complex__() must return" + " a number")) + # # no '__complex__' method, so we assume it is a float, # unless it is an instance of some subclass of complex. diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -249,10 +249,16 @@ assert complex(NS(1+10j), 5) == 1+15j assert complex(OS(1+10j), 5j) == -4+10j assert complex(NS(1+10j), 5j) == -4+10j + + assert complex(OS(2.0)) == 2+0j + assert complex(NS(2.0)) == 2+0j + assert complex(OS(2)) == 2+0j + assert complex(NS(2)) == 2+0j + assert complex(OS(2L)) == 2+0j + assert complex(NS(2L)) == 2+0j + raises(TypeError, complex, OS(None)) raises(TypeError, complex, NS(None)) - raises(TypeError, complex, OS(2.0)) # __complex__ must really - raises(TypeError, complex, NS(2.0)) # return a complex, not a float # -- The following cases are not supported by CPython, but they # -- are supported by PyPy, which is most probably ok From noreply at buildbot.pypy.org Wed Oct 17 14:53:26 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 14:53:26 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: Add reprs to the common descrs. Support raw_load, raw_store. Message-ID: <20121017125326.2A3EA1C1C8C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58169:823a1faa62d2 Date: 2012-10-17 14:53 +0200 http://bitbucket.org/pypy/pypy/changeset/823a1faa62d2/ Log: Add reprs to the common descrs. Support raw_load, raw_store. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -46,12 +46,17 @@ self.extrainfo = extrainfo def get_extra_info(self): return self.extrainfo + def __repr__(self): + return 'CallDescr(%r, %r, %r)' % (self.RESULT, self.ARGS, + self.extrainfo) class SizeDescr(AbstractDescr): def __init__(self, S): self.S = S def as_vtable_size_descr(self): return self + def __repr__(self): + return 'SizeDescr(%r)' % (self.S,) class FieldDescr(AbstractDescr): def __init__(self, S, fieldname): @@ -59,6 +64,9 @@ self.fieldname = fieldname self.FIELD = getattr(S, fieldname) + def __repr__(self): + return 'FieldDescr(%r, %r)' % (self.S, self.fieldname) + def sort_key(self): return self.fieldname @@ -69,6 +77,9 @@ def __init__(self, A): self.A = A + def __repr__(self): + return 'ArrayDescr(%r)' % (self.A,) + def is_array_of_pointers(self): return getkind(self.A.OF) == 'ref' @@ -78,6 +89,10 @@ self.fieldname = fieldname self.FIELD = getattr(A.OF, fieldname) + def __repr__(self): + return 'InteriorFieldDescr(%r, %r)' % (self.A, self.fieldname) + + class LLGraphCPU(model.AbstractCPU): supports_floats = True supports_longlong = True @@ -339,6 +354,41 @@ bh_setinteriorfield_gc_r = bh_setinteriorfield_gc bh_setinteriorfield_gc_f = bh_setinteriorfield_gc + def bh_raw_load_i(self, struct, offset, descr): + ll_p = rffi.cast(rffi.CCHARP, struct) + ll_p = rffi.cast(lltype.Ptr(descr.A), rffi.ptradd(ll_p, offset)) + value = ll_p[0] + return support.cast_result(descr.A.OF, value) + + def bh_raw_load_f(self, struct, offset, descr): + ll_p = rffi.cast(rffi.CCHARP, struct) + ll_p = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), + rffi.ptradd(ll_p, offset)) + return ll_p[0] + + def bh_raw_load(self, struct, offset, descr): + if descr.A.OF == lltype.Float: + return self.bh_raw_load_f(struct, offset, descr) + else: + return self.bh_raw_load_i(struct, offset, descr) + + def bh_raw_store_i(self, struct, offset, newvalue, descr): + ll_p = rffi.cast(rffi.CCHARP, struct) + ll_p = rffi.cast(lltype.Ptr(descr.A), rffi.ptradd(ll_p, offset)) + ll_p[0] = rffi.cast(descr.A.OF, newvalue) + + def bh_raw_store_f(self, struct, offset, newvalue, descr): + ll_p = rffi.cast(rffi.CCHARP, struct) + ll_p = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), + rffi.ptradd(ll_p, offset)) + ll_p[0] = newvalue + + def bh_raw_store(self, struct, offset, newvalue, descr): + if descr.A.OF == lltype.Float: + self.bh_raw_store_f(struct, offset, newvalue, descr) + else: + self.bh_raw_store_i(struct, offset, newvalue, descr) + def bh_newstr(self, length): return lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.STR, length)) From noreply at buildbot.pypy.org Wed Oct 17 15:56:04 2012 From: noreply at buildbot.pypy.org (bivab) Date: Wed, 17 Oct 2012 15:56:04 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: use same color for group and single plot Message-ID: <20121017135604.43DBE1C1C8D@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4869:edece417a029 Date: 2012-10-17 10:55 -0300 http://bitbucket.org/pypy/extradoc/changeset/edece417a029/ Log: use same color for group and single plot diff --git a/talk/vmil2012/presentation/figures/data.tex b/talk/vmil2012/presentation/figures/data.tex --- a/talk/vmil2012/presentation/figures/data.tex +++ b/talk/vmil2012/presentation/figures/data.tex @@ -3,51 +3,51 @@ (0.000000,1.000000) (0.006494,0.148545) (0.012987,0.143156) (0.019481,0.074262) (0.025974,0.070332) (0.032468,0.047160) (0.038961,0.046744) (0.045455,0.041526) (0.051948,0.032187) (0.058442,0.027040) (0.064935,0.020597) (0.071429,0.018534) (0.077922,0.017118) (0.084416,0.016888) (0.090909,0.011212) (0.097403,0.009493) (0.103896,0.007359) (0.110390,0.007268) (0.116883,0.006596) (0.123377,0.005563) (0.129870,0.005529) (0.136364,0.005470) (0.142857,0.003591) (0.149351,0.002948) (0.155844,0.002945) (0.162338,0.002749) (0.168831,0.002558) (0.175325,0.001651) (0.181818,0.001644) (0.188312,0.001592) (0.194805,0.001582) (0.201299,0.001365) (0.207792,0.001362) (0.214286,0.000933) (0.220779,0.000887) (0.227273,0.000871) (0.233766,0.000863) (0.240260,0.000843) (0.246753,0.000726) (0.253247,0.000695) (0.259740,0.000594) (0.266234,0.000558) (0.272727,0.000534) (0.279221,0.000498) (0.285714,0.000389) (0.292208,0.000389) (0.298701,0.000382) (0.305195,0.000381) (0.311688,0.000376) (0.318182,0.000364) (0.324675,0.000340) (0.331169,0.000312) (0.337662,0.000237) (0.344156,0.000219) (0.350649,0.000204) (0.357143,0.000202) (0.363636,0.000202) (0.370130,0.000193) (0.376623,0.000174) (0.383117,0.000162) (0.389610,0.000139) (0.396104,0.000137) (0.402597,0.000135) (0.409091,0.000130) (0.415584,0.000130) (0.422078,0.000122) (0.428571,0.000119) (0.435065,0.000104) (0.441558,0.000101) (0.448052,0.000097) (0.454545,0.000087) (0.461039,0.000079) (0.467532,0.000069) (0.474026,0.000058) (0.480519,0.000051) (0.487013,0.000041) (0.493506,0.000040) (0.500000,0.000035) (0.506494,0.000029) (0.512987,0.000028) (0.519481,0.000028) (0.525974,0.000027) (0.532468,0.000026) (0.538961,0.000026) (0.545455,0.000024) (0.551948,0.000021) (0.558442,0.000018) (0.564935,0.000018) (0.571429,0.000017) (0.577922,0.000016) (0.584416,0.000015) (0.590909,0.000015) (0.597403,0.000014) (0.603896,0.000014) (0.610390,0.000011) (0.616883,0.000011) (0.623377,0.000011) (0.629870,0.000011) (0.636364,0.000011) (0.642857,0.000011) (0.649351,0.000011) (0.655844,0.000011) (0.662338,0.000010) (0.668831,0.000009) (0.675325,0.000007) (0.681818,0.000007) (0.688312,0.000007) (0.694805,0.000007) (0.701299,0.000007) (0.707792,0.000006) (0.714286,0.000006) (0.720779,0.000005) (0.727273,0.000005) (0.733766,0.000005) (0.740260,0.000005) (0.746753,0.000004) (0.753247,0.000004) (0.759740,0.000003) (0.766234,0.000003) (0.772727,0.000003) (0.779221,0.000003) (0.785714,0.000002) (0.792208,0.000002) (0.798701,0.000002) (0.805195,0.000002) (0.811688,0.000002) (0.818182,0.000002) (0.824675,0.000002) (0.831169,0.000002) (0.837662,0.000002) (0.844156,0.000002) (0.850649,0.000002) (0.857143,0.000002) (0.863636,0.000002) (0.870130,0.000001) (0.876623,0.000001) (0.883117,0.000001) (0.889610,0.000001) (0.896104,0.000001) (0.902597,0.000001) (0.909091,0.000001) (0.915584,0.000001) (0.922078,0.000001) (0.928571,0.000001) (0.935065,0.000001) (0.941558,0.000001) (0.948052,0.000000) (0.954545,0.000000) (0.961039,0.000000) (0.967532,0.000000) (0.974026,0.000000) (0.980519,0.000000) (0.987013,0.000000) (0.993506,0.000000) (1.000000,0.000000) }; \addplot[red,only marks,mark=*] coordinates {(0.006494,0.148545) (0.201299,0.001365) (0.415584,0.000130)}; -\addplot[green,only marks,mark=*] coordinates {(0.060976,0.459611) (0.524390,0.006634) (0.756098,0.001243)}; \addplot[green,mark=none] coordinates { (0.000000,1.000000) (0.012195,0.997326) (0.024390,0.701335) (0.036585,0.503352) (0.048780,0.496172) (0.060976,0.459611) (0.073171,0.381570) (0.085366,0.349645) (0.097561,0.315892) (0.109756,0.312117) (0.121951,0.242322) (0.134146,0.213275) (0.146341,0.186336) (0.158537,0.114441) (0.170732,0.077514) (0.182927,0.054374) (0.195122,0.047764) (0.207317,0.043576) (0.219512,0.039644) (0.231707,0.029204) (0.243902,0.029145) (0.256098,0.027214) (0.268293,0.023030) (0.280488,0.016877) (0.292683,0.016283) (0.304878,0.015489) (0.317073,0.014624) (0.329268,0.014572) (0.341463,0.014451) (0.353659,0.009960) (0.365854,0.009811) (0.378049,0.009299) (0.390244,0.009197) (0.402439,0.009182) (0.414634,0.009178) (0.426829,0.007813) (0.439024,0.007797) (0.451220,0.007786) (0.463415,0.007715) (0.475610,0.007381) (0.487805,0.007172) (0.500000,0.006791) (0.512195,0.006783) (0.524390,0.006634) (0.536585,0.006366) (0.548780,0.005879) (0.560976,0.004203) (0.573171,0.004074) (0.585366,0.003983) (0.597561,0.003260) (0.609756,0.003252) (0.621951,0.003181) (0.634146,0.002945) (0.646341,0.002670) (0.658537,0.002399) (0.670732,0.002159) (0.682927,0.002143) (0.695122,0.001817) (0.707317,0.001793) (0.719512,0.001785) (0.731707,0.001577) (0.743902,0.001573) (0.756098,0.001243) (0.768293,0.001073) (0.780488,0.000598) (0.792683,0.000590) (0.804878,0.000492) (0.817073,0.000440) (0.829268,0.000240) (0.841463,0.000201) (0.853659,0.000201) (0.865854,0.000197) (0.878049,0.000177) (0.890244,0.000079) (0.902439,0.000079) (0.914634,0.000067) (0.926829,0.000031) (0.939024,0.000028) (0.951220,0.000024) (0.963415,0.000012) (0.975610,0.000008) (0.987805,0.000004) (1.000000,0.000004) }; -\addplot[blue,only marks,mark=*] coordinates {(0.045045,0.253942) (0.378378,0.003324) (0.585586,0.000480)}; +\addplot[green,only marks,mark=*] coordinates {(0.060976,0.459611) (0.524390,0.006634) (0.756098,0.001243)}; \addplot[blue,mark=none] coordinates { (0.000000,1.000000) (0.009009,0.274799) (0.018018,0.254401) (0.027027,0.254401) (0.036036,0.254400) (0.045045,0.253942) (0.054054,0.176493) (0.063063,0.170575) (0.072072,0.170575) (0.081081,0.166477) (0.090090,0.103439) (0.099099,0.087880) (0.108108,0.085545) (0.117117,0.085441) (0.126126,0.077913) (0.135135,0.075639) (0.144144,0.059419) (0.153153,0.052926) (0.162162,0.051446) (0.171171,0.040551) (0.180180,0.036356) (0.189189,0.031443) (0.198198,0.026162) (0.207207,0.023960) (0.216216,0.020391) (0.225225,0.018926) (0.234234,0.018265) (0.243243,0.018091) (0.252252,0.018011) (0.261261,0.015999) (0.270270,0.011937) (0.279279,0.010101) (0.288288,0.010101) (0.297297,0.009964) (0.306306,0.009956) (0.315315,0.009498) (0.324324,0.006923) (0.333333,0.006919) (0.342342,0.005088) (0.351351,0.004699) (0.360360,0.004400) (0.369369,0.004132) (0.378378,0.003324) (0.387387,0.003266) (0.396396,0.003017) (0.405405,0.002900) (0.414414,0.002389) (0.423423,0.001747) (0.432432,0.001717) (0.441441,0.001660) (0.450450,0.001634) (0.459459,0.001542) (0.468468,0.001353) (0.477477,0.001264) (0.486486,0.001263) (0.495495,0.001131) (0.504505,0.001046) (0.513514,0.000934) (0.522523,0.000928) (0.531532,0.000856) (0.540541,0.000850) (0.549550,0.000821) (0.558559,0.000745) (0.567568,0.000679) (0.576577,0.000581) (0.585586,0.000480) (0.594595,0.000316) (0.603604,0.000260) (0.612613,0.000256) (0.621622,0.000209) (0.630631,0.000195) (0.639640,0.000163) (0.648649,0.000161) (0.657658,0.000145) (0.666667,0.000136) (0.675676,0.000134) (0.684685,0.000128) (0.693694,0.000123) (0.702703,0.000117) (0.711712,0.000100) (0.720721,0.000099) (0.729730,0.000095) (0.738739,0.000088) (0.747748,0.000087) (0.756757,0.000065) (0.765766,0.000058) (0.774775,0.000052) (0.783784,0.000051) (0.792793,0.000045) (0.801802,0.000043) (0.810811,0.000033) (0.819820,0.000031) (0.828829,0.000028) (0.837838,0.000023) (0.846847,0.000019) (0.855856,0.000018) (0.864865,0.000017) (0.873874,0.000017) (0.882883,0.000016) (0.891892,0.000016) (0.900901,0.000016) (0.909910,0.000016) (0.918919,0.000015) (0.927928,0.000015) (0.936937,0.000012) (0.945946,0.000011) (0.954955,0.000009) (0.963964,0.000006) (0.972973,0.000005) (0.981982,0.000003) (0.990991,0.000001) (1.000000,0.000000) }; -\addplot[cyan,only marks,mark=*] coordinates {(0.040541,0.223088) (0.328829,0.004749) (0.563063,0.000352)}; +\addplot[blue,only marks,mark=*] coordinates {(0.045045,0.253942) (0.378378,0.003324) (0.585586,0.000480)}; \addplot[cyan,mark=none] coordinates { (0.000000,1.000000) (0.004505,0.536162) (0.009009,0.533859) (0.013514,0.483711) (0.018018,0.468958) (0.022523,0.385926) (0.027027,0.368855) (0.031532,0.330881) (0.036036,0.273385) (0.040541,0.223088) (0.045045,0.201529) (0.049550,0.188300) (0.054054,0.184877) (0.058559,0.165360) (0.063063,0.160965) (0.067568,0.151293) (0.072072,0.125402) (0.076577,0.121903) (0.081081,0.121395) (0.085586,0.117212) (0.090090,0.117117) (0.094595,0.099425) (0.099099,0.096936) (0.103604,0.096847) (0.108108,0.096552) (0.112613,0.096421) (0.117117,0.083108) (0.121622,0.076876) (0.126126,0.068604) (0.130631,0.064969) (0.135135,0.056385) (0.139640,0.056383) (0.144144,0.049812) (0.148649,0.049576) (0.153153,0.042719) (0.157658,0.042151) (0.162162,0.038817) (0.166667,0.038467) (0.171171,0.038437) (0.175676,0.038161) (0.180180,0.037712) (0.184685,0.037469) (0.189189,0.037434) (0.193694,0.037419) (0.198198,0.037035) (0.202703,0.037000) (0.207207,0.036987) (0.211712,0.035969) (0.216216,0.034370) (0.220721,0.033375) (0.225225,0.031819) (0.229730,0.031613) (0.234234,0.029056) (0.238739,0.028685) (0.243243,0.026102) (0.247748,0.023276) (0.252252,0.018629) (0.256757,0.018545) (0.261261,0.015560) (0.265766,0.013442) (0.270270,0.013322) (0.274775,0.011983) (0.279279,0.011599) (0.283784,0.008508) (0.288288,0.008463) (0.292793,0.008461) (0.297297,0.008456) (0.301802,0.007547) (0.306306,0.007021) (0.310811,0.006568) (0.315315,0.006344) (0.319820,0.005826) (0.324324,0.004751) (0.328829,0.004749) (0.333333,0.004749) (0.337838,0.003794) (0.342342,0.003082) (0.346847,0.002806) (0.351351,0.002767) (0.355856,0.002535) (0.360360,0.002472) (0.364865,0.002390) (0.369369,0.002320) (0.373874,0.002290) (0.378378,0.002275) (0.382883,0.002210) (0.387387,0.002049) (0.391892,0.001854) (0.396396,0.001647) (0.400901,0.001502) (0.405405,0.001322) (0.409910,0.001200) (0.414414,0.001161) (0.418919,0.001159) (0.423423,0.001146) (0.427928,0.001144) (0.432432,0.001116) (0.436937,0.001066) (0.441441,0.001059) (0.445946,0.001018) (0.450450,0.000873) (0.454955,0.000864) (0.459459,0.000840) (0.463964,0.000777) (0.468468,0.000766) (0.472973,0.000747) (0.477477,0.000729) (0.481982,0.000729) (0.486486,0.000621) (0.490991,0.000597) (0.495495,0.000590) (0.500000,0.000582) (0.504505,0.000577) (0.509009,0.000562) (0.513514,0.000558) (0.518018,0.000523) (0.522523,0.000478) (0.527027,0.000469) (0.531532,0.000456) (0.536036,0.000434) (0.540541,0.000432) (0.545045,0.000425) (0.549550,0.000425) (0.554054,0.000417) (0.558559,0.000412) (0.563063,0.000352) (0.567568,0.000332) (0.572072,0.000330) (0.576577,0.000326) (0.581081,0.000313) (0.585586,0.000289) (0.590090,0.000267) (0.594595,0.000247) (0.599099,0.000247) (0.603604,0.000217) (0.608108,0.000204) (0.612613,0.000195) (0.617117,0.000182) (0.621622,0.000165) (0.626126,0.000165) (0.630631,0.000163) (0.635135,0.000137) (0.639640,0.000137) (0.644144,0.000132) (0.648649,0.000130) (0.653153,0.000130) (0.657658,0.000122) (0.662162,0.000122) (0.666667,0.000122) (0.671171,0.000119) (0.675676,0.000115) (0.680180,0.000104) (0.684685,0.000104) (0.689189,0.000100) (0.693694,0.000096) (0.698198,0.000093) (0.702703,0.000087) (0.707207,0.000087) (0.711712,0.000087) (0.716216,0.000085) (0.720721,0.000085) (0.725225,0.000078) (0.729730,0.000074) (0.734234,0.000063) (0.738739,0.000059) (0.743243,0.000059) (0.747748,0.000059) (0.752252,0.000056) (0.756757,0.000056) (0.761261,0.000056) (0.765766,0.000054) (0.770270,0.000052) (0.774775,0.000052) (0.779279,0.000048) (0.783784,0.000046) (0.788288,0.000043) (0.792793,0.000041) (0.797297,0.000039) (0.801802,0.000039) (0.806306,0.000037) (0.810811,0.000037) (0.815315,0.000035) (0.819820,0.000035) (0.824324,0.000035) (0.828829,0.000033) (0.833333,0.000030) (0.837838,0.000030) (0.842342,0.000028) (0.846847,0.000028) (0.851351,0.000026) (0.855856,0.000026) (0.860360,0.000026) (0.864865,0.000024) (0.869369,0.000022) (0.873874,0.000020) (0.878378,0.000020) (0.882883,0.000017) (0.887387,0.000017) (0.891892,0.000017) (0.896396,0.000013) (0.900901,0.000013) (0.905405,0.000013) (0.909910,0.000011) (0.914414,0.000011) (0.918919,0.000011) (0.923423,0.000011) (0.927928,0.000011) (0.932432,0.000009) (0.936937,0.000009) (0.941441,0.000009) (0.945946,0.000009) (0.950450,0.000007) (0.954955,0.000007) (0.959459,0.000007) (0.963964,0.000004) (0.968468,0.000004) (0.972973,0.000004) (0.977477,0.000002) (0.981982,0.000002) (0.986486,0.000002) (0.990991,0.000002) (0.995495,0.000002) (1.000000,0.000002) }; -\addplot[magenta,only marks,mark=*] coordinates {(0.066667,0.333230) (0.300000,0.003317) (0.366667,0.000795)}; +\addplot[cyan,only marks,mark=*] coordinates {(0.040541,0.223088) (0.328829,0.004749) (0.563063,0.000352)}; \addplot[magenta,mark=none] coordinates { (0.000000,1.000000) (0.033333,0.333289) (0.066667,0.333230) (0.100000,0.330941) (0.133333,0.089999) (0.166667,0.087891) (0.200000,0.074485) (0.233333,0.074414) (0.266667,0.074281) (0.300000,0.003317) (0.333333,0.002204) (0.366667,0.000795) (0.400000,0.000294) (0.433333,0.000133) (0.466667,0.000099) (0.500000,0.000099) (0.533333,0.000067) (0.566667,0.000033) (0.600000,0.000032) (0.633333,0.000031) (0.666667,0.000025) (0.700000,0.000019) (0.733333,0.000010) (0.766667,0.000005) (0.800000,0.000003) (0.833333,0.000003) (0.866667,0.000003) (0.900000,0.000001) (0.933333,0.000001) (0.966667,0.000001) (1.000000,0.000001) }; -\addplot[yellow,only marks,mark=*] coordinates {(0.035088,0.506431) (0.070175,0.003334) (0.192982,0.000768)}; +\addplot[magenta,only marks,mark=*] coordinates {(0.066667,0.333230) (0.300000,0.003317) (0.366667,0.000795)}; \addplot[yellow,mark=none] coordinates { (0.000000,1.000000) (0.017544,0.993592) (0.035088,0.506431) (0.052632,0.496860) (0.070175,0.003334) (0.087719,0.003334) (0.105263,0.003290) (0.122807,0.003290) (0.140351,0.003290) (0.157895,0.003289) (0.175439,0.003250) (0.192982,0.000768) (0.210526,0.000464) (0.228070,0.000216) (0.245614,0.000205) (0.263158,0.000137) (0.280702,0.000133) (0.298246,0.000121) (0.315789,0.000105) (0.333333,0.000081) (0.350877,0.000067) (0.368421,0.000058) (0.385965,0.000055) (0.403509,0.000053) (0.421053,0.000052) (0.438596,0.000043) (0.456140,0.000034) (0.473684,0.000030) (0.491228,0.000029) (0.508772,0.000023) (0.526316,0.000022) (0.543860,0.000022) (0.561404,0.000022) (0.578947,0.000020) (0.596491,0.000019) (0.614035,0.000018) (0.631579,0.000014) (0.649123,0.000012) (0.666667,0.000011) (0.684211,0.000010) (0.701754,0.000006) (0.719298,0.000006) (0.736842,0.000005) (0.754386,0.000004) (0.771930,0.000004) (0.789474,0.000004) (0.807018,0.000003) (0.824561,0.000003) (0.842105,0.000002) (0.859649,0.000002) (0.877193,0.000001) (0.894737,0.000001) (0.912281,0.000001) (0.929825,0.000001) (0.947368,0.000000) (0.964912,0.000000) (0.982456,0.000000) (1.000000,0.000000) }; -\addplot[black,only marks,mark=*] coordinates {(0.001953,0.247783) (0.214844,0.000248) (0.519531,0.000021)}; +\addplot[yellow,only marks,mark=*] coordinates {(0.035088,0.506431) (0.070175,0.003334) (0.192982,0.000768)}; \addplot[black,mark=none] coordinates { (0.000000,1.000000) (0.001953,0.247783) (0.003906,0.056979) (0.005859,0.026968) (0.007812,0.019062) (0.009766,0.014136) (0.011719,0.011763) (0.013672,0.009968) (0.015625,0.009263) (0.017578,0.007132) (0.019531,0.006664) (0.021484,0.006547) (0.023438,0.006214) (0.025391,0.006190) (0.027344,0.005569) (0.029297,0.004773) (0.031250,0.004590) (0.033203,0.004576) (0.035156,0.004534) (0.037109,0.004497) (0.039062,0.004348) (0.041016,0.004135) (0.042969,0.003889) (0.044922,0.003631) (0.046875,0.003618) (0.048828,0.003285) (0.050781,0.003143) (0.052734,0.003024) (0.054688,0.003020) (0.056641,0.002903) (0.058594,0.002661) (0.060547,0.002589) (0.062500,0.002268) (0.064453,0.002194) (0.066406,0.002187) (0.068359,0.001941) (0.070312,0.001798) (0.072266,0.001740) (0.074219,0.001716) (0.076172,0.001704) (0.078125,0.001658) (0.080078,0.001649) (0.082031,0.001550) (0.083984,0.001484) (0.085938,0.001468) (0.087891,0.001432) (0.089844,0.001429) (0.091797,0.001423) (0.093750,0.001376) (0.095703,0.001359) (0.097656,0.001281) (0.099609,0.001224) (0.101562,0.001212) (0.103516,0.001182) (0.105469,0.001181) (0.107422,0.001174) (0.109375,0.001089) (0.111328,0.001037) (0.113281,0.001024) (0.115234,0.000993) (0.117188,0.000955) (0.119141,0.000955) (0.121094,0.000954) (0.123047,0.000954) (0.125000,0.000902) (0.126953,0.000889) (0.128906,0.000887) (0.130859,0.000881) (0.132812,0.000856) (0.134766,0.000823) (0.136719,0.000694) (0.138672,0.000676) (0.140625,0.000675) (0.142578,0.000675) (0.144531,0.000625) (0.146484,0.000616) (0.148438,0.000603) (0.150391,0.000591) (0.152344,0.000575) (0.154297,0.000573) (0.156250,0.000553) (0.158203,0.000514) (0.160156,0.000491) (0.162109,0.000467) (0.164062,0.000429) (0.166016,0.000426) (0.167969,0.000426) (0.169922,0.000421) (0.171875,0.000419) (0.173828,0.000418) (0.175781,0.000413) (0.177734,0.000408) (0.179688,0.000408) (0.181641,0.000388) (0.183594,0.000385) (0.185547,0.000355) (0.187500,0.000336) (0.189453,0.000334) (0.191406,0.000324) (0.193359,0.000303) (0.195312,0.000296) (0.197266,0.000291) (0.199219,0.000267) (0.201172,0.000265) (0.203125,0.000264) (0.205078,0.000261) (0.207031,0.000260) (0.208984,0.000259) (0.210938,0.000259) (0.212891,0.000251) (0.214844,0.000248) (0.216797,0.000245) (0.218750,0.000237) (0.220703,0.000215) (0.222656,0.000209) (0.224609,0.000208) (0.226562,0.000204) (0.228516,0.000201) (0.230469,0.000199) (0.232422,0.000197) (0.234375,0.000195) (0.236328,0.000179) (0.238281,0.000178) (0.240234,0.000178) (0.242188,0.000178) (0.244141,0.000178) (0.246094,0.000178) (0.248047,0.000178) (0.250000,0.000178) (0.251953,0.000171) (0.253906,0.000171) (0.255859,0.000170) (0.257812,0.000169) (0.259766,0.000166) (0.261719,0.000164) (0.263672,0.000163) (0.265625,0.000161) (0.267578,0.000160) (0.269531,0.000158) (0.271484,0.000155) (0.273438,0.000152) (0.275391,0.000148) (0.277344,0.000148) (0.279297,0.000148) (0.281250,0.000147) (0.283203,0.000147) (0.285156,0.000147) (0.287109,0.000146) (0.289062,0.000146) (0.291016,0.000145) (0.292969,0.000138) (0.294922,0.000136) (0.296875,0.000135) (0.298828,0.000134) (0.300781,0.000133) (0.302734,0.000132) (0.304688,0.000127) (0.306641,0.000125) (0.308594,0.000125) (0.310547,0.000124) (0.312500,0.000122) (0.314453,0.000121) (0.316406,0.000120) (0.318359,0.000119) (0.320312,0.000118) (0.322266,0.000118) (0.324219,0.000113) (0.326172,0.000110) (0.328125,0.000109) (0.330078,0.000107) (0.332031,0.000106) (0.333984,0.000104) (0.335938,0.000102) (0.337891,0.000097) (0.339844,0.000095) (0.341797,0.000092) (0.343750,0.000091) (0.345703,0.000089) (0.347656,0.000088) (0.349609,0.000086) (0.351562,0.000086) (0.353516,0.000086) (0.355469,0.000085) (0.357422,0.000085) (0.359375,0.000084) (0.361328,0.000083) (0.363281,0.000081) (0.365234,0.000081) (0.367188,0.000081) (0.369141,0.000077) (0.371094,0.000076) (0.373047,0.000076) (0.375000,0.000075) (0.376953,0.000074) (0.378906,0.000074) (0.380859,0.000067) (0.382812,0.000066) (0.384766,0.000065) (0.386719,0.000065) (0.388672,0.000062) (0.390625,0.000060) (0.392578,0.000055) (0.394531,0.000055) (0.396484,0.000051) (0.398438,0.000049) (0.400391,0.000049) (0.402344,0.000048) (0.404297,0.000046) (0.406250,0.000045) (0.408203,0.000044) (0.410156,0.000044) (0.412109,0.000044) (0.414062,0.000043) (0.416016,0.000042) (0.417969,0.000042) (0.419922,0.000041) (0.421875,0.000040) (0.423828,0.000040) (0.425781,0.000040) (0.427734,0.000038) (0.429688,0.000038) (0.431641,0.000037) (0.433594,0.000036) (0.435547,0.000035) (0.437500,0.000035) (0.439453,0.000034) (0.441406,0.000034) (0.443359,0.000034) (0.445312,0.000033) (0.447266,0.000032) (0.449219,0.000031) (0.451172,0.000031) (0.453125,0.000031) (0.455078,0.000029) (0.457031,0.000028) (0.458984,0.000027) (0.460938,0.000027) (0.462891,0.000027) (0.464844,0.000027) (0.466797,0.000026) (0.468750,0.000025) (0.470703,0.000025) (0.472656,0.000025) (0.474609,0.000024) (0.476562,0.000024) (0.478516,0.000023) (0.480469,0.000023) (0.482422,0.000023) (0.484375,0.000023) (0.486328,0.000023) (0.488281,0.000023) (0.490234,0.000023) (0.492188,0.000023) (0.494141,0.000023) (0.496094,0.000023) (0.498047,0.000023) (0.500000,0.000023) (0.501953,0.000023) (0.503906,0.000022) (0.505859,0.000022) (0.507812,0.000022) (0.509766,0.000022) (0.511719,0.000022) (0.513672,0.000021) (0.515625,0.000021) (0.517578,0.000021) (0.519531,0.000021) (0.521484,0.000021) (0.523438,0.000021) (0.525391,0.000021) (0.527344,0.000020) (0.529297,0.000020) (0.531250,0.000019) (0.533203,0.000019) (0.535156,0.000019) (0.537109,0.000019) (0.539062,0.000018) (0.541016,0.000018) (0.542969,0.000018) (0.544922,0.000018) (0.546875,0.000018) (0.548828,0.000018) (0.550781,0.000017) (0.552734,0.000017) (0.554688,0.000017) (0.556641,0.000017) (0.558594,0.000017) (0.560547,0.000016) (0.562500,0.000016) (0.564453,0.000016) (0.566406,0.000015) (0.568359,0.000015) (0.570312,0.000015) (0.572266,0.000015) (0.574219,0.000014) (0.576172,0.000014) (0.578125,0.000014) (0.580078,0.000014) (0.582031,0.000013) (0.583984,0.000013) (0.585938,0.000013) (0.587891,0.000013) (0.589844,0.000013) (0.591797,0.000012) (0.593750,0.000012) (0.595703,0.000012) (0.597656,0.000012) (0.599609,0.000012) (0.601562,0.000012) (0.603516,0.000012) (0.605469,0.000012) (0.607422,0.000011) (0.609375,0.000011) (0.611328,0.000011) (0.613281,0.000011) (0.615234,0.000011) (0.617188,0.000011) (0.619141,0.000011) (0.621094,0.000010) (0.623047,0.000010) (0.625000,0.000009) (0.626953,0.000009) (0.628906,0.000009) (0.630859,0.000009) (0.632812,0.000009) (0.634766,0.000009) (0.636719,0.000009) (0.638672,0.000009) (0.640625,0.000009) (0.642578,0.000009) (0.644531,0.000009) (0.646484,0.000009) (0.648438,0.000009) (0.650391,0.000009) (0.652344,0.000009) (0.654297,0.000009) (0.656250,0.000009) (0.658203,0.000009) (0.660156,0.000009) (0.662109,0.000009) (0.664062,0.000009) (0.666016,0.000009) (0.667969,0.000009) (0.669922,0.000008) (0.671875,0.000008) (0.673828,0.000008) (0.675781,0.000008) (0.677734,0.000008) (0.679688,0.000008) (0.681641,0.000008) (0.683594,0.000008) (0.685547,0.000008) (0.687500,0.000008) (0.689453,0.000008) (0.691406,0.000008) (0.693359,0.000008) (0.695312,0.000008) (0.697266,0.000008) (0.699219,0.000007) (0.701172,0.000007) (0.703125,0.000007) (0.705078,0.000007) (0.707031,0.000007) (0.708984,0.000007) (0.710938,0.000007) (0.712891,0.000007) (0.714844,0.000006) (0.716797,0.000006) (0.718750,0.000006) (0.720703,0.000006) (0.722656,0.000006) (0.724609,0.000006) (0.726562,0.000006) (0.728516,0.000006) (0.730469,0.000006) (0.732422,0.000005) (0.734375,0.000005) (0.736328,0.000005) (0.738281,0.000005) (0.740234,0.000005) (0.742188,0.000005) (0.744141,0.000005) (0.746094,0.000005) (0.748047,0.000005) (0.750000,0.000005) (0.751953,0.000005) (0.753906,0.000005) (0.755859,0.000004) (0.757812,0.000004) (0.759766,0.000004) (0.761719,0.000004) (0.763672,0.000004) (0.765625,0.000004) (0.767578,0.000004) (0.769531,0.000004) (0.771484,0.000004) (0.773438,0.000004) (0.775391,0.000004) (0.777344,0.000004) (0.779297,0.000004) (0.781250,0.000004) (0.783203,0.000004) (0.785156,0.000004) (0.787109,0.000004) (0.789062,0.000004) (0.791016,0.000004) (0.792969,0.000004) (0.794922,0.000004) (0.796875,0.000004) (0.798828,0.000004) (0.800781,0.000004) (0.802734,0.000003) (0.804688,0.000003) (0.806641,0.000003) (0.808594,0.000003) (0.810547,0.000003) (0.812500,0.000003) (0.814453,0.000003) (0.816406,0.000003) (0.818359,0.000003) (0.820312,0.000003) (0.822266,0.000003) (0.824219,0.000003) (0.826172,0.000003) (0.828125,0.000003) (0.830078,0.000003) (0.832031,0.000003) (0.833984,0.000003) (0.835938,0.000003) (0.837891,0.000003) (0.839844,0.000003) (0.841797,0.000003) (0.843750,0.000003) (0.845703,0.000003) (0.847656,0.000003) (0.849609,0.000003) (0.851562,0.000003) (0.853516,0.000002) (0.855469,0.000002) (0.857422,0.000002) (0.859375,0.000002) (0.861328,0.000002) (0.863281,0.000002) (0.865234,0.000002) (0.867188,0.000002) (0.869141,0.000002) (0.871094,0.000002) (0.873047,0.000002) (0.875000,0.000002) (0.876953,0.000002) (0.878906,0.000002) (0.880859,0.000002) (0.882812,0.000002) (0.884766,0.000002) (0.886719,0.000002) (0.888672,0.000002) (0.890625,0.000002) (0.892578,0.000002) (0.894531,0.000002) (0.896484,0.000002) (0.898438,0.000002) (0.900391,0.000001) (0.902344,0.000001) (0.904297,0.000001) (0.906250,0.000001) (0.908203,0.000001) (0.910156,0.000001) (0.912109,0.000001) (0.914062,0.000001) (0.916016,0.000001) (0.917969,0.000001) (0.919922,0.000001) (0.921875,0.000001) (0.923828,0.000001) (0.925781,0.000001) (0.927734,0.000001) (0.929688,0.000001) (0.931641,0.000001) (0.933594,0.000001) (0.935547,0.000001) (0.937500,0.000001) (0.939453,0.000001) (0.941406,0.000001) (0.943359,0.000001) (0.945312,0.000001) (0.947266,0.000001) (0.949219,0.000001) (0.951172,0.000001) (0.953125,0.000001) (0.955078,0.000001) (0.957031,0.000001) (0.958984,0.000001) (0.960938,0.000000) (0.962891,0.000000) (0.964844,0.000000) (0.966797,0.000000) (0.968750,0.000000) (0.970703,0.000000) (0.972656,0.000000) (0.974609,0.000000) (0.976562,0.000000) (0.978516,0.000000) (0.980469,0.000000) (0.982422,0.000000) (0.984375,0.000000) (0.986328,0.000000) (0.988281,0.000000) (0.990234,0.000000) (0.992188,0.000000) (0.994141,0.000000) (0.996094,0.000000) (0.998047,0.000000) (1.000000,0.000000) }; -\addplot[gray,only marks,mark=*] coordinates {(0.034483,0.386091) (0.396552,0.006830) (0.517241,0.000962)}; +\addplot[black,only marks,mark=*] coordinates {(0.001953,0.247783) (0.214844,0.000248) (0.519531,0.000021)}; \addplot[gray,mark=none] coordinates { (0.000000,1.000000) (0.017241,0.487558) (0.034483,0.386091) (0.051724,0.126229) (0.068966,0.108863) (0.086207,0.100941) (0.103448,0.097250) (0.120690,0.060934) (0.137931,0.054349) (0.155172,0.025283) (0.172414,0.025270) (0.189655,0.025262) (0.206897,0.025238) (0.224138,0.025208) (0.241379,0.022267) (0.258621,0.016262) (0.275862,0.016261) (0.293103,0.012610) (0.310345,0.009401) (0.327586,0.008822) (0.344828,0.008804) (0.362069,0.008801) (0.379310,0.007326) (0.396552,0.006830) (0.413793,0.003673) (0.431034,0.003672) (0.448276,0.003642) (0.465517,0.001939) (0.482759,0.001709) (0.500000,0.000965) (0.517241,0.000962) (0.534483,0.000277) (0.551724,0.000119) (0.568966,0.000093) (0.586207,0.000088) (0.603448,0.000050) (0.620690,0.000048) (0.637931,0.000043) (0.655172,0.000042) (0.672414,0.000025) (0.689655,0.000021) (0.706897,0.000011) (0.724138,0.000011) (0.741379,0.000011) (0.758621,0.000011) (0.775862,0.000011) (0.793103,0.000010) (0.810345,0.000009) (0.827586,0.000008) (0.844828,0.000006) (0.862069,0.000005) (0.879310,0.000004) (0.896552,0.000003) (0.913793,0.000002) (0.931034,0.000002) (0.948276,0.000001) (0.965517,0.000001) (0.982759,0.000001) (1.000000,0.000000) }; -\addplot[darkgray,only marks,mark=*] coordinates {(0.071429,0.409043) (0.285714,0.001856) (0.285714,0.001856)}; +\addplot[gray,only marks,mark=*] coordinates {(0.034483,0.386091) (0.396552,0.006830) (0.517241,0.000962)}; \addplot[darkgray,mark=none] coordinates { (0.000000,1.000000) (0.035714,0.909090) (0.071429,0.409043) (0.107143,0.409043) (0.142857,0.045445) (0.178571,0.045445) (0.214286,0.045437) (0.250000,0.045437) (0.285714,0.001856) (0.321429,0.000157) (0.357143,0.000150) (0.392857,0.000148) (0.428571,0.000138) (0.464286,0.000116) (0.500000,0.000070) (0.535714,0.000048) (0.571429,0.000032) (0.607143,0.000032) (0.642857,0.000032) (0.678571,0.000016) (0.714286,0.000009) (0.750000,0.000008) (0.785714,0.000008) (0.821429,0.000008) (0.857143,0.000006) (0.892857,0.000005) (0.928571,0.000002) (0.964286,0.000001) (1.000000,0.000001) }; -\addplot[lightgray,only marks,mark=*] coordinates {(0.038627,0.153140) (0.197425,0.002447) (0.433476,0.000174)}; +\addplot[darkgray,only marks,mark=*] coordinates {(0.071429,0.409043) (0.285714,0.001856) (0.285714,0.001856)}; \addplot[lightgray,mark=none] coordinates { (0.000000,1.000000) (0.004292,0.333547) (0.008584,0.333312) (0.012876,0.166857) (0.017167,0.166758) (0.021459,0.166551) (0.025751,0.166414) (0.030043,0.166294) (0.034335,0.165678) (0.038627,0.153140) (0.042918,0.084910) (0.047210,0.084877) (0.051502,0.083928) (0.055794,0.083394) (0.060086,0.083329) (0.064378,0.083328) (0.068670,0.083313) (0.072961,0.083313) (0.077253,0.083302) (0.081545,0.083301) (0.085837,0.083292) (0.090129,0.083239) (0.094421,0.083209) (0.098712,0.083176) (0.103004,0.083169) (0.107296,0.083125) (0.111588,0.083071) (0.115880,0.083067) (0.120172,0.083054) (0.124464,0.082872) (0.128755,0.082758) (0.133047,0.082151) (0.137339,0.081810) (0.141631,0.081809) (0.145923,0.081721) (0.150215,0.081378) (0.154506,0.081001) (0.158798,0.063929) (0.163090,0.041639) (0.167382,0.017348) (0.171674,0.012510) (0.175966,0.011755) (0.180258,0.004971) (0.184549,0.004140) (0.188841,0.003972) (0.193133,0.002505) (0.197425,0.002447) (0.201717,0.002335) (0.206009,0.002075) (0.210300,0.001713) (0.214592,0.001685) (0.218884,0.001622) (0.223176,0.001588) (0.227468,0.001512) (0.231760,0.001506) (0.236052,0.001486) (0.240343,0.001475) (0.244635,0.001291) (0.248927,0.001284) (0.253219,0.001203) (0.257511,0.001158) (0.261803,0.001088) (0.266094,0.001087) (0.270386,0.001028) (0.274678,0.001019) (0.278970,0.001010) (0.283262,0.000943) (0.287554,0.000860) (0.291845,0.000808) (0.296137,0.000797) (0.300429,0.000788) (0.304721,0.000773) (0.309013,0.000769) (0.313305,0.000686) (0.317597,0.000640) (0.321888,0.000621) (0.326180,0.000604) (0.330472,0.000548) (0.334764,0.000478) (0.339056,0.000468) (0.343348,0.000444) (0.347639,0.000424) (0.351931,0.000419) (0.356223,0.000404) (0.360515,0.000388) (0.364807,0.000384) (0.369099,0.000381) (0.373391,0.000333) (0.377682,0.000327) (0.381974,0.000318) (0.386266,0.000301) (0.390558,0.000271) (0.394850,0.000262) (0.399142,0.000255) (0.403433,0.000243) (0.407725,0.000238) (0.412017,0.000237) (0.416309,0.000235) (0.420601,0.000230) (0.424893,0.000209) (0.429185,0.000189) (0.433476,0.000174) (0.437768,0.000165) (0.442060,0.000164) (0.446352,0.000153) (0.450644,0.000151) (0.454936,0.000150) (0.459227,0.000140) (0.463519,0.000136) (0.467811,0.000136) (0.472103,0.000118) (0.476395,0.000117) (0.480687,0.000112) (0.484979,0.000111) (0.489270,0.000106) (0.493562,0.000106) (0.497854,0.000106) (0.502146,0.000106) (0.506438,0.000106) (0.510730,0.000102) (0.515021,0.000092) (0.519313,0.000087) (0.523605,0.000082) (0.527897,0.000079) (0.532189,0.000077) (0.536481,0.000076) (0.540773,0.000075) (0.545064,0.000074) (0.549356,0.000073) (0.553648,0.000068) (0.557940,0.000068) (0.562232,0.000066) (0.566524,0.000063) (0.570815,0.000063) (0.575107,0.000062) (0.579399,0.000061) (0.583691,0.000061) (0.587983,0.000060) (0.592275,0.000059) (0.596567,0.000053) (0.600858,0.000050) (0.605150,0.000047) (0.609442,0.000046) (0.613734,0.000042) (0.618026,0.000042) (0.622318,0.000041) (0.626609,0.000040) (0.630901,0.000035) (0.635193,0.000035) (0.639485,0.000033) (0.643777,0.000033) (0.648069,0.000032) (0.652361,0.000032) (0.656652,0.000031) (0.660944,0.000031) (0.665236,0.000031) (0.669528,0.000031) (0.673820,0.000030) (0.678112,0.000029) (0.682403,0.000028) (0.686695,0.000027) (0.690987,0.000026) (0.695279,0.000025) (0.699571,0.000023) (0.703863,0.000022) (0.708155,0.000022) (0.712446,0.000021) (0.716738,0.000019) (0.721030,0.000018) (0.725322,0.000017) (0.729614,0.000016) (0.733906,0.000013) (0.738197,0.000012) (0.742489,0.000011) (0.746781,0.000011) (0.751073,0.000011) (0.755365,0.000011) (0.759657,0.000011) (0.763948,0.000011) (0.768240,0.000011) (0.772532,0.000011) (0.776824,0.000011) (0.781116,0.000011) (0.785408,0.000010) (0.789700,0.000010) (0.793991,0.000009) (0.798283,0.000009) (0.802575,0.000009) (0.806867,0.000009) (0.811159,0.000008) (0.815451,0.000007) (0.819742,0.000005) (0.824034,0.000005) (0.828326,0.000005) (0.832618,0.000005) (0.836910,0.000005) (0.841202,0.000004) (0.845494,0.000004) (0.849785,0.000004) (0.854077,0.000004) (0.858369,0.000004) (0.862661,0.000004) (0.866953,0.000004) (0.871245,0.000003) (0.875536,0.000003) (0.879828,0.000003) (0.884120,0.000003) (0.888412,0.000003) (0.892704,0.000002) (0.896996,0.000002) (0.901288,0.000002) (0.905579,0.000002) (0.909871,0.000002) (0.914163,0.000002) (0.918455,0.000001) (0.922747,0.000001) (0.927039,0.000001) (0.931330,0.000001) (0.935622,0.000001) (0.939914,0.000001) (0.944206,0.000001) (0.948498,0.000001) (0.952790,0.000001) (0.957082,0.000001) (0.961373,0.000001) (0.965665,0.000001) (0.969957,0.000001) (0.974249,0.000001) (0.978541,0.000001) (0.982833,0.000001) (0.987124,0.000001) (0.991416,0.000001) (0.995708,0.000001) (1.000000,0.000001) }; +\addplot[lightgray,only marks,mark=*] coordinates {(0.038627,0.153140) (0.197425,0.002447) (0.433476,0.000174)}; \addplot[brown,mark=none] coordinates { (0.000000,1.000000) (0.000834,0.872400) (0.001668,0.683224) (0.002502,0.608314) (0.003336,0.542330) (0.004170,0.519721) (0.005004,0.447508) (0.005838,0.440065) (0.006672,0.420670) (0.007506,0.418862) (0.008340,0.418009) (0.009174,0.379519) (0.010008,0.357223) (0.010842,0.353534) (0.011676,0.333568) (0.012510,0.319704) (0.013344,0.268160) (0.014178,0.251065) (0.015013,0.226789) (0.015847,0.220089) (0.016681,0.215066) (0.017515,0.213903) (0.018349,0.213091) (0.019183,0.197153) (0.020017,0.187389) (0.020851,0.177430) (0.021685,0.173396) (0.022519,0.170787) (0.023353,0.160834) (0.024187,0.160045) (0.025021,0.157071) (0.025855,0.146612) (0.026689,0.144178) (0.027523,0.137699) (0.028357,0.136683) (0.029191,0.124833) (0.030025,0.121453) (0.030859,0.119189) (0.031693,0.115002) (0.032527,0.114249) (0.033361,0.107546) (0.034195,0.107268) (0.035029,0.104187) (0.035863,0.096624) (0.036697,0.089912) (0.037531,0.089585) (0.038365,0.087446) (0.039199,0.087298) (0.040033,0.084823) (0.040867,0.083414) (0.041701,0.083212) (0.042535,0.082227) (0.043369,0.079913) (0.044204,0.075734) (0.045038,0.073337) (0.045872,0.073039) (0.046706,0.072381) (0.047540,0.069693) (0.048374,0.067325) (0.049208,0.065996) (0.050042,0.057532) (0.050876,0.055707) (0.051710,0.055669) (0.052544,0.049083) (0.053378,0.048652) (0.054212,0.048015) (0.055046,0.045918) (0.055880,0.045234) (0.056714,0.042272) (0.057548,0.041798) (0.058382,0.040969) (0.059216,0.040163) (0.060050,0.040016) (0.060884,0.038778) (0.061718,0.038686) (0.062552,0.038456) (0.063386,0.033439) (0.064220,0.032381) (0.065054,0.031115) (0.065888,0.030103) (0.066722,0.029385) (0.067556,0.026654) (0.068390,0.025877) (0.069224,0.024467) (0.070058,0.024427) (0.070892,0.024134) (0.071726,0.024036) (0.072560,0.021379) (0.073394,0.020813) (0.074229,0.020166) (0.075063,0.020056) (0.075897,0.019981) (0.076731,0.019791) (0.077565,0.019672) (0.078399,0.019356) (0.079233,0.019269) (0.080067,0.019134) (0.080901,0.018119) (0.081735,0.017905) (0.082569,0.017878) (0.083403,0.017865) (0.084237,0.017769) (0.085071,0.017758) (0.085905,0.017065) (0.086739,0.016959) (0.087573,0.016686) (0.088407,0.015666) (0.089241,0.014908) (0.090075,0.014542) (0.090909,0.014518) (0.091743,0.014200) (0.092577,0.013865) (0.093411,0.013736) (0.094245,0.013273) (0.095079,0.013197) (0.095913,0.012997) (0.096747,0.012759) (0.097581,0.012642) (0.098415,0.012344) (0.099249,0.012031) (0.100083,0.011973) (0.100917,0.011805) (0.101751,0.011594) (0.102585,0.011387) (0.103420,0.011332) (0.104254,0.011246) (0.105088,0.010925) (0.105922,0.010566) (0.106756,0.010269) (0.107590,0.010235) (0.108424,0.010220) (0.109258,0.010135) (0.110092,0.010071) (0.110926,0.010048) (0.111760,0.010002) (0.112594,0.009762) (0.113428,0.009756) (0.114262,0.009751) (0.115096,0.009730) (0.115930,0.009551) (0.116764,0.009536) (0.117598,0.009404) (0.118432,0.009399) (0.119266,0.009298) (0.120100,0.009263) (0.120934,0.009245) (0.121768,0.009137) (0.122602,0.009120) (0.123436,0.009097) (0.124270,0.008816) (0.125104,0.008646) (0.125938,0.008484) (0.126772,0.008405) (0.127606,0.008149) (0.128440,0.008032) (0.129274,0.007872) (0.130108,0.007866) (0.130942,0.007823) (0.131776,0.007801) (0.132611,0.007718) (0.133445,0.007481) (0.134279,0.007373) (0.135113,0.007345) (0.135947,0.007296) (0.136781,0.007269) (0.137615,0.007233) (0.138449,0.006991) (0.139283,0.006905) (0.140117,0.006795) (0.140951,0.006738) (0.141785,0.006708) (0.142619,0.006551) (0.143453,0.006510) (0.144287,0.006435) (0.145121,0.006361) (0.145955,0.006238) (0.146789,0.006134) (0.147623,0.006027) (0.148457,0.005991) (0.149291,0.005921) (0.150125,0.005852) (0.150959,0.005852) (0.151793,0.005823) (0.152627,0.005794) (0.153461,0.005787) (0.154295,0.005746) (0.155129,0.005672) (0.155963,0.005619) (0.156797,0.005612) (0.157631,0.005557) (0.158465,0.005495) (0.159299,0.005495) (0.160133,0.005422) (0.160967,0.005324) (0.161802,0.005217) (0.162636,0.005196) (0.163470,0.005167) (0.164304,0.005107) (0.165138,0.005012) (0.165972,0.004999) (0.166806,0.004985) (0.167640,0.004981) (0.168474,0.004936) (0.169308,0.004912) (0.170142,0.004836) (0.170976,0.004822) (0.171810,0.004755) (0.172644,0.004692) (0.173478,0.004687) (0.174312,0.004667) (0.175146,0.004605) (0.175980,0.004546) (0.176814,0.004523) (0.177648,0.004518) (0.178482,0.004512) (0.179316,0.004447) (0.180150,0.004427) (0.180984,0.004408) (0.181818,0.004401) (0.182652,0.004336) (0.183486,0.004326) (0.184320,0.004255) (0.185154,0.004163) (0.185988,0.004152) (0.186822,0.004150) (0.187656,0.004132) (0.188490,0.004125) (0.189324,0.003972) (0.190158,0.003971) (0.190992,0.003942) (0.191827,0.003842) (0.192661,0.003797) (0.193495,0.003710) (0.194329,0.003703) (0.195163,0.003684) (0.195997,0.003626) (0.196831,0.003620) (0.197665,0.003576) (0.198499,0.003526) (0.199333,0.003451) (0.200167,0.003447) (0.201001,0.003402) (0.201835,0.003390) (0.202669,0.003364) (0.203503,0.003361) (0.204337,0.003356) (0.205171,0.003350) (0.206005,0.003341) (0.206839,0.003321) (0.207673,0.003278) (0.208507,0.003246) (0.209341,0.003239) (0.210175,0.003219) (0.211009,0.003208) (0.211843,0.003129) (0.212677,0.003123) (0.213511,0.003073) (0.214345,0.003063) (0.215179,0.003053) (0.216013,0.003053) (0.216847,0.003026) (0.217681,0.003007) (0.218515,0.002989) (0.219349,0.002929) (0.220183,0.002915) (0.221018,0.002913) (0.221852,0.002890) (0.222686,0.002861) (0.223520,0.002845) (0.224354,0.002804) (0.225188,0.002783) (0.226022,0.002781) (0.226856,0.002694) (0.227690,0.002669) (0.228524,0.002631) (0.229358,0.002579) (0.230192,0.002578) (0.231026,0.002573) (0.231860,0.002566) (0.232694,0.002507) (0.233528,0.002487) (0.234362,0.002486) (0.235196,0.002416) (0.236030,0.002367) (0.236864,0.002347) (0.237698,0.002344) (0.238532,0.002338) (0.239366,0.002330) (0.240200,0.002318) (0.241034,0.002315) (0.241868,0.002308) (0.242702,0.002308) (0.243536,0.002292) (0.244370,0.002287) (0.245204,0.002283) (0.246038,0.002264) (0.246872,0.002236) (0.247706,0.002227) (0.248540,0.002185) (0.249374,0.002173) (0.250209,0.002169) (0.251043,0.002135) (0.251877,0.002109) (0.252711,0.002039) (0.253545,0.002031) (0.254379,0.001987) (0.255213,0.001970) (0.256047,0.001966) (0.256881,0.001936) (0.257715,0.001908) (0.258549,0.001908) (0.259383,0.001893) (0.260217,0.001886) (0.261051,0.001882) (0.261885,0.001827) (0.262719,0.001827) (0.263553,0.001817) (0.264387,0.001797) (0.265221,0.001749) (0.266055,0.001742) (0.266889,0.001739) (0.267723,0.001727) (0.268557,0.001704) (0.269391,0.001700) (0.270225,0.001691) (0.271059,0.001690) (0.271893,0.001653) (0.272727,0.001600) (0.273561,0.001595) (0.274395,0.001555) (0.275229,0.001547) (0.276063,0.001546) (0.276897,0.001519) (0.277731,0.001513) (0.278565,0.001510) (0.279399,0.001505) (0.280234,0.001474) (0.281068,0.001468) (0.281902,0.001459) (0.282736,0.001458) (0.283570,0.001432) (0.284404,0.001410) (0.285238,0.001407) (0.286072,0.001401) (0.286906,0.001396) (0.287740,0.001391) (0.288574,0.001376) (0.289408,0.001372) (0.290242,0.001369) (0.291076,0.001345) (0.291910,0.001344) (0.292744,0.001318) (0.293578,0.001299) (0.294412,0.001295) (0.295246,0.001287) (0.296080,0.001285) (0.296914,0.001284) (0.297748,0.001270) (0.298582,0.001265) (0.299416,0.001253) (0.300250,0.001235) (0.301084,0.001233) (0.301918,0.001224) (0.302752,0.001222) (0.303586,0.001219) (0.304420,0.001209) (0.305254,0.001202) (0.306088,0.001191) (0.306922,0.001180) (0.307756,0.001173) (0.308590,0.001170) (0.309425,0.001167) (0.310259,0.001154) (0.311093,0.001147) (0.311927,0.001143) (0.312761,0.001130) (0.313595,0.001126) (0.314429,0.001124) (0.315263,0.001116) (0.316097,0.001115) (0.316931,0.001099) (0.317765,0.001088) (0.318599,0.001088) (0.319433,0.001082) (0.320267,0.001074) (0.321101,0.001071) (0.321935,0.001070) (0.322769,0.001066) (0.323603,0.001062) (0.324437,0.001047) (0.325271,0.001043) (0.326105,0.001041) (0.326939,0.001040) (0.327773,0.001038) (0.328607,0.001027) (0.329441,0.001025) (0.330275,0.001016) (0.331109,0.001016) (0.331943,0.000996) (0.332777,0.000992) (0.333611,0.000985) (0.334445,0.000979) (0.335279,0.000978) (0.336113,0.000978) (0.336947,0.000957) (0.337781,0.000953) (0.338616,0.000951) (0.339450,0.000947) (0.340284,0.000944) (0.341118,0.000939) (0.341952,0.000932) (0.342786,0.000930) (0.343620,0.000930) (0.344454,0.000928) (0.345288,0.000915) (0.346122,0.000914) (0.346956,0.000914) (0.347790,0.000911) (0.348624,0.000910) (0.349458,0.000908) (0.350292,0.000904) (0.351126,0.000895) (0.351960,0.000890) (0.352794,0.000887) (0.353628,0.000884) (0.354462,0.000879) (0.355296,0.000861) (0.356130,0.000861) (0.356964,0.000826) (0.357798,0.000814) (0.358632,0.000808) (0.359466,0.000800) (0.360300,0.000797) (0.361134,0.000796) (0.361968,0.000782) (0.362802,0.000779) (0.363636,0.000778) (0.364470,0.000777) (0.365304,0.000777) (0.366138,0.000775) (0.366972,0.000767) (0.367807,0.000764) (0.368641,0.000761) (0.369475,0.000758) (0.370309,0.000753) (0.371143,0.000753) (0.371977,0.000751) (0.372811,0.000738) (0.373645,0.000718) (0.374479,0.000718) (0.375313,0.000710) (0.376147,0.000709) (0.376981,0.000707) (0.377815,0.000701) (0.378649,0.000699) (0.379483,0.000694) (0.380317,0.000694) (0.381151,0.000688) (0.381985,0.000686) (0.382819,0.000683) (0.383653,0.000681) (0.384487,0.000665) (0.385321,0.000664) (0.386155,0.000660) (0.386989,0.000659) (0.387823,0.000657) (0.388657,0.000657) (0.389491,0.000655) (0.390325,0.000654) (0.391159,0.000647) (0.391993,0.000645) (0.392827,0.000644) (0.393661,0.000643) (0.394495,0.000642) (0.395329,0.000640) (0.396163,0.000639) (0.396997,0.000637) (0.397832,0.000634) (0.398666,0.000630) (0.399500,0.000614) (0.400334,0.000613) (0.401168,0.000607) (0.402002,0.000604) (0.402836,0.000603) (0.403670,0.000602) (0.404504,0.000602) (0.405338,0.000598) (0.406172,0.000597) (0.407006,0.000592) (0.407840,0.000588) (0.408674,0.000576) (0.409508,0.000572) (0.410342,0.000570) (0.411176,0.000570) (0.412010,0.000567) (0.412844,0.000567) (0.413678,0.000566) (0.414512,0.000564) (0.415346,0.000563) (0.416180,0.000554) (0.417014,0.000550) (0.417848,0.000548) (0.418682,0.000547) (0.419516,0.000547) (0.420350,0.000546) (0.421184,0.000542) (0.422018,0.000542) (0.422852,0.000535) (0.423686,0.000529) (0.424520,0.000518) (0.425354,0.000516) (0.426188,0.000515) (0.427023,0.000513) (0.427857,0.000512) (0.428691,0.000511) (0.429525,0.000503) (0.430359,0.000503) (0.431193,0.000503) (0.432027,0.000499) (0.432861,0.000497) (0.433695,0.000497) (0.434529,0.000495) (0.435363,0.000495) (0.436197,0.000494) (0.437031,0.000494) (0.437865,0.000492) (0.438699,0.000491) (0.439533,0.000490) (0.440367,0.000489) (0.441201,0.000488) (0.442035,0.000486) (0.442869,0.000484) (0.443703,0.000480) (0.444537,0.000479) (0.445371,0.000478) (0.446205,0.000471) (0.447039,0.000467) (0.447873,0.000466) (0.448707,0.000464) (0.449541,0.000460) (0.450375,0.000458) (0.451209,0.000456) (0.452043,0.000452) (0.452877,0.000451) (0.453711,0.000448) (0.454545,0.000446) (0.455379,0.000445) (0.456214,0.000444) (0.457048,0.000437) (0.457882,0.000436) (0.458716,0.000435) (0.459550,0.000431) (0.460384,0.000431) (0.461218,0.000430) (0.462052,0.000428) (0.462886,0.000428) (0.463720,0.000428) (0.464554,0.000427) (0.465388,0.000427) (0.466222,0.000422) (0.467056,0.000420) (0.467890,0.000415) (0.468724,0.000409) (0.469558,0.000408) (0.470392,0.000408) (0.471226,0.000406) (0.472060,0.000405) (0.472894,0.000404) (0.473728,0.000404) (0.474562,0.000402) (0.475396,0.000402) (0.476230,0.000402) (0.477064,0.000402) (0.477898,0.000399) (0.478732,0.000399) (0.479566,0.000398) (0.480400,0.000395) (0.481234,0.000395) (0.482068,0.000394) (0.482902,0.000390) (0.483736,0.000389) (0.484570,0.000387) (0.485405,0.000385) (0.486239,0.000383) (0.487073,0.000382) (0.487907,0.000381) (0.488741,0.000380) (0.489575,0.000380) (0.490409,0.000377) (0.491243,0.000375) (0.492077,0.000374) (0.492911,0.000373) (0.493745,0.000371) (0.494579,0.000370) (0.495413,0.000369) (0.496247,0.000368) (0.497081,0.000366) (0.497915,0.000364) (0.498749,0.000362) (0.499583,0.000362) (0.500417,0.000358) (0.501251,0.000354) (0.502085,0.000346) (0.502919,0.000345) (0.503753,0.000344) (0.504587,0.000343) (0.505421,0.000341) (0.506255,0.000340) (0.507089,0.000337) (0.507923,0.000337) (0.508757,0.000331) (0.509591,0.000328) (0.510425,0.000325) (0.511259,0.000323) (0.512093,0.000319) (0.512927,0.000319) (0.513761,0.000317) (0.514595,0.000315) (0.515430,0.000314) (0.516264,0.000313) (0.517098,0.000313) (0.517932,0.000312) (0.518766,0.000312) (0.519600,0.000311) (0.520434,0.000302) (0.521268,0.000300) (0.522102,0.000300) (0.522936,0.000295) (0.523770,0.000295) (0.524604,0.000295) (0.525438,0.000292) (0.526272,0.000290) (0.527106,0.000290) (0.527940,0.000288) (0.528774,0.000287) (0.529608,0.000285) (0.530442,0.000280) (0.531276,0.000278) (0.532110,0.000278) (0.532944,0.000278) (0.533778,0.000277) (0.534612,0.000276) (0.535446,0.000274) (0.536280,0.000273) (0.537114,0.000271) (0.537948,0.000271) (0.538782,0.000270) (0.539616,0.000266) (0.540450,0.000263) (0.541284,0.000260) (0.542118,0.000260) (0.542952,0.000258) (0.543786,0.000258) (0.544621,0.000256) (0.545455,0.000253) (0.546289,0.000252) (0.547123,0.000251) (0.547957,0.000249) (0.548791,0.000248) (0.549625,0.000248) (0.550459,0.000248) (0.551293,0.000246) (0.552127,0.000246) (0.552961,0.000244) (0.553795,0.000244) (0.554629,0.000242) (0.555463,0.000241) (0.556297,0.000240) (0.557131,0.000240) (0.557965,0.000239) (0.558799,0.000236) (0.559633,0.000236) (0.560467,0.000235) (0.561301,0.000234) (0.562135,0.000234) (0.562969,0.000234) (0.563803,0.000233) (0.564637,0.000233) (0.565471,0.000225) (0.566305,0.000223) (0.567139,0.000223) (0.567973,0.000220) (0.568807,0.000219) (0.569641,0.000218) (0.570475,0.000218) (0.571309,0.000217) (0.572143,0.000216) (0.572977,0.000213) (0.573812,0.000211) (0.574646,0.000207) (0.575480,0.000206) (0.576314,0.000206) (0.577148,0.000205) (0.577982,0.000205) (0.578816,0.000203) (0.579650,0.000203) (0.580484,0.000203) (0.581318,0.000203) (0.582152,0.000203) (0.582986,0.000201) (0.583820,0.000200) (0.584654,0.000200) (0.585488,0.000199) (0.586322,0.000199) (0.587156,0.000197) (0.587990,0.000194) (0.588824,0.000193) (0.589658,0.000191) (0.590492,0.000190) (0.591326,0.000190) (0.592160,0.000186) (0.592994,0.000186) (0.593828,0.000181) (0.594662,0.000178) (0.595496,0.000175) (0.596330,0.000174) (0.597164,0.000173) (0.597998,0.000173) (0.598832,0.000172) (0.599666,0.000171) (0.600500,0.000171) (0.601334,0.000170) (0.602168,0.000170) (0.603003,0.000169) (0.603837,0.000166) (0.604671,0.000165) (0.605505,0.000165) (0.606339,0.000165) (0.607173,0.000164) (0.608007,0.000163) (0.608841,0.000162) (0.609675,0.000162) (0.610509,0.000162) (0.611343,0.000162) (0.612177,0.000161) (0.613011,0.000161) (0.613845,0.000159) (0.614679,0.000158) (0.615513,0.000158) (0.616347,0.000157) (0.617181,0.000156) (0.618015,0.000155) (0.618849,0.000155) (0.619683,0.000152) (0.620517,0.000152) (0.621351,0.000151) (0.622185,0.000151) (0.623019,0.000149) (0.623853,0.000149) (0.624687,0.000148) (0.625521,0.000147) (0.626355,0.000147) (0.627189,0.000146) (0.628023,0.000146) (0.628857,0.000146) (0.629691,0.000146) (0.630525,0.000145) (0.631359,0.000145) (0.632193,0.000144) (0.633028,0.000144) (0.633862,0.000144) (0.634696,0.000144) (0.635530,0.000143) (0.636364,0.000142) (0.637198,0.000142) (0.638032,0.000142) (0.638866,0.000142) (0.639700,0.000141) (0.640534,0.000140) (0.641368,0.000139) (0.642202,0.000137) (0.643036,0.000137) (0.643870,0.000133) (0.644704,0.000131) (0.645538,0.000131) (0.646372,0.000129) (0.647206,0.000129) (0.648040,0.000129) (0.648874,0.000128) (0.649708,0.000128) (0.650542,0.000127) (0.651376,0.000124) (0.652210,0.000123) (0.653044,0.000119) (0.653878,0.000117) (0.654712,0.000117) (0.655546,0.000117) (0.656380,0.000115) (0.657214,0.000114) (0.658048,0.000114) (0.658882,0.000114) (0.659716,0.000113) (0.660550,0.000112) (0.661384,0.000111) (0.662219,0.000111) (0.663053,0.000111) (0.663887,0.000111) (0.664721,0.000110) (0.665555,0.000110) (0.666389,0.000109) (0.667223,0.000108) (0.668057,0.000108) (0.668891,0.000107) (0.669725,0.000105) (0.670559,0.000105) (0.671393,0.000105) (0.672227,0.000105) (0.673061,0.000105) (0.673895,0.000105) (0.674729,0.000105) (0.675563,0.000104) (0.676397,0.000104) (0.677231,0.000103) (0.678065,0.000102) (0.678899,0.000101) (0.679733,0.000101) (0.680567,0.000100) (0.681401,0.000100) (0.682235,0.000100) (0.683069,0.000099) (0.683903,0.000099) (0.684737,0.000098) (0.685571,0.000098) (0.686405,0.000098) (0.687239,0.000097) (0.688073,0.000094) (0.688907,0.000094) (0.689741,0.000092) (0.690575,0.000092) (0.691410,0.000091) (0.692244,0.000089) (0.693078,0.000089) (0.693912,0.000087) (0.694746,0.000087) (0.695580,0.000087) (0.696414,0.000086) (0.697248,0.000086) (0.698082,0.000086) (0.698916,0.000085) (0.699750,0.000085) (0.700584,0.000085) (0.701418,0.000085) (0.702252,0.000084) (0.703086,0.000084) (0.703920,0.000083) (0.704754,0.000083) (0.705588,0.000082) (0.706422,0.000081) (0.707256,0.000080) (0.708090,0.000080) (0.708924,0.000080) (0.709758,0.000079) (0.710592,0.000079) (0.711426,0.000078) (0.712260,0.000078) (0.713094,0.000077) (0.713928,0.000076) (0.714762,0.000076) (0.715596,0.000076) (0.716430,0.000075) (0.717264,0.000075) (0.718098,0.000072) (0.718932,0.000071) (0.719766,0.000071) (0.720601,0.000070) (0.721435,0.000070) (0.722269,0.000070) (0.723103,0.000070) (0.723937,0.000070) (0.724771,0.000070) (0.725605,0.000069) (0.726439,0.000068) (0.727273,0.000068) (0.728107,0.000068) (0.728941,0.000067) (0.729775,0.000067) (0.730609,0.000067) (0.731443,0.000067) (0.732277,0.000066) (0.733111,0.000066) (0.733945,0.000065) (0.734779,0.000065) (0.735613,0.000065) (0.736447,0.000065) (0.737281,0.000064) (0.738115,0.000064) (0.738949,0.000063) (0.739783,0.000063) (0.740617,0.000063) (0.741451,0.000062) (0.742285,0.000062) (0.743119,0.000060) (0.743953,0.000060) (0.744787,0.000059) (0.745621,0.000059) (0.746455,0.000059) (0.747289,0.000059) (0.748123,0.000058) (0.748957,0.000058) (0.749791,0.000057) (0.750626,0.000057) (0.751460,0.000057) (0.752294,0.000057) (0.753128,0.000057) (0.753962,0.000057) (0.754796,0.000057) (0.755630,0.000057) (0.756464,0.000057) (0.757298,0.000057) (0.758132,0.000057) (0.758966,0.000057) (0.759800,0.000057) (0.760634,0.000057) (0.761468,0.000057) (0.762302,0.000057) (0.763136,0.000056) (0.763970,0.000056) (0.764804,0.000055) (0.765638,0.000055) (0.766472,0.000055) (0.767306,0.000055) (0.768140,0.000055) (0.768974,0.000055) (0.769808,0.000054) (0.770642,0.000054) (0.771476,0.000054) (0.772310,0.000054) (0.773144,0.000054) (0.773978,0.000053) (0.774812,0.000053) (0.775646,0.000053) (0.776480,0.000053) (0.777314,0.000053) (0.778148,0.000053) (0.778982,0.000053) (0.779817,0.000052) (0.780651,0.000052) (0.781485,0.000052) (0.782319,0.000052) (0.783153,0.000052) (0.783987,0.000052) (0.784821,0.000052) (0.785655,0.000051) (0.786489,0.000051) (0.787323,0.000051) (0.788157,0.000051) (0.788991,0.000050) (0.789825,0.000050) (0.790659,0.000050) (0.791493,0.000049) (0.792327,0.000049) (0.793161,0.000049) (0.793995,0.000049) (0.794829,0.000049) (0.795663,0.000049) (0.796497,0.000049) (0.797331,0.000047) (0.798165,0.000047) (0.798999,0.000047) (0.799833,0.000047) (0.800667,0.000046) (0.801501,0.000046) (0.802335,0.000046) (0.803169,0.000046) (0.804003,0.000045) (0.804837,0.000045) (0.805671,0.000044) (0.806505,0.000044) (0.807339,0.000043) (0.808173,0.000043) (0.809008,0.000043) (0.809842,0.000043) (0.810676,0.000042) (0.811510,0.000042) (0.812344,0.000041) (0.813178,0.000041) (0.814012,0.000041) (0.814846,0.000041) (0.815680,0.000040) (0.816514,0.000040) (0.817348,0.000038) (0.818182,0.000038) (0.819016,0.000038) (0.819850,0.000037) (0.820684,0.000037) (0.821518,0.000037) (0.822352,0.000037) (0.823186,0.000037) (0.824020,0.000036) (0.824854,0.000036) (0.825688,0.000035) (0.826522,0.000035) (0.827356,0.000035) (0.828190,0.000035) (0.829024,0.000034) (0.829858,0.000034) (0.830692,0.000033) (0.831526,0.000033) (0.832360,0.000033) (0.833194,0.000033) (0.834028,0.000032) (0.834862,0.000032) (0.835696,0.000031) (0.836530,0.000031) (0.837364,0.000030) (0.838198,0.000030) (0.839033,0.000030) (0.839867,0.000030) (0.840701,0.000029) (0.841535,0.000029) (0.842369,0.000029) (0.843203,0.000029) (0.844037,0.000029) (0.844871,0.000028) (0.845705,0.000028) (0.846539,0.000028) (0.847373,0.000028) (0.848207,0.000028) (0.849041,0.000028) (0.849875,0.000028) (0.850709,0.000028) (0.851543,0.000028) (0.852377,0.000028) (0.853211,0.000028) (0.854045,0.000028) (0.854879,0.000028) (0.855713,0.000028) (0.856547,0.000028) (0.857381,0.000028) (0.858215,0.000028) (0.859049,0.000027) (0.859883,0.000027) (0.860717,0.000027) (0.861551,0.000027) (0.862385,0.000027) (0.863219,0.000027) (0.864053,0.000027) (0.864887,0.000027) (0.865721,0.000027) (0.866555,0.000027) (0.867389,0.000027) (0.868224,0.000027) (0.869058,0.000027) (0.869892,0.000026) (0.870726,0.000026) (0.871560,0.000026) (0.872394,0.000025) (0.873228,0.000025) (0.874062,0.000025) (0.874896,0.000025) (0.875730,0.000025) (0.876564,0.000025) (0.877398,0.000025) (0.878232,0.000025) (0.879066,0.000025) (0.879900,0.000025) (0.880734,0.000024) (0.881568,0.000024) (0.882402,0.000024) (0.883236,0.000024) (0.884070,0.000024) (0.884904,0.000024) (0.885738,0.000023) (0.886572,0.000023) (0.887406,0.000023) (0.888240,0.000023) (0.889074,0.000023) (0.889908,0.000023) (0.890742,0.000022) (0.891576,0.000022) (0.892410,0.000022) (0.893244,0.000022) (0.894078,0.000022) (0.894912,0.000022) (0.895746,0.000022) (0.896580,0.000022) (0.897415,0.000021) (0.898249,0.000021) (0.899083,0.000021) (0.899917,0.000021) (0.900751,0.000021) (0.901585,0.000021) (0.902419,0.000021) (0.903253,0.000021) (0.904087,0.000021) (0.904921,0.000021) (0.905755,0.000021) (0.906589,0.000021) (0.907423,0.000021) (0.908257,0.000020) (0.909091,0.000020) (0.909925,0.000020) (0.910759,0.000020) (0.911593,0.000020) (0.912427,0.000020) (0.913261,0.000020) (0.914095,0.000019) (0.914929,0.000019) (0.915763,0.000019) (0.916597,0.000018) (0.917431,0.000018) (0.918265,0.000018) (0.919099,0.000017) (0.919933,0.000017) (0.920767,0.000017) (0.921601,0.000017) (0.922435,0.000017) (0.923269,0.000016) (0.924103,0.000016) (0.924937,0.000016) (0.925771,0.000016) (0.926606,0.000016) (0.927440,0.000016) (0.928274,0.000015) (0.929108,0.000015) (0.929942,0.000015) (0.930776,0.000015) (0.931610,0.000015) (0.932444,0.000015) (0.933278,0.000015) (0.934112,0.000015) (0.934946,0.000014) (0.935780,0.000014) (0.936614,0.000014) (0.937448,0.000014) (0.938282,0.000013) (0.939116,0.000013) (0.939950,0.000012) (0.940784,0.000012) (0.941618,0.000012) (0.942452,0.000012) (0.943286,0.000012) (0.944120,0.000012) (0.944954,0.000012) (0.945788,0.000012) (0.946622,0.000011) (0.947456,0.000011) (0.948290,0.000011) (0.949124,0.000011) (0.949958,0.000011) (0.950792,0.000011) (0.951626,0.000010) (0.952460,0.000010) (0.953294,0.000010) (0.954128,0.000010) (0.954962,0.000009) (0.955796,0.000009) (0.956631,0.000009) (0.957465,0.000009) (0.958299,0.000008) (0.959133,0.000008) (0.959967,0.000008) (0.960801,0.000008) (0.961635,0.000008) (0.962469,0.000008) (0.963303,0.000008) (0.964137,0.000008) (0.964971,0.000007) (0.965805,0.000007) (0.966639,0.000007) (0.967473,0.000007) (0.968307,0.000007) (0.969141,0.000007) (0.969975,0.000006) (0.970809,0.000006) (0.971643,0.000006) (0.972477,0.000005) (0.973311,0.000005) (0.974145,0.000004) (0.974979,0.000004) (0.975813,0.000004) (0.976647,0.000004) (0.977481,0.000004) (0.978315,0.000003) (0.979149,0.000003) (0.979983,0.000003) (0.980817,0.000003) (0.981651,0.000002) (0.982485,0.000002) (0.983319,0.000002) (0.984153,0.000002) (0.984987,0.000002) (0.985822,0.000002) (0.986656,0.000001) (0.987490,0.000001) (0.988324,0.000001) (0.989158,0.000001) (0.989992,0.000001) (0.990826,0.000001) (0.991660,0.000001) (0.992494,0.000001) (0.993328,0.000001) (0.994162,0.000001) (0.994996,0.000001) (0.995830,0.000001) (0.996664,0.000001) (0.997498,0.000001) (0.998332,0.000001) (0.999166,0.000001) (1.000000,0.000001) diff --git a/talk/vmil2012/presentation/figures/go_data.tex b/talk/vmil2012/presentation/figures/go_data.tex --- a/talk/vmil2012/presentation/figures/go_data.tex +++ b/talk/vmil2012/presentation/figures/go_data.tex @@ -1,6 +1,6 @@ -\addplot[green,mark=none] coordinates { +\addplot[brown,mark=none] coordinates { (0.000000,1.000000) (0.000834,0.872400) (0.001668,0.683224) (0.002502,0.608314) (0.003336,0.542330) (0.004170,0.519721) (0.005004,0.447508) (0.005838,0.440065) (0.006672,0.420670) (0.007506,0.418862) (0.008340,0.418009) (0.009174,0.379519) (0.010008,0.357223) (0.010842,0.353534) (0.011676,0.333568) (0.012510,0.319704) (0.013344,0.268160) (0.014178,0.251065) (0.015013,0.226789) (0.015847,0.220089) (0.016681,0.215066) (0.017515,0.213903) (0.018349,0.213091) (0.019183,0.197153) (0.020017,0.187389) (0.020851,0.177430) (0.021685,0.173396) (0.022519,0.170787) (0.023353,0.160834) (0.024187,0.160045) (0.025021,0.157071) (0.025855,0.146612) (0.026689,0.144178) (0.027523,0.137699) (0.028357,0.136683) (0.029191,0.124833) (0.030025,0.121453) (0.030859,0.119189) (0.031693,0.115002) (0.032527,0.114249) (0.033361,0.107546) (0.034195,0.107268) (0.035029,0.104187) (0.035863,0.096624) (0.036697,0.089912) (0.037531,0.089585) (0.038365,0.087446) (0.039199,0.087298) (0.040033,0.084823) (0.040867,0.083414) (0.041701,0.083212) (0.042535,0.082227) (0.043369,0.079913) (0.044204,0.075734) (0.045038,0.073337) (0.045872,0.073039) (0.046706,0.072381) (0.047540,0.069693) (0.048374,0.067325) (0.049208,0.065996) (0.050042,0.057532) (0.050876,0.055707) (0.051710,0.055669) (0.052544,0.049083) (0.053378,0.048652) (0.054212,0.048015) (0.055046,0.045918) (0.055880,0.045234) (0.056714,0.042272) (0.057548,0.041798) (0.058382,0.040969) (0.059216,0.040163) (0.060050,0.040016) (0.060884,0.038778) (0.061718,0.038686) (0.062552,0.038456) (0.063386,0.033439) (0.064220,0.032381) (0.065054,0.031115) (0.065888,0.030103) (0.066722,0.029385) (0.067556,0.026654) (0.068390,0.025877) (0.069224,0.024467) (0.070058,0.024427) (0.070892,0.024134) (0.071726,0.024036) (0.072560,0.021379) (0.073394,0.020813) (0.074229,0.020166) (0.075063,0.020056) (0.075897,0.019981) (0.076731,0.019791) (0.077565,0.019672) (0.078399,0.019356) (0.079233,0.019269) (0.080067,0.019134) (0.080901,0.018119) (0.081735,0.017905) (0.082569,0.017878) (0.083403,0.017865) (0.084237,0.017769) (0.085071,0.017758) (0.085905,0.017065) (0.086739,0.016959) (0.087573,0.016686) (0.088407,0.015666) (0.089241,0.014908) (0.090075,0.014542) (0.090909,0.014518) (0.091743,0.014200) (0.092577,0.013865) (0.093411,0.013736) (0.094245,0.013273) (0.095079,0.013197) (0.095913,0.012997) (0.096747,0.012759) (0.097581,0.012642) (0.098415,0.012344) (0.099249,0.012031) (0.100083,0.011973) (0.100917,0.011805) (0.101751,0.011594) (0.102585,0.011387) (0.103420,0.011332) (0.104254,0.011246) (0.105088,0.010925) (0.105922,0.010566) (0.106756,0.010269) (0.107590,0.010235) (0.108424,0.010220) (0.109258,0.010135) (0.110092,0.010071) (0.110926,0.010048) (0.111760,0.010002) (0.112594,0.009762) (0.113428,0.009756) (0.114262,0.009751) (0.115096,0.009730) (0.115930,0.009551) (0.116764,0.009536) (0.117598,0.009404) (0.118432,0.009399) (0.119266,0.009298) (0.120100,0.009263) (0.120934,0.009245) (0.121768,0.009137) (0.122602,0.009120) (0.123436,0.009097) (0.124270,0.008816) (0.125104,0.008646) (0.125938,0.008484) (0.126772,0.008405) (0.127606,0.008149) (0.128440,0.008032) (0.129274,0.007872) (0.130108,0.007866) (0.130942,0.007823) (0.131776,0.007801) (0.132611,0.007718) (0.133445,0.007481) (0.134279,0.007373) (0.135113,0.007345) (0.135947,0.007296) (0.136781,0.007269) (0.137615,0.007233) (0.138449,0.006991) (0.139283,0.006905) (0.140117,0.006795) (0.140951,0.006738) (0.141785,0.006708) (0.142619,0.006551) (0.143453,0.006510) (0.144287,0.006435) (0.145121,0.006361) (0.145955,0.006238) (0.146789,0.006134) (0.147623,0.006027) (0.148457,0.005991) (0.149291,0.005921) (0.150125,0.005852) (0.150959,0.005852) (0.151793,0.005823) (0.152627,0.005794) (0.153461,0.005787) (0.154295,0.005746) (0.155129,0.005672) (0.155963,0.005619) (0.156797,0.005612) (0.157631,0.005557) (0.158465,0.005495) (0.159299,0.005495) (0.160133,0.005422) (0.160967,0.005324) (0.161802,0.005217) (0.162636,0.005196) (0.163470,0.005167) (0.164304,0.005107) (0.165138,0.005012) (0.165972,0.004999) (0.166806,0.004985) (0.167640,0.004981) (0.168474,0.004936) (0.169308,0.004912) (0.170142,0.004836) (0.170976,0.004822) (0.171810,0.004755) (0.172644,0.004692) (0.173478,0.004687) (0.174312,0.004667) (0.175146,0.004605) (0.175980,0.004546) (0.176814,0.004523) (0.177648,0.004518) (0.178482,0.004512) (0.179316,0.004447) (0.180150,0.004427) (0.180984,0.004408) (0.181818,0.004401) (0.182652,0.004336) (0.183486,0.004326) (0.184320,0.004255) (0.185154,0.004163) (0.185988,0.004152) (0.186822,0.004150) (0.187656,0.004132) (0.188490,0.004125) (0.189324,0.003972) (0.190158,0.003971) (0.190992,0.003942) (0.191827,0.003842) (0.192661,0.003797) (0.193495,0.003710) (0.194329,0.003703) (0.195163,0.003684) (0.195997,0.003626) (0.196831,0.003620) (0.197665,0.003576) (0.198499,0.003526) (0.199333,0.003451) (0.200167,0.003447) (0.201001,0.003402) (0.201835,0.003390) (0.202669,0.003364) (0.203503,0.003361) (0.204337,0.003356) (0.205171,0.003350) (0.206005,0.003341) (0.206839,0.003321) (0.207673,0.003278) (0.208507,0.003246) (0.209341,0.003239) (0.210175,0.003219) (0.211009,0.003208) (0.211843,0.003129) (0.212677,0.003123) (0.213511,0.003073) (0.214345,0.003063) (0.215179,0.003053) (0.216013,0.003053) (0.216847,0.003026) (0.217681,0.003007) (0.218515,0.002989) (0.219349,0.002929) (0.220183,0.002915) (0.221018,0.002913) (0.221852,0.002890) (0.222686,0.002861) (0.223520,0.002845) (0.224354,0.002804) (0.225188,0.002783) (0.226022,0.002781) (0.226856,0.002694) (0.227690,0.002669) (0.228524,0.002631) (0.229358,0.002579) (0.230192,0.002578) (0.231026,0.002573) (0.231860,0.002566) (0.232694,0.002507) (0.233528,0.002487) (0.234362,0.002486) (0.235196,0.002416) (0.236030,0.002367) (0.236864,0.002347) (0.237698,0.002344) (0.238532,0.002338) (0.239366,0.002330) (0.240200,0.002318) (0.241034,0.002315) (0.241868,0.002308) (0.242702,0.002308) (0.243536,0.002292) (0.244370,0.002287) (0.245204,0.002283) (0.246038,0.002264) (0.246872,0.002236) (0.247706,0.002227) (0.248540,0.002185) (0.249374,0.002173) (0.250209,0.002169) (0.251043,0.002135) (0.251877,0.002109) (0.252711,0.002039) (0.253545,0.002031) (0.254379,0.001987) (0.255213,0.001970) (0.256047,0.001966) (0.256881,0.001936) (0.257715,0.001908) (0.258549,0.001908) (0.259383,0.001893) (0.260217,0.001886) (0.261051,0.001882) (0.261885,0.001827) (0.262719,0.001827) (0.263553,0.001817) (0.264387,0.001797) (0.265221,0.001749) (0.266055,0.001742) (0.266889,0.001739) (0.267723,0.001727) (0.268557,0.001704) (0.269391,0.001700) (0.270225,0.001691) (0.271059,0.001690) (0.271893,0.001653) (0.272727,0.001600) (0.273561,0.001595) (0.274395,0.001555) (0.275229,0.001547) (0.276063,0.001546) (0.276897,0.001519) (0.277731,0.001513) (0.278565,0.001510) (0.279399,0.001505) (0.280234,0.001474) (0.281068,0.001468) (0.281902,0.001459) (0.282736,0.001458) (0.283570,0.001432) (0.284404,0.001410) (0.285238,0.001407) (0.286072,0.001401) (0.286906,0.001396) (0.287740,0.001391) (0.288574,0.001376) (0.289408,0.001372) (0.290242,0.001369) (0.291076,0.001345) (0.291910,0.001344) (0.292744,0.001318) (0.293578,0.001299) (0.294412,0.001295) (0.295246,0.001287) (0.296080,0.001285) (0.296914,0.001284) (0.297748,0.001270) (0.298582,0.001265) (0.299416,0.001253) (0.300250,0.001235) (0.301084,0.001233) (0.301918,0.001224) (0.302752,0.001222) (0.303586,0.001219) (0.304420,0.001209) (0.305254,0.001202) (0.306088,0.001191) (0.306922,0.001180) (0.307756,0.001173) (0.308590,0.001170) (0.309425,0.001167) (0.310259,0.001154) (0.311093,0.001147) (0.311927,0.001143) (0.312761,0.001130) (0.313595,0.001126) (0.314429,0.001124) (0.315263,0.001116) (0.316097,0.001115) (0.316931,0.001099) (0.317765,0.001088) (0.318599,0.001088) (0.319433,0.001082) (0.320267,0.001074) (0.321101,0.001071) (0.321935,0.001070) (0.322769,0.001066) (0.323603,0.001062) (0.324437,0.001047) (0.325271,0.001043) (0.326105,0.001041) (0.326939,0.001040) (0.327773,0.001038) (0.328607,0.001027) (0.329441,0.001025) (0.330275,0.001016) (0.331109,0.001016) (0.331943,0.000996) (0.332777,0.000992) (0.333611,0.000985) (0.334445,0.000979) (0.335279,0.000978) (0.336113,0.000978) (0.336947,0.000957) (0.337781,0.000953) (0.338616,0.000951) (0.339450,0.000947) (0.340284,0.000944) (0.341118,0.000939) (0.341952,0.000932) (0.342786,0.000930) (0.343620,0.000930) (0.344454,0.000928) (0.345288,0.000915) (0.346122,0.000914) (0.346956,0.000914) (0.347790,0.000911) (0.348624,0.000910) (0.349458,0.000908) (0.350292,0.000904) (0.351126,0.000895) (0.351960,0.000890) (0.352794,0.000887) (0.353628,0.000884) (0.354462,0.000879) (0.355296,0.000861) (0.356130,0.000861) (0.356964,0.000826) (0.357798,0.000814) (0.358632,0.000808) (0.359466,0.000800) (0.360300,0.000797) (0.361134,0.000796) (0.361968,0.000782) (0.362802,0.000779) (0.363636,0.000778) (0.364470,0.000777) (0.365304,0.000777) (0.366138,0.000775) (0.366972,0.000767) (0.367807,0.000764) (0.368641,0.000761) (0.369475,0.000758) (0.370309,0.000753) (0.371143,0.000753) (0.371977,0.000751) (0.372811,0.000738) (0.373645,0.000718) (0.374479,0.000718) (0.375313,0.000710) (0.376147,0.000709) (0.376981,0.000707) (0.377815,0.000701) (0.378649,0.000699) (0.379483,0.000694) (0.380317,0.000694) (0.381151,0.000688) (0.381985,0.000686) (0.382819,0.000683) (0.383653,0.000681) (0.384487,0.000665) (0.385321,0.000664) (0.386155,0.000660) (0.386989,0.000659) (0.387823,0.000657) (0.388657,0.000657) (0.389491,0.000655) (0.390325,0.000654) (0.391159,0.000647) (0.391993,0.000645) (0.392827,0.000644) (0.393661,0.000643) (0.394495,0.000642) (0.395329,0.000640) (0.396163,0.000639) (0.396997,0.000637) (0.397832,0.000634) (0.398666,0.000630) (0.399500,0.000614) (0.400334,0.000613) (0.401168,0.000607) (0.402002,0.000604) (0.402836,0.000603) (0.403670,0.000602) (0.404504,0.000602) (0.405338,0.000598) (0.406172,0.000597) (0.407006,0.000592) (0.407840,0.000588) (0.408674,0.000576) (0.409508,0.000572) (0.410342,0.000570) (0.411176,0.000570) (0.412010,0.000567) (0.412844,0.000567) (0.413678,0.000566) (0.414512,0.000564) (0.415346,0.000563) (0.416180,0.000554) (0.417014,0.000550) (0.417848,0.000548) (0.418682,0.000547) (0.419516,0.000547) (0.420350,0.000546) (0.421184,0.000542) (0.422018,0.000542) (0.422852,0.000535) (0.423686,0.000529) (0.424520,0.000518) (0.425354,0.000516) (0.426188,0.000515) (0.427023,0.000513) (0.427857,0.000512) (0.428691,0.000511) (0.429525,0.000503) (0.430359,0.000503) (0.431193,0.000503) (0.432027,0.000499) (0.432861,0.000497) (0.433695,0.000497) (0.434529,0.000495) (0.435363,0.000495) (0.436197,0.000494) (0.437031,0.000494) (0.437865,0.000492) (0.438699,0.000491) (0.439533,0.000490) (0.440367,0.000489) (0.441201,0.000488) (0.442035,0.000486) (0.442869,0.000484) (0.443703,0.000480) (0.444537,0.000479) (0.445371,0.000478) (0.446205,0.000471) (0.447039,0.000467) (0.447873,0.000466) (0.448707,0.000464) (0.449541,0.000460) (0.450375,0.000458) (0.451209,0.000456) (0.452043,0.000452) (0.452877,0.000451) (0.453711,0.000448) (0.454545,0.000446) (0.455379,0.000445) (0.456214,0.000444) (0.457048,0.000437) (0.457882,0.000436) (0.458716,0.000435) (0.459550,0.000431) (0.460384,0.000431) (0.461218,0.000430) (0.462052,0.000428) (0.462886,0.000428) (0.463720,0.000428) (0.464554,0.000427) (0.465388,0.000427) (0.466222,0.000422) (0.467056,0.000420) (0.467890,0.000415) (0.468724,0.000409) (0.469558,0.000408) (0.470392,0.000408) (0.471226,0.000406) (0.472060,0.000405) (0.472894,0.000404) (0.473728,0.000404) (0.474562,0.000402) (0.475396,0.000402) (0.476230,0.000402) (0.477064,0.000402) (0.477898,0.000399) (0.478732,0.000399) (0.479566,0.000398) (0.480400,0.000395) (0.481234,0.000395) (0.482068,0.000394) (0.482902,0.000390) (0.483736,0.000389) (0.484570,0.000387) (0.485405,0.000385) (0.486239,0.000383) (0.487073,0.000382) (0.487907,0.000381) (0.488741,0.000380) (0.489575,0.000380) (0.490409,0.000377) (0.491243,0.000375) (0.492077,0.000374) (0.492911,0.000373) (0.493745,0.000371) (0.494579,0.000370) (0.495413,0.000369) (0.496247,0.000368) (0.497081,0.000366) (0.497915,0.000364) (0.498749,0.000362) (0.499583,0.000362) (0.500417,0.000358) (0.501251,0.000354) (0.502085,0.000346) (0.502919,0.000345) (0.503753,0.000344) (0.504587,0.000343) (0.505421,0.000341) (0.506255,0.000340) (0.507089,0.000337) (0.507923,0.000337) (0.508757,0.000331) (0.509591,0.000328) (0.510425,0.000325) (0.511259,0.000323) (0.512093,0.000319) (0.512927,0.000319) (0.513761,0.000317) (0.514595,0.000315) (0.515430,0.000314) (0.516264,0.000313) (0.517098,0.000313) (0.517932,0.000312) (0.518766,0.000312) (0.519600,0.000311) (0.520434,0.000302) (0.521268,0.000300) (0.522102,0.000300) (0.522936,0.000295) (0.523770,0.000295) (0.524604,0.000295) (0.525438,0.000292) (0.526272,0.000290) (0.527106,0.000290) (0.527940,0.000288) (0.528774,0.000287) (0.529608,0.000285) (0.530442,0.000280) (0.531276,0.000278) (0.532110,0.000278) (0.532944,0.000278) (0.533778,0.000277) (0.534612,0.000276) (0.535446,0.000274) (0.536280,0.000273) (0.537114,0.000271) (0.537948,0.000271) (0.538782,0.000270) (0.539616,0.000266) (0.540450,0.000263) (0.541284,0.000260) (0.542118,0.000260) (0.542952,0.000258) (0.543786,0.000258) (0.544621,0.000256) (0.545455,0.000253) (0.546289,0.000252) (0.547123,0.000251) (0.547957,0.000249) (0.548791,0.000248) (0.549625,0.000248) (0.550459,0.000248) (0.551293,0.000246) (0.552127,0.000246) (0.552961,0.000244) (0.553795,0.000244) (0.554629,0.000242) (0.555463,0.000241) (0.556297,0.000240) (0.557131,0.000240) (0.557965,0.000239) (0.558799,0.000236) (0.559633,0.000236) (0.560467,0.000235) (0.561301,0.000234) (0.562135,0.000234) (0.562969,0.000234) (0.563803,0.000233) (0.564637,0.000233) (0.565471,0.000225) (0.566305,0.000223) (0.567139,0.000223) (0.567973,0.000220) (0.568807,0.000219) (0.569641,0.000218) (0.570475,0.000218) (0.571309,0.000217) (0.572143,0.000216) (0.572977,0.000213) (0.573812,0.000211) (0.574646,0.000207) (0.575480,0.000206) (0.576314,0.000206) (0.577148,0.000205) (0.577982,0.000205) (0.578816,0.000203) (0.579650,0.000203) (0.580484,0.000203) (0.581318,0.000203) (0.582152,0.000203) (0.582986,0.000201) (0.583820,0.000200) (0.584654,0.000200) (0.585488,0.000199) (0.586322,0.000199) (0.587156,0.000197) (0.587990,0.000194) (0.588824,0.000193) (0.589658,0.000191) (0.590492,0.000190) (0.591326,0.000190) (0.592160,0.000186) (0.592994,0.000186) (0.593828,0.000181) (0.594662,0.000178) (0.595496,0.000175) (0.596330,0.000174) (0.597164,0.000173) (0.597998,0.000173) (0.598832,0.000172) (0.599666,0.000171) (0.600500,0.000171) (0.601334,0.000170) (0.602168,0.000170) (0.603003,0.000169) (0.603837,0.000166) (0.604671,0.000165) (0.605505,0.000165) (0.606339,0.000165) (0.607173,0.000164) (0.608007,0.000163) (0.608841,0.000162) (0.609675,0.000162) (0.610509,0.000162) (0.611343,0.000162) (0.612177,0.000161) (0.613011,0.000161) (0.613845,0.000159) (0.614679,0.000158) (0.615513,0.000158) (0.616347,0.000157) (0.617181,0.000156) (0.618015,0.000155) (0.618849,0.000155) (0.619683,0.000152) (0.620517,0.000152) (0.621351,0.000151) (0.622185,0.000151) (0.623019,0.000149) (0.623853,0.000149) (0.624687,0.000148) (0.625521,0.000147) (0.626355,0.000147) (0.627189,0.000146) (0.628023,0.000146) (0.628857,0.000146) (0.629691,0.000146) (0.630525,0.000145) (0.631359,0.000145) (0.632193,0.000144) (0.633028,0.000144) (0.633862,0.000144) (0.634696,0.000144) (0.635530,0.000143) (0.636364,0.000142) (0.637198,0.000142) (0.638032,0.000142) (0.638866,0.000142) (0.639700,0.000141) (0.640534,0.000140) (0.641368,0.000139) (0.642202,0.000137) (0.643036,0.000137) (0.643870,0.000133) (0.644704,0.000131) (0.645538,0.000131) (0.646372,0.000129) (0.647206,0.000129) (0.648040,0.000129) (0.648874,0.000128) (0.649708,0.000128) (0.650542,0.000127) (0.651376,0.000124) (0.652210,0.000123) (0.653044,0.000119) (0.653878,0.000117) (0.654712,0.000117) (0.655546,0.000117) (0.656380,0.000115) (0.657214,0.000114) (0.658048,0.000114) (0.658882,0.000114) (0.659716,0.000113) (0.660550,0.000112) (0.661384,0.000111) (0.662219,0.000111) (0.663053,0.000111) (0.663887,0.000111) (0.664721,0.000110) (0.665555,0.000110) (0.666389,0.000109) (0.667223,0.000108) (0.668057,0.000108) (0.668891,0.000107) (0.669725,0.000105) (0.670559,0.000105) (0.671393,0.000105) (0.672227,0.000105) (0.673061,0.000105) (0.673895,0.000105) (0.674729,0.000105) (0.675563,0.000104) (0.676397,0.000104) (0.677231,0.000103) (0.678065,0.000102) (0.678899,0.000101) (0.679733,0.000101) (0.680567,0.000100) (0.681401,0.000100) (0.682235,0.000100) (0.683069,0.000099) (0.683903,0.000099) (0.684737,0.000098) (0.685571,0.000098) (0.686405,0.000098) (0.687239,0.000097) (0.688073,0.000094) (0.688907,0.000094) (0.689741,0.000092) (0.690575,0.000092) (0.691410,0.000091) (0.692244,0.000089) (0.693078,0.000089) (0.693912,0.000087) (0.694746,0.000087) (0.695580,0.000087) (0.696414,0.000086) (0.697248,0.000086) (0.698082,0.000086) (0.698916,0.000085) (0.699750,0.000085) (0.700584,0.000085) (0.701418,0.000085) (0.702252,0.000084) (0.703086,0.000084) (0.703920,0.000083) (0.704754,0.000083) (0.705588,0.000082) (0.706422,0.000081) (0.707256,0.000080) (0.708090,0.000080) (0.708924,0.000080) (0.709758,0.000079) (0.710592,0.000079) (0.711426,0.000078) (0.712260,0.000078) (0.713094,0.000077) (0.713928,0.000076) (0.714762,0.000076) (0.715596,0.000076) (0.716430,0.000075) (0.717264,0.000075) (0.718098,0.000072) (0.718932,0.000071) (0.719766,0.000071) (0.720601,0.000070) (0.721435,0.000070) (0.722269,0.000070) (0.723103,0.000070) (0.723937,0.000070) (0.724771,0.000070) (0.725605,0.000069) (0.726439,0.000068) (0.727273,0.000068) (0.728107,0.000068) (0.728941,0.000067) (0.729775,0.000067) (0.730609,0.000067) (0.731443,0.000067) (0.732277,0.000066) (0.733111,0.000066) (0.733945,0.000065) (0.734779,0.000065) (0.735613,0.000065) (0.736447,0.000065) (0.737281,0.000064) (0.738115,0.000064) (0.738949,0.000063) (0.739783,0.000063) (0.740617,0.000063) (0.741451,0.000062) (0.742285,0.000062) (0.743119,0.000060) (0.743953,0.000060) (0.744787,0.000059) (0.745621,0.000059) (0.746455,0.000059) (0.747289,0.000059) (0.748123,0.000058) (0.748957,0.000058) (0.749791,0.000057) (0.750626,0.000057) (0.751460,0.000057) (0.752294,0.000057) (0.753128,0.000057) (0.753962,0.000057) (0.754796,0.000057) (0.755630,0.000057) (0.756464,0.000057) (0.757298,0.000057) (0.758132,0.000057) (0.758966,0.000057) (0.759800,0.000057) (0.760634,0.000057) (0.761468,0.000057) (0.762302,0.000057) (0.763136,0.000056) (0.763970,0.000056) (0.764804,0.000055) (0.765638,0.000055) (0.766472,0.000055) (0.767306,0.000055) (0.768140,0.000055) (0.768974,0.000055) (0.769808,0.000054) (0.770642,0.000054) (0.771476,0.000054) (0.772310,0.000054) (0.773144,0.000054) (0.773978,0.000053) (0.774812,0.000053) (0.775646,0.000053) (0.776480,0.000053) (0.777314,0.000053) (0.778148,0.000053) (0.778982,0.000053) (0.779817,0.000052) (0.780651,0.000052) (0.781485,0.000052) (0.782319,0.000052) (0.783153,0.000052) (0.783987,0.000052) (0.784821,0.000052) (0.785655,0.000051) (0.786489,0.000051) (0.787323,0.000051) (0.788157,0.000051) (0.788991,0.000050) (0.789825,0.000050) (0.790659,0.000050) (0.791493,0.000049) (0.792327,0.000049) (0.793161,0.000049) (0.793995,0.000049) (0.794829,0.000049) (0.795663,0.000049) (0.796497,0.000049) (0.797331,0.000047) (0.798165,0.000047) (0.798999,0.000047) (0.799833,0.000047) (0.800667,0.000046) (0.801501,0.000046) (0.802335,0.000046) (0.803169,0.000046) (0.804003,0.000045) (0.804837,0.000045) (0.805671,0.000044) (0.806505,0.000044) (0.807339,0.000043) (0.808173,0.000043) (0.809008,0.000043) (0.809842,0.000043) (0.810676,0.000042) (0.811510,0.000042) (0.812344,0.000041) (0.813178,0.000041) (0.814012,0.000041) (0.814846,0.000041) (0.815680,0.000040) (0.816514,0.000040) (0.817348,0.000038) (0.818182,0.000038) (0.819016,0.000038) (0.819850,0.000037) (0.820684,0.000037) (0.821518,0.000037) (0.822352,0.000037) (0.823186,0.000037) (0.824020,0.000036) (0.824854,0.000036) (0.825688,0.000035) (0.826522,0.000035) (0.827356,0.000035) (0.828190,0.000035) (0.829024,0.000034) (0.829858,0.000034) (0.830692,0.000033) (0.831526,0.000033) (0.832360,0.000033) (0.833194,0.000033) (0.834028,0.000032) (0.834862,0.000032) (0.835696,0.000031) (0.836530,0.000031) (0.837364,0.000030) (0.838198,0.000030) (0.839033,0.000030) (0.839867,0.000030) (0.840701,0.000029) (0.841535,0.000029) (0.842369,0.000029) (0.843203,0.000029) (0.844037,0.000029) (0.844871,0.000028) (0.845705,0.000028) (0.846539,0.000028) (0.847373,0.000028) (0.848207,0.000028) (0.849041,0.000028) (0.849875,0.000028) (0.850709,0.000028) (0.851543,0.000028) (0.852377,0.000028) (0.853211,0.000028) (0.854045,0.000028) (0.854879,0.000028) (0.855713,0.000028) (0.856547,0.000028) (0.857381,0.000028) (0.858215,0.000028) (0.859049,0.000027) (0.859883,0.000027) (0.860717,0.000027) (0.861551,0.000027) (0.862385,0.000027) (0.863219,0.000027) (0.864053,0.000027) (0.864887,0.000027) (0.865721,0.000027) (0.866555,0.000027) (0.867389,0.000027) (0.868224,0.000027) (0.869058,0.000027) (0.869892,0.000026) (0.870726,0.000026) (0.871560,0.000026) (0.872394,0.000025) (0.873228,0.000025) (0.874062,0.000025) (0.874896,0.000025) (0.875730,0.000025) (0.876564,0.000025) (0.877398,0.000025) (0.878232,0.000025) (0.879066,0.000025) (0.879900,0.000025) (0.880734,0.000024) (0.881568,0.000024) (0.882402,0.000024) (0.883236,0.000024) (0.884070,0.000024) (0.884904,0.000024) (0.885738,0.000023) (0.886572,0.000023) (0.887406,0.000023) (0.888240,0.000023) (0.889074,0.000023) (0.889908,0.000023) (0.890742,0.000022) (0.891576,0.000022) (0.892410,0.000022) (0.893244,0.000022) (0.894078,0.000022) (0.894912,0.000022) (0.895746,0.000022) (0.896580,0.000022) (0.897415,0.000021) (0.898249,0.000021) (0.899083,0.000021) (0.899917,0.000021) (0.900751,0.000021) (0.901585,0.000021) (0.902419,0.000021) (0.903253,0.000021) (0.904087,0.000021) (0.904921,0.000021) (0.905755,0.000021) (0.906589,0.000021) (0.907423,0.000021) (0.908257,0.000020) (0.909091,0.000020) (0.909925,0.000020) (0.910759,0.000020) (0.911593,0.000020) (0.912427,0.000020) (0.913261,0.000020) (0.914095,0.000019) (0.914929,0.000019) (0.915763,0.000019) (0.916597,0.000018) (0.917431,0.000018) (0.918265,0.000018) (0.919099,0.000017) (0.919933,0.000017) (0.920767,0.000017) (0.921601,0.000017) (0.922435,0.000017) (0.923269,0.000016) (0.924103,0.000016) (0.924937,0.000016) (0.925771,0.000016) (0.926606,0.000016) (0.927440,0.000016) (0.928274,0.000015) (0.929108,0.000015) (0.929942,0.000015) (0.930776,0.000015) (0.931610,0.000015) (0.932444,0.000015) (0.933278,0.000015) (0.934112,0.000015) (0.934946,0.000014) (0.935780,0.000014) (0.936614,0.000014) (0.937448,0.000014) (0.938282,0.000013) (0.939116,0.000013) (0.939950,0.000012) (0.940784,0.000012) (0.941618,0.000012) (0.942452,0.000012) (0.943286,0.000012) (0.944120,0.000012) (0.944954,0.000012) (0.945788,0.000012) (0.946622,0.000011) (0.947456,0.000011) (0.948290,0.000011) (0.949124,0.000011) (0.949958,0.000011) (0.950792,0.000011) (0.951626,0.000010) (0.952460,0.000010) (0.953294,0.000010) (0.954128,0.000010) (0.954962,0.000009) (0.955796,0.000009) (0.956631,0.000009) (0.957465,0.000009) (0.958299,0.000008) (0.959133,0.000008) (0.959967,0.000008) (0.960801,0.000008) (0.961635,0.000008) (0.962469,0.000008) (0.963303,0.000008) (0.964137,0.000008) (0.964971,0.000007) (0.965805,0.000007) (0.966639,0.000007) (0.967473,0.000007) (0.968307,0.000007) (0.969141,0.000007) (0.969975,0.000006) (0.970809,0.000006) (0.971643,0.000006) (0.972477,0.000005) (0.973311,0.000005) (0.974145,0.000004) (0.974979,0.000004) (0.975813,0.000004) (0.976647,0.000004) (0.977481,0.000004) (0.978315,0.000003) (0.979149,0.000003) (0.979983,0.000003) (0.980817,0.000003) (0.981651,0.000002) (0.982485,0.000002) (0.983319,0.000002) (0.984153,0.000002) (0.984987,0.000002) (0.985822,0.000002) (0.986656,0.000001) (0.987490,0.000001) (0.988324,0.000001) (0.989158,0.000001) (0.989992,0.000001) (0.990826,0.000001) (0.991660,0.000001) (0.992494,0.000001) (0.993328,0.000001) (0.994162,0.000001) (0.994996,0.000001) (0.995830,0.000001) (0.996664,0.000001) (0.997498,0.000001) (0.998332,0.000001) (0.999166,0.000001) (1.000000,0.000001) }; -\addplot[green,only marks,mark=*] coordinates {(0.015013,0.226789) (0.341952,0.000932) (0.663053,0.000111)}; +\addplot[brown,only marks,mark=*] coordinates {(0.015013,0.226789) (0.341952,0.000932) (0.663053,0.000111)}; \ No newline at end of file diff --git a/talk/vmil2012/presentation/tool/data.py b/talk/vmil2012/presentation/tool/data.py --- a/talk/vmil2012/presentation/tool/data.py +++ b/talk/vmil2012/presentation/tool/data.py @@ -49,6 +49,7 @@ for j, (bench, info) in enumerate(failures.iteritems()): data = [] marks = [] + color_map = {} results = info['results'].values() results.sort() results.reverse() @@ -66,14 +67,15 @@ for i, result in enumerate(results): data.append("(%04f,%04f)" % (float(i) / (len(results) - 1), float(result) / max(results))) - + # + color_map[bench] = COLORS[j] if bench == 'go': with open('figures/go_data.tex', 'w') as f: - f.write(plot % {'color': 'green', + f.write(plot % {'color': color_map[bench], 'name': bench, 'marks': " ".join(marks), 'data': " ".join(data)}) - output.append(plot % {'color': COLORS[j], + output.append(plot % {'color': color_map[bench], 'name': bench, 'marks': " ".join(marks), 'data': " ".join(data)}) From noreply at buildbot.pypy.org Wed Oct 17 16:05:43 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 16:05:43 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: fixfixfix trying to make the front-end pass Message-ID: <20121017140543.8A77E1C1CA0@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58170:0b0261125eea Date: 2012-10-17 15:23 +0200 http://bitbucket.org/pypy/pypy/changeset/0b0261125eea/ Log: fixfixfix trying to make the front-end pass diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -73,6 +73,16 @@ def is_pointer_field(self): return getkind(self.FIELD) == 'ref' + def is_float_field(self): + return getkind(self.FIELD) == 'float' + + def is_field_signed(self): + return _is_signed_kind(self.FIELD) + +def _is_signed_kind(TYPE): + return (TYPE is not lltype.Bool and isinstance(TYPE, lltype.Number) and + rffi.cast(TYPE, -1) == -1) + class ArrayDescr(AbstractDescr): def __init__(self, A): self.A = A @@ -83,6 +93,15 @@ def is_array_of_pointers(self): return getkind(self.A.OF) == 'ref' + def is_array_of_floats(self): + return getkind(self.A.OF) == 'float' + + def is_item_signed(self): + return _is_signed_kind(self.A.OF) + + def is_array_of_structs(self): + return isinstance(self.A.OF, lltype.Struct) + class InteriorFieldDescr(AbstractDescr): def __init__(self, A, fieldname): self.A = A @@ -94,57 +113,73 @@ class LLGraphCPU(model.AbstractCPU): + from pypy.jit.metainterp.typesystem import llhelper as ts supports_floats = True supports_longlong = True supports_singlefloats = True + translate_support_code = False - def __init__(self, rtyper): + def __init__(self, rtyper, stats=None, *ignored_args, **ignored_kwds): model.AbstractCPU.__init__(self) self.rtyper = rtyper self.llinterp = LLInterpreter(rtyper) self.known_labels = WeakKeyDictionary() self.last_exception = None self.descrs = {} + class MiniStats: + pass + self.stats = stats or MiniStats() def compile_loop(self, inputargs, operations, looptoken, log=True, name=''): + clt = model.CompiledLoopToken(self, looptoken.number) + looptoken.compiled_loop_token = clt lltrace = LLTrace(inputargs, operations, looptoken) - looptoken._llgraph_loop = lltrace - looptoken._llgraph_alltraces = [lltrace] + clt._llgraph_loop = lltrace + clt._llgraph_alltraces = [lltrace] self._record_labels(lltrace) - self.total_compiled_loops += 1 def compile_bridge(self, faildescr, inputargs, operations, - original_loop_token): + original_loop_token, log=True): + clt = original_loop_token.compiled_loop_token + clt.compiling_a_bridge() lltrace = LLTrace(inputargs, operations, original_loop_token) faildescr._llgraph_bridge = lltrace - original_loop_token._llgraph_alltraces.append(lltrace) + clt._llgraph_alltraces.append(lltrace) self._record_labels(lltrace) - self.total_compiled_bridges += 1 def _record_labels(self, lltrace): + # xxx pfff, we need to clone the list of operations because the + # front-end will mutate them under our feet again + lltrace.operations = [op.copy_and_change(op.getopnum()) + for op in lltrace.operations] for i, op in enumerate(lltrace.operations): if op.getopnum() == rop.LABEL: self.known_labels[op.getdescr()] = (lltrace, i) def invalidate_loop(self, looptoken): - for trace in looptoken._llgraph_alltraces: + for trace in looptoken.compiled_loop_token._llgraph_alltraces: trace.invalid = True def redirect_call_assembler(self, oldlooptoken, newlooptoken): - oldtrace = oldlooptoken._llgraph_loop - newtrace = newlooptoken._llgraph_loop + oldtrace = oldlooptoken.compiled_loop_token._llgraph_loop + newtrace = newlooptoken.compiled_loop_token._llgraph_loop OLD = [box.type for box in oldtrace.inputargs] NEW = [box.type for box in newtrace.inputargs] assert OLD == NEW assert not hasattr(oldlooptoken, '_llgraph_redirected') - oldlooptoken._llgraph_redirected = True - oldlooptoken._llgraph_loop = newtrace + oldlooptoken.compiled_loop_token._llgraph_redirected = True + oldlooptoken.compiled_loop_token._llgraph_loop = newtrace + + def free_loop_and_bridges(self, compiled_loop_token): + for c in compiled_loop_token._llgraph_alltraces: + c.has_been_freed = True + model.AbstractCPU.free_loop_and_bridges(self, compiled_loop_token) def make_execute_token(self, *argtypes): return self._execute_token def _execute_token(self, loop_token, *args): - lltrace = loop_token._llgraph_loop + lltrace = loop_token.compiled_loop_token._llgraph_loop frame = LLFrame(self, lltrace.inputargs, args) try: frame.execute(lltrace) @@ -270,7 +305,12 @@ def _do_call(self, func, args_i, args_r, args_f, calldescr): TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE args = support.cast_call_args(TP.ARGS, args_i, args_r, args_f) - func = llmemory.cast_int_to_adr(func).ptr._obj._callable + ptr = llmemory.cast_int_to_adr(func).ptr + if hasattr(ptr._obj, 'graph'): + def func(*args): + return self.llinterp.eval_graph(ptr._obj.graph, args) + else: + func = ptr._obj._callable return self.call(func, args, TP.RESULT, calldescr) bh_call_i = _do_call @@ -282,6 +322,7 @@ p = support.cast_arg(lltype.Ptr(descr.S), p) return support.cast_result(descr.FIELD, getattr(p, descr.fieldname)) + bh_getfield_gc_pure = bh_getfield_gc bh_getfield_gc_i = bh_getfield_gc bh_getfield_gc_r = bh_getfield_gc bh_getfield_gc_f = bh_getfield_gc @@ -467,6 +508,7 @@ del lltrace i = 0 while True: + assert not self.lltrace.has_been_freed op = self.lltrace.operations[i] if op.getopnum() == -124: # force_spill, for tests i += 1 @@ -637,6 +679,7 @@ self.fail_guard(descr) def execute_jump(self, descr, *args): + assert descr is not None raise Jump(descr, args) def _do_math_sqrt(self, value): diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py b/pypy/jit/metainterp/optimizeopt/test/test_util.py --- a/pypy/jit/metainterp/optimizeopt/test/test_util.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py @@ -87,7 +87,7 @@ node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True) node_vtable2.name = rclass.alloc_array_name('node2') node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2) - cpu = runner.LLtypeCPU(None) + cpu = runner.LLGraphCPU(None) NODE = lltype.GcForwardReference() NODE.become(lltype.GcStruct('NODE', ('parent', OBJECT), diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py --- a/pypy/jit/metainterp/test/support.py +++ b/pypy/jit/metainterp/test/support.py @@ -233,7 +233,7 @@ class LLJitMixin(JitMixin): type_system = 'lltype' - CPUClass = runner.LLtypeCPU + CPUClass = runner.LLGraphCPU @staticmethod def Ptr(T): diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -45,6 +45,9 @@ def clone(self): return FORCE_SPILL(self.OPNUM, self.getarglist()[:]) + def copy_and_change(self, opnum): # no arguments accepted + return self.clone() + def default_fail_descr(model, fail_args=None): return model.BasicFailDescr() From noreply at buildbot.pypy.org Wed Oct 17 16:05:44 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 16:05:44 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: Whack whack whack. Also start to remove the forever-skipped OO tests. Message-ID: <20121017140544.BBAC21C1CA0@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58171:39f1ae8df9a4 Date: 2012-10-17 16:01 +0200 http://bitbucket.org/pypy/pypy/changeset/39f1ae8df9a4/ Log: Whack whack whack. Also start to remove the forever-skipped OO tests. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -44,12 +44,20 @@ self.RESULT = RESULT self.ARGS = ARGS self.extrainfo = extrainfo - def get_extra_info(self): - return self.extrainfo + def __repr__(self): return 'CallDescr(%r, %r, %r)' % (self.RESULT, self.ARGS, self.extrainfo) + def get_extra_info(self): + return self.extrainfo + + def get_arg_types(self): + return ''.join([getkind(ARG)[0] for ARG in self.ARGS]) + + def get_result_type(self): + return getkind(self.RESULT)[0] + class SizeDescr(AbstractDescr): def __init__(self, S): self.S = S @@ -289,29 +297,18 @@ # ------------------------------------------------------------ - def call(self, func, args, RESULT, calldescr): - try: - res = func(*args) - self.last_exception = None - except LLException, lle: - self.last_exception = lle - d = {'void': None, - 'ref': lltype.nullptr(llmemory.GCREF.TO), - 'int': 0, - 'float': 0.0} - res = d[getkind(RESULT)] + def maybe_on_top_of_llinterp(self, func, args, RESULT): + ptr = llmemory.cast_int_to_adr(func).ptr + if hasattr(ptr._obj, 'graph'): + res = self.llinterp.eval_graph(ptr._obj.graph, args) + else: + res = ptr._obj._callable(*args) return support.cast_result(RESULT, res) def _do_call(self, func, args_i, args_r, args_f, calldescr): TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE args = support.cast_call_args(TP.ARGS, args_i, args_r, args_f) - ptr = llmemory.cast_int_to_adr(func).ptr - if hasattr(ptr._obj, 'graph'): - def func(*args): - return self.llinterp.eval_graph(ptr._obj.graph, args) - else: - func = ptr._obj._callable - return self.call(func, args, TP.RESULT, calldescr) + return self.maybe_on_top_of_llinterp(func, args, TP.RESULT) bh_call_i = _do_call bh_call_r = _do_call @@ -485,6 +482,11 @@ array = lltype.malloc(arraydescr.A, length, zero=True) return lltype.cast_opaque_ptr(llmemory.GCREF, array) + def bh_classof(self, struct): + struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) + result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) + return heaptracker.adr2int(result_adr) + def bh_read_timestamp(self): return read_timestamp() @@ -695,16 +697,27 @@ if oopspecindex == EffectInfo.OS_MATH_SQRT: return self._do_math_sqrt(args[0]) TP = llmemory.cast_int_to_adr(func).ptr._obj._TYPE - ARGS = TP.ARGS - call_args = support.cast_call_args_in_order(ARGS, args) - func = llmemory.cast_int_to_adr(func).ptr._obj._callable - return self.cpu.call(func, call_args, TP.RESULT, calldescr) + call_args = support.cast_call_args_in_order(TP.ARGS, args) + try: + res = self.cpu.maybe_on_top_of_llinterp(func, call_args, TP.RESULT) + self.cpu.last_exception = None + except LLException, lle: + self.cpu.last_exception = lle + d = {'void': None, + 'ref': lltype.nullptr(llmemory.GCREF.TO), + 'int': 0, + 'float': 0.0} + res = d[getkind(TP.RESULT)] + return res + + execute_call_may_force = execute_call def execute_call_release_gil(self, descr, func, *args): call_args = support.cast_call_args_in_order(descr.ARGS, args) FUNC = lltype.FuncType(descr.ARGS, descr.RESULT) func_to_call = rffi.cast(lltype.Ptr(FUNC), func) - return self.cpu.call(func_to_call, call_args, descr.RESULT, descr) + result = func_to_call(*call_args) + return support.cast_result(descr.RESULT, result) def execute_call_assembler(self, descr, *args): faildescr = self.cpu._execute_token(descr, *args) diff --git a/pypy/jit/backend/llgraph/support.py b/pypy/jit/backend/llgraph/support.py --- a/pypy/jit/backend/llgraph/support.py +++ b/pypy/jit/backend/llgraph/support.py @@ -136,13 +136,22 @@ def cast_call_args_in_order(ARGS, args): call_args = [] - for ARG, arg in zip(ARGS, args): + i = 0 + for ARG in ARGS: kind = getkind(ARG) if kind == 'int': - n = cast_from_int(ARG, arg) + n = cast_from_int(ARG, args[i]) + i += 1 elif kind == 'ref': - n = cast_from_ptr(ARG, arg) + n = cast_from_ptr(ARG, args[i]) + i += 1 + elif kind == 'float': + n = cast_from_floatstorage(ARG, args[i]) + i += 1 + elif kind == 'void': + n = None else: - n = cast_from_floatstorage(ARG, arg) + raise AssertionError(kind) call_args.append(n) + assert i == len(args) return call_args diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py --- a/pypy/jit/metainterp/executor.py +++ b/pypy/jit/metainterp/executor.py @@ -49,28 +49,28 @@ rettype = descr.get_result_type() if rettype == INT or rettype == 'S': # *S*ingle float try: - result = cpu.bh_call_i(func, descr, args_i, args_r, args_f) + result = cpu.bh_call_i(func, args_i, args_r, args_f, descr) except Exception, e: metainterp.execute_raised(e) result = 0 return BoxInt(result) if rettype == REF: try: - result = cpu.bh_call_r(func, descr, args_i, args_r, args_f) + result = cpu.bh_call_r(func, args_i, args_r, args_f, descr) except Exception, e: metainterp.execute_raised(e) result = NULL return BoxPtr(result) if rettype == FLOAT or rettype == 'L': # *L*ong long try: - result = cpu.bh_call_f(func, descr, args_i, args_r, args_f) + result = cpu.bh_call_f(func, args_i, args_r, args_f, descr) except Exception, e: metainterp.execute_raised(e) result = longlong.ZEROF return BoxFloat(result) if rettype == VOID: try: - cpu.bh_call_v(func, descr, args_i, args_r, args_f) + cpu.bh_call_v(func, args_i, args_r, args_f, descr) except Exception, e: metainterp.execute_raised(e) return None @@ -83,42 +83,42 @@ array = arraybox.getref_base() index = indexbox.getint() if arraydescr.is_array_of_pointers(): - return BoxPtr(cpu.bh_getarrayitem_gc_r(arraydescr, array, index)) + return BoxPtr(cpu.bh_getarrayitem_gc_r(array, index, arraydescr)) elif arraydescr.is_array_of_floats(): - return BoxFloat(cpu.bh_getarrayitem_gc_f(arraydescr, array, index)) + return BoxFloat(cpu.bh_getarrayitem_gc_f(array, index, arraydescr)) else: - return BoxInt(cpu.bh_getarrayitem_gc_i(arraydescr, array, index)) + return BoxInt(cpu.bh_getarrayitem_gc_i(array, index, arraydescr)) def do_getarrayitem_raw(cpu, _, arraybox, indexbox, arraydescr): array = arraybox.getint() index = indexbox.getint() assert not arraydescr.is_array_of_pointers() if arraydescr.is_array_of_floats(): - return BoxFloat(cpu.bh_getarrayitem_raw_f(arraydescr, array, index)) + return BoxFloat(cpu.bh_getarrayitem_raw_f(array, index, arraydescr)) else: - return BoxInt(cpu.bh_getarrayitem_raw_i(arraydescr, array, index)) + return BoxInt(cpu.bh_getarrayitem_raw_i(array, index, arraydescr)) def do_setarrayitem_gc(cpu, _, arraybox, indexbox, itembox, arraydescr): array = arraybox.getref_base() index = indexbox.getint() if arraydescr.is_array_of_pointers(): - cpu.bh_setarrayitem_gc_r(arraydescr, array, index, - itembox.getref_base()) + cpu.bh_setarrayitem_gc_r(array, index, + itembox.getref_base(), arraydescr) elif arraydescr.is_array_of_floats(): - cpu.bh_setarrayitem_gc_f(arraydescr, array, index, - itembox.getfloatstorage()) + cpu.bh_setarrayitem_gc_f(array, index, + itembox.getfloatstorage(), arraydescr) else: - cpu.bh_setarrayitem_gc_i(arraydescr, array, index, itembox.getint()) + cpu.bh_setarrayitem_gc_i(array, index, itembox.getint(), arraydescr) def do_setarrayitem_raw(cpu, _, arraybox, indexbox, itembox, arraydescr): array = arraybox.getint() index = indexbox.getint() assert not arraydescr.is_array_of_pointers() if arraydescr.is_array_of_floats(): - cpu.bh_setarrayitem_raw_f(arraydescr, array, index, - itembox.getfloatstorage()) + cpu.bh_setarrayitem_raw_f(array, index, + itembox.getfloatstorage(), arraydescr) else: - cpu.bh_setarrayitem_raw_i(arraydescr, array, index, itembox.getint()) + cpu.bh_setarrayitem_raw_i(array, index, itembox.getint(), arraydescr) def do_getinteriorfield_gc(cpu, _, arraybox, indexbox, descr): array = arraybox.getref_base() @@ -134,14 +134,14 @@ array = arraybox.getref_base() index = indexbox.getint() if descr.is_pointer_field(): - cpu.bh_setinteriorfield_gc_r(array, index, descr, - valuebox.getref_base()) + cpu.bh_setinteriorfield_gc_r(array, index, + valuebox.getref_base(), descr) elif descr.is_float_field(): - cpu.bh_setinteriorfield_gc_f(array, index, descr, - valuebox.getfloatstorage()) + cpu.bh_setinteriorfield_gc_f(array, index, + valuebox.getfloatstorage(), descr) else: - cpu.bh_setinteriorfield_gc_i(array, index, descr, - valuebox.getint()) + cpu.bh_setinteriorfield_gc_i(array, index, + valuebox.getint(), descr) def do_getfield_gc(cpu, _, structbox, fielddescr): struct = structbox.getref_base() @@ -165,20 +165,20 @@ def do_setfield_gc(cpu, _, structbox, itembox, fielddescr): struct = structbox.getref_base() if fielddescr.is_pointer_field(): - cpu.bh_setfield_gc_r(struct, fielddescr, itembox.getref_base()) + cpu.bh_setfield_gc_r(struct, itembox.getref_base(), fielddescr) elif fielddescr.is_float_field(): - cpu.bh_setfield_gc_f(struct, fielddescr, itembox.getfloatstorage()) + cpu.bh_setfield_gc_f(struct, itembox.getfloatstorage(), fielddescr) else: - cpu.bh_setfield_gc_i(struct, fielddescr, itembox.getint()) + cpu.bh_setfield_gc_i(struct, itembox.getint(), fielddescr) def do_setfield_raw(cpu, _, structbox, itembox, fielddescr): struct = structbox.getint() if fielddescr.is_pointer_field(): - cpu.bh_setfield_raw_r(struct, fielddescr, itembox.getref_base()) + cpu.bh_setfield_raw_r(struct, itembox.getref_base(), fielddescr) elif fielddescr.is_float_field(): - cpu.bh_setfield_raw_f(struct, fielddescr, itembox.getfloatstorage()) + cpu.bh_setfield_raw_f(struct, itembox.getfloatstorage(), fielddescr) else: - cpu.bh_setfield_raw_i(struct, fielddescr, itembox.getint()) + cpu.bh_setfield_raw_i(struct, itembox.getint(), fielddescr) def do_raw_store(cpu, _, addrbox, offsetbox, valuebox, arraydescr): addr = addrbox.getint() @@ -186,9 +186,10 @@ if arraydescr.is_array_of_pointers(): raise AssertionError("cannot store GC pointers in raw store") elif arraydescr.is_array_of_floats(): - cpu.bh_raw_store_f(addr, offset, arraydescr,valuebox.getfloatstorage()) + cpu.bh_raw_store_f(addr, offset, valuebox.getfloatstorage(), + arraydescr) else: - cpu.bh_raw_store_i(addr, offset, arraydescr, valuebox.getint()) + cpu.bh_raw_store_i(addr, offset, valuebox.getint(), arraydescr) def do_raw_load(cpu, _, addrbox, offsetbox, arraydescr): addr = addrbox.getint() @@ -204,7 +205,7 @@ from pypy.jit.codewriter import heaptracker vtable = clsbox.getint() descr = heaptracker.vtable2descr(cpu, vtable) - return cpu.bh_new_with_vtable(descr, vtable) + return cpu.bh_new_with_vtable(vtable, descr) def do_new_with_vtable(cpu, _, clsbox): return BoxPtr(exec_new_with_vtable(cpu, clsbox)) diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py --- a/pypy/jit/metainterp/resume.py +++ b/pypy/jit/metainterp/resume.py @@ -1142,7 +1142,7 @@ return self.cpu.bh_new(typedescr) def allocate_array(self, arraydescr, length): - return self.cpu.bh_new_array(arraydescr, length) + return self.cpu.bh_new_array(length, arraydescr) def allocate_string(self, length): return self.cpu.bh_newstr(length) @@ -1201,36 +1201,36 @@ def setfield(self, descr, struct, fieldnum): if descr.is_pointer_field(): newvalue = self.decode_ref(fieldnum) - self.cpu.bh_setfield_gc_r(struct, descr, newvalue) + self.cpu.bh_setfield_gc_r(struct, newvalue, descr) elif descr.is_float_field(): newvalue = self.decode_float(fieldnum) - self.cpu.bh_setfield_gc_f(struct, descr, newvalue) + self.cpu.bh_setfield_gc_f(struct, newvalue, descr) else: newvalue = self.decode_int(fieldnum) - self.cpu.bh_setfield_gc_i(struct, descr, newvalue) + self.cpu.bh_setfield_gc_i(struct, newvalue, descr) def setinteriorfield(self, index, descr, array, fieldnum): if descr.is_pointer_field(): newvalue = self.decode_ref(fieldnum) - self.cpu.bh_setinteriorfield_gc_r(array, index, descr, newvalue) + self.cpu.bh_setinteriorfield_gc_r(array, index, newvalue, descr) elif descr.is_float_field(): newvalue = self.decode_float(fieldnum) - self.cpu.bh_setinteriorfield_gc_f(array, index, descr, newvalue) + self.cpu.bh_setinteriorfield_gc_f(array, index, newvalue, descr) else: newvalue = self.decode_int(fieldnum) - self.cpu.bh_setinteriorfield_gc_i(array, index, descr, newvalue) + self.cpu.bh_setinteriorfield_gc_i(array, index, newvalue, descr) def setarrayitem_int(self, arraydescr, array, index, fieldnum): newvalue = self.decode_int(fieldnum) - self.cpu.bh_setarrayitem_gc_i(arraydescr, array, index, newvalue) + self.cpu.bh_setarrayitem_gc_i(array, index, newvalue, arraydescr) def setarrayitem_ref(self, arraydescr, array, index, fieldnum): newvalue = self.decode_ref(fieldnum) - self.cpu.bh_setarrayitem_gc_r(arraydescr, array, index, newvalue) + self.cpu.bh_setarrayitem_gc_r(array, index, newvalue, arraydescr) def setarrayitem_float(self, arraydescr, array, index, fieldnum): newvalue = self.decode_float(fieldnum) - self.cpu.bh_setarrayitem_gc_f(arraydescr, array, index, newvalue) + self.cpu.bh_setarrayitem_gc_f(array, index, newvalue, arraydescr) def decode_int(self, tagged): num, tag = untag(tagged) diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py --- a/pypy/jit/metainterp/test/support.py +++ b/pypy/jit/metainterp/test/support.py @@ -256,38 +256,6 @@ NODE.become(lltype.GcStruct('NODE', ('value', lltype.Signed), ('next', lltype.Ptr(NODE)))) return NODE - -class OOJitMixin(JitMixin): - type_system = 'ootype' - #CPUClass = runner.OOtypeCPU - - def setup_class(cls): - py.test.skip("ootype tests skipped for now") - - @staticmethod - def Ptr(T): - return T - - @staticmethod - def GcStruct(name, *fields, **kwds): - if 'hints' in kwds: - kwds['_hints'] = kwds['hints'] - del kwds['hints'] - I = ootype.Instance(name, ootype.ROOT, dict(fields), **kwds) - return I - - malloc = staticmethod(ootype.new) - nullptr = staticmethod(ootype.null) - - @staticmethod - def malloc_immortal(T): - return ootype.new(T) - - def _get_NODE(self): - NODE = ootype.Instance('NODE', ootype.ROOT, {}) - NODE._add_fields({'value': ootype.Signed, - 'next': NODE}) - return NODE # ____________________________________________________________ diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py --- a/pypy/jit/metainterp/test/test_ajit.py +++ b/pypy/jit/metainterp/test/test_ajit.py @@ -8,7 +8,7 @@ from pypy.jit.codewriter.policy import JitPolicy, StopAtXPolicy from pypy.jit.metainterp import pyjitpl, history from pypy.jit.metainterp.optimizeopt import ALL_OPTS_DICT -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin, noConst +from pypy.jit.metainterp.test.support import LLJitMixin, noConst from pypy.jit.metainterp.typesystem import LLTypeHelper, OOTypeHelper from pypy.jit.metainterp.warmspot import get_stats from pypy.rlib import rerased @@ -3053,86 +3053,6 @@ assert res == f(32) -class TestOOtype(BasicTests, OOJitMixin): - - def test_oohash(self): - def f(n): - s = ootype.oostring(n, -1) - return s.ll_hash() - res = self.interp_operations(f, [5]) - assert res == ootype.oostring(5, -1).ll_hash() - - def test_identityhash(self): - A = ootype.Instance("A", ootype.ROOT) - def f(): - obj1 = ootype.new(A) - obj2 = ootype.new(A) - return ootype.identityhash(obj1) == ootype.identityhash(obj2) - assert not f() - res = self.interp_operations(f, []) - assert not res - - def test_oois(self): - A = ootype.Instance("A", ootype.ROOT) - def f(n): - obj1 = ootype.new(A) - if n: - obj2 = obj1 - else: - obj2 = ootype.new(A) - return obj1 is obj2 - res = self.interp_operations(f, [0]) - assert not res - res = self.interp_operations(f, [1]) - assert res - - def test_oostring_instance(self): - A = ootype.Instance("A", ootype.ROOT) - B = ootype.Instance("B", ootype.ROOT) - def f(n): - obj1 = ootype.new(A) - obj2 = ootype.new(B) - s1 = ootype.oostring(obj1, -1) - s2 = ootype.oostring(obj2, -1) - ch1 = s1.ll_stritem_nonneg(1) - ch2 = s2.ll_stritem_nonneg(1) - return ord(ch1) + ord(ch2) - res = self.interp_operations(f, [0]) - assert res == ord('A') + ord('B') - - def test_subclassof(self): - A = ootype.Instance("A", ootype.ROOT) - B = ootype.Instance("B", A) - clsA = ootype.runtimeClass(A) - clsB = ootype.runtimeClass(B) - myjitdriver = JitDriver(greens = [], reds = ['n', 'flag', 'res']) - - def getcls(flag): - if flag: - return clsA - else: - return clsB - - def f(flag, n): - res = True - while n > -100: - myjitdriver.can_enter_jit(n=n, flag=flag, res=res) - myjitdriver.jit_merge_point(n=n, flag=flag, res=res) - cls = getcls(flag) - n -= 1 - res = ootype.subclassof(cls, clsB) - return res - - res = self.meta_interp(f, [1, 100], - policy=StopAtXPolicy(getcls), - enable_opts='') - assert not res - - res = self.meta_interp(f, [0, 100], - policy=StopAtXPolicy(getcls), - enable_opts='') - assert res - class BaseLLtypeTests(BasicTests): def test_identityhash(self): diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py --- a/pypy/objspace/flow/model.py +++ b/pypy/objspace/flow/model.py @@ -33,6 +33,9 @@ class FunctionGraph(object): + __slots__ = ('startblock', '__dict__') + # xxx the __slots__ is for try_show(), to make get_referrers() work. HACK + def __init__(self, name, startblock, return_var=None): self.name = name # function name (possibly mangled already) self.startblock = startblock From noreply at buildbot.pypy.org Wed Oct 17 16:19:22 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 16:19:22 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: Fixes Message-ID: <20121017141922.A5BD71C1CA0@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58172:5032a1570a3a Date: 2012-10-17 16:19 +0200 http://bitbucket.org/pypy/pypy/changeset/5032a1570a3a/ Log: Fixes diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -61,8 +61,13 @@ class SizeDescr(AbstractDescr): def __init__(self, S): self.S = S + def as_vtable_size_descr(self): return self + + def count_fields_if_immutable(self): + return heaptracker.count_fields_if_immutable(self.S) + def __repr__(self): return 'SizeDescr(%r)' % (self.S,) @@ -119,6 +124,15 @@ def __repr__(self): return 'InteriorFieldDescr(%r, %r)' % (self.A, self.fieldname) + def sort_key(self): + return self.fieldname + + def is_pointer_field(self): + return getkind(self.FIELD) == 'ref' + + def is_float_field(self): + return getkind(self.FIELD) == 'float' + class LLGraphCPU(model.AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts @@ -158,6 +172,7 @@ def _record_labels(self, lltrace): # xxx pfff, we need to clone the list of operations because the # front-end will mutate them under our feet again + # xXX pffffffff2 not enough to make sure things are freed lltrace.operations = [op.copy_and_change(op.getopnum()) for op in lltrace.operations] for i, op in enumerate(lltrace.operations): @@ -351,6 +366,7 @@ array = a._obj return support.cast_result(descr.A.OF, array.getitem(index)) + bh_getarrayitem_gc_pure = bh_getarrayitem_gc bh_getarrayitem_gc_i = bh_getarrayitem_gc bh_getarrayitem_gc_r = bh_getarrayitem_gc bh_getarrayitem_gc_f = bh_getarrayitem_gc @@ -538,8 +554,9 @@ if op.result is not None: # typecheck the result if op.result.type == INT: - resval = int(resval) - assert isinstance(resval, int) + if isinstance(resval, bool): + resval = int(resval) + assert lltype.typeOf(resval) == lltype.Signed elif op.result.type == REF: assert lltype.typeOf(resval) == llmemory.GCREF elif op.result.type == FLOAT: From noreply at buildbot.pypy.org Wed Oct 17 16:23:37 2012 From: noreply at buildbot.pypy.org (bivab) Date: Wed, 17 Oct 2012 16:23:37 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: Arrange elements in the loop diagram in the same way as in the following ones Message-ID: <20121017142337.B517A1C1CA0@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: extradoc Changeset: r4870:badaabdf7726 Date: 2012-10-17 11:23 -0300 http://bitbucket.org/pypy/extradoc/changeset/badaabdf7726/ Log: Arrange elements in the loop diagram in the same way as in the following ones diff --git a/talk/vmil2012/presentation/Makefile b/talk/vmil2012/presentation/Makefile --- a/talk/vmil2012/presentation/Makefile +++ b/talk/vmil2012/presentation/Makefile @@ -1,4 +1,4 @@ -talk.pdf: talk.tex figures/data.tex figures/go_data.tex tool/data.py +talk.pdf: talk.tex figures/data.tex figures/go_data.tex tool/data.py figures/*.pdf figures/*.graffle pdflatex talk.tex &> /dev/null UNAME := $(shell "uname") diff --git a/talk/vmil2012/presentation/figures/loop.graffle b/talk/vmil2012/presentation/figures/loop.graffle --- a/talk/vmil2012/presentation/figures/loop.graffle +++ b/talk/vmil2012/presentation/figures/loop.graffle @@ -14,7 +14,7 @@ BackgroundGraphic Bounds - {{0, 0}, {559, 783}} + {{0, 0}, {1118, 783}} Class SolidGraphic ID @@ -132,15 +132,13 @@ Bounds - {{353.00001525878906, 92.5}, {166.99998474121094, 93.5}} + {{232.00001379686913, 294.74999999999989}, {150.99998620313085, 93.5}} Class ShapedGraphic ID 59 Magnets - {0, 1} - {0, -1} {1, 0} {-1, 0} @@ -163,7 +161,7 @@ Bounds - {{353, 59}, {167, 33.5}} + {{232, 261.25}, {151, 33.5}} Class ShapedGraphic ID @@ -189,13 +187,6 @@ ID 58 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - Class @@ -209,9 +200,9 @@ 54 Points - {186, 334.75} - {232, 285.49998514226786} - {242.89735689328157, 270.5} + {82.536736108577472, 339.10023442863826} + {52, 351.5} + {34.428503435249759, 361.50264298468693} Style @@ -233,6 +224,8 @@ ID 42 + Info + 2 @@ -247,9 +240,9 @@ 53 Points - {186, 301.25} - {211, 234} - {242.89735689328157, 147} + {83, 301.25} + {60, 286} + {33.993974985969523, 268.75} Style @@ -271,8 +264,6 @@ ID 37 - Info - 1 @@ -287,9 +278,9 @@ 48 Points - {186, 334.75} - {327, 318} - {436.50000762939453, 186} + {134.5, 351.5} + {186, 384} + {232.0000137968691, 341.49999999999989} Style @@ -324,8 +315,8 @@ Points {186, 301.25} - {260, 220} - {353.00001525878906, 139.25} + {211, 307} + {232.0000137968691, 341.49999999999989} Style @@ -392,6 +383,8 @@ 42 Magnets + {0, 1} + {0, -1} {1, 0} {-1, 0} @@ -410,7 +403,7 @@ Bounds - {{237, 247}, {85, 47}} + {{-46, 338.25}, {85, 47}} Class ShapedGraphic ID @@ -437,7 +430,7 @@ Bounds - {{237, 123.5}, {85, 47}} + {{-46, 245.25}, {85, 47}} Class ShapedGraphic ID @@ -713,6 +706,997 @@ Shape Rectangle + + Class + LineGraphic + Head + + ID + 67 + + ID + 68 + Points + + {531, 333.75} + {555, 351} + {580.89735689328165, 373.74999618530273} + + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + Draws + YES + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 44 + + + + Class + LineGraphic + Head + + ID + 65 + + ID + 66 + Points + + {531, 301.25} + {580, 278} + {580.415709839653, 277.88418648722006} + + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + Draws + YES + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + Pattern + 1 + TailArrow + 0 + + + Tail + + ID + 43 + + + + Class + LineGraphic + Head + + ID + 44 + + ID + 52 + Points + + {532, 205} + {566, 277} + {531, 333.75} + + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + Draws + YES + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 34 + + + + Class + LineGraphic + Head + + ID + 43 + + ID + 51 + Points + + {532, 159} + {569, 211} + {531, 301.25} + + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + Draws + YES + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + HeadArrow + FilledArrow + Legacy + + LineType + 1 + TailArrow + 0 + + + Tail + + ID + 32 + + + + Bounds + {{428, 317}, {103, 33.5}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 44 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 Trampoline #4} + + + + Bounds + {{428, 284.5}, {103, 33.5}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 43 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 Trampoline #3} + + + + Bounds + {{575.00001069962946, 254.25000040105692}, {85, 47}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 65 + Magnets + + {1, 0} + {-1, 0} + + Shape + Cloud + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 backend map #3} + + + + Bounds + {{575, 350.24999618530273}, {85, 47}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 67 + Magnets + + {1, 0} + {-1, 0} + + Shape + Cloud + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 backend map #4} + + + + Bounds + {{427, 238.5}, {105, 23}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 36 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 jump} + + + + Bounds + {{427, 215.5}, {105, 23}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 35 + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 operation} + + + + Bounds + {{427, 193.5}, {105, 23}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 34 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 guard #4} + + + + Bounds + {{427, 170.5}, {105, 23}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 33 + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 operation} + + + + Bounds + {{427, 147.5}, {105, 23}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 32 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 guard #3} + + + + Bounds + {{427, 124.5}, {105, 23}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 31 + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 operation} + + + + Bounds + {{427, 101.5}, {105, 23}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 30 + Magnets + + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 operation} + + + + Bounds + {{404, 59}, {151, 24}} + Class + ShapedGraphic + FitText + Vertical + Flow + Resize + FontInfo + + Color + + w + 1 + + + ID + 29 + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf1 Bridge from guard #2} + + + + Bounds + {{404, 83}, {151, 286}} + Class + ShapedGraphic + FontInfo + + Color + + w + 1 + + + ID + 28 + Shape + Rectangle + Style + + shadow + + Color + + b + 1 + g + 1 + r + 1 + + + stroke + + Color + + b + 1 + g + 1 + r + 1 + + + + GridInfo @@ -721,7 +1705,12 @@ GuidesVisible YES HPages - 1 + 2 + HorizontalGuides + + 244 + 384 + ImageCounter 1 KeepToScale @@ -761,7 +1750,7 @@ MasterSheets ModificationDate - 2012-10-12 14:55:13 +0000 + 2012-10-17 14:19:41 +0000 Modifier David Schneider NotesVisible @@ -835,20 +1824,15 @@ CurrentSheet 0 ExpandedCanvases - - - name - Canvas 1 - - + Frame - {{513, 146}, {693, 882}} + {{196, 205}, {1457, 783}} ListView OutlineWidth 142 RightSidebar - + ShowRuler Sidebar @@ -856,7 +1840,7 @@ SidebarWidth 120 VisibleRegion - {{0, 0}, {558, 743}} + {{-54, 0}, {1179, 644}} Zoom 1 ZoomValues diff --git a/talk/vmil2012/presentation/figures/loop.pdf b/talk/vmil2012/presentation/figures/loop.pdf index 9e3d9a833ab11876cc81f55d64a9e82735a24e6c..a950daa5a03960c3388aee8b3f451043abd7e32b GIT binary patch [cut] From noreply at buildbot.pypy.org Wed Oct 17 16:34:52 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 16:34:52 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal, arigo) Remove more of the OOJitMixin usages. Message-ID: <20121017143452.CC9151C1CA0@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58173:24b34b9f1bb8 Date: 2012-10-17 16:34 +0200 http://bitbucket.org/pypy/pypy/changeset/24b34b9f1bb8/ Log: (fijal, arigo) Remove more of the OOJitMixin usages. diff --git a/pypy/jit/metainterp/quasiimmut.py b/pypy/jit/metainterp/quasiimmut.py --- a/pypy/jit/metainterp/quasiimmut.py +++ b/pypy/jit/metainterp/quasiimmut.py @@ -22,7 +22,7 @@ qmut = QuasiImmut.show(cpu, qmut_gcref) else: qmut = QuasiImmut(cpu) - cpu.bh_setfield_gc_r(gcref, mutatefielddescr, qmut.hide()) + cpu.bh_setfield_gc_r(gcref, qmut.hide(), mutatefielddescr) return qmut def make_invalidation_function(STRUCT, mutatefieldname): @@ -43,7 +43,7 @@ def do_force_quasi_immutable(cpu, p, mutatefielddescr): qmut_ref = cpu.bh_getfield_gc_r(p, mutatefielddescr) if qmut_ref: - cpu.bh_setfield_gc_r(p, mutatefielddescr, cpu.ts.NULLREF) + cpu.bh_setfield_gc_r(p, cpu.ts.NULLREF, mutatefielddescr) qmut_ptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, qmut_ref) qmut = cast_base_ptr_to_instance(QuasiImmut, qmut_ptr) qmut.invalidate() diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py --- a/pypy/jit/metainterp/test/test_ajit.py +++ b/pypy/jit/metainterp/test/test_ajit.py @@ -3757,8 +3757,6 @@ res = self.interp_operations(f, [x]) assert res == x or isnan(x) and isnan(res) - -class TestLLtype(BaseLLtypeTests, LLJitMixin): def test_tagged(self): from pypy.rlib.objectmodel import UnboxedValue class Base(object): @@ -3883,3 +3881,7 @@ return 42 self.interp_operations(f, [1, 2, 3]) self.check_operations_history(call=1, guard_no_exception=0) + + +class TestLLtype(BaseLLtypeTests, LLJitMixin): + pass diff --git a/pypy/jit/metainterp/test/test_blackhole.py b/pypy/jit/metainterp/test/test_blackhole.py --- a/pypy/jit/metainterp/test/test_blackhole.py +++ b/pypy/jit/metainterp/test/test_blackhole.py @@ -1,6 +1,6 @@ import py from pypy.rlib.jit import JitDriver -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder from pypy.jit.metainterp.blackhole import BlackholeInterpreter from pypy.jit.metainterp.blackhole import convert_and_run_from_pyjitpl @@ -15,7 +15,7 @@ class FakeAssembler: pass class FakeCPU: - def bh_call_i(self, func, calldescr, args_i, args_r, args_f): + def bh_call_i(self, func, args_i, args_r, args_f, calldescr): assert func == 321 assert calldescr == "" if args_i[0] < 0: diff --git a/pypy/jit/metainterp/test/test_compile.py b/pypy/jit/metainterp/test/test_compile.py --- a/pypy/jit/metainterp/test/test_compile.py +++ b/pypy/jit/metainterp/test/test_compile.py @@ -152,7 +152,7 @@ from pypy.rpython.annlowlevel import llhelper from pypy.rpython.llinterp import LLException # - cpu = runner.LLtypeCPU(None) + cpu = runner.LLGraphCPU(None) FUNC = lltype.FuncType([lltype.Signed]*4, lltype.Signed) def ll_portal_runner(g1, g2, r3, r4): assert (g1, g2, r3, r4) == (12, 34, -156, -178) diff --git a/pypy/jit/metainterp/test/test_del.py b/pypy/jit/metainterp/test/test_del.py --- a/pypy/jit/metainterp/test/test_del.py +++ b/pypy/jit/metainterp/test/test_del.py @@ -2,7 +2,7 @@ from pypy.rlib.jit import JitDriver, dont_look_inside from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib import rgc -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin class DelTests: @@ -124,7 +124,6 @@ assert res == 1001 -class TestLLtype(DelTests, LLJitMixin): def test_signal_action(self): from pypy.module.signal.interp_signal import SignalActionFlag action = SignalActionFlag() @@ -148,7 +147,6 @@ self.meta_interp(f, [20]) self.check_resops(call_pure=0, setfield_raw=2, call=0, getfield_raw=2) -class TestOOtype(DelTests, OOJitMixin): - def setup_class(cls): - py.test.skip("XXX dels are not implemented in the" - " static CLI or JVM backend") + +class TestLLtype(DelTests, LLJitMixin): + pass diff --git a/pypy/jit/metainterp/test/test_dict.py b/pypy/jit/metainterp/test/test_dict.py --- a/pypy/jit/metainterp/test/test_dict.py +++ b/pypy/jit/metainterp/test/test_dict.py @@ -1,5 +1,5 @@ import py -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.rlib.jit import JitDriver from pypy.rlib import objectmodel @@ -178,8 +178,5 @@ 'jump': 1}) -class TestOOtype(DictTests, OOJitMixin): - pass - class TestLLtype(DictTests, LLJitMixin): pass diff --git a/pypy/jit/metainterp/test/test_exception.py b/pypy/jit/metainterp/test/test_exception.py --- a/pypy/jit/metainterp/test/test_exception.py +++ b/pypy/jit/metainterp/test/test_exception.py @@ -1,5 +1,5 @@ import py, sys -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.rlib.jit import JitDriver, dont_look_inside from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT, intmask from pypy.jit.codewriter.policy import StopAtXPolicy @@ -617,8 +617,5 @@ self.n = n -class TestOOtype(ExceptionTests, OOJitMixin): - pass - class TestLLtype(ExceptionTests, LLJitMixin): pass diff --git a/pypy/jit/metainterp/test/test_float.py b/pypy/jit/metainterp/test/test_float.py --- a/pypy/jit/metainterp/test/test_float.py +++ b/pypy/jit/metainterp/test/test_float.py @@ -1,5 +1,5 @@ import math, sys -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.rlib.rarithmetic import intmask, r_uint @@ -75,8 +75,5 @@ assert type(res) is float and res == float(long(r_uint(-12345))) -class TestOOtype(FloatTests, OOJitMixin): - pass - class TestLLtype(FloatTests, LLJitMixin): pass diff --git a/pypy/jit/metainterp/test/test_greenfield.py b/pypy/jit/metainterp/test/test_greenfield.py --- a/pypy/jit/metainterp/test/test_greenfield.py +++ b/pypy/jit/metainterp/test/test_greenfield.py @@ -1,4 +1,4 @@ -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.rlib.jit import JitDriver @@ -55,6 +55,3 @@ class TestLLtypeGreenFieldsTests(GreenFieldsTests, LLJitMixin): pass - -class TestOOtypeGreenFieldsTests(GreenFieldsTests, OOJitMixin): - pass diff --git a/pypy/jit/metainterp/test/test_immutable.py b/pypy/jit/metainterp/test/test_immutable.py --- a/pypy/jit/metainterp/test/test_immutable.py +++ b/pypy/jit/metainterp/test/test_immutable.py @@ -1,5 +1,5 @@ from pypy.rlib import jit -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin @jit.dont_look_inside def escape(x): @@ -177,6 +177,3 @@ class TestLLtypeImmutableFieldsTests(ImmutableFieldsTests, LLJitMixin): pass - -class TestOOtypeImmutableFieldsTests(ImmutableFieldsTests, OOJitMixin): - pass diff --git a/pypy/jit/metainterp/test/test_jitdriver.py b/pypy/jit/metainterp/test/test_jitdriver.py --- a/pypy/jit/metainterp/test/test_jitdriver.py +++ b/pypy/jit/metainterp/test/test_jitdriver.py @@ -1,6 +1,6 @@ """Tests for multiple JitDrivers.""" from pypy.rlib.jit import JitDriver, unroll_safe, set_param -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp.warmspot import get_stats @@ -145,6 +145,3 @@ class TestLLtype(MultipleJitDriversTests, LLJitMixin): pass - -class TestOOtype(MultipleJitDriversTests, OOJitMixin): - pass diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py --- a/pypy/jit/metainterp/test/test_list.py +++ b/pypy/jit/metainterp/test/test_list.py @@ -1,7 +1,7 @@ import py from pypy.rlib.objectmodel import newlist_hint from pypy.rlib.jit import JitDriver -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin class ListTests: @@ -261,10 +261,6 @@ r = self.interp_operations(f, [-1]) assert r == 0 -class TestOOtype(ListTests, OOJitMixin): - pass - -class TestLLtype(ListTests, LLJitMixin): def test_listops_dont_invalidate_caches(self): class A(object): pass @@ -292,3 +288,7 @@ # There is the one actual field on a, plus several fields on the list # itself self.check_resops(getfield_gc=10) + + +class TestLLtype(ListTests, LLJitMixin): + pass diff --git a/pypy/jit/metainterp/test/test_loop.py b/pypy/jit/metainterp/test/test_loop.py --- a/pypy/jit/metainterp/test/test_loop.py +++ b/pypy/jit/metainterp/test/test_loop.py @@ -2,7 +2,7 @@ from pypy.rlib.jit import JitDriver, hint, set_param from pypy.rlib.objectmodel import compute_hash from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.codewriter.policy import StopAtXPolicy from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp import history @@ -907,8 +907,6 @@ res = self.meta_interp(f, [20, 10]) assert res == f(20, 10) -class TestOOtype(LoopTest, OOJitMixin): - pass class TestLLtype(LoopTest, LLJitMixin): pass diff --git a/pypy/jit/metainterp/test/test_loop_unroll.py b/pypy/jit/metainterp/test/test_loop_unroll.py --- a/pypy/jit/metainterp/test/test_loop_unroll.py +++ b/pypy/jit/metainterp/test/test_loop_unroll.py @@ -1,7 +1,7 @@ import py from pypy.rlib.jit import JitDriver from pypy.jit.metainterp.test import test_loop -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp.optimizeopt import ALL_OPTS_NAMES class LoopUnrollTest(test_loop.LoopTest): @@ -16,7 +16,3 @@ class TestLLtype(LoopUnrollTest, LLJitMixin): pass - -class TestOOtype(LoopUnrollTest, OOJitMixin): - pass - diff --git a/pypy/jit/metainterp/test/test_loop_unroll_disopt.py b/pypy/jit/metainterp/test/test_loop_unroll_disopt.py --- a/pypy/jit/metainterp/test/test_loop_unroll_disopt.py +++ b/pypy/jit/metainterp/test/test_loop_unroll_disopt.py @@ -1,7 +1,7 @@ import py from pypy.rlib.jit import JitDriver from pypy.jit.metainterp.test import test_loop -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp.optimizeopt import ALL_OPTS_NAMES allopts = ALL_OPTS_NAMES.split(':') diff --git a/pypy/jit/metainterp/test/test_math.py b/pypy/jit/metainterp/test/test_math.py --- a/pypy/jit/metainterp/test/test_math.py +++ b/pypy/jit/metainterp/test/test_math.py @@ -1,5 +1,5 @@ import math -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.rlib.rfloat import isinf, isnan, INFINITY, NAN class MathTests: @@ -40,8 +40,5 @@ self.check_operations_history(call_pure=0) -class TestOOtype(MathTests, OOJitMixin): - pass - class TestLLtype(MathTests, LLJitMixin): pass diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -3,7 +3,7 @@ from pypy.rlib.jit import unroll_safe, dont_look_inside, promote from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import fatalerror -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.codewriter.policy import StopAtXPolicy from pypy.rpython.annlowlevel import hlstr from pypy.jit.metainterp.warmspot import get_stats @@ -1265,6 +1265,3 @@ class TestLLtype(RecursiveTests, LLJitMixin): pass - -class TestOOtype(RecursiveTests, OOJitMixin): - pass diff --git a/pypy/jit/metainterp/test/test_send.py b/pypy/jit/metainterp/test/test_send.py --- a/pypy/jit/metainterp/test/test_send.py +++ b/pypy/jit/metainterp/test/test_send.py @@ -1,7 +1,7 @@ import py from pypy.rlib.jit import JitDriver, promote, elidable, set_param from pypy.jit.codewriter.policy import StopAtXPolicy -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin class SendTests(object): @@ -635,8 +635,5 @@ assert res == 21 -class TestOOtype(SendTests, OOJitMixin): - pass - class TestLLtype(SendTests, LLJitMixin): pass diff --git a/pypy/jit/metainterp/test/test_slist.py b/pypy/jit/metainterp/test/test_slist.py --- a/pypy/jit/metainterp/test/test_slist.py +++ b/pypy/jit/metainterp/test/test_slist.py @@ -1,5 +1,5 @@ import py -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.rlib.jit import JitDriver class ListTests(object): @@ -94,9 +94,6 @@ assert res == 41 self.check_resops(call=0, guard_value=0) -# we don't support resizable lists on ootype -#class TestOOtype(ListTests, OOJitMixin): -# pass class TestLLtype(ListTests, LLJitMixin): pass diff --git a/pypy/jit/metainterp/test/test_string.py b/pypy/jit/metainterp/test/test_string.py --- a/pypy/jit/metainterp/test/test_string.py +++ b/pypy/jit/metainterp/test/test_string.py @@ -1,7 +1,7 @@ import py from pypy.jit.codewriter.policy import StopAtXPolicy -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.rlib.debug import debug_print from pypy.rlib.jit import JitDriver, dont_look_inside, we_are_jitted,\ promote_string @@ -30,7 +30,7 @@ return i res = self.meta_interp(f, [10, True, _str('h')], listops=True) assert res == 5 - self.check_resops(**{self.CALL: 1, self.CALL_PURE: 0}) + self.check_resops(call=1, call_pure=0) def test_eq_folded(self): _str = self._str @@ -50,7 +50,7 @@ return i res = self.meta_interp(f, [10, True, _str('h')], listops=True) assert res == 5 - self.check_resops(**{self.CALL: 0, self.CALL_PURE: 0}) + self.check_resops(call=0, call_pure=0) def test_newstr(self): _str, _chr = self._str, self._chr @@ -516,13 +516,9 @@ self.meta_interp(f, [0]) self.check_resops(call=7) -#class TestOOtype(StringTests, OOJitMixin): -# CALL = "oosend" -# CALL_PURE = "oosend_pure" class TestLLtype(StringTests, LLJitMixin): - CALL = "call" - CALL_PURE = "call_pure" + pass class TestLLtypeUnicode(TestLLtype): _str, _chr = unicode, unichr diff --git a/pypy/jit/metainterp/test/test_tl.py b/pypy/jit/metainterp/test/test_tl.py --- a/pypy/jit/metainterp/test/test_tl.py +++ b/pypy/jit/metainterp/test/test_tl.py @@ -1,6 +1,6 @@ import py from pypy.jit.codewriter.policy import StopAtXPolicy -from pypy.jit.metainterp.test.support import OOJitMixin, LLJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin class ToyLanguageTests: @@ -141,8 +141,6 @@ meth_func = meth.im_func del meth_func._jit_look_inside_ -class TestOOtype(ToyLanguageTests, OOJitMixin): - pass class TestLLtype(ToyLanguageTests, LLJitMixin): pass diff --git a/pypy/jit/metainterp/test/test_tlc.py b/pypy/jit/metainterp/test/test_tlc.py --- a/pypy/jit/metainterp/test/test_tlc.py +++ b/pypy/jit/metainterp/test/test_tlc.py @@ -3,7 +3,7 @@ from pypy.jit.tl import tlc -from pypy.jit.metainterp.test.support import OOJitMixin, LLJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin class TLCTests: diff --git a/pypy/jit/metainterp/test/test_virtual.py b/pypy/jit/metainterp/test/test_virtual.py --- a/pypy/jit/metainterp/test/test_virtual.py +++ b/pypy/jit/metainterp/test/test_virtual.py @@ -2,7 +2,7 @@ from pypy.rlib.jit import JitDriver, promote, dont_look_inside from pypy.rlib.objectmodel import compute_unique_id from pypy.jit.codewriter.policy import StopAtXPolicy -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.rpython.lltypesystem import lltype, rclass from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.ootypesystem import ootype @@ -1178,15 +1178,6 @@ self.check_resops(new_with_vtable=0, setfield_gc=0, getfield_gc=0, new=0) -class TestOOtype_Instance(VirtualTests, OOJitMixin): - _new_op = 'new_with_vtable' - _field_prefix = 'o' - - @staticmethod - def _new(): - return MyClass() - - test_class_with_default_fields = TestLLtype_Instance.test_class_with_default_fields.im_func # ____________________________________________________________ # Run 2: all the tests use lltype.malloc to make a NODE @@ -1204,19 +1195,6 @@ return lltype.malloc(NODE) -OONODE = ootype.Instance('NODE', ootype.ROOT, {}) -OONODE._add_fields({'value': ootype.Signed, - 'floatval' : ootype.Float, - 'extra': ootype.Signed}) - -class TestOOtype_NotObject(VirtualTests, OOJitMixin): - _new_op = 'new_with_vtable' - _field_prefix = '' - - @staticmethod - def _new(): - return ootype.new(OONODE) - # ____________________________________________________________ # Run 3: all the tests use lltype.malloc to make a NODE2 # (same as Run 2 but it is part of the OBJECT hierarchy) @@ -1239,10 +1217,9 @@ p.parent.typeptr = vtable2 return p + +# ____________________________________________________________ # misc -class TestOOTypeMisc(VirtualMiscTests, OOJitMixin): - pass - class TestLLTypeMisc(VirtualMiscTests, LLJitMixin): pass diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py --- a/pypy/jit/metainterp/test/test_virtualizable.py +++ b/pypy/jit/metainterp/test/test_virtualizable.py @@ -7,7 +7,7 @@ from pypy.jit.codewriter import heaptracker from pypy.rlib.jit import JitDriver, hint, dont_look_inside, promote from pypy.rlib.rarithmetic import intmask -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.rpython.rclass import FieldListAccessor from pypy.jit.metainterp.warmspot import get_stats, get_translator from pypy.jit.metainterp import history @@ -1374,12 +1374,7 @@ print main(100) res = self.meta_interp(main, [100], inline=True, enable_opts='') -class TestOOtype(#ExplicitVirtualizableTests, - ImplicitVirtualizableTests, - OOJitMixin): - pass - class TestLLtype(ExplicitVirtualizableTests, ImplicitVirtualizableTests, LLJitMixin): diff --git a/pypy/jit/metainterp/test/test_virtualref.py b/pypy/jit/metainterp/test/test_virtualref.py --- a/pypy/jit/metainterp/test/test_virtualref.py +++ b/pypy/jit/metainterp/test/test_virtualref.py @@ -5,7 +5,7 @@ from pypy.rlib.jit import virtual_ref, virtual_ref_finish, InvalidVirtualRef from pypy.rlib.jit import non_virtual_ref from pypy.rlib.objectmodel import compute_unique_id -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin, _get_jitcodes +from pypy.jit.metainterp.test.support import LLJitMixin, _get_jitcodes from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp.virtualref import VirtualRefInfo diff --git a/pypy/jit/metainterp/test/test_warmspot.py b/pypy/jit/metainterp/test/test_warmspot.py --- a/pypy/jit/metainterp/test/test_warmspot.py +++ b/pypy/jit/metainterp/test/test_warmspot.py @@ -3,7 +3,7 @@ from pypy.rlib.jit import JitDriver, set_param, unroll_safe from pypy.jit.backend.llgraph import runner -from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin +from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp.optimizeopt import ALL_OPTS_NAMES @@ -313,12 +313,8 @@ class TestLLWarmspot(WarmspotTests, LLJitMixin): - CPUClass = runner.LLtypeCPU - type_system = 'lltype' + pass -class TestOOWarmspot(WarmspotTests, OOJitMixin): - ##CPUClass = runner.OOtypeCPU - type_system = 'ootype' class TestWarmspotDirect(object): def setup_class(cls): From noreply at buildbot.pypy.org Wed Oct 17 16:53:43 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 16:53:43 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: Small fixes Message-ID: <20121017145343.AFB641C1CA0@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58174:f2a4a97675ba Date: 2012-10-17 16:53 +0200 http://bitbucket.org/pypy/pypy/changeset/f2a4a97675ba/ Log: Small fixes diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -40,7 +40,7 @@ self.args = args class CallDescr(AbstractDescr): - def __init__(self, RESULT, ARGS, extrainfo=None): + def __init__(self, RESULT, ARGS, extrainfo): self.RESULT = RESULT self.ARGS = ARGS self.extrainfo = extrainfo @@ -306,7 +306,7 @@ try: return self.descrs[key] except KeyError: - descr = CallDescr(RESULT, ARGS) + descr = CallDescr(RESULT, ARGS, extrainfo) self.descrs[key] = descr return descr @@ -485,7 +485,7 @@ def bh_new(self, sizedescr): return lltype.cast_opaque_ptr(llmemory.GCREF, - lltype.malloc(sizedescr.S)) + lltype.malloc(sizedescr.S, zero=True)) def bh_new_with_vtable(self, vtable, descr): result = lltype.malloc(descr.S) diff --git a/pypy/jit/backend/llgraph/support.py b/pypy/jit/backend/llgraph/support.py --- a/pypy/jit/backend/llgraph/support.py +++ b/pypy/jit/backend/llgraph/support.py @@ -67,9 +67,7 @@ if isinstance(TYPE, lltype.Ptr): if isinstance(x, (int, long, llmemory.AddressAsInt)): x = llmemory.cast_int_to_adr(x) - if TYPE is rffi.VOIDP or ( - hasattr(TYPE.TO, '_hints') and - TYPE.TO._hints.get("uncast_on_llgraph")): + if repr(x.ptr).startswith('<* Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58175:318a6e951ea6 Date: 2012-10-17 16:57 +0200 http://bitbucket.org/pypy/pypy/changeset/318a6e951ea6/ Log: More diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -339,7 +339,8 @@ bh_getfield_gc_r = bh_getfield_gc bh_getfield_gc_f = bh_getfield_gc - bh_getfield_raw = bh_getfield_gc + bh_getfield_raw = bh_getfield_gc + bh_getfield_raw_pure = bh_getfield_raw bh_getfield_raw_i = bh_getfield_raw bh_getfield_raw_r = bh_getfield_raw bh_getfield_raw_f = bh_getfield_raw @@ -371,7 +372,8 @@ bh_getarrayitem_gc_r = bh_getarrayitem_gc bh_getarrayitem_gc_f = bh_getarrayitem_gc - bh_getarrayitem_raw = bh_getarrayitem_gc + bh_getarrayitem_raw = bh_getarrayitem_gc + bh_getarrayitem_raw_pure = bh_getarrayitem_raw bh_getarrayitem_raw_i = bh_getarrayitem_raw bh_getarrayitem_raw_r = bh_getarrayitem_raw bh_getarrayitem_raw_f = bh_getarrayitem_raw From noreply at buildbot.pypy.org Wed Oct 17 17:20:21 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 17 Oct 2012 17:20:21 +0200 (CEST) Subject: [pypy-commit] pypy py3k: hg merge default Message-ID: <20121017152021.3304C1C1C8D@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58176:b4e0f5b4079b Date: 2012-10-17 16:04 +0200 http://bitbucket.org/pypy/pypy/changeset/b4e0f5b4079b/ Log: hg merge default diff too long, truncating to 2000 out of 4137 lines diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -17,12 +17,6 @@ projects, or anything else in PyPy, pop up on IRC or write to us on the `mailing list`_. -Make big integers faster -------------------------- - -PyPy's implementation of the Python ``long`` type is slower than CPython's. -Find out why and optimize them. **UPDATE:** this was done (thanks stian). - Make bytearray type fast ------------------------ @@ -81,14 +75,6 @@ * Allow separate compilation of extension modules. -Work on some of other languages -------------------------------- - -There are various languages implemented using the RPython translation toolchain. -One of the most interesting is the `JavaScript implementation`_, but there -are others like scheme or prolog. An interesting project would be to improve -the jittability of those or to experiment with various optimizations. - Various GCs ----------- @@ -144,8 +130,6 @@ * `hg` -* `sympy` - Experiment (again) with LLVM backend for RPython compilation ------------------------------------------------------------ @@ -191,4 +175,3 @@ .. _`issue tracker`: http://bugs.pypy.org .. _`mailing list`: http://mail.python.org/mailman/listinfo/pypy-dev .. _`jitviewer`: http://bitbucket.org/pypy/jitviewer -.. _`JavaScript implementation`: https://bitbucket.org/pypy/lang-js/overview diff --git a/pypy/jit/backend/llvm/__init__.py b/pypy/jit/backend/llvm/__init__.py deleted file mode 100644 diff --git a/pypy/jit/backend/llvm/compile.py b/pypy/jit/backend/llvm/compile.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/compile.py +++ /dev/null @@ -1,732 +0,0 @@ -import py -from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp.history import Const, INT -from pypy.jit.backend.llvm import llvm_rffi -from pypy.jit.metainterp import resoperation -from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.llsupport import symbolic -from pypy.jit.backend.llvm.runner import SizeDescr, CallDescr -from pypy.jit.backend.llvm.runner import FieldDescr, ArrayDescr - -# ____________________________________________________________ - -class LLVMJITCompiler(object): - FUNC = lltype.FuncType([], lltype.Signed) - lastovf = lltype.nullptr(llvm_rffi.LLVMValueRef.TO) - - def __init__(self, cpu, loop): - self.cpu = cpu - self.loop = loop - - def compile(self): - self.start_generating_function() - self.generate_initial_arguments_load() - self.generate_loop_body() - self.close_phi_nodes() - self.done_generating_function() - - def start_generating_function(self): - func = llvm_rffi.LLVMAddFunction(self.cpu.module, "", self.cpu.ty_func) - self.compiling_func = func - self.builder = llvm_rffi.LLVMCreateBuilder() - self.vars = {} - - def generate_initial_arguments_load(self): - loop = self.loop - func = self.compiling_func - bb_entry = llvm_rffi.LLVMAppendBasicBlock(func, "entry") - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_entry) - self.cpu._ensure_in_args(len(loop.inputargs)) - self.phi_incoming_blocks = [bb_entry] - self.phi_incoming_values = [] - for i in range(len(loop.inputargs)): - ty = self.cpu._get_pointer_type(loop.inputargs[i]) - llvmconstptr = self.cpu._make_const(self.cpu.in_out_args[i], ty) - res = llvm_rffi.LLVMBuildLoad(self.builder, llvmconstptr, "") - self.phi_incoming_values.append([res]) - self.bb_start = llvm_rffi.LLVMAppendBasicBlock(func, "") - llvm_rffi.LLVMBuildBr(self.builder, self.bb_start) - # - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, self.bb_start) - for v in loop.inputargs: - ty = self.cpu._get_var_type(v) - phi = llvm_rffi.LLVMBuildPhi(self.builder, ty, "") - self.vars[v] = phi - - def generate_loop_body(self): - func = self.compiling_func - self.pending_blocks = [(self.loop.operations, self.bb_start, False)] - while self.pending_blocks: - operations, bb, exc = self.pending_blocks.pop() - self._generate_branch(operations, bb, exc) - self.bb_start = lltype.nullptr(llvm_rffi.LLVMBasicBlockRef.TO) - - def close_phi_nodes(self): - incoming_blocks = lltype.malloc( - rffi.CArray(llvm_rffi.LLVMBasicBlockRef), - len(self.phi_incoming_blocks), flavor='raw') - incoming_values = lltype.malloc( - rffi.CArray(llvm_rffi.LLVMValueRef), - len(self.phi_incoming_blocks), flavor='raw') - for j in range(len(self.phi_incoming_blocks)): - incoming_blocks[j] = self.phi_incoming_blocks[j] - loop = self.loop - for i in range(len(loop.inputargs)): - phi = self.vars[loop.inputargs[i]] - incoming = self.phi_incoming_values[i] - for j in range(len(self.phi_incoming_blocks)): - incoming_values[j] = incoming[j] - llvm_rffi.LLVMAddIncoming(phi, incoming_values, incoming_blocks, - len(self.phi_incoming_blocks)) - lltype.free(incoming_values, flavor='raw') - lltype.free(incoming_blocks, flavor='raw') - - def done_generating_function(self): - llvm_rffi.LLVMDisposeBuilder(self.builder) - llvm_rffi.LLVMDumpValue(self.compiling_func) # xxx for debugging - # - func_addr = llvm_rffi.LLVM_EE_getPointerToFunction(self.cpu.ee, - self.compiling_func) - if not we_are_translated(): - print '--- function is at %r ---' % (func_addr,) - # - func_ptr = rffi.cast(lltype.Ptr(self.FUNC), func_addr) - index = self.loop._llvm_compiled_index - if index < 0: - self.loop._llvm_compiled_index = len(self.cpu.compiled_functions) - self.cpu.compiled_functions.append(func_ptr) - else: - self.cpu.compiled_functions[index] = func_ptr - - def _generate_branch(self, operations, basicblock, exc): - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, basicblock) - # The flag 'exc' is set to True if we are a branch handling a - # GUARD_EXCEPTION or GUARD_NO_EXCEPTION. In this case, we have to - # store away the exception into self.backup_exc_xxx, *unless* the - # branch starts with a further GUARD_EXCEPTION/GUARD_NO_EXCEPTION. - if exc: - opnum = operations[0].getopnum() - if opnum not in (rop.GUARD_EXCEPTION, rop.GUARD_NO_EXCEPTION): - self._store_away_exception() - # Normal handling of the operations follows. - for op in operations: - self._generate_op(op) - - def _generate_op(self, op): - opnum = op.getopnum() - for i, name in all_operations: - if opnum == i: - meth = getattr(self, name) - meth(op) - return - else: - raise MissingOperation(resoperation.opname[opnum]) - - def _store_away_exception(self): - # etype, evalue: ty_char_ptr - etype = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_type, "") - llvm_rffi.LLVMBuildStore(self.builder, - self.cpu.const_null_charptr, - self.cpu.const_exc_type) - llvm_rffi.LLVMBuildStore(self.builder, - etype, - self.cpu.const_backup_exc_type) - evalue = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_value, "") - llvm_rffi.LLVMBuildStore(self.builder, - self.cpu.const_null_charptr, - self.cpu.const_exc_value) - llvm_rffi.LLVMBuildStore(self.builder, - evalue, - self.cpu.const_backup_exc_value) - - def getintarg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_int(v.getint()) - else: - return self._cast_to_int(value_ref) - - def _cast_to_int(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_int: - return value_ref - else: - return llvm_rffi.LLVMBuildZExt(self.builder, value_ref, - self.cpu.ty_int, "") - - def getbitarg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_bit(v.getint()) - else: - return self._cast_to_bit(value_ref) - - def _cast_to_bit(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_bit: - return value_ref - else: - return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref, - self.cpu.ty_bit, "") - - def getchararg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_char(v.getint()) - else: - return self._cast_to_char(value_ref) - - def _cast_to_char(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_char: - return value_ref - elif ty == self.cpu.ty_int or ty == self.cpu.ty_unichar: - return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref, - self.cpu.ty_char, "") - elif ty == self.cpu.ty_bit: - return llvm_rffi.LLVMBuildZExt(self.builder, value_ref, - self.cpu.ty_char, "") - else: - raise AssertionError("type is not an int nor a bit") - - def getunichararg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_unichar(v.getint()) - else: - return self._cast_to_unichar(value_ref) - - def _cast_to_unichar(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_unichar: - return value_ref - elif ty == self.cpu.ty_int: - return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref, - self.cpu.ty_char, "") - elif ty == self.cpu.ty_bit or ty == self.cpu.ty_char: - return llvm_rffi.LLVMBuildZExt(self.builder, value_ref, - self.cpu.ty_char, "") - else: - raise AssertionError("type is not an int nor a bit") - - def getptrarg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - return self.cpu._make_const(v.getaddr(self.cpu), - self.cpu.ty_char_ptr) - else: - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_int: - value_ref = llvm_rffi.LLVMBuildIntToPtr(self.builder, - value_ref, - self.cpu.ty_char_ptr, - "") - else: - assert (ty != self.cpu.ty_bit and - ty != self.cpu.ty_char and - ty != self.cpu.ty_unichar) - return value_ref - - for _opname, _llvmname in [('INT_ADD', 'Add'), - ('INT_SUB', 'Sub'), - ('INT_MUL', 'Mul'), - ('INT_FLOORDIV', 'SDiv'), - ('INT_MOD', 'SRem'), - ('INT_LSHIFT', 'Shl'), - ('INT_RSHIFT', 'AShr'), - ('UINT_RSHIFT', 'LShr'), - ('INT_AND', 'And'), - ('INT_OR', 'Or'), - ('INT_XOR', 'Xor'), - ]: - exec py.code.Source(''' - def generate_%s(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuild%s( - self.builder, - self.getintarg(op.args[0]), - self.getintarg(op.args[1]), - "") - ''' % (_opname, _llvmname)).compile() - - for _opname, _predicate in [('INT_LT', llvm_rffi.Predicate.SLT), - ('INT_LE', llvm_rffi.Predicate.SLE), - ('INT_EQ', llvm_rffi.Predicate.EQ), - ('INT_NE', llvm_rffi.Predicate.NE), - ('INT_GT', llvm_rffi.Predicate.SGT), - ('INT_GE', llvm_rffi.Predicate.SGE), - ('UINT_LT', llvm_rffi.Predicate.ULT), - ('UINT_LE', llvm_rffi.Predicate.ULE), - ('UINT_GT', llvm_rffi.Predicate.UGT), - ('UINT_GE', llvm_rffi.Predicate.UGE)]: - exec py.code.Source(''' - def generate_%s(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, - %d, - self.getintarg(op.args[0]), - self.getintarg(op.args[1]), - "") - ''' % (_opname, _predicate)).compile() - - def generate_INT_NEG(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildNeg(self.builder, - self.getintarg(op.args[0]), - "") - - def generate_INT_INVERT(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildNot(self.builder, - self.getintarg(op.args[0]), - "") - - def generate_INT_IS_TRUE(self, op): - v = op.args[0] - try: - value_ref = self.vars[v] - if llvm_rffi.LLVMTypeOf(value_ref) != self.cpu.ty_bit: - raise KeyError - except KeyError: - res = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.NE, - self.getintarg(op.args[0]), - self.cpu.const_zero, - "") - else: - res = value_ref # value_ref: ty_bit. this is a no-op - self.vars[op.result] = res - - def generate_BOOL_NOT(self, op): - v = op.args[0] - try: - value_ref = self.vars[v] - if llvm_rffi.LLVMTypeOf(value_ref) != self.cpu.ty_bit: - raise KeyError - except KeyError: - res = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - self.getintarg(op.args[0]), - self.cpu.const_zero, - "") - else: - # value_ref: ty_bit - res = llvm_rffi.LLVMBuildNot(self.builder, value_ref, "") - self.vars[op.result] = res - - def generate_INT_ADD_OVF(self, op): - self._generate_ovf_op(op, self.cpu.f_add_ovf) - - def generate_INT_SUB_OVF(self, op): - self._generate_ovf_op(op, self.cpu.f_sub_ovf) - - def generate_INT_MUL_OVF(self, op): - self._generate_ovf_op(op, self.cpu.f_mul_ovf) - - def _generate_ovf_op(self, op, f_intrinsic): - self._generate_ovf_test(f_intrinsic, - self.getintarg(op.args[0]), - self.getintarg(op.args[1]), - op.result) - - def _generate_ovf_test(self, f_intrinsic, arg0, arg1, result): - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 2, - flavor='raw') - arglist[0] = arg0 - arglist[1] = arg1 - tmp = llvm_rffi.LLVMBuildCall(self.builder, f_intrinsic, - arglist, 2, "") - lltype.free(arglist, flavor='raw') - self.vars[result] = llvm_rffi.LLVMBuildExtractValue(self.builder, - tmp, 0, "") - self.lastovf = llvm_rffi.LLVMBuildExtractValue(self.builder, tmp, 1, - "") - - def generate_GUARD_FALSE(self, op): - self._generate_guard(op, self.getbitarg(op.args[0]), True) - - def generate_GUARD_TRUE(self, op): - self._generate_guard(op, self.getbitarg(op.args[0]), False) - - def generate_GUARD_VALUE(self, op): - if op.args[0].type == INT: - arg0 = self.getintarg(op.args[0]) - arg1 = self.getintarg(op.args[1]) - else: - arg0 = self.getptrarg(op.args[0]) - arg1 = self.getptrarg(op.args[1]) - equal = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - arg0, arg1, "") - self._generate_guard(op, equal, False) - - def generate_GUARD_CLASS(self, op): - loc = self._generate_field_gep(op.args[0], self.cpu.fielddescr_vtable) - cls = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - equal = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - cls, - self.getintarg(op.args[1]), "") - self._generate_guard(op, equal, False) - - def generate_GUARD_NO_EXCEPTION(self, op): - # etype: ty_char_ptr - etype = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_type, "") - eisnull = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - etype, - self.cpu.const_null_charptr, "") - self._generate_guard(op, eisnull, False, exc=True) - - def generate_GUARD_EXCEPTION(self, op): - v = op.args[0] - assert isinstance(v, Const) - # etype, expectedtype: ty_char_ptr - expectedtype = self.cpu._make_const(v.getint(), self.cpu.ty_char_ptr) - etype = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_type, "") - eisequal = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - etype, - expectedtype, "") - self._generate_guard(op, eisequal, False, exc=True) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_value, - "") - - def generate_GUARD_NO_OVERFLOW(self, op): - self._generate_guard(op, self.lastovf, True) - - def generate_GUARD_OVERFLOW(self, op): - self._generate_guard(op, self.lastovf, False) - - def _generate_guard(self, op, verify_condition, reversed, exc=False): - func = self.compiling_func - bb_on_track = llvm_rffi.LLVMAppendBasicBlock(func, "") - bb_off_track = llvm_rffi.LLVMAppendBasicBlock(func, "") - llvm_rffi.LLVMBuildCondBr(self.builder, verify_condition, - bb_on_track, bb_off_track) - if reversed: - bb_on_track, bb_off_track = bb_off_track, bb_on_track - # generate the on-track part first, and the off-track part later - self.pending_blocks.append((op.suboperations, bb_off_track, exc)) - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_on_track) - - def generate_JUMP(self, op): - if op.jump_target is self.loop: - basicblock = llvm_rffi.LLVMGetInsertBlock(self.builder) - self.phi_incoming_blocks.append(basicblock) - for i in range(len(op.args)): - incoming = self.phi_incoming_values[i] - v = op.args[i] - if v.type == INT: - value_ref = self.getintarg(v) - else: - value_ref = self.getptrarg(v) - incoming.append(value_ref) - llvm_rffi.LLVMBuildBr(self.builder, self.bb_start) - else: - index = op.jump_target._llvm_compiled_index - assert index >= 0 - self._generate_fail(op.args, index) - - def generate_FAIL(self, op): - i = len(self.cpu.fail_ops) - self.cpu.fail_ops.append(op) - self._generate_fail(op.args, ~i) - - def _generate_fail(self, args, index): - self.cpu._ensure_out_args(len(args)) - for i in range(len(args)): - v = args[i] - if v.type == INT: - value_ref = self.getintarg(v) - ty = self.cpu.ty_int_ptr - else: - value_ref = self.getptrarg(v) - ty = self.cpu.ty_char_ptr_ptr - llvmconstptr = self.cpu._make_const(self.cpu.in_out_args[i], ty) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, - llvmconstptr) - llvm_rffi.LLVMBuildRet(self.builder, self.cpu._make_const_int(index)) - - def _generate_field_gep(self, v_structure, fielddescr): - assert isinstance(fielddescr, FieldDescr) - indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 1, - flavor='raw') - indices[0] = self.cpu._make_const_int(fielddescr.offset) - location = llvm_rffi.LLVMBuildGEP(self.builder, - self.getptrarg(v_structure), - indices, 1, "") - lltype.free(indices, flavor='raw') - ty = self.cpu.types_ptr_by_index[fielddescr.size_index] - location = llvm_rffi.LLVMBuildBitCast(self.builder, location, ty, "") - return location - - def generate_GETFIELD_GC(self, op): - loc = self._generate_field_gep(op.args[0], op.getdescr()) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - generate_GETFIELD_GC_PURE = generate_GETFIELD_GC - generate_GETFIELD_RAW = generate_GETFIELD_GC - generate_GETFIELD_RAW_PURE = generate_GETFIELD_GC - - def generate_SETFIELD_GC(self, op): - fielddescr = op.getdescr() - loc = self._generate_field_gep(op.args[0], fielddescr) - assert isinstance(fielddescr, FieldDescr) - getarg = self.cpu.getarg_by_index[fielddescr.size_index] - value_ref = getarg(self, op.args[1]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def generate_CALL(self, op): - calldescr = op.getdescr() - assert isinstance(calldescr, CallDescr) - ty_function_ptr = self.cpu.get_calldescr_ty_function_ptr(calldescr) - v = op.args[0] - if isinstance(v, Const): - func = self.cpu._make_const(v.getint(), ty_function_ptr) - else: - func = self.getintarg(v) - func = llvm_rffi.LLVMBuildIntToPtr(self.builder, - func, - ty_function_ptr, "") - nb_args = len(op.args) - 1 - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), nb_args, - flavor='raw') - for i in range(nb_args): - v = op.args[1 + i] - index = calldescr.args_indices[i] - getarg = self.cpu.getarg_by_index[index] - value_ref = getarg(self, v) - arglist[i] = value_ref - res = llvm_rffi.LLVMBuildCall(self.builder, - func, arglist, nb_args, "") - lltype.free(arglist, flavor='raw') - if op.result is not None: - assert calldescr.res_index >= 0 - self.vars[op.result] = res - - generate_CALL_PURE = generate_CALL - - def generate_CAST_PTR_TO_INT(self, op): - res = llvm_rffi.LLVMBuildPtrToInt(self.builder, - self.getptrarg(op.args[0]), - self.cpu.ty_int, "") - self.vars[op.result] = res - - def generate_CAST_INT_TO_PTR(self, op): - res = llvm_rffi.LLVMBuildIntToPtr(self.builder, - self.getintarg(op.args[0]), - self.cpu.ty_char_ptr, "") - self.vars[op.result] = res - - def generate_OOIS(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.EQ, - self.getptrarg(op.args[0]), - self.getptrarg(op.args[1]), "") - - def generate_OOISNOT(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.NE, - self.getptrarg(op.args[0]), - self.getptrarg(op.args[1]), "") - - def generate_OOISNULL(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.EQ, - self.getptrarg(op.args[0]), - self.cpu.const_null_charptr, "") - - def generate_OONONNULL(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.NE, - self.getptrarg(op.args[0]), - self.cpu.const_null_charptr, "") - - def generate_SAME_AS(self, op): - if op.args[0].type == INT: - self.vars[op.result] = self.getintarg(op.args[0]) - else: - self.vars[op.result] = self.getptrarg(op.args[0]) - - def _generate_len_gep(self, array_ref, ty, const_index_length): - array = llvm_rffi.LLVMBuildBitCast(self.builder, - array_ref, ty, "") - indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 2, - flavor='raw') - indices[0] = self.cpu.const_zero - indices[1] = const_index_length - loc = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 2, "") - lltype.free(indices, flavor='raw') - return loc - - def _generate_len(self, op, ty, const_index_length): - loc = self._generate_len_gep(self.getptrarg(op.args[0]), - ty, const_index_length) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - def generate_ARRAYLEN_GC(self, op): - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - self._generate_len(op, arraydescr.ty_array_ptr, - self.cpu.const_array_index_length) - - def _generate_gep(self, op, ty, const_index_array): - array = llvm_rffi.LLVMBuildBitCast(self.builder, - self.getptrarg(op.args[0]), - ty, "") - indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 3, - flavor='raw') - indices[0] = self.cpu.const_zero - indices[1] = const_index_array - indices[2] = self.getintarg(op.args[1]) - location = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 3, "") - lltype.free(indices, flavor='raw') - return location - - def _generate_array_gep(self, op): - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - location = self._generate_gep(op, arraydescr.ty_array_ptr, - self.cpu.const_array_index_array) - return location - - def generate_GETARRAYITEM_GC(self, op): - loc = self._generate_array_gep(op) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - generate_GETARRAYITEM_GC_PURE = generate_GETARRAYITEM_GC - - def generate_SETARRAYITEM_GC(self, op): - loc = self._generate_array_gep(op) - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - getarg = self.cpu.getarg_by_index[arraydescr.itemsize_index] - value_ref = getarg(self, op.args[2]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def generate_STRLEN(self, op): - self._generate_len(op, self.cpu.ty_string_ptr, - self.cpu.const_string_index_length) - - def generate_UNICODELEN(self, op): - self._generate_len(op, self.cpu.ty_unicode_ptr, - self.cpu.const_unicode_index_length) - - def generate_STRGETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_string_ptr, - self.cpu.const_string_index_array) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - def generate_UNICODEGETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_unicode_ptr, - self.cpu.const_unicode_index_array) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - def generate_STRSETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_string_ptr, - self.cpu.const_string_index_array) - value_ref = self.getchararg(op.args[2]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def generate_UNICODESETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_unicode_ptr, - self.cpu.const_unicode_index_array) - value_ref = self.getunichararg(op.args[2]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def _generate_new(self, size_ref): - malloc_func = self.cpu._make_const(self.cpu.malloc_fn_ptr, - self.cpu.ty_malloc_fn) - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 1, - flavor='raw') - arglist[0] = size_ref - res = llvm_rffi.LLVMBuildCall(self.builder, malloc_func, - arglist, 1, "") - lltype.free(arglist, flavor='raw') - return res - - def generate_NEW(self, op): - sizedescr = op.getdescr() - assert isinstance(sizedescr, SizeDescr) - res = self._generate_new(self.cpu._make_const_int(sizedescr.size)) - self.vars[op.result] = res - - def generate_NEW_WITH_VTABLE(self, op): - sizedescr = self.cpu.class_sizes[op.args[0].getint()] - res = self._generate_new(self.cpu._make_const_int(sizedescr.size)) - self.vars[op.result] = res - loc = self._generate_field_gep(op.result, self.cpu.vtable_descr) - value_ref = self.getintarg(op.args[0]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def _generate_new_array(self, op, ty_array, const_item_size, - const_index_array, const_index_length): - length_ref = self.getintarg(op.args[0]) - if const_item_size == self.cpu.const_one: - arraysize_ref = length_ref - else: - arraysize_ref = llvm_rffi.LLVMBuildMul(self.builder, - length_ref, - const_item_size, - "") - size_ref = llvm_rffi.LLVMBuildAdd(self.builder, - const_index_array, - arraysize_ref, - "") - res = self._generate_new(size_ref) - loc = self._generate_len_gep(res, ty_array, const_index_length) - llvm_rffi.LLVMBuildStore(self.builder, - length_ref, - loc, "") - self.vars[op.result] = res - - def generate_NEW_ARRAY(self, op): - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - self._generate_new_array(op, arraydescr.ty_array_ptr, - self.cpu._make_const_int(arraydescr.itemsize), - self.cpu.const_array_index_array, - self.cpu.const_array_index_length) - - def generate_NEWSTR(self, op): - self._generate_new_array(op, self.cpu.ty_string_ptr, - self.cpu.const_one, - self.cpu.const_string_index_array, - self.cpu.const_string_index_length) - - def generate_NEWUNICODE(self, op): - self._generate_new_array(op, self.cpu.ty_unicode_ptr, - self.cpu._make_const_int(self.cpu.size_of_unicode), - self.cpu.const_unicode_index_array, - self.cpu.const_unicode_index_length) - - def generate_DEBUG_MERGE_POINT(self, op): - pass - -# ____________________________________________________________ - -class MissingOperation(Exception): - pass - -all_operations = {} -for _key, _value in rop.__dict__.items(): - if 'A' <= _key <= 'Z': - assert _value not in all_operations - methname = 'generate_' + _key - if hasattr(LLVMJITCompiler, methname): - all_operations[_value] = methname -all_operations = unrolling_iterable(all_operations.items()) diff --git a/pypy/jit/backend/llvm/demo1.c b/pypy/jit/backend/llvm/demo1.c deleted file mode 100644 --- a/pypy/jit/backend/llvm/demo1.c +++ /dev/null @@ -1,17 +0,0 @@ -/* LLVM includes */ -#include "llvm-c/Analysis.h" -#include "llvm-c/Transforms/Scalar.h" -#include "llvm-c/ExecutionEngine.h" -#include "demo2.h" - -/* The following list of functions seems to be necessary to force the - * functions to be included in pypy_cache_llvm.so. The list is never - * used. Actually, any single function seems to be enough... - */ -void* llvm_c_functions[] = { - (void*) LLVMModuleCreateWithName, - (void*) _LLVM_EE_getPointerToFunction, - (void*) _LLVM_Intrinsic_add_ovf, - (void*) _LLVM_Intrinsic_sub_ovf, - (void*) _LLVM_Intrinsic_mul_ovf -}; diff --git a/pypy/jit/backend/llvm/demo2.cpp b/pypy/jit/backend/llvm/demo2.cpp deleted file mode 100644 --- a/pypy/jit/backend/llvm/demo2.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* LLVM includes */ -#include -#include "llvm-c/ExecutionEngine.h" -#include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Intrinsics.h" -#include "demo2.h" - -using namespace llvm; - - -/* Set the flag to true. - */ -void _LLVM_SetFlags(void) -{ - //PerformTailCallOpt = true; -} - -/* This piece of code regroups conveniently a part of the initialization. - */ -LLVMExecutionEngineRef _LLVM_EE_Create(LLVMModuleRef M) -{ - LLVMModuleProviderRef mp = LLVMCreateModuleProviderForExistingModule(M); - LLVMExecutionEngineRef ee; - char* errormsg; - int error = LLVMCreateJITCompiler(&ee, mp, 0 /*Fast*/, &errormsg); - if (error) - { - fprintf(stderr, "Error creating the JIT compiler:\n%s", errormsg); - abort(); - } - return ee; -} - -/* Missing pieces of the C interface... - */ -void *_LLVM_EE_getPointerToFunction(LLVMExecutionEngineRef EE, - LLVMValueRef F) -{ - return unwrap(EE)->getPointerToFunction(unwrap(F)); -} - -static LLVMValueRef _LLVM_Intrinsic_ovf(LLVMModuleRef M, LLVMTypeRef Ty, - Intrinsic::ID num) -{ - const Type *array_of_types[1]; - Function *F; - array_of_types[0] = unwrap(Ty); - F = Intrinsic::getDeclaration(unwrap(M), num, array_of_types, 1); - return wrap(F); -} - -LLVMValueRef _LLVM_Intrinsic_add_ovf(LLVMModuleRef M, LLVMTypeRef Ty) -{ - return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::sadd_with_overflow); -} - -LLVMValueRef _LLVM_Intrinsic_sub_ovf(LLVMModuleRef M, LLVMTypeRef Ty) -{ - return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::ssub_with_overflow); -} - -LLVMValueRef _LLVM_Intrinsic_mul_ovf(LLVMModuleRef M, LLVMTypeRef Ty) -{ - return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::smul_with_overflow); -} diff --git a/pypy/jit/backend/llvm/demo2.h b/pypy/jit/backend/llvm/demo2.h deleted file mode 100644 --- a/pypy/jit/backend/llvm/demo2.h +++ /dev/null @@ -1,16 +0,0 @@ - -#ifdef __cplusplus -extern "C" { -#endif - -void _LLVM_SetFlags(void); -LLVMExecutionEngineRef _LLVM_EE_Create(LLVMModuleRef M); -void *_LLVM_EE_getPointerToFunction(LLVMExecutionEngineRef EE, - LLVMValueRef F); -LLVMValueRef _LLVM_Intrinsic_add_ovf(LLVMModuleRef M, LLVMTypeRef Ty); -LLVMValueRef _LLVM_Intrinsic_sub_ovf(LLVMModuleRef M, LLVMTypeRef Ty); -LLVMValueRef _LLVM_Intrinsic_mul_ovf(LLVMModuleRef M, LLVMTypeRef Ty); - -#ifdef __cplusplus -} -#endif diff --git a/pypy/jit/backend/llvm/llvm_rffi.py b/pypy/jit/backend/llvm/llvm_rffi.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/llvm_rffi.py +++ /dev/null @@ -1,371 +0,0 @@ -import py, os, sys -import pypy -from pypy.rpython.lltypesystem import lltype, rffi -from pypy.translator.tool.cbuild import ExternalCompilationInfo, log - -if not sys.platform.startswith('linux'): - py.test.skip("Linux only for now") - -# ____________________________________________________________ - -llvm_config = 'llvm-config' -cachename = os.path.join(os.path.dirname(pypy.__file__), '_cache') -dirname = os.path.join(cachename, 'libs') -libname = os.path.join(dirname, 'pypy_cache_llvm.so') -cname = os.path.join(os.path.dirname(__file__), 'demo1.c') -cppname = os.path.join(os.path.dirname(__file__), 'demo2.cpp') -o1name = os.path.join(dirname, 'demo1.o') -o2name = os.path.join(dirname, 'demo2.o') - -if (not os.path.isfile(libname) or - os.path.getmtime(cname) > os.path.getmtime(libname) or - os.path.getmtime(cppname) > os.path.getmtime(libname)): - g = os.popen('%s --version' % llvm_config, 'r') - data = g.read() - g.close() - if not data.startswith('2.'): - py.test.skip("llvm (version 2) is required") - - if not os.path.isdir(dirname): - if not os.path.isdir(cachename): - os.mkdir(cachename) - os.mkdir(dirname) - - def do(cmdline): - log(cmdline) - err = os.system(cmdline) - if err: - raise Exception("gcc command failed") - - do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cname, o1name, llvm_config)) - do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cppname, o2name, llvm_config)) - do("g++ -g -shared '%s' '%s' -o '%s'" % (o1name, o2name, libname) + - " `%s --cflags --ldflags --libs jit engine`" % llvm_config) - -ctypes_compilation_info = ExternalCompilationInfo( - library_dirs = [dirname], - libraries = ['pypy_cache_llvm'], -) - -compilation_info = ExternalCompilationInfo.from_linker_flags( - os.popen("%s --ldflags --libs jit engine" % llvm_config, 'r').read()) - -compilation_info = compilation_info.merge(ExternalCompilationInfo( - link_extra = [o1name, o2name], - use_cpp_linker = True, - )) - -compilation_info._with_ctypes = ctypes_compilation_info - -_teardown = None - -def set_teardown_function(fn): - global _teardown - _teardown = fn - -def teardown_now(): - global _teardown - fn = _teardown - _teardown = None - if fn is not None: - fn() - -# ____________________________________________________________ - -Debug = True - -def llexternal(name, args, result, **kwds): - ll = rffi.llexternal(name, args, result, - compilation_info=compilation_info, - **kwds) - if Debug: - def func(*args): - print name - res = ll(*args) - print '\t->', res - return res - return func - else: - return ll - -def opaqueptr(name): - return rffi.VOIDP # lltype.Ptr(rffi.COpaque(name)) - -LLVMModuleRef = opaqueptr('struct LLVMOpaqueModule') -LLVMTypeRef = opaqueptr('struct LLVMOpaqueType') -LLVMValueRef = opaqueptr('struct LLVMOpaqueValue') -LLVMBasicBlockRef = opaqueptr('struct LLVMOpaqueBasicBlock') -LLVMBuilderRef = opaqueptr('struct LLVMOpaqueBuilder') -LLVMModuleProviderRef = opaqueptr('struct LLVMOpaqueModuleProvider') -LLVMGenericValueRef = opaqueptr('struct LLVMOpaqueGenericValue') -LLVMExecutionEngineRef = opaqueptr('struct LLVMOpaqueExecutionEngine') - -class Predicate: - EQ = 32 # equal - NE = 33 # not equal - UGT = 34 # unsigned greater than - UGE = 35 # unsigned greater or equal - ULT = 36 # unsigned less than - ULE = 37 # unsigned less or equal - SGT = 38 # signed greater than - SGE = 39 # signed greater or equal - SLT = 40 # signed less than - SLE = 41 # signed less or equal - -class CallConv: - C = 0 - Fast = 8 - Cold = 9 - X86Stdcall = 64 - X86Fastcall = 65 - -# ____________________________________________________________ - -LLVMDisposeMessage = llexternal('LLVMDisposeMessage', [rffi.CCHARP], - lltype.Void) - -LLVMModuleCreateWithName = llexternal('LLVMModuleCreateWithName', - [rffi.CCHARP], - LLVMModuleRef) -LLVMDumpModule = llexternal('LLVMDumpModule', [LLVMModuleRef], lltype.Void) - -LLVMInt1Type = llexternal('LLVMInt1Type', [], LLVMTypeRef) -LLVMInt8Type = llexternal('LLVMInt8Type', [], LLVMTypeRef) -LLVMInt16Type = llexternal('LLVMInt16Type', [], LLVMTypeRef) -LLVMInt32Type = llexternal('LLVMInt32Type', [], LLVMTypeRef) -LLVMInt64Type = llexternal('LLVMInt64Type', [], LLVMTypeRef) -LLVMFunctionType = llexternal('LLVMFunctionType', - [LLVMTypeRef, # return type - rffi.CArrayPtr(LLVMTypeRef), # param types - rffi.UINT, # param count - rffi.INT], # flag: is_vararg - LLVMTypeRef) -LLVMStructType = llexternal('LLVMStructType', - [rffi.CArrayPtr(LLVMTypeRef), # element types - rffi.UINT, # element count - rffi.INT], # flag: packed - LLVMTypeRef) -LLVMArrayType = llexternal('LLVMArrayType', [LLVMTypeRef, # element type - rffi.UINT], # element count - LLVMTypeRef) -LLVMPointerType = llexternal('LLVMPointerType', [LLVMTypeRef, # element type - rffi.UINT], # address space - LLVMTypeRef) -LLVMVoidType = llexternal('LLVMVoidType', [], LLVMTypeRef) - -LLVMTypeOf = llexternal('LLVMTypeOf', [LLVMValueRef], LLVMTypeRef) -LLVMDumpValue = llexternal('LLVMDumpValue', [LLVMValueRef], lltype.Void) -LLVMConstNull = llexternal('LLVMConstNull', [LLVMTypeRef], LLVMValueRef) -LLVMConstInt = llexternal('LLVMConstInt', [LLVMTypeRef, # type - rffi.ULONGLONG, # value - rffi.INT], # flag: is_signed - LLVMValueRef) -LLVMConstIntToPtr = llexternal('LLVMConstIntToPtr', - [LLVMValueRef, # constant integer value - LLVMTypeRef], # type of the result - LLVMValueRef) - -LLVMAddFunction = llexternal('LLVMAddFunction', - [LLVMModuleRef, # module - rffi.CCHARP, # name - LLVMTypeRef], # function type - LLVMValueRef) -LLVMSetFunctionCallConv = llexternal('LLVMSetFunctionCallConv', - [LLVMValueRef, # function - rffi.UINT], # new call conv - lltype.Void) -LLVMGetParam = llexternal('LLVMGetParam', - [LLVMValueRef, # function - rffi.UINT], # index - LLVMValueRef) - -LLVMAppendBasicBlock = llexternal('LLVMAppendBasicBlock', - [LLVMValueRef, # function - rffi.CCHARP], # name - LLVMBasicBlockRef) - -LLVMSetInstructionCallConv = llexternal('LLVMSetInstructionCallConv', - [LLVMValueRef, # call instruction - rffi.UINT], # new call conv - lltype.Void) -LLVMSetTailCall = llexternal('LLVMSetTailCall', - [LLVMValueRef, # call instruction - rffi.INT], # flag: is_tail - lltype.Void) -LLVMAddIncoming = llexternal('LLVMAddIncoming', - [LLVMValueRef, # phi node - rffi.CArrayPtr(LLVMValueRef), # incoming values - rffi.CArrayPtr(LLVMBasicBlockRef), # incom.blocks - rffi.UINT], # count - lltype.Void) -LLVMCreateBuilder = llexternal('LLVMCreateBuilder', [], LLVMBuilderRef) -LLVMPositionBuilderAtEnd = llexternal('LLVMPositionBuilderAtEnd', - [LLVMBuilderRef, # builder - LLVMBasicBlockRef], # block - lltype.Void) -LLVMGetInsertBlock = llexternal('LLVMGetInsertBlock', [LLVMBuilderRef], - LLVMBasicBlockRef) -LLVMDisposeBuilder = llexternal('LLVMDisposeBuilder', [LLVMBuilderRef], - lltype.Void) - -LLVMBuildRet = llexternal('LLVMBuildRet', [LLVMBuilderRef, # builder, - LLVMValueRef], # result - LLVMValueRef) -LLVMBuildBr = llexternal('LLVMBuildBr', [LLVMBuilderRef, # builder, - LLVMBasicBlockRef],# destination block - LLVMValueRef) -LLVMBuildCondBr = llexternal('LLVMBuildCondBr', - [LLVMBuilderRef, # builder - LLVMValueRef, # condition - LLVMBasicBlockRef, # block if true - LLVMBasicBlockRef], # block if false - LLVMValueRef) - -for _name in ['Add', 'Sub', 'Mul', 'SDiv', 'SRem', 'Shl', 'LShr', 'AShr', - 'And', 'Or', 'Xor']: - globals()['LLVMBuild' + _name] = llexternal('LLVMBuild' + _name, - [LLVMBuilderRef, # builder - LLVMValueRef, # left-hand side - LLVMValueRef, # right-hand side - rffi.CCHARP], # name of result - LLVMValueRef) - -for _name in ['Neg', 'Not']: - globals()['LLVMBuild' + _name] = llexternal('LLVMBuild' + _name, - [LLVMBuilderRef, # builder - LLVMValueRef, # argument - rffi.CCHARP], # name of result - LLVMValueRef) - -LLVMBuildLoad = llexternal('LLVMBuildLoad', - [LLVMBuilderRef, # builder - LLVMValueRef, # pointer location - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildStore = llexternal('LLVMBuildStore', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMValueRef], # pointer location - LLVMValueRef) -LLVMBuildGEP = llexternal('LLVMBuildGEP', # GEP = 'getelementptr' - [LLVMBuilderRef, # builder - LLVMValueRef, # base pointer - rffi.CArrayPtr(LLVMValueRef), # indices - rffi.UINT, # num indices - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildTrunc = llexternal('LLVMBuildTrunc', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildZExt = llexternal('LLVMBuildZExt', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildPtrToInt = llexternal('LLVMBuildPtrToInt', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildIntToPtr = llexternal('LLVMBuildIntToPtr', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildBitCast = llexternal('LLVMBuildBitCast', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildICmp = llexternal('LLVMBuildICmp', - [LLVMBuilderRef, # builder - rffi.INT, # predicate (see Predicate above) - LLVMValueRef, # left-hand side - LLVMValueRef, # right-hand side - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildPhi = llexternal('LLVMBuildPhi', - [LLVMBuilderRef, # builder - LLVMTypeRef, # type of value - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildCall = llexternal('LLVMBuildCall', - [LLVMBuilderRef, # builder - LLVMValueRef, # function - rffi.CArrayPtr(LLVMValueRef), # arguments - rffi.UINT, # argument count - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildSelect = llexternal('LLVMBuildSelect', - [LLVMBuilderRef, # builder - LLVMValueRef, # if - LLVMValueRef, # then - LLVMValueRef, # else - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildExtractValue = llexternal('LLVMBuildExtractValue', - [LLVMBuilderRef, # builder - LLVMValueRef, # aggregated value - rffi.UINT, # index - rffi.CCHARP], # name of result - LLVMValueRef) - -LLVMCreateModuleProviderForExistingModule = llexternal( - 'LLVMCreateModuleProviderForExistingModule', [LLVMModuleRef], - LLVMModuleProviderRef) - -# ____________________________________________________________ - -LLVMCreateGenericValueOfInt = llexternal('LLVMCreateGenericValueOfInt', - [LLVMTypeRef, # type - rffi.ULONGLONG, # value - rffi.INT], # flag: is_signed - LLVMGenericValueRef) -LLVMDisposeGenericValue = llexternal('LLVMDisposeGenericValue', - [LLVMGenericValueRef], lltype.Void) - -LLVMGenericValueToInt = llexternal('LLVMGenericValueToInt', - [LLVMGenericValueRef, - rffi.INT], # flag: is_signed - rffi.ULONGLONG) - -LLVMCreateJITCompiler = llexternal('LLVMCreateJITCompiler', - [rffi.CArrayPtr(LLVMExecutionEngineRef), - LLVMModuleProviderRef, - rffi.INT, # "fast" - rffi.CArrayPtr(rffi.CCHARP)], # -> error - rffi.INT) -LLVMDisposeExecutionEngine = llexternal('LLVMDisposeExecutionEngine', - [LLVMExecutionEngineRef], - lltype.Void) - -LLVMRunFunction = llexternal('LLVMRunFunction', - [LLVMExecutionEngineRef, - LLVMValueRef, # function - rffi.UINT, # num args - rffi.CArrayPtr(LLVMGenericValueRef)], # args - LLVMGenericValueRef) # return value - -LLVM_SetFlags = llexternal('_LLVM_SetFlags', [], lltype.Void) -LLVM_EE_Create = llexternal('_LLVM_EE_Create', [LLVMModuleRef], - LLVMExecutionEngineRef) -LLVM_EE_getPointerToFunction = llexternal('_LLVM_EE_getPointerToFunction', - [LLVMExecutionEngineRef, - LLVMValueRef], # function - rffi.VOIDP) -LLVM_Intrinsic_add_ovf = llexternal('_LLVM_Intrinsic_add_ovf', - [LLVMModuleRef, LLVMTypeRef], - LLVMValueRef) -LLVM_Intrinsic_sub_ovf = llexternal('_LLVM_Intrinsic_sub_ovf', - [LLVMModuleRef, LLVMTypeRef], - LLVMValueRef) -LLVM_Intrinsic_mul_ovf = llexternal('_LLVM_Intrinsic_mul_ovf', - [LLVMModuleRef, LLVMTypeRef], - LLVMValueRef) diff --git a/pypy/jit/backend/llvm/runner.py b/pypy/jit/backend/llvm/runner.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/runner.py +++ /dev/null @@ -1,731 +0,0 @@ -import sys -from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr -from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rlib.objectmodel import we_are_translated, specialize -from pypy.rlib import runicode -from pypy.jit.metainterp.history import AbstractDescr, INT -from pypy.jit.metainterp.history import BoxInt, BoxPtr -from pypy.jit.backend.model import AbstractCPU -from pypy.jit.backend.llvm import llvm_rffi -from pypy.jit.metainterp import history -from pypy.jit.metainterp.resoperation import rop, ResOperation -from pypy.jit.backend.llsupport import symbolic -from pypy.jit.metainterp.typesystem import llhelper - -history.TreeLoop._llvm_compiled_index = -1 - - -class LLVMCPU(object): - ts = llhelper - RAW_VALUE = rffi.CFixedArray(rffi.ULONGLONG, 1) - SIGNED_VALUE = rffi.CFixedArray(lltype.Signed, 1) - POINTER_VALUE = rffi.CFixedArray(llmemory.GCREF, 1) - - SIZE_GCPTR = 0 - SIZE_INT = 1 - SIZE_CHAR = 2 - SIZE_UNICHAR = 3 - - def __init__(self, rtyper, stats=None, translate_support_code=False, - annmixlevel=None, gcdescr=None): - self.rtyper = rtyper - self.translate_support_code = translate_support_code - self.compiled_functions = [] - self.fail_ops = [] - self.in_out_args = [] - if translate_support_code: - get_size = llmemory.sizeof - else: - get_size = rffi.sizeof - self._arraydescrs = [ - ArrayDescr(get_size(llmemory.GCREF), self.SIZE_GCPTR), # 0 - ArrayDescr(get_size(lltype.Signed), self.SIZE_INT), # 1 - ArrayDescr(get_size(lltype.Char), self.SIZE_CHAR), # 2 - ArrayDescr(get_size(lltype.UniChar), self.SIZE_UNICHAR), # 3 - ] - self._descr_caches = {} - self.fielddescr_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr') - if sys.maxint == 2147483647: - self.size_of_int = 4 - else: - self.size_of_int = 8 - if runicode.MAXUNICODE > 0xffff: - self.size_of_unicode = 4 - else: - self.size_of_unicode = 2 - self.gcarray_gcref = lltype.GcArray(llmemory.GCREF) - self.gcarray_signed = lltype.GcArray(lltype.Signed) - self.gcarray_char = lltype.GcArray(lltype.Char) - self.gcarray_unichar = lltype.GcArray(lltype.UniChar) - basesize, _, ofs_length = symbolic.get_array_token( - self.gcarray_signed, self.translate_support_code) - self.array_index_array = basesize - self.array_index_length = ofs_length - basesize, _, ofs_length = symbolic.get_array_token( - rstr.STR, self.translate_support_code) - self.string_index_array = basesize - self.string_index_length = ofs_length - basesize, _, ofs_length = symbolic.get_array_token( - rstr.UNICODE, self.translate_support_code) - self.unicode_index_array = basesize - self.unicode_index_length = ofs_length - self.vtable_descr = self.fielddescrof(rclass.OBJECT, 'typeptr') - self._ovf_error_instance = self._get_prebuilt_error(OverflowError) - self._zer_error_instance = self._get_prebuilt_error(ZeroDivisionError) - # - # temporary (Boehm only) - from pypy.translator.tool.cbuild import ExternalCompilationInfo - compilation_info = ExternalCompilationInfo(libraries=['gc']) - self.malloc_fn_ptr = rffi.llexternal("GC_malloc", - [rffi.SIZE_T], - llmemory.GCREF, - compilation_info=compilation_info, - sandboxsafe=True, - _nowrapper=True) - assert rffi.sizeof(rffi.SIZE_T) == self.size_of_int - - def set_class_sizes(self, class_sizes): - self.class_sizes = class_sizes - - def setup_once(self): - if not we_are_translated(): - llvm_rffi.teardown_now() - llvm_rffi.LLVM_SetFlags() - self.module = llvm_rffi.LLVMModuleCreateWithName("pypyjit") - if self.size_of_int == 4: - self.ty_int = llvm_rffi.LLVMInt32Type() - else: - self.ty_int = llvm_rffi.LLVMInt64Type() - if self.size_of_unicode == 2: - self.ty_unichar = llvm_rffi.LLVMInt16Type() - else: - self.ty_unichar = llvm_rffi.LLVMInt32Type() - self.ty_void = llvm_rffi.LLVMVoidType() - self.ty_bit = llvm_rffi.LLVMInt1Type() - self.ty_char = llvm_rffi.LLVMInt8Type() - self.ty_char_ptr = llvm_rffi.LLVMPointerType(self.ty_char, 0) - self.ty_char_ptr_ptr = llvm_rffi.LLVMPointerType(self.ty_char_ptr, 0) - self.ty_int_ptr = llvm_rffi.LLVMPointerType(self.ty_int, 0) - self.ty_int_ptr_ptr = llvm_rffi.LLVMPointerType(self.ty_int_ptr, 0) - self.ty_unichar_ptr = llvm_rffi.LLVMPointerType(self.ty_unichar, 0) - self.const_zero = self._make_const_int(0) - self.const_one = self._make_const_int(1) - self.const_null_charptr = self._make_const(0, self.ty_char_ptr) - # - from pypy.jit.backend.llvm.compile import LLVMJITCompiler - self.types_by_index = [self.ty_char_ptr, # SIZE_GCPTR - self.ty_int, # SIZE_INT - self.ty_char, # SIZE_CHAR - self.ty_unichar] # SIZE_UNICHAR - self.types_ptr_by_index = [self.ty_char_ptr_ptr, # SIZE_GCPTR - self.ty_int_ptr, # SIZE_INT - self.ty_char_ptr, # SIZE_CHAR - self.ty_unichar_ptr] # SIZE_UNICHAR - self.getarg_by_index = [LLVMJITCompiler.getptrarg, # SIZE_GCPTR - LLVMJITCompiler.getintarg, # SIZE_INT - LLVMJITCompiler.getchararg, # SIZE_CHAR - LLVMJITCompiler.getunichararg] # SIZE_UNICHAR - for i in range(len(self.types_by_index)): - arraydescr = self._arraydescrs[i] - (arraydescr.ty_array_ptr, - self.const_array_index_length, - self.const_array_index_array) = \ - self._build_ty_array_ptr(self.array_index_array, - self.types_by_index[i], - self.array_index_length) - (self.ty_string_ptr, - self.const_string_index_length, - self.const_string_index_array) = \ - self._build_ty_array_ptr(self.string_index_array, - self.ty_char, - self.string_index_length) - (self.ty_unicode_ptr, - self.const_unicode_index_length, - self.const_unicode_index_array) = \ - self._build_ty_array_ptr(self.unicode_index_array, - self.ty_unichar, - self.unicode_index_length) - # - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), 0, - flavor='raw') - self.ty_func = llvm_rffi.LLVMFunctionType(self.ty_int, arglist, 0, - False) - lltype.free(arglist, flavor='raw') - # - self.f_add_ovf = llvm_rffi.LLVM_Intrinsic_add_ovf(self.module, - self.ty_int) - self.f_sub_ovf = llvm_rffi.LLVM_Intrinsic_sub_ovf(self.module, - self.ty_int) - self.f_mul_ovf = llvm_rffi.LLVM_Intrinsic_mul_ovf(self.module, - self.ty_int) - if we_are_translated(): - addr = llop.get_exception_addr(llmemory.Address) - self.exc_type = rffi.cast(rffi.CArrayPtr(lltype.Signed), addr) - addr = llop.get_exc_value_addr(llmemory.Address) - self.exc_value = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), addr) - else: - self.exc_type = lltype.malloc(rffi.CArray(lltype.Signed), 1, - zero=True, flavor='raw') - self.exc_value = lltype.malloc(rffi.CArray(llmemory.GCREF), 1, - zero=True, flavor='raw') - self.backup_exc_type = lltype.malloc(rffi.CArray(lltype.Signed), 1, - zero=True, flavor='raw') - self.backup_exc_value = lltype.malloc(rffi.CArray(llmemory.GCREF), 1, - zero=True, flavor='raw') - self.const_exc_type = self._make_const(self.exc_type, - self.ty_char_ptr_ptr) - self.const_exc_value = self._make_const(self.exc_value, - self.ty_char_ptr_ptr) - self.const_backup_exc_type = self._make_const(self.backup_exc_type, - self.ty_char_ptr_ptr) - self.const_backup_exc_value = self._make_const(self.backup_exc_value, - self.ty_char_ptr_ptr) - # - self._setup_prebuilt_error('ovf') - self._setup_prebuilt_error('zer') - # - # temporary (Boehm only) - param_types = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), 1, - flavor='raw') - param_types[0] = self.ty_int - self.ty_malloc_fn = llvm_rffi.LLVMPointerType( - llvm_rffi.LLVMFunctionType(self.ty_char_ptr, param_types, 1, 0), - 0) - lltype.free(param_types, flavor='raw') - # - self.ee = llvm_rffi.LLVM_EE_Create(self.module) - if not we_are_translated(): - llvm_rffi.set_teardown_function(self._teardown) - - def _teardown(self): - llvm_rffi.LLVMDisposeExecutionEngine(self.ee) - - def _get_prebuilt_error(self, Class): - "NOT_RPYTHON" - if self.rtyper is not None: # normal case - bk = self.rtyper.annotator.bookkeeper - clsdef = bk.getuniqueclassdef(Class) - ll_inst = self.rtyper.exceptiondata.get_standard_ll_exc_instance( - self.rtyper, clsdef) - else: - # for tests, a random emulated ll_inst will do - ll_inst = lltype.malloc(rclass.OBJECT) - ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, - immortal=True) - return ll_inst - - @specialize.arg(1) - def _setup_prebuilt_error(self, prefix): - ll_inst = getattr(self, '_' + prefix + '_error_instance') - setattr(self, '_' + prefix + '_error_type', - rffi.cast(lltype.Signed, ll_inst.typeptr)) - setattr(self, '_' + prefix + '_error_value', - lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst)) - setattr(self, 'const_' + prefix + '_error_type', - self._make_const(ll_inst.typeptr, self.ty_char_ptr)) - setattr(self, 'const_' + prefix + '_error_value', - self._make_const(ll_inst, self.ty_char_ptr)) - - def _build_ty_array_ptr(self, basesize, ty_item, ofs_length): - pad1 = ofs_length - pad2 = basesize - ofs_length - self.size_of_int - assert pad1 >= 0 and pad2 >= 0 - const_index_length = self._make_const_int(pad1) - const_index_array = self._make_const_int(pad1 + 1 + pad2) - # build the type "struct{pad1.., length, pad2.., array{type}}" - typeslist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), - pad1+pad2+2, flavor='raw') - # add the first padding - for n in range(pad1): - typeslist[n] = self.ty_char - # add the length field - typeslist[pad1] = self.ty_int - # add the second padding - for n in range(pad1+1, pad1+1+pad2): - typeslist[n] = self.ty_char - # add the array field - typeslist[pad1+1+pad2] = llvm_rffi.LLVMArrayType(ty_item, 0) - # done - ty_array = llvm_rffi.LLVMStructType(typeslist, - pad1+pad2+2, - 1) - lltype.free(typeslist, flavor='raw') - ty_array_ptr = llvm_rffi.LLVMPointerType(ty_array, 0) - return (ty_array_ptr, const_index_length, const_index_array) - - # ------------------------------ - # Compilation - - def compile_operations(self, loop, _guard_op=None): - from pypy.jit.backend.llvm.compile import LLVMJITCompiler - compiler = LLVMJITCompiler(self, loop) - compiler.compile() - - def _ensure_in_args(self, count): - while len(self.in_out_args) < count: - self.in_out_args.append(lltype.malloc(self.RAW_VALUE, flavor='raw')) - - _ensure_out_args = _ensure_in_args - - def _make_const_int(self, value): - return llvm_rffi.LLVMConstInt(self.ty_int, value, True) - - def _make_const_char(self, value): - assert (value & ~255) == 0, "value is not in range(256)" - return llvm_rffi.LLVMConstInt(self.ty_char, value, True) - - def _make_const_unichar(self, value): - #xxx assert something about 'value' - return llvm_rffi.LLVMConstInt(self.ty_unichar, value, True) - - def _make_const_bit(self, value): - assert (value & ~1) == 0, "value is not 0 or 1" - return llvm_rffi.LLVMConstInt(self.ty_bit, value, True) - - @specialize.arglltype(1) - def _make_const(self, value, ty_result): - value_as_signed = rffi.cast(lltype.Signed, value) - llvmconstint = self._make_const_int(value_as_signed) - llvmconstptr = llvm_rffi.LLVMConstIntToPtr(llvmconstint, ty_result) - return llvmconstptr - - def _get_var_type(self, v): - if v.type == INT: - return self.ty_int - else: - return self.ty_char_ptr - - def _get_pointer_type(self, v): - if v.type == INT: - return self.ty_int_ptr - else: - return self.ty_char_ptr_ptr - - # ------------------------------ - # Execution - - def set_future_value_int(self, index, intvalue): - p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index]) - p[0] = intvalue - - def set_future_value_ref(self, index, ptrvalue): - p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index]) - p[0] = ptrvalue - - def execute_operations(self, loop): - index = loop._llvm_compiled_index - assert index >= 0 - while True: - func_ptr = self.compiled_functions[index] - print 'execute_operations: %d (at 0x%x)' % ( - index, rffi.cast(lltype.Signed, func_ptr)) - index = func_ptr() - print '\t--->', index - if index < 0: - break - return self.fail_ops[~index] - - def get_latest_value_int(self, index): - p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index]) - return p[0] - - def get_latest_value_ref(self, index): - p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index]) - return p[0] - - def get_exception(self): - return self.backup_exc_type[0] - - def get_exc_value(self): - return self.backup_exc_value[0] - - def clear_exception(self): - self.backup_exc_type[0] = 0 - self.backup_exc_value[0] = lltype.nullptr(llmemory.GCREF.TO) - - # XXX wrong, but untested - - def set_overflow_error(self): - self.backup_exc_type[0] = self._ovf_error_type - self.backup_exc_value[0] = self._ovf_error_value - - def set_zero_division_error(self): - self.backup_exc_type[0] = self._zer_error_type - self.backup_exc_value[0] = self._zer_error_value - - @staticmethod - def cast_adr_to_int(x): - return rffi.cast(lltype.Signed, x) - - @staticmethod - def cast_int_to_adr(x): - assert x == 0 or x > (1<<20) or x < (-1<<20) - if we_are_translated(): - return rffi.cast(llmemory.Address, x) - else: - # indirect casting because the above doesn't work with ll2ctypes - return llmemory.cast_ptr_to_adr(rffi.cast(llmemory.GCREF, x)) - - def _get_size_index(self, TYPE): - if isinstance(TYPE, lltype.Ptr): - if TYPE.TO._gckind == 'gc': - return self.SIZE_GCPTR - else: - return self.SIZE_INT - else: - if TYPE == lltype.Signed or TYPE == lltype.Unsigned: - return self.SIZE_INT - elif TYPE == lltype.Char or TYPE == lltype.Bool: - return self.SIZE_CHAR - elif TYPE == lltype.UniChar: - return self.SIZE_UNICHAR - else: - raise BadSizeError(TYPE) - - def sizeof(self, S): - try: - return self._descr_caches['size', S] - except KeyError: - pass - descr = SizeDescr(symbolic.get_size(S, self.translate_support_code)) - self._descr_caches['size', S] = descr - return descr - - def fielddescrof(self, S, fieldname): - try: - return self._descr_caches['field', S, fieldname] - except KeyError: - pass - ofs, _ = symbolic.get_field_token(S, fieldname, - self.translate_support_code) - size_index = self._get_size_index(getattr(S, fieldname)) - descr = FieldDescr(ofs, size_index) - self._descr_caches['field', S, fieldname] = descr - return descr - - def arraydescrof(self, A): - basesize, _, ofs_length = symbolic.get_array_token(A, - self.translate_support_code) - if isinstance(basesize, int): # else Symbolics, can't be compared... - assert self.array_index_array == basesize - assert self.array_index_length == ofs_length - itemsize_index = self._get_size_index(A.OF) - return self._arraydescrs[itemsize_index] - - def calldescrof(self, FUNC, ARGS, RESULT): - args_indices = [self._get_size_index(ARG) for ARG in ARGS] - if RESULT is lltype.Void: - res_index = -1 - else: - res_index = self._get_size_index(RESULT) - # - key = ('call', tuple(args_indices), res_index) - try: - descr = self._descr_caches[key] - except KeyError: - descr = CallDescr(args_indices, res_index) - self._descr_caches[key] = descr - return descr - - def get_calldescr_ty_function_ptr(self, calldescr): - if not calldescr.ty_function_ptr: - # - args_indices = calldescr.args_indices - param_types = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), - len(args_indices), flavor='raw') - for i in range(len(args_indices)): - param_types[i] = self.types_by_index[args_indices[i]] - # - res_index = calldescr.res_index - if res_index < 0: - ty_result = self.ty_void - else: - ty_result = self.types_by_index[res_index] - # - ty_func = llvm_rffi.LLVMFunctionType(ty_result, param_types, - len(args_indices), 0) - lltype.free(param_types, flavor='raw') - ty_funcptr = llvm_rffi.LLVMPointerType(ty_func, 0) - calldescr.ty_function_ptr = ty_funcptr - # - return calldescr.ty_function_ptr - - # ------------------------------ - # do_xxx methods - - def do_arraylen_gc(self, args, arraydescr): - array = args[0].getref_base() - p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) - res = len(p) - return BoxInt(res) - - def do_strlen(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) - res = len(p.chars) - return BoxInt(res) - - def do_strgetitem(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) - res = ord(p.chars[args[1].getint()]) - return BoxInt(res) - - def do_unicodelen(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) - res = len(p.chars) - return BoxInt(res) - - def do_unicodegetitem(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) - res = ord(p.chars[args[1].getint()]) - return BoxInt(res) - - def do_getarrayitem_gc(self, args, arraydescr): - array = args[0].getref_base() - index = args[1].getint() - assert isinstance(arraydescr, ArrayDescr) - itemsize_index = arraydescr.itemsize_index - if itemsize_index == self.SIZE_GCPTR: - p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) - res = p[index] - return BoxPtr(res) - elif itemsize_index == self.SIZE_INT: - p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) - res = p[index] - elif itemsize_index == self.SIZE_CHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_char), array) - res = ord(p[index]) - elif itemsize_index == self.SIZE_UNICHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_unichar), array) - res = ord(p[index]) - else: - raise BadSizeError - return BoxInt(res) - - @specialize.argtype(1) - def _do_getfield(self, struct, fielddescr): - assert isinstance(fielddescr, FieldDescr) - size_index = fielddescr.size_index - if size_index == self.SIZE_GCPTR: - p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct) - res = p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] - return BoxPtr(res) - elif size_index == self.SIZE_INT: - p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct) - res = p[fielddescr.offset / rffi.sizeof(lltype.Signed)] - elif size_index == self.SIZE_CHAR: - p = rffi.cast(rffi.CArrayPtr(lltype.Char), struct) - res = ord(p[fielddescr.offset / rffi.sizeof(lltype.Char)]) - elif size_index == self.SIZE_UNICHAR: - p = rffi.cast(rffi.CArrayPtr(lltype.UniChar), struct) - res = ord(p[fielddescr.offset / rffi.sizeof(lltype.UniChar)]) - else: - raise BadSizeError - return BoxInt(res) - - def do_getfield_gc(self, args, fielddescr): - struct = args[0].getref_base() - return self._do_getfield(struct, fielddescr) - - def do_getfield_raw(self, args, fielddescr): - struct = args[0].getaddr(self) - return self._do_getfield(struct, fielddescr) - - def do_new(self, args, sizedescr): - assert isinstance(sizedescr, SizeDescr) - res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, sizedescr.size)) - return BoxPtr(res) - - def do_new_with_vtable(self, args, descr=None): - assert descr is None - sizedescr = self.class_sizes[args[0].getint()] - res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, sizedescr.size)) - self._do_setfield(res, args[0], self.vtable_descr) - return BoxPtr(res) - - def _allocate_new_array(self, args, item_size, index_array, index_length): - length = args[0].getint() - #try: - size = index_array + length * item_size - #except OverflowError: - # ... - res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, size)) - p = rffi.cast(rffi.CArrayPtr(lltype.Signed), res) - p[index_length / rffi.sizeof(lltype.Signed)] = length - return BoxPtr(res) - - def do_new_array(self, args, arraydescr): - assert isinstance(arraydescr, ArrayDescr) - return self._allocate_new_array(args, arraydescr.itemsize, - self.array_index_array, - self.array_index_length) - - def do_setarrayitem_gc(self, args, arraydescr): - array = args[0].getref_base() - index = args[1].getint() - assert isinstance(arraydescr, ArrayDescr) - itemsize_index = arraydescr.itemsize_index - if itemsize_index == self.SIZE_GCPTR: - p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) - res = args[2].getref_base() - p[index] = res - elif itemsize_index == self.SIZE_INT: - p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) - res = args[2].getint() - p[index] = res - elif itemsize_index == self.SIZE_CHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_char), array) - res = chr(args[2].getint()) - p[index] = res - elif itemsize_index == self.SIZE_UNICHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_unichar), array) - res = unichr(args[2].getint()) - p[index] = res - else: - raise BadSizeError - - @specialize.argtype(1) - def _do_setfield(self, struct, v_value, fielddescr): - assert isinstance(fielddescr, FieldDescr) - size_index = fielddescr.size_index - if size_index == self.SIZE_GCPTR: - p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct) - res = v_value.getref_base() - p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] = res - elif size_index == self.SIZE_INT: - p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct) - res = v_value.getint() - p[fielddescr.offset / rffi.sizeof(lltype.Signed)] = res - elif size_index == self.SIZE_CHAR: - p = rffi.cast(rffi.CArrayPtr(lltype.Char), struct) - res = chr(v_value.getint()) - p[fielddescr.offset / rffi.sizeof(lltype.Char)] = res - elif size_index == self.SIZE_UNICHAR: - p = rffi.cast(rffi.CArrayPtr(lltype.UniChar), struct) - res = unichr(v_value.getint()) - p[fielddescr.offset / rffi.sizeof(lltype.UniChar)] = res - else: - raise BadSizeError - - def do_setfield_gc(self, args, fielddescr): - struct = args[0].getref_base() - self._do_setfield(struct, args[1], fielddescr) - - def do_setfield_raw(self, args, fielddescr): - struct = args[0].getaddr(self) - self._do_setfield(struct, args[1], fielddescr) - - def do_newstr(self, args, descr=None): - return self._allocate_new_array(args, 1, - self.string_index_array, - self.string_index_length) - - def do_newunicode(self, args, descr=None): - return self._allocate_new_array(args, self.size_of_unicode, - self.unicode_index_array, - self.unicode_index_length) - - def do_strsetitem(self, args, descr=None): - s = args[0].getref_base() - res = chr(args[2].getint()) - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) - p.chars[args[1].getint()] = res - - def do_unicodesetitem(self, args, descr=None): - s = args[0].getref_base() - res = unichr(args[2].getint()) - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) - p.chars[args[1].getint()] = res - - def _get_loop_for_call(self, argnum, calldescr): - loop = calldescr._generated_mp - if loop is None: - args = [BoxInt() for i in range(argnum + 1)] - if calldescr.res_index < 0: - result = None - elif calldescr.res_index == self.SIZE_GCPTR: - result = BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) - else: - result = BoxInt(0) - result_list = [] - if result is not None: - result_list.append(result) - operations = [ - ResOperation(rop.CALL, args, result, calldescr), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None), - ResOperation(rop.FAIL, result_list, None)] - operations[1].suboperations = [ResOperation(rop.FAIL, [], None)] - loop = history.TreeLoop('call') - loop.inputargs = args - loop.operations = operations - self.compile_operations(loop) - calldescr._generated_mp = loop - return loop - - def do_call(self, args, calldescr): - assert isinstance(calldescr, CallDescr) - num_args = len(calldescr.args_indices) - assert num_args == len(args) - 1 - loop = self._get_loop_for_call(num_args, calldescr) - history.set_future_values(self, args) - self.execute_operations(loop) - # Note: if an exception is set, the rest of the code does a bit of - # nonsense but nothing wrong (the return value should be ignored) - if calldescr.res_index < 0: - return None - elif calldescr.res_index == self.SIZE_GCPTR: - return BoxPtr(self.get_latest_value_ref(0)) - else: - return BoxInt(self.get_latest_value_int(0)) - - def do_cast_int_to_ptr(self, args, descr=None): - int = args[0].getint() - res = rffi.cast(llmemory.GCREF, int) - return BoxPtr(res) - - def do_cast_ptr_to_int(self, args, descr=None): - ptr = args[0].getref_base() - res = rffi.cast(lltype.Signed, ptr) - return BoxInt(res) - - -class SizeDescr(AbstractDescr): - def __init__(self, size): - self.size = size - -class FieldDescr(AbstractDescr): - def __init__(self, offset, size_index): - self.offset = offset - self.size_index = size_index # index in cpu.types_by_index - def is_pointer_field(self): - return self.size_index == LLVMCPU.SIZE_GCPTR - -class ArrayDescr(AbstractDescr): - def __init__(self, itemsize, itemsize_index): - self.itemsize = itemsize - self.itemsize_index = itemsize_index # index in cpu.types_by_index - self.ty_array_ptr = lltype.nullptr(llvm_rffi.LLVMTypeRef.TO) - # ^^^ set by setup_once() - def is_array_of_pointers(self): - return self.itemsize_index == LLVMCPU.SIZE_GCPTR - -class CallDescr(AbstractDescr): - ty_function_ptr = lltype.nullptr(llvm_rffi.LLVMTypeRef.TO) - args_indices = [0] # dummy value to make annotation happy - res_index = 0 - _generated_mp = None - # From noreply at buildbot.pypy.org Wed Oct 17 17:20:22 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 17 Oct 2012 17:20:22 +0200 (CEST) Subject: [pypy-commit] pypy default: bah, our old value for CO_CONTAINSGLOBAL conflicts with PyCF_IGNORE_COOKIE. Add a test to check that we don't have duplicate flags, fix the value of CO_CONTAINSGLOBAL and remove a magic number from test_code_extra, which now passes Message-ID: <20121017152022.61F731C1C8D@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r58177:b1a5512d3fbb Date: 2012-10-17 17:15 +0200 http://bitbucket.org/pypy/pypy/changeset/b1a5512d3fbb/ Log: bah, our old value for CO_CONTAINSGLOBAL conflicts with PyCF_IGNORE_COOKIE. Add a test to check that we don't have duplicate flags, fix the value of CO_CONTAINSGLOBAL and remove a magic number from test_code_extra, which now passes diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py --- a/pypy/interpreter/astcompiler/consts.py +++ b/pypy/interpreter/astcompiler/consts.py @@ -9,13 +9,14 @@ CO_NESTED = 0x0010 CO_GENERATOR = 0x0020 CO_NOFREE = 0x0040 -CO_CONTAINSGLOBALS = 0x0800 CO_GENERATOR_ALLOWED = 0x1000 CO_FUTURE_DIVISION = 0x2000 CO_FUTURE_ABSOLUTE_IMPORT = 0x4000 CO_FUTURE_WITH_STATEMENT = 0x8000 CO_FUTURE_PRINT_FUNCTION = 0x10000 CO_FUTURE_UNICODE_LITERALS = 0x20000 +CO_CONTAINSGLOBALS = 0x80000 # pypy-specific: need to check that it's not used + # by any other flag PyCF_SOURCE_IS_UTF8 = 0x0100 PyCF_DONT_IMPLY_DEDENT = 0x0200 diff --git a/pypy/interpreter/test/test_code.py b/pypy/interpreter/test/test_code.py --- a/pypy/interpreter/test/test_code.py +++ b/pypy/interpreter/test/test_code.py @@ -1,5 +1,6 @@ from pypy.conftest import gettestobjspace from pypy.interpreter import gateway +from pypy.interpreter.astcompiler import consts import py class AppTestCodeIntrospection: @@ -11,6 +12,7 @@ filename = filename[:-1] cls.w_file = space.wrap(filename) + cls.w_CO_CONTAINSGLOBALS = space.wrap(consts.CO_CONTAINSGLOBALS) def test_attributes(self): def f(): pass @@ -185,7 +187,7 @@ assert f(4).func_code.co_flags & 0x10 assert f.func_code.co_flags & 0x10 == 0 # check for CO_CONTAINSGLOBALS - assert not f.func_code.co_flags & 0x0800 + assert not f.func_code.co_flags & self.CO_CONTAINSGLOBALS exec """if 1: @@ -197,8 +199,8 @@ """ # check for CO_CONTAINSGLOBALS - assert f.func_code.co_flags & 0x0800 - assert not g.func_code.co_flags & 0x0800 + assert f.func_code.co_flags & self.CO_CONTAINSGLOBALS + assert not g.func_code.co_flags & self.CO_CONTAINSGLOBALS exec """if 1: b = 2 @@ -207,4 +209,4 @@ return a + b + x """ # check for CO_CONTAINSGLOBALS - assert f.func_code.co_flags & 0x0800 + assert f.func_code.co_flags & self.CO_CONTAINSGLOBALS From noreply at buildbot.pypy.org Wed Oct 17 17:20:23 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 17 Oct 2012 17:20:23 +0200 (CEST) Subject: [pypy-commit] pypy py3k: hg merge default Message-ID: <20121017152023.85E661C1C8D@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58178:5e7742f91b48 Date: 2012-10-17 17:20 +0200 http://bitbucket.org/pypy/pypy/changeset/5e7742f91b48/ Log: hg merge default diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py --- a/pypy/interpreter/astcompiler/consts.py +++ b/pypy/interpreter/astcompiler/consts.py @@ -9,13 +9,14 @@ CO_NESTED = 0x0010 CO_GENERATOR = 0x0020 CO_NOFREE = 0x0040 -CO_CONTAINSGLOBALS = 0x0800 CO_GENERATOR_ALLOWED = 0x1000 CO_FUTURE_DIVISION = 0x2000 CO_FUTURE_ABSOLUTE_IMPORT = 0x4000 CO_FUTURE_WITH_STATEMENT = 0x8000 CO_FUTURE_PRINT_FUNCTION = 0x10000 CO_FUTURE_UNICODE_LITERALS = 0x20000 +CO_CONTAINSGLOBALS = 0x80000 # pypy-specific: need to check that it's not used + # by any other flag PyCF_SOURCE_IS_UTF8 = 0x0100 PyCF_DONT_IMPLY_DEDENT = 0x0200 diff --git a/pypy/interpreter/test/test_code.py b/pypy/interpreter/test/test_code.py --- a/pypy/interpreter/test/test_code.py +++ b/pypy/interpreter/test/test_code.py @@ -1,5 +1,6 @@ from pypy.conftest import gettestobjspace from pypy.interpreter import gateway +from pypy.interpreter.astcompiler import consts import py class AppTestCodeIntrospection: @@ -11,6 +12,7 @@ filename = filename[:-1] cls.w_file = space.wrap(filename) + cls.w_CO_CONTAINSGLOBALS = space.wrap(consts.CO_CONTAINSGLOBALS) def test_attributes(self): def f(): pass @@ -194,7 +196,7 @@ assert d['f'](4).__code__.co_flags & 0x10 assert d['f'].__code__.co_flags & 0x10 == 0 # check for CO_CONTAINSGLOBALS - assert not d['f'].__code__.co_flags & 0x0800 + assert not d['f'].__code__.co_flags & self.CO_CONTAINSGLOBALS exec("""if 1: @@ -206,8 +208,8 @@ """, d) # check for CO_CONTAINSGLOBALS - assert d['f'].__code__.co_flags & 0x0800 - assert not d['g'].__code__.co_flags & 0x0800 + assert d['f'].__code__.co_flags & self.CO_CONTAINSGLOBALS + assert not d['g'].__code__.co_flags & self.CO_CONTAINSGLOBALS exec("""if 1: b = 2 @@ -216,4 +218,4 @@ return a + b + x """, d) # check for CO_CONTAINSGLOBALS - assert d['f'].__code__.co_flags & 0x0800 + assert d['f'].__code__.co_flags & self.CO_CONTAINSGLOBALS From noreply at buildbot.pypy.org Wed Oct 17 17:36:39 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 17 Oct 2012 17:36:39 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal, arigo) in-progress Message-ID: <20121017153639.F3DE21C1C8D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58179:6b95b9479e1a Date: 2012-10-17 17:36 +0200 http://bitbucket.org/pypy/pypy/changeset/6b95b9479e1a/ Log: (fijal, arigo) in-progress diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -19,10 +19,9 @@ has_been_freed = False invalid = False - def __init__(self, inputargs, operations, looptoken): + def __init__(self, inputargs, operations): self.inputargs = inputargs self.operations = operations - self.looptoken = looptoken class GuardFailed(Exception): def __init__(self, failargs, descr): @@ -155,7 +154,7 @@ def compile_loop(self, inputargs, operations, looptoken, log=True, name=''): clt = model.CompiledLoopToken(self, looptoken.number) looptoken.compiled_loop_token = clt - lltrace = LLTrace(inputargs, operations, looptoken) + lltrace = LLTrace(inputargs, operations) clt._llgraph_loop = lltrace clt._llgraph_alltraces = [lltrace] self._record_labels(lltrace) @@ -164,7 +163,7 @@ original_loop_token, log=True): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() - lltrace = LLTrace(inputargs, operations, original_loop_token) + lltrace = LLTrace(inputargs, operations) faildescr._llgraph_bridge = lltrace clt._llgraph_alltraces.append(lltrace) self._record_labels(lltrace) @@ -196,6 +195,8 @@ def free_loop_and_bridges(self, compiled_loop_token): for c in compiled_loop_token._llgraph_alltraces: c.has_been_freed = True + compiled_loop_token._llgraph_alltraces = [] + compiled_loop_token._llgraph_loop = None model.AbstractCPU.free_loop_and_bridges(self, compiled_loop_token) def make_execute_token(self, *argtypes): @@ -447,7 +448,8 @@ def bh_newstr(self, length): return lltype.cast_opaque_ptr(llmemory.GCREF, - lltype.malloc(rstr.STR, length)) + lltype.malloc(rstr.STR, length, + zero=True)) def bh_strlen(self, s): return s._obj.container.chars.getlength() @@ -467,7 +469,8 @@ def bh_newunicode(self, length): return lltype.cast_opaque_ptr(llmemory.GCREF, - lltype.malloc(rstr.UNICODE, length)) + lltype.malloc(rstr.UNICODE, length, + zero=True)) def bh_unicodelen(self, string): return string._obj.container.chars.getlength() @@ -490,7 +493,7 @@ lltype.malloc(sizedescr.S, zero=True)) def bh_new_with_vtable(self, vtable, descr): - result = lltype.malloc(descr.S) + result = lltype.malloc(descr.S, zero=True) result_as_objptr = lltype.cast_pointer(rclass.OBJECTPTR, result) result_as_objptr.typeptr = support.cast_from_int(rclass.CLASSTYPE, vtable) diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -26,7 +26,7 @@ def show_procedures(metainterp_sd, procedure=None, error=None): # debugging - if option.view or option.viewloops: + if option and (option.view or option.viewloops): if error: errmsg = error.__class__.__name__ if str(error): diff --git a/pypy/jit/metainterp/memmgr.py b/pypy/jit/metainterp/memmgr.py --- a/pypy/jit/metainterp/memmgr.py +++ b/pypy/jit/metainterp/memmgr.py @@ -10,7 +10,7 @@ # in warmstate.py), apart from the 'alive_loops' set in MemoryManager, # which is the only (long-living) place that keeps them alive. If a # loop was not called for long enough, then it is removed from -# 'alive_loops'. It will soon be freed by the GC. LoopToken.__del__ +# 'alive_loops'. It will soon be freed by the GC. CompiledLoopToken.__del__ # calls the method cpu.free_loop_and_bridges(). # # The alive_loops set is maintained using the notion of a global diff --git a/pypy/jit/metainterp/test/test_memmgr.py b/pypy/jit/metainterp/test/test_memmgr.py --- a/pypy/jit/metainterp/test/test_memmgr.py +++ b/pypy/jit/metainterp/test/test_memmgr.py @@ -218,6 +218,7 @@ res = self.meta_interp(f, [1], loop_longevity=4, inline=True) assert res == 42 self.check_jitcell_token_count(6) + import pdb;pdb.set_trace() tokens = [t() for t in get_stats().jitcell_token_wrefs] # Some loops have been freed assert None in tokens @@ -254,4 +255,3 @@ finally: if hasattr(test, 'teardown_class'): test.teardown_class() - diff --git a/pypy/translator/tool/reftracker.py b/pypy/translator/tool/reftracker.py --- a/pypy/translator/tool/reftracker.py +++ b/pypy/translator/tool/reftracker.py @@ -33,7 +33,10 @@ self.links[word] = linktext s = '<%s> %s\\n%s' % (typename, word, s) nodename = 'node%d' % len(nodes) - dotgen.emit_node(nodename, label=s, shape="box") + kwds = {} + if i == len(objectlist) - 1: + kwds['color'] = 'red' + dotgen.emit_node(nodename, label=s, shape="box", **kwds) nodes[uid(objectlist[i])] = nodename for o2 in self.get_referents(objectlist[i]): if o2 is None: From noreply at buildbot.pypy.org Wed Oct 17 18:55:54 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 17 Oct 2012 18:55:54 +0200 (CEST) Subject: [pypy-commit] pypy py3k: long is no longer there in py3k (sorry for the word play) Message-ID: <20121017165554.F2F911C1C84@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58180:11b6adfbf682 Date: 2012-10-17 18:25 +0200 http://bitbucket.org/pypy/pypy/changeset/11b6adfbf682/ Log: long is no longer there in py3k (sorry for the word play) diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py --- a/pypy/objspace/std/complextype.py +++ b/pypy/objspace/std/complextype.py @@ -185,7 +185,6 @@ # __complex__() must return a complex or (float,int,long) object # (XXX should not use isinstance here) if (space.isinstance_w(w_z, space.w_int) or - space.isinstance_w(w_z, space.w_long) or space.isinstance_w(w_z, space.w_float)): return (space.float_w(w_z), 0.0) elif isinstance(w_z, W_ComplexObject): diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -251,8 +251,6 @@ assert complex(NS(2.0)) == 2+0j assert complex(OS(2)) == 2+0j assert complex(NS(2)) == 2+0j - assert complex(OS(2L)) == 2+0j - assert complex(NS(2L)) == 2+0j raises(TypeError, complex, OS(None)) raises(TypeError, complex, NS(None)) From noreply at buildbot.pypy.org Wed Oct 17 18:55:56 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 17 Oct 2012 18:55:56 +0200 (CEST) Subject: [pypy-commit] pypy py3k: allow special unicode decimal digits and spaces in complex ctor Message-ID: <20121017165556.4F5221C1C84@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58181:487439d3c669 Date: 2012-10-17 18:48 +0200 http://bitbucket.org/pypy/pypy/changeset/487439d3c669/ Log: allow special unicode decimal digits and spaces in complex ctor diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py --- a/pypy/objspace/std/complextype.py +++ b/pypy/objspace/std/complextype.py @@ -6,6 +6,7 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef from pypy.objspace.std.stdtypedef import StdObjSpaceMultiMethod +from pypy.objspace.std.unicodeobject import unicode_to_decimal_w # ERRORCODES @@ -130,15 +131,15 @@ and space.is_w(space.type(w_real), space.w_complex)): return w_real - if space.isinstance_w(w_real, space.w_str) or \ - space.isinstance_w(w_real, space.w_unicode): + if space.isinstance_w(w_real, space.w_unicode): # a string argument if not noarg2: raise OperationError(space.w_TypeError, space.wrap("complex() can't take second arg" " if first is a string")) + unistr = unicode_to_decimal_w(space, w_real) try: - realstr, imagstr = _split_complex(space.unicode_w(w_real)) + realstr, imagstr = _split_complex(unistr) except ValueError: raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED)) try: diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -1,3 +1,4 @@ +# -*- encoding: utf-8 -*- from __future__ import print_function import py @@ -87,6 +88,8 @@ class AppTestAppComplexTest: + spaceconfig = {'usemodules': ('unicodedata',)} + def w_check_div(self, x, y): """Compute complex z=x*y, and check that z/x==y and z/y==x.""" z = x * y @@ -254,6 +257,7 @@ raises(TypeError, complex, OS(None)) raises(TypeError, complex, NS(None)) + raises(TypeError, complex, b'10') # -- The following cases are not supported by CPython, but they # -- are supported by PyPy, which is most probably ok @@ -349,6 +353,13 @@ assert self.almost_equal(complex(real=float2(17.), imag=float2(23.)), 17+23j) raises(TypeError, complex, float2(None)) + def test_constructor_unicode(self): + b1 = '\N{MATHEMATICAL BOLD DIGIT ONE}' # 𝟏 + b2 = '\N{MATHEMATICAL BOLD DIGIT TWO}' # 𝟐 + s = '{0} + {1}j'.format(b1, b2) + assert complex(s) == 1+2j + assert complex('\N{EM SPACE}(1+1j)') + def test_hash(self): for x in range(-30, 30): assert hash(x) == hash(complex(x, 0)) From noreply at buildbot.pypy.org Wed Oct 17 18:55:57 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 17 Oct 2012 18:55:57 +0200 (CEST) Subject: [pypy-commit] pypy py3k: add one more edge case to complex parsing Message-ID: <20121017165557.796791C1C84@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58182:a3f4c69543dc Date: 2012-10-17 18:55 +0200 http://bitbucket.org/pypy/pypy/changeset/a3f4c69543dc/ Log: add one more edge case to complex parsing diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py --- a/pypy/objspace/std/complextype.py +++ b/pypy/objspace/std/complextype.py @@ -29,9 +29,11 @@ imagstop = 0 imagsign = ' ' i = 0 - # ignore whitespace + # ignore whitespace at beginning and end while i < slen and s[i] == ' ': i += 1 + while slen > 0 and s[slen-1] == ' ': + slen -= 1 if s[i] == '(' and s[slen-1] == ')': i += 1 diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -295,7 +295,7 @@ assert self.almost_equal(complex(), 0) assert self.almost_equal(complex("-1"), -1) assert self.almost_equal(complex("+1"), +1) - assert self.almost_equal(complex(" ( +3.14-6J )"), 3.14-6j) + assert self.almost_equal(complex(" ( +3.14-6J ) "), 3.14-6j) class complex2(complex): pass @@ -358,7 +358,7 @@ b2 = '\N{MATHEMATICAL BOLD DIGIT TWO}' # 𝟐 s = '{0} + {1}j'.format(b1, b2) assert complex(s) == 1+2j - assert complex('\N{EM SPACE}(1+1j)') + assert complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) ') == 1+1j def test_hash(self): for x in range(-30, 30): From noreply at buildbot.pypy.org Wed Oct 17 18:57:29 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 17 Oct 2012 18:57:29 +0200 (CEST) Subject: [pypy-commit] pypy default: add one more edge case to complex parsing Message-ID: <20121017165729.D95971C1C84@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r58183:2da948c3eb75 Date: 2012-10-17 18:57 +0200 http://bitbucket.org/pypy/pypy/changeset/2da948c3eb75/ Log: add one more edge case to complex parsing diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py --- a/pypy/objspace/std/complextype.py +++ b/pypy/objspace/std/complextype.py @@ -26,9 +26,11 @@ imagstop = 0 imagsign = ' ' i = 0 - # ignore whitespace + # ignore whitespace at beginning and end while i < slen and s[i] == ' ': i += 1 + while slen > 0 and s[slen-1] == ' ': + slen -= 1 if s[i] == '(' and s[slen-1] == ')': i += 1 diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -304,7 +304,7 @@ assert self.almost_equal(complex(), 0) assert self.almost_equal(complex("-1"), -1) assert self.almost_equal(complex("+1"), +1) - assert self.almost_equal(complex(" ( +3.14-6J )"), 3.14-6j) + assert self.almost_equal(complex(" ( +3.14-6J ) "), 3.14-6j) class complex2(complex): pass From noreply at buildbot.pypy.org Wed Oct 17 19:07:51 2012 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 17 Oct 2012 19:07:51 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: fix to_str, clean up debug cruft; now passes test_stringarray Message-ID: <20121017170751.2F0241C1C84@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-problems Changeset: r58184:0fcfcdb4f777 Date: 2012-10-16 23:39 +0200 http://bitbucket.org/pypy/pypy/changeset/0fcfcdb4f777/ Log: fix to_str, clean up debug cruft; now passes test_stringarray 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 @@ -275,6 +275,9 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) + def convert_to(self, dtype): + return self.arr + class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): from pypy.module.micronumpy.interp_dtype import new_unicode_dtype 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 @@ -684,7 +684,6 @@ arr = W_NDimArray.from_shape(shape, dtype, order=order) arr_iter = arr.create_iter(arr.get_shape()) for w_elem in elems_w: - print 'setting',arr_iter.offset,'to',w_elem arr_iter.setitem(dtype.coerce(space, w_elem)) arr_iter.next() return arr diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2259,7 +2259,7 @@ assert a[0] == 'abc' assert a[1] == 'defg' assert a[2] == 'ab' - assert repr(a) == "array(['abc', 'defg', ab'])" + assert repr(a) == "array(['abc', 'defg', 'ab'])" class AppTestPyPy(BaseNumpyAppTest): 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 @@ -1478,28 +1478,23 @@ def store(self, arr, i, offset, box): assert isinstance(box, interp_boxes.W_StringBox) - for k in range(min(self.size-i, box.arr.size-offset)): + for k in range(min(self.size, box.arr.size-offset)): arr.storage[k + i] = box.arr.storage[k + offset] def read(self, arr, i, offset, dtype=None): if dtype is None: dtype = arr.dtype return interp_boxes.W_StringBox(arr, i + offset, dtype) - #print 'read',arr, arr.dtype - #xxx - #builder = StringBuilder() - #i = 0 - #while i < self.size: - # assert isinstance(arr.storage[i], str) - # builder.append(arr.storage[i]) - # i += 1 - #return builder.build() + def to_str(self, item): builder = StringBuilder() assert isinstance(item, interp_boxes.W_StringBox) - i = 0 - while i < self.size: + i = item.ofs + end = i+self.size + while i < end: assert isinstance(item.arr.storage[i], str) + if item.arr.storage[i] == '\x00': + break builder.append(item.arr.storage[i]) i += 1 return builder.build() From noreply at buildbot.pypy.org Wed Oct 17 19:07:52 2012 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 17 Oct 2012 19:07:52 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: fixes for translation, running all test_numarray tests fail but running singly succeeds Message-ID: <20121017170752.71C541C1C84@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-problems Changeset: r58185:428ac7a5eb40 Date: 2012-10-17 00:31 +0200 http://bitbucket.org/pypy/pypy/changeset/428ac7a5eb40/ Log: fixes for translation, running all test_numarray tests fail but running singly succeeds 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 @@ -275,8 +275,13 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - def convert_to(self, dtype): - return self.arr + # Running entire test suite needs this function to succeed, + # running single test_stringarray succeeds without it. + # With convert_to() test_ztranslation fails since + # W_CharacterBox is not a W_GenericBox. + # Why is it needed for multiple tests? + #def convert_to(self, dtype): + # xxx class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): 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 @@ -478,7 +478,7 @@ return interp_dtype.variable_dtype(space, 'S%d' % space.len_w(w_obj)) elif current_guess.num ==18: - if current_guess.itemtype.size < space.len_w(w_obj): + if current_guess.itemtype.get_size() < space.len_w(w_obj): return interp_dtype.variable_dtype(space, 'S%d' % space.len_w(w_obj)) return current_guess 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 @@ -1465,6 +1465,9 @@ def get_element_size(self): return self.size * rffi.sizeof(self.T) + def get_size(self): + return self.size + class StringType(BaseType, BaseStringType): T = lltype.Char From noreply at buildbot.pypy.org Wed Oct 17 19:07:53 2012 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 17 Oct 2012 19:07:53 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: add some jit hints Message-ID: <20121017170753.90DA61C1C84@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-problems Changeset: r58186:c9c13d8f38a8 Date: 2012-10-17 19:04 +0200 http://bitbucket.org/pypy/pypy/changeset/c9c13d8f38a8/ Log: add some jit hints 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 @@ -1471,6 +1471,7 @@ class StringType(BaseType, BaseStringType): T = lltype.Char + @jit.unroll_safe def coerce(self, space, dtype, w_item): from pypy.module.micronumpy.interp_dtype import new_string_dtype arg = space.str_w(space.str(w_item)) @@ -1479,6 +1480,7 @@ arr.storage[i] = arg[i] return interp_boxes.W_StringBox(arr, 0, None) + @jit.unroll_safe def store(self, arr, i, offset, box): assert isinstance(box, interp_boxes.W_StringBox) for k in range(min(self.size, box.arr.size-offset)): @@ -1489,6 +1491,7 @@ dtype = arr.dtype return interp_boxes.W_StringBox(arr, i + offset, dtype) + @jit.unroll_safe def to_str(self, item): builder = StringBuilder() assert isinstance(item, interp_boxes.W_StringBox) From noreply at buildbot.pypy.org Wed Oct 17 21:56:45 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 17 Oct 2012 21:56:45 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fix for py3 map Message-ID: <20121017195645.E99CD1C1C8D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58187:19919f902c31 Date: 2012-10-17 11:23 -0700 http://bitbucket.org/pypy/pypy/changeset/19919f902c31/ Log: fix for py3 map diff --git a/pypy/module/_collections/test/test_deque.py b/pypy/module/_collections/test/test_deque.py --- a/pypy/module/_collections/test/test_deque.py +++ b/pypy/module/_collections/test/test_deque.py @@ -171,7 +171,7 @@ assert list(d) == list(reversed(range(1000, 1200))) # n = 100 - data = map(str, range(n)) + data = list(map(str, range(n))) for i in range(n): d = deque(data[:i]) r = d.reverse() From noreply at buildbot.pypy.org Wed Oct 17 21:56:47 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 17 Oct 2012 21:56:47 +0200 (CEST) Subject: [pypy-commit] pypy py3k: avoid OverflowErrors in specialised int tuples now that our w_int is long Message-ID: <20121017195647.2FCA51C1C92@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58188:fae3f8237b0e Date: 2012-10-17 12:56 -0700 http://bitbucket.org/pypy/pypy/changeset/fae3f8237b0e/ Log: avoid OverflowErrors in specialised int tuples now that our w_int is long diff --git a/pypy/objspace/std/specialisedtupleobject.py b/pypy/objspace/std/specialisedtupleobject.py --- a/pypy/objspace/std/specialisedtupleobject.py +++ b/pypy/objspace/std/specialisedtupleobject.py @@ -188,15 +188,26 @@ Cls_ff = make_specialised_class((float, float)) #Cls_ooo = make_specialised_class((object, object, object)) +def is_int_w(space, w_obj): + """Determine if obj can be safely casted to an int_w""" + try: + space.int_w(w_obj) + except OperationError, e: + if not (e.match(space, space.w_OverflowError) or + e.match(space, space.w_TypeError)): + raise + return False + return True + def makespecialisedtuple(space, list_w): if len(list_w) == 2: w_arg1, w_arg2 = list_w w_type1 = space.type(w_arg1) #w_type2 = space.type(w_arg2) # - if w_type1 is space.w_int: + if w_type1 is space.w_int and is_int_w(space, w_arg1): w_type2 = space.type(w_arg2) - if w_type2 is space.w_int: + if w_type2 is space.w_int and is_int_w(space, w_arg2): return Cls_ii(space, w_arg1, w_arg2) #elif w_type2 is space.w_str: # return Cls_is(space, w_arg1, w_arg2) diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py b/pypy/objspace/std/test/test_specialisedtupleobject.py --- a/pypy/objspace/std/test/test_specialisedtupleobject.py +++ b/pypy/objspace/std/test/test_specialisedtupleobject.py @@ -243,6 +243,10 @@ assert a == (1, 2.2,) + b assert not a != (1, 2.2) + b + def test_ovfl_bug(self): + # previously failed + a = (0xffffffffffffffff, 0) + class AppTestAll(test_tupleobject.AppTestW_TupleObject): pass From noreply at buildbot.pypy.org Wed Oct 17 23:38:18 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 17 Oct 2012 23:38:18 +0200 (CEST) Subject: [pypy-commit] pypy py3k: we still need to special case unwrapped defaults too, now w/ a test Message-ID: <20121017213818.3563F1C1C8D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58189:4ab357f7d06d Date: 2012-10-17 10:39 -0700 http://bitbucket.org/pypy/pypy/changeset/4ab357f7d06d/ Log: we still need to special case unwrapped defaults too, now w/ a test diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -852,7 +852,8 @@ def _getdefaults(self, space): "NOT_RPYTHON" defs_w = [] - for name, defaultval in self._staticdefs: + unwrap_spec = self._code._unwrap_spec[-len(self._staticdefs):] + for i, (name, defaultval) in enumerate(self._staticdefs): if name.startswith('w_'): assert defaultval is None, ( "%s: default value for '%s' can only be None; " @@ -860,7 +861,11 @@ self._code.identifier, name)) defs_w.append(None) else: - defs_w.append(space.wrap(defaultval)) + spec = unwrap_spec[i] + if isinstance(defaultval, str) and spec not in [str]: + defs_w.append(space.wrapbytes(defaultval)) + else: + defs_w.append(space.wrap(defaultval)) if self._code._unwrap_spec: UNDEFINED = object() alldefs_w = [UNDEFINED] * len(self._code.sig[0]) 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 @@ -611,6 +611,16 @@ never_called py.test.raises(AssertionError, space.wrap, gateway.interp2app_temp(g)) + def test_unwrap_spec_default_bytes(self): + space = self.space + @gateway.unwrap_spec(s='bufferstr') + def g(space, s=''): + return space.wrap(type(s) is str) + w_g = space.wrap(gateway.interp2app_temp(g)) + args = argument.Arguments(space, []) + w_res = space.call_args(w_g, args) + assert space.eq_w(w_res, space.w_True) + def test_unwrap_spec_default_applevel_bytes(self): space = self.space @gateway.unwrap_spec(w_x=WrappedDefault('foo')) From noreply at buildbot.pypy.org Thu Oct 18 08:32:50 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 08:32:50 +0200 (CEST) Subject: [pypy-commit] pypy default: Remove this lone small test file and merge it into test_lib_pypy. Message-ID: <20121018063250.391031C0502@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58190:acb6eb26ce8f Date: 2012-10-18 08:24 +0200 http://bitbucket.org/pypy/pypy/changeset/acb6eb26ce8f/ Log: Remove this lone small test file and merge it into test_lib_pypy. diff --git a/lib_pypy/pypy_test/test_ctypes_support.py b/lib_pypy/pypy_test/test_ctypes_support.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_ctypes_support.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import absolute_import - -import py -from ctypes import * -try: - from ctypes_support import standard_c_lib, get_errno, set_errno -except ImportError: # on top of cpython - from lib_pypy.ctypes_support import standard_c_lib, get_errno, set_errno - - -def test_stdlib_and_errno(): - py.test.skip("this is expected on top of pypy, we need to fix ctypes in a way that is now in 2.6 in order to make this reliable") - write = standard_c_lib.write - write.argtypes = [c_int, c_char_p, c_size_t] - write.restype = c_size_t - # clear errno first - set_errno(0) - assert get_errno() == 0 - write(-345, "abc", 3) - assert get_errno() != 0 - set_errno(0) - assert get_errno() == 0 - -def test_argument_conversion_and_checks(): - strlen = standard_c_lib.strlen - strlen.argtypes = [c_char_p] - strlen.restype = c_size_t - assert strlen("eggs") == 4 - - # Should raise ArgumentError, not segfault - py.test.raises(ArgumentError, strlen, False) - diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py b/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py +++ b/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py @@ -462,6 +462,15 @@ callback = proto(callback) raises(ArgumentError, lambda: callback((1, 2, 3, 4), POINT())) + def test_argument_conversion_and_checks(self): + strlen = dll.my_strchr + strlen.argtypes = [c_char_p, c_int] + strlen.restype = c_char_p + assert strlen("eggs", ord("g")) == "ggs" + + # Should raise ArgumentError, not segfault + py.test.raises(ArgumentError, strlen, False, 0) + def test_union_as_passed_value(self): class UN(Union): _fields_ = [("x", c_short), @@ -545,3 +554,5 @@ res = test_errno() n = get_errno() assert (res, n) == (42, 43) + set_errno(0) + assert get_errno() == 0 From noreply at buildbot.pypy.org Thu Oct 18 08:32:51 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 08:32:51 +0200 (CEST) Subject: [pypy-commit] pypy default: Skip the segfaulting test. Broken by the fast-path. Meh. Message-ID: <20121018063251.722FF1C0502@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58191:5ce4b0c23b17 Date: 2012-10-18 08:32 +0200 http://bitbucket.org/pypy/pypy/changeset/5ce4b0c23b17/ Log: Skip the segfaulting test. Broken by the fast-path. Meh. diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py b/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py +++ b/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py @@ -463,12 +463,14 @@ raises(ArgumentError, lambda: callback((1, 2, 3, 4), POINT())) def test_argument_conversion_and_checks(self): + py.test.skip("XXX currently broken on PyPy, sorry") strlen = dll.my_strchr strlen.argtypes = [c_char_p, c_int] strlen.restype = c_char_p assert strlen("eggs", ord("g")) == "ggs" # Should raise ArgumentError, not segfault + py.test.raises(ArgumentError, strlen, 0, 0) py.test.raises(ArgumentError, strlen, False, 0) def test_union_as_passed_value(self): From noreply at buildbot.pypy.org Thu Oct 18 10:18:29 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 10:18:29 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: fix mostly everything Message-ID: <20121018081829.DF8A11C0502@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58192:ffad6c83a68b Date: 2012-10-18 10:18 +0200 http://bitbucket.org/pypy/pypy/changeset/ffad6c83a68b/ Log: fix mostly everything diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -12,7 +12,7 @@ from pypy.rpython.llinterp import LLInterpreter, LLException from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr -from pypy.rlib.rarithmetic import ovfcheck +from pypy.rlib.rarithmetic import ovfcheck, r_uint, r_ulonglong from pypy.rlib.rtimer import read_timestamp class LLTrace(object): @@ -132,11 +132,18 @@ def is_float_field(self): return getkind(self.FIELD) == 'float' +def _example_res(kind): + d = {'v': None, + 'r': lltype.nullptr(llmemory.GCREF.TO), + 'i': 0, + 'f': 0.0} + return d[kind[0]] + class LLGraphCPU(model.AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts supports_floats = True - supports_longlong = True + supports_longlong = r_uint is not r_ulonglong supports_singlefloats = True translate_support_code = False @@ -191,6 +198,8 @@ assert not hasattr(oldlooptoken, '_llgraph_redirected') oldlooptoken.compiled_loop_token._llgraph_redirected = True oldlooptoken.compiled_loop_token._llgraph_loop = newtrace + alltraces = newlooptoken.compiled_loop_token._llgraph_alltraces + oldlooptoken.compiled_loop_token._llgraph_alltraces = alltraces def free_loop_and_bridges(self, compiled_loop_token): for c in compiled_loop_token._llgraph_alltraces: @@ -725,11 +734,7 @@ self.cpu.last_exception = None except LLException, lle: self.cpu.last_exception = lle - d = {'void': None, - 'ref': lltype.nullptr(llmemory.GCREF.TO), - 'int': 0, - 'float': 0.0} - res = d[getkind(TP.RESULT)] + res = _example_res[getkind(TP.RESULT)] return res execute_call_may_force = execute_call @@ -768,14 +773,11 @@ try: result = assembler_helper_ptr(failindex, vable) except LLException, lle: - xxxxxxxxxx - assert _last_exception is None, "exception left behind" - _last_exception = lle - # fish op - op = self.loop.operations[self.opindex] - if op.result is not None: - yyyyyyyyyyyyy - return 0 + assert self.cpu.last_exception is None, "exception left behind" + self.cpu.last_exception = lle + if self.current_op.result is not None: + return _example_res(self.current_op.result.type) + return None return support.cast_result(lltype.typeOf(result), result) def _reset_vable(self, jd, vable): diff --git a/pypy/jit/backend/llgraph/support.py b/pypy/jit/backend/llgraph/support.py --- a/pypy/jit/backend/llgraph/support.py +++ b/pypy/jit/backend/llgraph/support.py @@ -67,10 +67,10 @@ if isinstance(TYPE, lltype.Ptr): if isinstance(x, (int, long, llmemory.AddressAsInt)): x = llmemory.cast_int_to_adr(x) - if repr(x.ptr).startswith('<* Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58193:f3dfbc8684db Date: 2012-10-18 10:27 +0200 http://bitbucket.org/pypy/pypy/changeset/f3dfbc8684db/ Log: Trying to understand why, in-progress diff --git a/pypy/jit/metainterp/test/test_memmgr.py b/pypy/jit/metainterp/test/test_memmgr.py --- a/pypy/jit/metainterp/test/test_memmgr.py +++ b/pypy/jit/metainterp/test/test_memmgr.py @@ -212,13 +212,34 @@ g(u, 0); g(u+2, 0) # \ make more loops for g(u+1) to g(u+4), g(u, 0); g(u+3, 0) # / but keeps g(u) alive g(u, 0); g(u+4, 0) # / + g(u, 0); g(u+5, 0) # / + g(u, 0); g(u+6, 0) # / + g(u, 0); g(u+7, 0) # / + g(u, 0); g(u+8, 0) # / + g(u, 0); g(u+9, 0) # / + g(u, 0); g(u+10, 0) # / + g(u, 0); g(u+11, 0) # / + g(u, 0); g(u+12, 0) # / g(u, 8) # call g(u) again, with its call_assembler to h(u) return 42 - res = self.meta_interp(f, [1], loop_longevity=4, inline=True) + res = self.meta_interp(f, [1], loop_longevity=3, inline=True) assert res == 42 - self.check_jitcell_token_count(6) + self.check_jitcell_token_count(6+8) + # + # manually free the inner loops of the llgraph backend + tokens = [t() for t in get_stats().jitcell_token_wrefs] + for token in tokens: + if token is not None: + for key in token.compiled_loop_token.__dict__.keys(): + if key.startswith('_llgraph_'): + setattr(token.compiled_loop_token, key, 'STUBBED') + del tokens, token + import gc; gc.collect(); gc.collect(); gc.collect(); gc.collect() import pdb;pdb.set_trace() + # from pypy.translator.tool.reftracker import track + # track(get_stats().jitcell_token_wrefs[8]()) + # tokens = [t() for t in get_stats().jitcell_token_wrefs] # Some loops have been freed assert None in tokens diff --git a/pypy/translator/tool/reftracker.py b/pypy/translator/tool/reftracker.py --- a/pypy/translator/tool/reftracker.py +++ b/pypy/translator/tool/reftracker.py @@ -14,7 +14,7 @@ class BaseRefTrackerPage(GraphPage): - def compute(self, objectlist): + def compute(self, objectlist, highlight=set()): assert objectlist[0] is MARKER self.objectlist = objectlist dotgen = DotGen('reftracker') @@ -34,7 +34,7 @@ s = '<%s> %s\\n%s' % (typename, word, s) nodename = 'node%d' % len(nodes) kwds = {} - if i == len(objectlist) - 1: + if i in highlight: kwds['color'] = 'red' dotgen.emit_node(nodename, label=s, shape="box", **kwds) nodes[uid(objectlist[i])] = nodename @@ -78,11 +78,13 @@ for o2 in self.get_referrers(objectlist[i]): if uid(o2) == id1: found = o2 + highlight = set() if found is not None: + highlight.add(len(objectlist)) objectlist = objectlist + [found] else: print '*** NOTE: object not found' - return self.newpage(objectlist) + return self.newpage(objectlist, highlight) def formatobject(self, o): header = self.shortrepr(o, compact=False) @@ -106,8 +108,8 @@ def edgelabel(self, o1, o2): return '' - def newpage(self, objectlist): - return self.__class__(objectlist) + def newpage(self, *args): + return self.__class__(*args) class RefTrackerPage(BaseRefTrackerPage): From noreply at buildbot.pypy.org Thu Oct 18 10:34:39 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 10:34:39 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: WeakKeyDictionary does not seem to work Message-ID: <20121018083439.38B2D1C0502@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58194:4c23aeda02ca Date: 2012-10-18 10:34 +0200 http://bitbucket.org/pypy/pypy/changeset/4c23aeda02ca/ Log: WeakKeyDictionary does not seem to work diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -1,5 +1,3 @@ - -from weakref import WeakKeyDictionary from pypy.jit.backend import model from pypy.jit.backend.llgraph import support @@ -151,7 +149,6 @@ model.AbstractCPU.__init__(self) self.rtyper = rtyper self.llinterp = LLInterpreter(rtyper) - self.known_labels = WeakKeyDictionary() self.last_exception = None self.descrs = {} class MiniStats: @@ -183,7 +180,7 @@ for op in lltrace.operations] for i, op in enumerate(lltrace.operations): if op.getopnum() == rop.LABEL: - self.known_labels[op.getdescr()] = (lltrace, i) + op.getdescr()._llgraph_target = (lltrace, i) def invalidate_loop(self, looptoken): for trace in looptoken.compiled_loop_token._llgraph_alltraces: @@ -551,7 +548,7 @@ resval = getattr(self, 'execute_' + op.getopname())(op.getdescr(), *args) except Jump, j: - self.lltrace, i = self.cpu.known_labels[j.descr] + self.lltrace, i = j.descr._llgraph_target label_op = self.lltrace.operations[i] self.do_renaming(label_op.getarglist(), j.args) i += 1 From noreply at buildbot.pypy.org Thu Oct 18 10:43:11 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 10:43:11 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: fix the last test Message-ID: <20121018084311.88D7A1C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58195:d7ee947cd7bd Date: 2012-10-18 10:42 +0200 http://bitbucket.org/pypy/pypy/changeset/d7ee947cd7bd/ Log: fix the last test diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -786,7 +786,13 @@ return x def execute_debug_merge_point(self, descr, *args): - pass + from pypy.jit.metainterp.warmspot import get_stats + try: + stats = get_stats() + except AttributeError: + pass + else: + stats.add_merge_point_location(args[1:]) def execute_new_with_vtable(self, _, vtable): descr = heaptracker.vtable2descr(self.cpu, vtable) From noreply at buildbot.pypy.org Thu Oct 18 10:44:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 10:44:34 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: Skip two tests that are annoying in the new simplified llgraph backend. Message-ID: <20121018084434.7D9E31C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: cleanup-llgraph-backend Changeset: r58196:32c1fddcbb1a Date: 2012-10-18 10:44 +0200 http://bitbucket.org/pypy/pypy/changeset/32c1fddcbb1a/ Log: Skip two tests that are annoying in the new simplified llgraph backend. diff --git a/pypy/jit/metainterp/test/test_memmgr.py b/pypy/jit/metainterp/test/test_memmgr.py --- a/pypy/jit/metainterp/test/test_memmgr.py +++ b/pypy/jit/metainterp/test/test_memmgr.py @@ -117,7 +117,8 @@ # we should see only the loop and the entry bridge self.check_target_token_count(2) - def test_target_loop_kept_alive_or_not(self): + def XXXskipped_test_target_loop_kept_alive_or_not(self): + # SKIPPED: the llgraph backend keeps too much things alive myjitdriver = JitDriver(greens=['m'], reds=['n']) def g(m): n = 10 @@ -160,7 +161,8 @@ # we should see a loop for each call to g() self.check_enter_count(8 + 20*2) - def test_throw_away_old_loops(self): + def XXXskipped_test_throw_away_old_loops(self): + # SKIPPED: the llgraph backend keeps too much things alive myjitdriver = JitDriver(greens=['m'], reds=['n']) def g(m): n = 10 @@ -236,7 +238,6 @@ setattr(token.compiled_loop_token, key, 'STUBBED') del tokens, token import gc; gc.collect(); gc.collect(); gc.collect(); gc.collect() - import pdb;pdb.set_trace() # from pypy.translator.tool.reftracker import track # track(get_stats().jitcell_token_wrefs[8]()) # From noreply at buildbot.pypy.org Thu Oct 18 10:48:16 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 10:48:16 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: (fijal, arigo) remove the old llgraph backend Message-ID: <20121018084816.81BEE1C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58197:e49874fae436 Date: 2012-10-18 10:47 +0200 http://bitbucket.org/pypy/pypy/changeset/e49874fae436/ Log: (fijal, arigo) remove the old llgraph backend diff too long, truncating to 2000 out of 2922 lines diff --git a/pypy/jit/backend/llgraph/+runner.py b/pypy/jit/backend/llgraph/+runner.py deleted file mode 100644 --- a/pypy/jit/backend/llgraph/+runner.py +++ /dev/null @@ -1,912 +0,0 @@ -""" -Minimal-API wrapper around the llinterpreter to run operations. -""" - -from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.jit_hooks import LOOP_RUN_CONTAINER -from pypy.rpython.lltypesystem import lltype, llmemory, rclass -from pypy.rpython.ootypesystem import ootype -from pypy.rpython.llinterp import LLInterpreter -from pypy.jit.metainterp import history -from pypy.jit.metainterp.history import REF, INT, FLOAT, STRUCT -from pypy.jit.metainterp.warmstate import unwrap -from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend import model -from pypy.jit.backend.llgraph import llimpl, symbolic -from pypy.jit.metainterp.typesystem import llhelper, oohelper -from pypy.jit.codewriter import heaptracker, longlong - -class MiniStats: - pass - - -class Descr(history.AbstractDescr): - - def __init__(self, ofs, typeinfo, extrainfo=None, name=None, - arg_types=None, count_fields_if_immut=-1, ffi_flags=0, width=-1): - - self.ofs = ofs - self.width = width - self.typeinfo = typeinfo - self.extrainfo = extrainfo - self.name = name - self.arg_types = arg_types - self.count_fields_if_immut = count_fields_if_immut - self.ffi_flags = ffi_flags - self._debug = False - - def set_debug(self, v): - self._debug = True - - def get_arg_types(self): - return self.arg_types - - def get_result_type(self): - return self.typeinfo - - def get_extra_info(self): - return self.extrainfo - - def sort_key(self): - """Returns an integer that can be used as a key when sorting the - field descrs of a single structure. The property that this - number has is simply that two different field descrs of the same - structure give different numbers.""" - return self.ofs - - def is_pointer_field(self): - return self.typeinfo == REF - - def is_float_field(self): - return self.typeinfo == FLOAT - - def is_array_of_pointers(self): - return self.typeinfo == REF - - def is_array_of_floats(self): - return self.typeinfo == FLOAT - - def is_array_of_structs(self): - return self.typeinfo == STRUCT - - def as_vtable_size_descr(self): - return self - - def count_fields_if_immutable(self): - return self.count_fields_if_immut - - def get_ffi_flags(self): - return self.ffi_flags - - def __lt__(self, other): - raise TypeError("cannot use comparison on Descrs") - def __le__(self, other): - raise TypeError("cannot use comparison on Descrs") - def __gt__(self, other): - raise TypeError("cannot use comparison on Descrs") - def __ge__(self, other): - raise TypeError("cannot use comparison on Descrs") - - def __repr__(self): - args = [repr(self.ofs), repr(self.typeinfo)] - if self.name is not None: - args.append(repr(self.name)) - if self.extrainfo is not None: - args.append('E') - return '' % (', '.join(args),) - - -history.TreeLoop._compiled_version = lltype.nullptr(llimpl.COMPILEDLOOP.TO) - - -class BaseCPU(model.AbstractCPU): - supports_floats = True - supports_longlong = llimpl.IS_32_BIT - supports_singlefloats = True - - def __init__(self, rtyper, stats=None, opts=None, - translate_support_code=False, - annmixlevel=None, gcdescr=None): - assert type(opts) is not bool - model.AbstractCPU.__init__(self) - self.rtyper = rtyper - self.translate_support_code = translate_support_code - self.stats = stats or MiniStats() - self.stats.exec_counters = {} - self.stats.exec_jumps = 0 - self.stats.exec_conditional_jumps = 0 - llimpl._stats = self.stats - llimpl._llinterp = LLInterpreter(self.rtyper) - self._future_values = [] - self._descrs = {} - - def _cleanup_(self): - assert self.translate_support_code - - def getdescr(self, ofs, typeinfo='?', extrainfo=None, name=None, - arg_types=None, count_fields_if_immut=-1, ffi_flags=0, width=-1): - key = (ofs, typeinfo, extrainfo, name, arg_types, - count_fields_if_immut, ffi_flags, width) - try: - return self._descrs[key] - except KeyError: - descr = Descr(ofs, typeinfo, extrainfo, name, arg_types, - count_fields_if_immut, ffi_flags, width) - self._descrs[key] = descr - return descr - - def compile_bridge(self, faildescr, inputargs, operations, - original_loop_token, log=True): - c = llimpl.compile_start() - clt = original_loop_token.compiled_loop_token - clt.loop_and_bridges.append(c) - clt.compiling_a_bridge() - self._compile_loop_or_bridge(c, inputargs, operations, clt) - old, oldindex = faildescr._compiled_fail - llimpl.compile_redirect_fail(old, oldindex, c) - - def compile_loop(self, inputargs, operations, jitcell_token, - log=True, name=''): - """In a real assembler backend, this should assemble the given - list of operations. Here we just generate a similar CompiledLoop - instance. The code here is RPython, whereas the code in llimpl - is not. - """ - c = llimpl.compile_start() - clt = model.CompiledLoopToken(self, jitcell_token.number) - clt.loop_and_bridges = [c] - clt.compiled_version = c - jitcell_token.compiled_loop_token = clt - self._compile_loop_or_bridge(c, inputargs, operations, clt) - - def free_loop_and_bridges(self, compiled_loop_token): - for c in compiled_loop_token.loop_and_bridges: - llimpl.mark_as_free(c) - model.AbstractCPU.free_loop_and_bridges(self, compiled_loop_token) - - def _compile_loop_or_bridge(self, c, inputargs, operations, clt): - var2index = {} - for box in inputargs: - if isinstance(box, history.BoxInt): - var2index[box] = llimpl.compile_start_int_var(c) - elif isinstance(box, self.ts.BoxRef): - TYPE = self.ts.BASETYPE - var2index[box] = llimpl.compile_start_ref_var(c, TYPE) - elif isinstance(box, history.BoxFloat): - var2index[box] = llimpl.compile_start_float_var(c) - else: - raise Exception("box is: %r" % (box,)) - llimpl.compile_started_vars(clt) - self._compile_operations(c, operations, var2index, clt) - return c - - def _compile_operations(self, c, operations, var2index, clt): - for op in operations: - if op.getopnum() == -124: # force_spill - continue - llimpl.compile_add(c, op.getopnum()) - descr = op.getdescr() - if isinstance(descr, Descr): - llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo, - descr.arg_types, descr.extrainfo, - descr.width) - if isinstance(descr, history.JitCellToken): - assert op.getopnum() != rop.JUMP - llimpl.compile_add_loop_token(c, descr) - if isinstance(descr, history.TargetToken) and op.getopnum() == rop.LABEL: - llimpl.compile_add_target_token(c, descr, clt) - if self.is_oo and isinstance(descr, (OODescr, MethDescr)): - # hack hack, not rpython - c._obj.externalobj.operations[-1].setdescr(descr) - for i in range(op.numargs()): - x = op.getarg(i) - if isinstance(x, history.Box): - llimpl.compile_add_var(c, var2index[x]) - elif isinstance(x, history.ConstInt): - llimpl.compile_add_int_const(c, x.value) - elif isinstance(x, self.ts.ConstRef): - llimpl.compile_add_ref_const(c, x.value, self.ts.BASETYPE) - elif isinstance(x, history.ConstFloat): - llimpl.compile_add_float_const(c, x.value) - elif isinstance(x, Descr): - llimpl.compile_add_descr_arg(c, x.ofs, x.typeinfo, - x.arg_types) - else: - raise Exception("'%s' args contain: %r" % (op.getopname(), - x)) - if op.is_guard(): - faildescr = op.getdescr() - assert isinstance(faildescr, history.AbstractFailDescr) - faildescr._fail_args_types = [] - for box in op.getfailargs(): - if box is None: - type = history.HOLE - else: - type = box.type - faildescr._fail_args_types.append(type) - fail_index = self.get_fail_descr_number(faildescr) - index = llimpl.compile_add_fail(c, fail_index) - faildescr._compiled_fail = c, index - for box in op.getfailargs(): - if box is not None: - llimpl.compile_add_fail_arg(c, var2index[box]) - else: - llimpl.compile_add_fail_arg(c, -1) - - x = op.result - if x is not None: - if isinstance(x, history.BoxInt): - var2index[x] = llimpl.compile_add_int_result(c) - elif isinstance(x, self.ts.BoxRef): - var2index[x] = llimpl.compile_add_ref_result(c, self.ts.BASETYPE) - elif isinstance(x, history.BoxFloat): - var2index[x] = llimpl.compile_add_float_result(c) - else: - raise Exception("%s.result contain: %r" % (op.getopname(), - x)) - op = operations[-1] - assert op.is_final() - if op.getopnum() == rop.JUMP: - targettoken = op.getdescr() - llimpl.compile_add_jump_target(c, targettoken, clt) - elif op.getopnum() == rop.FINISH: - faildescr = op.getdescr() - index = self.get_fail_descr_number(faildescr) - llimpl.compile_add_fail(c, index) - else: - assert False, "unknown operation" - - def _execute_token(self, loop_token): - compiled_version = loop_token.compiled_loop_token.compiled_version - frame = llimpl.new_frame(self.is_oo, self) - # setup the frame - llimpl.frame_clear(frame, compiled_version) - # run the loop - fail_index = llimpl.frame_execute(frame) - # we hit a FAIL operation. - self.latest_frame = frame - return fail_index - - def make_execute_token(self, *argtypes): - nb_args = len(argtypes) - unroll_argtypes = unrolling_iterable(list(enumerate(argtypes))) - # - def execute_token(loop_token, *args): - assert len(args) == nb_args - for index, TYPE in unroll_argtypes: - x = args[index] - assert TYPE == lltype.typeOf(x) - if TYPE == lltype.Signed: - llimpl.set_future_value_int(index, x) - elif TYPE == llmemory.GCREF: - llimpl.set_future_value_ref(index, x) - elif TYPE == longlong.FLOATSTORAGE: - llimpl.set_future_value_float(index, x) - else: - assert 0 - # - fail_index = self._execute_token(loop_token) - return self.get_fail_descr_from_number(fail_index) - # - return execute_token - - def get_latest_value_int(self, index): - return llimpl.frame_int_getvalue(self.latest_frame, index) - - def get_latest_value_ref(self, index): - return llimpl.frame_ptr_getvalue(self.latest_frame, index) - - def get_latest_value_float(self, index): - return llimpl.frame_float_getvalue(self.latest_frame, index) - - def get_latest_value_count(self): - return llimpl.frame_get_value_count(self.latest_frame) - - def get_latest_force_token(self): - token = llimpl.get_frame_forced_token(self.latest_frame) - return heaptracker.adr2int(token) - - def clear_latest_values(self, count): - llimpl.frame_clear_latest_values(self.latest_frame, count) - - def redirect_call_assembler(self, oldlooptoken, newlooptoken): - if we_are_translated(): - raise ValueError("CALL_ASSEMBLER not supported") - llimpl.redirect_call_assembler(self, oldlooptoken, newlooptoken) - - def invalidate_loop(self, looptoken): - for loop in looptoken.compiled_loop_token.loop_and_bridges: - loop._obj.externalobj.invalid = True - - # ---------- - - def sizeof(self, S): - assert not isinstance(S, lltype.Ptr) - count = heaptracker.count_fields_if_immutable(S) - return self.getdescr(symbolic.get_size(S), count_fields_if_immut=count) - - -class LLtypeCPU(BaseCPU): - is_oo = False - ts = llhelper - - def __init__(self, *args, **kwds): - BaseCPU.__init__(self, *args, **kwds) - self.fielddescrof_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr') - - def fielddescrof(self, S, fieldname): - ofs, size = symbolic.get_field_token(S, fieldname) - token = history.getkind(getattr(S, fieldname)) - return self.getdescr(ofs, token[0], name=fieldname) - - def interiorfielddescrof(self, A, fieldname): - S = A.OF - width = symbolic.get_size(A) - ofs, size = symbolic.get_field_token(S, fieldname) - token = history.getkind(getattr(S, fieldname)) - return self.getdescr(ofs, token[0], name=fieldname, width=width) - - def calldescrof(self, FUNC, ARGS, RESULT, extrainfo): - arg_types = [] - for ARG in ARGS: - token = history.getkind(ARG) - if token != 'void': - if token == 'float' and longlong.is_longlong(ARG): - token = 'L' - arg_types.append(token[0]) - token = history.getkind(RESULT) - if token == 'float' and longlong.is_longlong(RESULT): - token = 'L' - return self.getdescr(0, token[0], extrainfo=extrainfo, - arg_types=''.join(arg_types)) - - def calldescrof_dynamic(self, cif_description, extrainfo): - from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind - from pypy.jit.backend.llsupport.ffisupport import UnsupportedKind - arg_types = [] - try: - for itp in range(cif_description.nargs): - arg = cif_description.atypes[itp] - kind = get_ffi_type_kind(self, arg) - if kind != history.VOID: - arg_types.append(kind) - reskind = get_ffi_type_kind(self, cif_description.rtype) - except UnsupportedKind: - return None - return self.getdescr(0, reskind, extrainfo=extrainfo, - arg_types=''.join(arg_types), - ffi_flags=cif_description.abi) - - def _calldescr_dynamic_for_tests(self, atypes, rtype, - abiname='FFI_DEFAULT_ABI'): - from pypy.jit.backend.llsupport import ffisupport - return ffisupport.calldescr_dynamic_for_tests(self, atypes, rtype, - abiname) - - def grab_exc_value(self): - return llimpl.grab_exc_value() - - def arraydescrof(self, A): - assert A.OF != lltype.Void - assert isinstance(A, lltype.GcArray) or A._hints.get('nolength', False) - size = symbolic.get_size(A) - if isinstance(A.OF, lltype.Ptr) or isinstance(A.OF, lltype.Primitive): - token = history.getkind(A.OF)[0] - elif isinstance(A.OF, lltype.Struct): - token = 's' - else: - token = '?' - return self.getdescr(size, token) - - # ---------- the backend-dependent operations ---------- - - def bh_strlen(self, string): - return llimpl.do_strlen(string) - - def bh_strgetitem(self, string, index): - return llimpl.do_strgetitem(string, index) - - def bh_unicodelen(self, string): - return llimpl.do_unicodelen(string) - - def bh_unicodegetitem(self, string, index): - return llimpl.do_unicodegetitem(string, index) - - def bh_getarrayitem_gc_i(self, arraydescr, array, index): - assert isinstance(arraydescr, Descr) - return llimpl.do_getarrayitem_gc_int(array, index) - def bh_getarrayitem_raw_i(self, arraydescr, array, index): - assert isinstance(arraydescr, Descr) - return llimpl.do_getarrayitem_raw_int(array, index, arraydescr.ofs) - def bh_getarrayitem_gc_r(self, arraydescr, array, index): - assert isinstance(arraydescr, Descr) - return llimpl.do_getarrayitem_gc_ptr(array, index) - def bh_getarrayitem_gc_f(self, arraydescr, array, index): - assert isinstance(arraydescr, Descr) - return llimpl.do_getarrayitem_gc_float(array, index) - def bh_getarrayitem_raw_f(self, arraydescr, array, index): - assert isinstance(arraydescr, Descr) - return llimpl.do_getarrayitem_raw_float(array, index) - - def bh_getfield_gc_i(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_gc_int(struct, fielddescr.ofs) - def bh_getfield_gc_r(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs) - def bh_getfield_gc_f(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_gc_float(struct, fielddescr.ofs) - - def bh_getfield_raw_i(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_raw_int(struct, fielddescr.ofs) - def bh_getfield_raw_r(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_raw_ptr(struct, fielddescr.ofs) - def bh_getfield_raw_f(self, struct, fielddescr): - assert isinstance(fielddescr, Descr) - return llimpl.do_getfield_raw_float(struct, fielddescr.ofs) - - def bh_getinteriorfield_gc_i(self, array, index, descr): - assert isinstance(descr, Descr) - return llimpl.do_getinteriorfield_gc_int(array, index, descr.ofs) - def bh_getinteriorfield_gc_r(self, array, index, descr): - assert isinstance(descr, Descr) - return llimpl.do_getinteriorfield_gc_ptr(array, index, descr.ofs) - def bh_getinteriorfield_gc_f(self, array, index, descr): - assert isinstance(descr, Descr) - return llimpl.do_getinteriorfield_gc_float(array, index, descr.ofs) - - def bh_setinteriorfield_gc_i(self, array, index, descr, value): - assert isinstance(descr, Descr) - return llimpl.do_setinteriorfield_gc_int(array, index, descr.ofs, - value) - def bh_setinteriorfield_gc_r(self, array, index, descr, value): - assert isinstance(descr, Descr) - return llimpl.do_setinteriorfield_gc_ptr(array, index, descr.ofs, - value) - def bh_setinteriorfield_gc_f(self, array, index, descr, value): - assert isinstance(descr, Descr) - return llimpl.do_setinteriorfield_gc_float(array, index, descr.ofs, - value) - - def bh_raw_store_i(self, struct, offset, descr, newvalue): - assert isinstance(descr, Descr) - return llimpl.do_raw_store_int(struct, offset, descr.ofs, newvalue) - def bh_raw_store_f(self, struct, offset, descr, newvalue): - assert isinstance(descr, Descr) - return llimpl.do_raw_store_float(struct, offset, newvalue) - def bh_raw_load_i(self, struct, offset, descr): - assert isinstance(descr, Descr) - return llimpl.do_raw_load_int(struct, offset, descr.ofs) - def bh_raw_load_f(self, struct, offset, descr): - assert isinstance(descr, Descr) - return llimpl.do_raw_load_float(struct, offset) - - def bh_new(self, sizedescr): - assert isinstance(sizedescr, Descr) - return llimpl.do_new(sizedescr.ofs) - - def bh_new_with_vtable(self, sizedescr, vtable): - assert isinstance(sizedescr, Descr) - result = llimpl.do_new(sizedescr.ofs) - llimpl.do_setfield_gc_int(result, self.fielddescrof_vtable.ofs, vtable) - return result - - def bh_classof(self, struct): - struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) - result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) - return heaptracker.adr2int(result_adr) - - def bh_new_array(self, arraydescr, length): - assert isinstance(arraydescr, Descr) - return llimpl.do_new_array(arraydescr.ofs, length) - - def bh_arraylen_gc(self, arraydescr, array): - assert isinstance(arraydescr, Descr) - return llimpl.do_arraylen_gc(arraydescr, array) - - def bh_setarrayitem_gc_i(self, arraydescr, array, index, newvalue): - assert isinstance(arraydescr, Descr) - llimpl.do_setarrayitem_gc_int(array, index, newvalue) - - def bh_setarrayitem_raw_i(self, arraydescr, array, index, newvalue): - assert isinstance(arraydescr, Descr) - llimpl.do_setarrayitem_raw_int(array, index, newvalue, arraydescr.ofs) - - def bh_setarrayitem_gc_r(self, arraydescr, array, index, newvalue): - assert isinstance(arraydescr, Descr) - llimpl.do_setarrayitem_gc_ptr(array, index, newvalue) - - def bh_setarrayitem_gc_f(self, arraydescr, array, index, newvalue): - assert isinstance(arraydescr, Descr) - llimpl.do_setarrayitem_gc_float(array, index, newvalue) - - def bh_setarrayitem_raw_f(self, arraydescr, array, index, newvalue): - assert isinstance(arraydescr, Descr) - llimpl.do_setarrayitem_raw_float(array, index, newvalue) - - def bh_setfield_gc_i(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_gc_int(struct, fielddescr.ofs, newvalue) - def bh_setfield_gc_r(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) - def bh_setfield_gc_f(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_gc_float(struct, fielddescr.ofs, newvalue) - - def bh_setfield_raw_i(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_raw_int(struct, fielddescr.ofs, newvalue) - def bh_setfield_raw_r(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue) - def bh_setfield_raw_f(self, struct, fielddescr, newvalue): - assert isinstance(fielddescr, Descr) - llimpl.do_setfield_raw_float(struct, fielddescr.ofs, newvalue) - - def bh_newstr(self, length): - return llimpl.do_newstr(length) - - def bh_newunicode(self, length): - return llimpl.do_newunicode(length) - - def bh_strsetitem(self, string, index, newvalue): - llimpl.do_strsetitem(string, index, newvalue) - - def bh_unicodesetitem(self, string, index, newvalue): - llimpl.do_unicodesetitem(string, index, newvalue) - - def bh_call_i(self, func, calldescr, args_i, args_r, args_f): - self._prepare_call(INT, calldescr, args_i, args_r, args_f) - return llimpl.do_call_int(func) - def bh_call_r(self, func, calldescr, args_i, args_r, args_f): - self._prepare_call(REF, calldescr, args_i, args_r, args_f) - return llimpl.do_call_ptr(func) - def bh_call_f(self, func, calldescr, args_i, args_r, args_f): - self._prepare_call(FLOAT + 'L', calldescr, args_i, args_r, args_f) - return llimpl.do_call_float(func) - def bh_call_v(self, func, calldescr, args_i, args_r, args_f): - self._prepare_call('v', calldescr, args_i, args_r, args_f) - llimpl.do_call_void(func) - - def _prepare_call(self, resulttypeinfo, calldescr, args_i, args_r, args_f): - assert isinstance(calldescr, Descr) - assert calldescr.typeinfo in resulttypeinfo - if args_i is not None: - for x in args_i: - llimpl.do_call_pushint(x) - if args_r is not None: - for x in args_r: - llimpl.do_call_pushptr(x) - if args_f is not None: - for x in args_f: - llimpl.do_call_pushfloat(x) - - def get_all_loop_runs(self): - return lltype.malloc(LOOP_RUN_CONTAINER, 0) - - def force(self, force_token): - token = llmemory.cast_int_to_adr(force_token) - frame = llimpl.get_forced_token_frame(token) - fail_index = llimpl.force(frame) - self.latest_frame = frame - return self.get_fail_descr_from_number(fail_index) - - -class OOtypeCPU_xxx_disabled(BaseCPU): - is_oo = True - ts = oohelper - - @staticmethod - def fielddescrof(T, fieldname): - # use class where the field is really defined as a key - T1, _ = T._lookup_field(fieldname) - return FieldDescr.new(T1, fieldname) - - @staticmethod - def calldescrof(FUNC, ARGS, RESULT, extrainfo): - return StaticMethDescr.new(FUNC, ARGS, RESULT, extrainfo) - - @staticmethod - def methdescrof(SELFTYPE, methname): - return MethDescr.new(SELFTYPE, methname) - - @staticmethod - def typedescrof(TYPE): - return TypeDescr.new(TYPE) - - @staticmethod - def arraydescrof(A): - assert isinstance(A, ootype.Array) - TYPE = A.ITEM - return TypeDescr.new(TYPE) - - def typedescr2classbox(self, descr): - assert isinstance(descr, TypeDescr) - return history.ConstObj(ootype.cast_to_object( - ootype.runtimeClass(descr.TYPE))) - - def get_exception(self): - if llimpl._last_exception: - e = llimpl._last_exception.args[0] - return ootype.cast_to_object(e) - else: - return ootype.NULL - - def get_exc_value(self): - if llimpl._last_exception: - earg = llimpl._last_exception.args[1] - return ootype.cast_to_object(earg) - else: - return ootype.NULL - - def get_overflow_error(self): - ll_err = llimpl._get_error(OverflowError) - return (ootype.cast_to_object(ll_err.args[0]), - ootype.cast_to_object(ll_err.args[1])) - - def get_zero_division_error(self): - ll_err = llimpl._get_error(ZeroDivisionError) - return (ootype.cast_to_object(ll_err.args[0]), - ootype.cast_to_object(ll_err.args[1])) - - def do_new_with_vtable(self, clsbox): - cls = clsbox.getref_base() - typedescr = self.class_sizes[cls] - return typedescr.create() - - def do_new_array(self, lengthbox, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.create_array(lengthbox) - - def do_new(self, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.create() - - def do_runtimenew(self, classbox): - "NOT_RPYTHON" - classobj = classbox.getref(ootype.Class) - res = ootype.runtimenew(classobj) - return history.BoxObj(ootype.cast_to_object(res)) - - def do_instanceof(self, box1, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.instanceof(box1) - - def do_getfield_gc(self, box1, fielddescr): - assert isinstance(fielddescr, FieldDescr) - return fielddescr.getfield(box1) - - def do_setfield_gc(self, box1, box2, fielddescr): - assert isinstance(fielddescr, FieldDescr) - return fielddescr.setfield(box1, box2) - - def do_getarrayitem_gc(self, box1, box2, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.getarrayitem(box1, box2) - - def do_setarrayitem_gc(self, box1, box2, box3, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.setarrayitem(box1, box2, box3) - - def do_arraylen_gc(self, box1, typedescr): - assert isinstance(typedescr, TypeDescr) - return typedescr.getarraylength(box1) - - def do_call_XXX(self, args, descr): - assert isinstance(descr, StaticMethDescr) - funcbox = args[0] - argboxes = args[1:] - x = descr.callfunc(funcbox, argboxes) - # XXX: return None if RESULT is Void - return x - - def do_oosend(self, args, descr): - assert isinstance(descr, MethDescr) - selfbox = args[0] - argboxes = args[1:] - x = descr.callmeth(selfbox, argboxes) - # XXX: return None if METH.RESULT is Void - return x - - -def make_getargs(ARGS): - argsiter = unrolling_iterable(ARGS) - args_n = len([ARG for ARG in ARGS if ARG is not ootype.Void]) - def getargs(argboxes): - funcargs = () - assert len(argboxes) == args_n - i = 0 - for ARG in argsiter: - if ARG is ootype.Void: - funcargs += (None,) - else: - box = argboxes[i] - i+=1 - funcargs += (unwrap(ARG, box),) - return funcargs - return getargs - -def boxresult(RESULT, result): - if isinstance(RESULT, ootype.OOType): - return history.BoxObj(ootype.cast_to_object(result)) - elif RESULT is lltype.Float: - return history.BoxFloat(result) - else: - return history.BoxInt(lltype.cast_primitive(ootype.Signed, result)) -boxresult._annspecialcase_ = 'specialize:arg(0)' - - -class KeyManager(object): - """ - Helper class to convert arbitrary dictionary keys to integers. - """ - - def __init__(self): - self.keys = {} - - def getkey(self, key): - try: - return self.keys[key] - except KeyError: - n = len(self.keys) - self.keys[key] = n - return n - - def _freeze_(self): - raise Exception("KeyManager is not supposed to be turned into a pbc") - - -descr_cache = {} -class OODescr(history.AbstractDescr): - - @classmethod - def new(cls, *args): - 'NOT_RPYTHON' - key = (cls, args) - try: - return descr_cache[key] - except KeyError: - res = cls(*args) - descr_cache[key] = res - return res - -class StaticMethDescr(OODescr): - - def __init__(self, FUNC, ARGS, RESULT, extrainfo=None): - self.FUNC = FUNC - getargs = make_getargs(FUNC.ARGS) - def callfunc(funcbox, argboxes): - funcobj = funcbox.getref(FUNC) - funcargs = getargs(argboxes) - res = llimpl.call_maybe_on_top_of_llinterp(funcobj, funcargs) - if RESULT is not ootype.Void: - return boxresult(RESULT, res) - self.callfunc = callfunc - self.extrainfo = extrainfo - - def get_extra_info(self): - return self.extrainfo - -class MethDescr(history.AbstractMethDescr): - - callmeth = None - - new = classmethod(OODescr.new.im_func) - - def __init__(self, SELFTYPE, methname): - _, meth = SELFTYPE._lookup(methname) - METH = ootype.typeOf(meth) - self.SELFTYPE = SELFTYPE - self.METH = METH - self.methname = methname - RESULT = METH.RESULT - getargs = make_getargs(METH.ARGS) - def callmeth(selfbox, argboxes): - selfobj = selfbox.getref(SELFTYPE) - meth = getattr(selfobj, methname) - methargs = getargs(argboxes) - res = llimpl.call_maybe_on_top_of_llinterp(meth, methargs) - if RESULT is not ootype.Void: - return boxresult(RESULT, res) - self.callmeth = callmeth - - def __repr__(self): - return '' % self.methname - -class TypeDescr(OODescr): - - create = None - - def __init__(self, TYPE): - self.TYPE = TYPE - self.ARRAY = ARRAY = ootype.Array(TYPE) - def create(): - return boxresult(TYPE, ootype.new(TYPE)) - - def create_array(lengthbox): - n = lengthbox.getint() - return boxresult(ARRAY, ootype.oonewarray(ARRAY, n)) - - def getarrayitem(arraybox, ibox): - array = arraybox.getref(ARRAY) - i = ibox.getint() - return boxresult(TYPE, array.ll_getitem_fast(i)) - - def setarrayitem(arraybox, ibox, valuebox): - array = arraybox.getref(ARRAY) - i = ibox.getint() - value = unwrap(TYPE, valuebox) - array.ll_setitem_fast(i, value) - - def getarraylength(arraybox): - array = arraybox.getref(ARRAY) - return boxresult(ootype.Signed, array.ll_length()) - - def instanceof(box): - obj = box.getref(ootype.ROOT) - return history.BoxInt(ootype.instanceof(obj, TYPE)) - - self.create = create - self.create_array = create_array - self.getarrayitem = getarrayitem - self.setarrayitem = setarrayitem - self.getarraylength = getarraylength - self.instanceof = instanceof - self._is_array_of_pointers = (history.getkind(TYPE) == 'ref') - self._is_array_of_floats = (history.getkind(TYPE) == 'float') - - def is_array_of_pointers(self): - # for arrays, TYPE is the type of the array item. - return self._is_array_of_pointers - - def is_array_of_floats(self): - # for arrays, TYPE is the type of the array item. - return self._is_array_of_floats - - def __repr__(self): - return '' % self.TYPE._short_name() - -class FieldDescr(OODescr): - - getfield = None - _keys = KeyManager() - - def __init__(self, TYPE, fieldname): - self.TYPE = TYPE - self.fieldname = fieldname - - _, T = TYPE._lookup_field(fieldname) - def getfield(objbox): - obj = objbox.getref(TYPE) - value = getattr(obj, fieldname) - return boxresult(T, value) - def setfield(objbox, valuebox): - obj = objbox.getref(TYPE) - value = unwrap(T, valuebox) - setattr(obj, fieldname, value) - - self.getfield = getfield - self.setfield = setfield - self._is_pointer_field = (history.getkind(T) == 'ref') - self._is_float_field = (history.getkind(T) == 'float') - - def sort_key(self): - return self._keys.getkey((self.TYPE, self.fieldname)) - - def is_pointer_field(self): - return self._is_pointer_field - - def is_float_field(self): - return self._is_float_field - - def equals(self, other): - return self.TYPE == other.TYPE and \ - self.fieldname == other.fieldname - - def __repr__(self): - return '' % self.fieldname diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py deleted file mode 100644 --- a/pypy/jit/backend/llgraph/llimpl.py +++ /dev/null @@ -1,1968 +0,0 @@ -""" -The non-RPythonic part of the llgraph backend. -This contains all the code that is directly run -when executing on top of the llinterpreter. -""" - -import weakref -from pypy.objspace.flow.model import Variable, Constant -from pypy.annotation import model as annmodel -from pypy.jit.metainterp.history import REF, INT, FLOAT -from pypy.jit.metainterp import history -from pypy.jit.codewriter import heaptracker -from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr, rffi -from pypy.rpython.ootypesystem import ootype -from pypy.rpython.module.support import LLSupport, OOSupport -from pypy.rpython.llinterp import LLException -from pypy.rpython.extregistry import ExtRegistryEntry - -from pypy.jit.metainterp import resoperation -from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.llgraph import symbolic -from pypy.jit.codewriter import longlong -from pypy.jit.codewriter.effectinfo import EffectInfo - -from pypy.rlib.objectmodel import ComputedIntSymbolic, we_are_translated -from pypy.rlib.rarithmetic import ovfcheck -from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint -from pypy.rlib.rtimer import read_timestamp - -import py -from pypy.tool.ansi_print import ansi_log -log = py.log.Producer('runner') -py.log.setconsumer('runner', ansi_log) - -IS_32_BIT = r_ulonglong is not r_uint - - -def _from_opaque(opq): - return opq._obj.externalobj - -_TO_OPAQUE = {} - -def _to_opaque(value): - try: - return value._the_opaque_pointer - except AttributeError: - op = lltype.opaqueptr(_TO_OPAQUE[value.__class__], 'opaque', - externalobj=value) - value._the_opaque_pointer = op - return op - -def _normalize(value): - if isinstance(value, lltype._ptr): - value = lltype.top_container(value._obj) - return value - -def from_opaque_string(s): - if isinstance(s, str): - return s - elif isinstance(s, ootype._string): - return OOSupport.from_rstr(s) - else: - return LLSupport.from_rstr(s) - -FLOAT_ARRAY_TP = lltype.Ptr(lltype.Array(lltype.Float, hints={"nolength": True})) -def maybe_uncast(TP, array): - if array._TYPE.TO.OF != lltype.Float: - # array._TYPE.TO._hints.get("uncast_on_llgraph"): - array = rffi.cast(TP, array) - return array - -# a list of argtypes of all operations - couldn't find any and it's -# very useful. Note however that the table is half-broken here and -# there, in ways that are sometimes a bit hard to fix; that's why -# it is not "official". -TYPES = { - 'int_add' : (('int', 'int'), 'int'), - 'int_sub' : (('int', 'int'), 'int'), - 'int_mul' : (('int', 'int'), 'int'), - 'int_floordiv' : (('int', 'int'), 'int'), - 'int_mod' : (('int', 'int'), 'int'), - 'int_and' : (('int', 'int'), 'int'), - 'int_or' : (('int', 'int'), 'int'), - 'int_xor' : (('int', 'int'), 'int'), - 'int_lshift' : (('int', 'int'), 'int'), - 'int_rshift' : (('int', 'int'), 'int'), - 'int_lt' : (('int', 'int'), 'bool'), - 'int_gt' : (('int', 'int'), 'bool'), - 'int_ge' : (('int', 'int'), 'bool'), - 'int_le' : (('int', 'int'), 'bool'), - 'int_eq' : (('int', 'int'), 'bool'), - 'int_ne' : (('int', 'int'), 'bool'), - 'int_is_true' : (('int',), 'bool'), - 'int_is_zero' : (('int',), 'bool'), - 'int_neg' : (('int',), 'int'), - 'int_invert' : (('int',), 'int'), - 'int_add_ovf' : (('int', 'int'), 'int'), - 'int_sub_ovf' : (('int', 'int'), 'int'), - 'int_mul_ovf' : (('int', 'int'), 'int'), - 'int_force_ge_zero':(('int',), 'int'), - 'uint_add' : (('int', 'int'), 'int'), - 'uint_sub' : (('int', 'int'), 'int'), - 'uint_mul' : (('int', 'int'), 'int'), - 'uint_lt' : (('int', 'int'), 'bool'), - 'uint_le' : (('int', 'int'), 'bool'), - 'uint_eq' : (('int', 'int'), 'bool'), - 'uint_ne' : (('int', 'int'), 'bool'), - 'uint_gt' : (('int', 'int'), 'bool'), - 'uint_ge' : (('int', 'int'), 'bool'), - 'uint_xor' : (('int', 'int'), 'int'), - 'uint_rshift' : (('int', 'int'), 'int'), - 'uint_floordiv' : (('int', 'int'), 'int'), - 'float_add' : (('float', 'float'), 'float'), - 'float_sub' : (('float', 'float'), 'float'), - 'float_mul' : (('float', 'float'), 'float'), - 'float_truediv' : (('float', 'float'), 'float'), - 'float_lt' : (('float', 'float'), 'bool'), - 'float_le' : (('float', 'float'), 'bool'), - 'float_eq' : (('float', 'float'), 'bool'), - 'float_ne' : (('float', 'float'), 'bool'), - 'float_gt' : (('float', 'float'), 'bool'), - 'float_ge' : (('float', 'float'), 'bool'), - 'float_neg' : (('float',), 'float'), - 'float_abs' : (('float',), 'float'), - 'cast_float_to_int':(('float',), 'int'), - 'cast_int_to_float':(('int',), 'float'), - 'same_as' : (('int',), 'int'), # could also be ptr=>ptr - 'new_with_vtable' : (('ref',), 'ref'), - 'new' : ((), 'ref'), - 'new_array' : (('int',), 'ref'), - 'oois' : (('ref', 'ref'), 'bool'), - 'ooisnot' : (('ref', 'ref'), 'bool'), - 'instanceof' : (('ref',), 'bool'), - 'subclassof' : (('ref', 'ref'), 'bool'), - 'runtimenew' : (('ref',), 'ref'), - 'setfield_gc' : (('ref', 'intorptr'), None), - 'getfield_gc' : (('ref',), 'intorptr'), - 'getfield_gc_pure': (('ref',), 'intorptr'), - 'setfield_raw' : (('ref', 'intorptr'), None), - 'getfield_raw' : (('ref',), 'intorptr'), - 'getfield_raw_pure': (('ref',), 'intorptr'), - 'setarrayitem_gc' : (('ref', 'int', 'intorptr'), None), - 'getarrayitem_gc' : (('ref', 'int'), 'intorptr'), - 'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'), - 'setarrayitem_raw' : (('ref', 'int', 'intorptr'), None), - 'getarrayitem_raw' : (('ref', 'int'), 'intorptr'), - 'getarrayitem_raw_pure' : (('ref', 'int'), 'intorptr'), - 'arraylen_gc' : (('ref',), 'int'), - 'call' : (('ref', 'varargs'), 'intorptr'), - 'call_assembler' : (('varargs',), 'intorptr'), - 'cond_call_gc_wb' : (('ptr', 'ptr'), None), - 'cond_call_gc_wb_array': (('ptr', 'int', 'ptr'), None), - 'oosend' : (('varargs',), 'intorptr'), - 'oosend_pure' : (('varargs',), 'intorptr'), - 'guard_true' : (('bool',), None), - 'guard_false' : (('bool',), None), - 'guard_value' : (('int', 'int'), None), - 'guard_class' : (('ref', 'ref'), None), - 'guard_no_exception' : ((), None), - 'guard_exception' : (('ref',), 'ref'), - 'guard_no_overflow' : ((), None), - 'guard_overflow' : ((), None), - 'guard_nonnull' : (('ref',), None), - 'guard_isnull' : (('ref',), None), - 'guard_nonnull_class' : (('ref', 'ref'), None), - 'newstr' : (('int',), 'ref'), - 'strlen' : (('ref',), 'int'), - 'strgetitem' : (('ref', 'int'), 'int'), - 'strsetitem' : (('ref', 'int', 'int'), None), - 'newunicode' : (('int',), 'ref'), - 'unicodelen' : (('ref',), 'int'), - 'unicodegetitem' : (('ref', 'int'), 'int'), - 'unicodesetitem' : (('ref', 'int', 'int'), 'int'), - 'cast_ptr_to_int' : (('ref',), 'int'), - 'cast_int_to_ptr' : (('int',), 'ref'), - 'debug_merge_point': (('ref', 'int', 'int'), None), - 'force_token' : ((), 'int'), - 'call_may_force' : (('int', 'varargs'), 'intorptr'), - 'guard_not_forced': ((), None), -} - -# ____________________________________________________________ - -class CompiledLoop(object): - has_been_freed = False - invalid = False - - def __init__(self): - self.inputargs = [] - self.operations = [] - - def getargtypes(self): - return [v.concretetype for v in self.inputargs] - - def __repr__(self): - lines = [] - self.as_text(lines, 1) - return 'CompiledLoop %s:\n%s' % (self.inputargs, '\n'.join(lines)) - - def as_text(self, lines, indent): - for op in self.operations: - lines.append('\t'*indent + repr(op)) - -class Operation(object): - result = None - descr = None - jump_target = None - fail_args = None - - def __init__(self, opnum): - self.opnum = opnum - self.args = [] - - def __repr__(self): - if self.result is not None: - sres = repr0(self.result) + ' = ' - else: - sres = '' - return '{%s%s(%s)}' % (sres, self.getopname(), - ', '.join(map(repr0, self.args))) - - def getopname(self): - try: - return resoperation.opname[self.opnum] - except KeyError: - return '<%d>' % self.opnum - - def is_guard(self): - return rop._GUARD_FIRST <= self.opnum <= rop._GUARD_LAST - - def is_final(self): - return rop._FINAL_FIRST <= self.opnum <= rop._FINAL_LAST - -def repr0(x): - if isinstance(x, list): - return '[' + ', '.join(repr0(y) for y in x) + ']' - elif isinstance(x, Constant): - return '(' + repr0(x.value) + ')' - elif isinstance(x, lltype._ptr): - x = llmemory.cast_ptr_to_adr(x) - if x.ptr: - try: - container = x.ptr._obj._normalizedcontainer() - return '* %s' % (container._TYPE._short_name(),) - except AttributeError: - return repr(x) - else: - return 'NULL' - else: - return repr(x) - -def repr_list(lst, types): - res_l = [] - if types and types[-1] == 'varargs': - types = types[:-1] + ('int',) * (len(lst) - len(types) + 1) - assert len(types) == len(lst) - for elem, tp in zip(lst, types): - if isinstance(elem, Constant): - res_l.append('(%s)' % repr1(elem, tp)) - else: - res_l.append(repr1(elem, tp)) - return '[%s]' % (', '.join(res_l)) - -def repr1(x, tp): - if tp == "intorptr": - TYPE = lltype.typeOf(x) - if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc': - tp = "ref" - else: - tp = "int" - if tp == 'int': - return str(x) - elif tp == 'void': - return '---' - elif tp == 'ref': - if not x: - return '(* None)' - if isinstance(x, int): - # XXX normalize? - ptr = str(llmemory.cast_int_to_adr(x)) - elif isinstance(ootype.typeOf(x), ootype.OOType): - return repr(x) - else: - if getattr(x, '_fake', None): - return repr(x) - if lltype.typeOf(x) == llmemory.GCREF: - TP = lltype.Ptr(lltype.typeOf(x._obj.container)) - ptr = lltype.cast_opaque_ptr(TP, x) - else: - ptr = x - try: - container = ptr._obj._normalizedcontainer() - return '(* %s)' % (container._TYPE._short_name(),) - except AttributeError: - return '(%r)' % (ptr,) - elif tp == 'bool': - assert x == 0 or x == 1 - return str(bool(x)) - #elif tp == 'fieldname': - # return str(symbolic.TokenToField[x...][1]) - elif tp == 'float': - return str(x) - else: - raise NotImplementedError("tp = %s" % tp) - -_variables = [] - -def compile_start(): - del _variables[:] - return _to_opaque(CompiledLoop()) - -def mark_as_free(loop): - loop = _from_opaque(loop) - assert not loop.has_been_freed - loop.has_been_freed = True - -def compile_start_int_var(loop): - return compile_start_ref_var(loop, lltype.Signed) - -def compile_start_float_var(loop): - return compile_start_ref_var(loop, longlong.FLOATSTORAGE) - -def compile_start_ref_var(loop, TYPE): - loop = _from_opaque(loop) - assert not loop.operations - v = Variable() - v.concretetype = TYPE - loop.inputargs.append(v) - r = len(_variables) - _variables.append(v) - return r - -def compile_started_vars(clt): - if not hasattr(clt, '_debug_argtypes'): # only when compiling the loop - argtypes = [v.concretetype for v in _variables] - try: - clt._debug_argtypes = argtypes - except AttributeError: # when 'clt' is actually a translated - pass # GcStruct - -def compile_add(loop, opnum): - loop = _from_opaque(loop) - loop.operations.append(Operation(opnum)) - -def compile_add_descr(loop, ofs, type, arg_types, extrainfo, width): - from pypy.jit.backend.llgraph.runner import Descr - loop = _from_opaque(loop) - op = loop.operations[-1] - assert isinstance(type, str) and len(type) == 1 - op.descr = Descr(ofs, type, arg_types=arg_types, extrainfo=extrainfo, width=width) - -def compile_add_descr_arg(loop, ofs, type, arg_types): - from pypy.jit.backend.llgraph.runner import Descr - loop = _from_opaque(loop) - op = loop.operations[-1] - assert isinstance(type, str) and len(type) == 1 - op.args.append(Descr(ofs, type, arg_types=arg_types)) - -def compile_add_loop_token(loop, descr): - if we_are_translated(): - raise ValueError("CALL_ASSEMBLER not supported") - loop = _from_opaque(loop) - op = loop.operations[-1] - op.descr = weakref.ref(descr) - -TARGET_TOKENS = weakref.WeakKeyDictionary() - -def compile_add_target_token(loop, descr, clt): - # here, 'clt' is the compiled_loop_token of the original loop that - # we are compiling - loop = _from_opaque(loop) - op = loop.operations[-1] - descrobj = _normalize(descr) - TARGET_TOKENS[descrobj] = loop, len(loop.operations), op.args, clt - -def compile_add_var(loop, intvar): - loop = _from_opaque(loop) - op = loop.operations[-1] - op.args.append(_variables[intvar]) - -def compile_add_int_const(loop, value): - compile_add_ref_const(loop, value, lltype.Signed) - -def compile_add_float_const(loop, value): - compile_add_ref_const(loop, value, longlong.FLOATSTORAGE) - -def compile_add_ref_const(loop, value, TYPE): - loop = _from_opaque(loop) - const = Constant(value) - const.concretetype = TYPE - op = loop.operations[-1] - op.args.append(const) - -def compile_add_int_result(loop): - return compile_add_ref_result(loop, lltype.Signed) - -def compile_add_float_result(loop): - return compile_add_ref_result(loop, longlong.FLOATSTORAGE) - -def compile_add_ref_result(loop, TYPE): - loop = _from_opaque(loop) - v = Variable() - v.concretetype = TYPE - op = loop.operations[-1] - op.result = v - r = len(_variables) - _variables.append(v) - return r - -def compile_add_jump_target(loop, targettoken, source_clt): - loop = _from_opaque(loop) - descrobj = _normalize(targettoken) - (loop_target, target_opindex, target_inputargs, target_clt - ) = TARGET_TOKENS[descrobj] - # - try: - assert source_clt._debug_argtypes == target_clt._debug_argtypes - except AttributeError: # when translated - pass - # - op = loop.operations[-1] - op.jump_target = loop_target - op.jump_target_opindex = target_opindex - op.jump_target_inputargs = target_inputargs - assert op.opnum == rop.JUMP - assert [v.concretetype for v in op.args] == ( - [v.concretetype for v in target_inputargs]) - # - if loop_target == loop: - log.info("compiling new loop") - else: - log.info("compiling new bridge") - -def compile_add_guard_jump_target(loop, loop_target): - loop = _from_opaque(loop) - loop_target = _from_opaque(loop_target) - op = loop.operations[-1] - assert op.is_guard() - op.jump_target = loop_target - -def compile_add_fail(loop, fail_index): - loop = _from_opaque(loop) - index = len(loop.operations)-1 - op = loop.operations[index] - op.fail_index = fail_index - return index - -def compile_add_fail_arg(loop, intvar): - loop = _from_opaque(loop) - op = loop.operations[-1] - if op.fail_args is None: - op.fail_args = [] - if intvar == -1: - op.fail_args.append(None) - else: - op.fail_args.append(_variables[intvar]) - -def compile_redirect_fail(old_loop, old_index, new_loop): - old_loop = _from_opaque(old_loop) - new_loop = _from_opaque(new_loop) - guard_op = old_loop.operations[old_index] - assert guard_op.is_guard() - guard_op.jump_target = new_loop - # check that the bridge's inputargs are of the correct number and - # kind for the guard - if guard_op.fail_args is not None: - argkinds = [v.concretetype for v in guard_op.fail_args if v] - else: - argkinds = [] - assert argkinds == [v.concretetype for v in new_loop.inputargs] - -# ------------------------------ - -class Frame(object): - OPHANDLERS = [None] * (rop._LAST+1) - - def __init__(self, cpu): - self.verbose = False - self.cpu = cpu - self.opindex = 1 - self._forced = False - self._may_force = -1 - - def getenv(self, v): - from pypy.jit.backend.llgraph.runner import Descr - if isinstance(v, Constant): - return v.value - elif isinstance(v, Descr): - return v - else: - return self.env[v] - - def _populate_fail_args(self, op, skip=None): - fail_args = [] - if op.fail_args: - for fail_arg in op.fail_args: - if fail_arg is None: - fail_args.append(None) - elif fail_arg is skip: - fail_args.append(fail_arg.concretetype._defl()) - else: - fail_args.append(self.getenv(fail_arg)) - self.fail_args = fail_args - self.fail_index = op.fail_index - - def execute(self): - """Execute all operations in a loop, - possibly following to other loops as well. - """ - global _last_exception - assert _last_exception is None, "exception left behind" - verbose = True - self.opindex = 0 - while True: - assert not self.loop.has_been_freed - op = self.loop.operations[self.opindex] - args = [self.getenv(v) for v in op.args] - if not op.is_final(): - try: - result = self.execute_operation(op.opnum, args, op.descr, - verbose) - except GuardFailed: - assert op.is_guard() - _stats.exec_conditional_jumps += 1 - if op.jump_target is not None: - # a patched guard, pointing to further code - if op.fail_args: - args = [self.getenv(v) for v in op.fail_args if v] - else: - args = [] - assert len(op.jump_target.inputargs) == len(args) - self.env = dict(zip(op.jump_target.inputargs, args)) - self.loop = op.jump_target - self.opindex = 0 - continue - else: - self._populate_fail_args(op) - # a non-patched guard - if self.verbose: - log.trace('failed: %s' % ( - ', '.join(map(str, fail_args)),)) - return op.fail_index - #verbose = self.verbose - assert (result is None) == (op.result is None) - if op.result is not None: - RESTYPE = op.result.concretetype - if RESTYPE is lltype.Signed: - x = self.as_int(result) - elif RESTYPE is llmemory.GCREF: - x = self.as_ptr(result) - elif RESTYPE is ootype.Object: - x = self.as_object(result) - elif RESTYPE is longlong.FLOATSTORAGE: - x = self.as_floatstorage(result) - else: - raise Exception("op.result.concretetype is %r" - % (RESTYPE,)) - self.env[op.result] = x - self.opindex += 1 - continue - if op.opnum == rop.JUMP: - inputargs = op.jump_target_inputargs - assert len(inputargs) == len(args) - self.env = dict(zip(inputargs, args)) - self.loop = op.jump_target - self.opindex = op.jump_target_opindex - _stats.exec_jumps += 1 - elif op.opnum == rop.FINISH: - if self.verbose: - log.trace('finished: %s' % ( - ', '.join(map(str, args)),)) - self.fail_args = args - return op.fail_index - - else: - assert 0, "unknown final operation %d" % (op.opnum,) - - def execute_operation(self, opnum, values, descr, verbose): - """Execute a single operation. - """ - ophandler = self.OPHANDLERS[opnum] - if ophandler is None: - self._define_impl(opnum) - ophandler = self.OPHANDLERS[opnum] - assert ophandler is not None, "missing impl for op %d" % opnum - opname = resoperation.opname[opnum].lower() - exec_counters = _stats.exec_counters - exec_counters[opname] = exec_counters.get(opname, 0) + 1 - for i in range(len(values)): - if isinstance(values[i], ComputedIntSymbolic): - values[i] = values[i].compute_fn() - res = NotImplemented - try: - res = ophandler(self, descr, *values) - finally: - if 0: # if verbose: - argtypes, restype = TYPES[opname] - if res is None: - resdata = '' - elif res is NotImplemented: - resdata = '*fail*' - else: - resdata = '-> ' + repr1(res, restype) - # fish the types - log.cpu('\t%s %s %s' % (opname, repr_list(values, argtypes), - resdata)) - return res - - def as_int(self, x): - return cast_to_int(x) - - def as_ptr(self, x): - return cast_to_ptr(x) - - def as_object(self, x): - return ootype.cast_to_object(x) - - def as_floatstorage(self, x): - return cast_to_floatstorage(x) - - def log_progress(self): - count = sum(_stats.exec_counters.values()) - count_jumps = _stats.exec_jumps - log.trace('ran %d operations, %d jumps' % (count, count_jumps)) - - # ---------- - - @classmethod - def _define_impl(cls, opnum): - opname = resoperation.opname[opnum] - try: - op = getattr(cls, 'op_' + opname.lower()) # op_guard_true etc. - except AttributeError: - try: - impl = globals()['do_' + opname.lower()] # do_arraylen_gc etc. - def op(self, descr, *args): - if descr is None: - return impl(*args) - else: - return impl(descr, *args) - except KeyError: - op = cls._make_impl_from_blackhole_interp(opname) - cls.OPHANDLERS[opnum] = op - - @classmethod - def _make_impl_from_blackhole_interp(cls, opname): - from pypy.jit.metainterp.blackhole import BlackholeInterpreter - name = 'bhimpl_' + opname.lower() - func = BlackholeInterpreter.__dict__[name] - for argtype in func.argtypes: - assert argtype in ('i', 'r', 'f') - # - def _op_default_implementation(self, descr, *args): - # for all operations implemented in the blackhole interpreter - return func(*args) - # - return _op_default_implementation - - def op_label(self, _, *args): - op = self.loop.operations[self.opindex] - assert op.opnum == rop.LABEL - assert len(op.args) == len(args) - newenv = {} - for v, value in zip(op.args, args): - newenv[v] = value - self.env = newenv - - def op_debug_merge_point(self, _, *args): - from pypy.jit.metainterp.warmspot import get_stats - try: - stats = get_stats() - except AttributeError: - pass - else: - stats.add_merge_point_location(args[1:]) - pass - - def op_guard_true(self, _, value): - if not value: - raise GuardFailed - - def op_guard_false(self, _, value): - if value: - raise GuardFailed - - op_guard_nonnull = op_guard_true - op_guard_isnull = op_guard_false - - def op_guard_class(self, _, value, expected_class): - value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, value) - expected_class = llmemory.cast_adr_to_ptr( - llmemory.cast_int_to_adr(expected_class), - rclass.CLASSTYPE) - if value.typeptr != expected_class: - raise GuardFailed - - def op_guard_nonnull_class(self, _, value, expected_class): - if not value: - raise GuardFailed - self.op_guard_class(_, value, expected_class) - - def op_guard_value(self, _, value, expected_value): - if value != expected_value: - raise GuardFailed - - def op_guard_no_exception(self, _): - if _last_exception: - raise GuardFailed - - def _check_exception(self, expected_exception): - global _last_exception - expected_exception = self._cast_exception(expected_exception) - assert expected_exception - exc = _last_exception - if exc: - got = exc.args[0] - # exact match! - if got != expected_exception: - return False - return True - else: - return False - - def _cast_exception(self, exception): - return llmemory.cast_adr_to_ptr( - llmemory.cast_int_to_adr(exception), - rclass.CLASSTYPE) - - def _issubclass(self, cls1, cls2): - return rclass.ll_issubclass(cls1, cls2) - - def op_guard_exception(self, _, expected_exception): - global _last_exception - if not self._check_exception(expected_exception): - raise GuardFailed - res = _last_exception[1] - _last_exception = None - return res - - def op_guard_no_overflow(self, _): - flag = self.overflow_flag - del self.overflow_flag - if flag: - raise GuardFailed - - def op_guard_overflow(self, _): - flag = self.overflow_flag - del self.overflow_flag - if not flag: - raise GuardFailed - - def op_int_add_ovf(self, _, x, y): - try: - z = ovfcheck(x + y) - except OverflowError: - ovf = True - z = 0 - else: - ovf = False - self.overflow_flag = ovf - return z - - def op_int_sub_ovf(self, _, x, y): - try: - z = ovfcheck(x - y) - except OverflowError: - ovf = True - z = 0 - else: - ovf = False - self.overflow_flag = ovf - return z - - def op_int_mul_ovf(self, _, x, y): - try: - z = ovfcheck(x * y) - except OverflowError: - ovf = True - z = 0 - else: - ovf = False - self.overflow_flag = ovf - return z - - def op_keepalive(self, _, x): - pass - - # ---------- - # delegating to the builtins do_xxx() (done automatically for simple cases) - - def op_getarrayitem_gc(self, arraydescr, array, index): - if arraydescr.typeinfo == REF: - return do_getarrayitem_gc_ptr(array, index) - elif arraydescr.typeinfo == INT: - return do_getarrayitem_gc_int(array, index) - elif arraydescr.typeinfo == FLOAT: - return do_getarrayitem_gc_float(array, index) - else: - raise NotImplementedError - - op_getarrayitem_gc_pure = op_getarrayitem_gc - - def op_getarrayitem_raw(self, arraydescr, array, index): - if arraydescr.typeinfo == REF: - raise NotImplementedError("getarrayitem_raw -> gcref") - elif arraydescr.typeinfo == INT: - return do_getarrayitem_raw_int(array, index, arraydescr.ofs) - elif arraydescr.typeinfo == FLOAT: - return do_getarrayitem_raw_float(array, index) - else: - raise NotImplementedError - - op_getarrayitem_raw_pure = op_getarrayitem_raw - - def op_getfield_gc(self, fielddescr, struct): - if fielddescr.typeinfo == REF: - return do_getfield_gc_ptr(struct, fielddescr.ofs) - elif fielddescr.typeinfo == INT: - return do_getfield_gc_int(struct, fielddescr.ofs) - elif fielddescr.typeinfo == FLOAT: - return do_getfield_gc_float(struct, fielddescr.ofs) - else: - raise NotImplementedError - - op_getfield_gc_pure = op_getfield_gc - - def op_getfield_raw(self, fielddescr, struct): - if fielddescr.typeinfo == REF: - return do_getfield_raw_ptr(struct, fielddescr.ofs) - elif fielddescr.typeinfo == INT: - return do_getfield_raw_int(struct, fielddescr.ofs) - elif fielddescr.typeinfo == FLOAT: - return do_getfield_raw_float(struct, fielddescr.ofs) - else: - raise NotImplementedError - - op_getfield_raw_pure = op_getfield_raw - - def op_raw_store(self, arraydescr, addr, offset, value): - if arraydescr.typeinfo == REF: - raise AssertionError("cannot store GC pointer in raw storage") - elif arraydescr.typeinfo == INT: - do_raw_store_int(addr, offset, arraydescr.ofs, value) - elif arraydescr.typeinfo == FLOAT: - do_raw_store_float(addr, offset, value) - else: - raise NotImplementedError - - def op_raw_load(self, arraydescr, addr, offset): - if arraydescr.typeinfo == REF: - raise AssertionError("cannot store GC pointer in raw storage") - elif arraydescr.typeinfo == INT: - return do_raw_load_int(addr, offset, arraydescr.ofs) - elif arraydescr.typeinfo == FLOAT: - return do_raw_load_float(addr, offset) - else: - raise NotImplementedError - - def op_new(self, size): - return do_new(size.ofs) - - def op_new_with_vtable(self, descr, vtable): - assert descr is None - descr = heaptracker.vtable2descr(self.cpu, vtable) - result = do_new(descr.ofs) - value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, result) - value.typeptr = cast_from_int(rclass.CLASSTYPE, vtable) - return result - - def op_setarrayitem_gc(self, arraydescr, array, index, newvalue): - if arraydescr.typeinfo == REF: - do_setarrayitem_gc_ptr(array, index, newvalue) - elif arraydescr.typeinfo == INT: - do_setarrayitem_gc_int(array, index, newvalue) - elif arraydescr.typeinfo == FLOAT: - do_setarrayitem_gc_float(array, index, newvalue) - else: - raise NotImplementedError - - def op_setarrayitem_raw(self, arraydescr, array, index, newvalue): - if arraydescr.typeinfo == REF: - raise NotImplementedError("setarrayitem_raw <- gcref") - elif arraydescr.typeinfo == INT: - do_setarrayitem_raw_int(array, index, newvalue, arraydescr.ofs) - elif arraydescr.typeinfo == FLOAT: - do_setarrayitem_raw_float(array, index, newvalue) - else: - raise NotImplementedError - - def op_getinteriorfield_gc(self, descr, array, index): - if descr.typeinfo == REF: - return do_getinteriorfield_gc_ptr(array, index, descr.ofs) - elif descr.typeinfo == INT: - return do_getinteriorfield_gc_int(array, index, descr.ofs) - elif descr.typeinfo == FLOAT: - return do_getinteriorfield_gc_float(array, index, descr.ofs) - else: - raise NotImplementedError - - def op_getinteriorfield_raw(self, descr, array, index): - if descr.typeinfo == REF: - return do_getinteriorfield_raw_ptr(array, index, descr.width, descr.ofs) - elif descr.typeinfo == INT: - return do_getinteriorfield_raw_int(array, index, descr.width, descr.ofs) - elif descr.typeinfo == FLOAT: - return do_getinteriorfield_raw_float(array, index, descr.width, descr.ofs) - else: - raise NotImplementedError - - def op_setinteriorfield_gc(self, descr, array, index, newvalue): - if descr.typeinfo == REF: - return do_setinteriorfield_gc_ptr(array, index, descr.ofs, - newvalue) - elif descr.typeinfo == INT: - return do_setinteriorfield_gc_int(array, index, descr.ofs, - newvalue) - elif descr.typeinfo == FLOAT: - return do_setinteriorfield_gc_float(array, index, descr.ofs, - newvalue) - else: - raise NotImplementedError - - def op_setinteriorfield_raw(self, descr, array, index, newvalue): - if descr.typeinfo == REF: - return do_setinteriorfield_raw_ptr(array, index, newvalue, descr.width, descr.ofs) - elif descr.typeinfo == INT: - return do_setinteriorfield_raw_int(array, index, newvalue, descr.width, descr.ofs) - elif descr.typeinfo == FLOAT: - return do_setinteriorfield_raw_float(array, index, newvalue, descr.width, descr.ofs) - else: - raise NotImplementedError - - def op_setfield_gc(self, fielddescr, struct, newvalue): - if fielddescr.typeinfo == REF: - do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == INT: - do_setfield_gc_int(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == FLOAT: - do_setfield_gc_float(struct, fielddescr.ofs, newvalue) - else: - raise NotImplementedError - - def op_setfield_raw(self, fielddescr, struct, newvalue): - if fielddescr.typeinfo == REF: - do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == INT: - do_setfield_raw_int(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == FLOAT: - do_setfield_raw_float(struct, fielddescr.ofs, newvalue) - else: - raise NotImplementedError - - def op_call(self, calldescr, func, *args): - effectinfo = calldescr.get_extra_info() - if effectinfo is not None and hasattr(effectinfo, 'oopspecindex'): - oopspecindex = effectinfo.oopspecindex - if oopspecindex == EffectInfo.OS_MATH_SQRT: - return do_math_sqrt(args[0]) - return self._do_call(calldescr, func, args, call_with_llptr=False) - - def op_call_release_gil(self, calldescr, func, *args): - return self._do_call(calldescr, func, args, call_with_llptr=True) - - def _do_call(self, calldescr, func, args, call_with_llptr): - global _last_exception - assert _last_exception is None, "exception left behind" - assert _call_args_i == _call_args_r == _call_args_f == [] - args_in_order = [] - for x in args: - T = lltype.typeOf(x) - if T is lltype.Signed: - args_in_order.append('i') - _call_args_i.append(x) - elif T == llmemory.GCREF: - args_in_order.append('r') - _call_args_r.append(x) - elif T is longlong.FLOATSTORAGE: - args_in_order.append('f') - _call_args_f.append(x) - else: - raise TypeError(x) - try: - return _do_call_common(func, args_in_order, calldescr, - call_with_llptr) - except LLException, lle: - _last_exception = lle - d = {'v': None, - REF: lltype.nullptr(llmemory.GCREF.TO), - INT: 0, - FLOAT: 0.0} - return d[calldescr.typeinfo] - - def op_cond_call_gc_wb(self, descr, a, b): - py.test.skip("cond_call_gc_wb not supported") - - def op_cond_call_gc_wb_array(self, descr, a, b, c): - py.test.skip("cond_call_gc_wb_array not supported") - - def op_oosend(self, descr, obj, *args): - raise NotImplementedError("oosend for lltype backend??") - - op_oosend_pure = op_oosend - - def op_new_array(self, arraydescr, count): - return do_new_array(arraydescr.ofs, count) - - def op_force_token(self, descr): - opaque_frame = _to_opaque(self) - return llmemory.cast_ptr_to_adr(opaque_frame) - - def op_read_timestamp(self, descr): - return read_timestamp() - - def op_call_may_force(self, calldescr, func, *args): - assert not self._forced - self._may_force = self.opindex - try: - return self.op_call(calldescr, func, *args) - finally: - self._may_force = -1 - - def op_call_assembler(self, wref_loop_token, *args): - if we_are_translated(): - raise ValueError("CALL_ASSEMBLER not supported") - return self._do_call_assembler(wref_loop_token, *args) - - def _do_call_assembler(self, wref_loop_token, *args): - global _last_exception - loop_token = wref_loop_token() - assert loop_token, "CALL_ASSEMBLER to a target that already died" - ctl = loop_token.compiled_loop_token - if hasattr(ctl, 'redirected'): - return self._do_call_assembler(ctl.redirected, *args) - assert not self._forced - self._may_force = self.opindex - try: - inpargs = _from_opaque(ctl.compiled_version).inputargs - assert len(inpargs) == len(args) - for i, inparg in enumerate(inpargs): - TYPE = inparg.concretetype - if TYPE is lltype.Signed: - set_future_value_int(i, args[i]) - elif isinstance(TYPE, lltype.Ptr): - set_future_value_ref(i, args[i]) - elif TYPE is longlong.FLOATSTORAGE: - set_future_value_float(i, args[i]) - else: - raise Exception("Nonsense type %s" % TYPE) - - failindex = self.cpu._execute_token(loop_token) - jd = loop_token.outermost_jitdriver_sd - assert jd is not None, ("call_assembler(): the loop_token needs " - "to have 'outermost_jitdriver_sd'") - if jd.index_of_virtualizable != -1: - vable = args[jd.index_of_virtualizable] - else: - vable = lltype.nullptr(llmemory.GCREF.TO) - # - # Emulate the fast path - if failindex == self.cpu.done_with_this_frame_int_v: - reset_vable(jd, vable) - return self.cpu.get_latest_value_int(0) - if failindex == self.cpu.done_with_this_frame_ref_v: - reset_vable(jd, vable) - return self.cpu.get_latest_value_ref(0) - if failindex == self.cpu.done_with_this_frame_float_v: - reset_vable(jd, vable) - return self.cpu.get_latest_value_float(0) - if failindex == self.cpu.done_with_this_frame_void_v: - reset_vable(jd, vable) - return None - # - assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish - try: - return assembler_helper_ptr(failindex, vable) - except LLException, lle: - assert _last_exception is None, "exception left behind" - _last_exception = lle From noreply at buildbot.pypy.org Thu Oct 18 10:48:17 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 10:48:17 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: close to-be-merged branch Message-ID: <20121018084817.8EDC51C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58198:25d5662199c3 Date: 2012-10-18 10:47 +0200 http://bitbucket.org/pypy/pypy/changeset/25d5662199c3/ Log: close to-be-merged branch From noreply at buildbot.pypy.org Thu Oct 18 10:49:49 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 10:49:49 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: oops Message-ID: <20121018084949.321A31C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58199:59010aee74ec Date: 2012-10-18 10:49 +0200 http://bitbucket.org/pypy/pypy/changeset/59010aee74ec/ Log: oops diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -130,13 +130,10 @@ def is_float_field(self): return getkind(self.FIELD) == 'float' -def _example_res(kind): - d = {'v': None, - 'r': lltype.nullptr(llmemory.GCREF.TO), - 'i': 0, - 'f': 0.0} - return d[kind[0]] - +_example_res = {'v': None, + 'r': lltype.nullptr(llmemory.GCREF.TO), + 'i': 0, + 'f': 0.0} class LLGraphCPU(model.AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts @@ -731,7 +728,7 @@ self.cpu.last_exception = None except LLException, lle: self.cpu.last_exception = lle - res = _example_res[getkind(TP.RESULT)] + res = _example_res[getkind(TP.RESULT)[0]] return res execute_call_may_force = execute_call @@ -773,7 +770,7 @@ assert self.cpu.last_exception is None, "exception left behind" self.cpu.last_exception = lle if self.current_op.result is not None: - return _example_res(self.current_op.result.type) + return _example_res[self.current_op.result.type] return None return support.cast_result(lltype.typeOf(result), result) From noreply at buildbot.pypy.org Thu Oct 18 10:49:50 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 10:49:50 +0200 (CEST) Subject: [pypy-commit] pypy cleanup-llgraph-backend: close to-be-merged branch Message-ID: <20121018084950.54BA51C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: cleanup-llgraph-backend Changeset: r58200:31dfc44554f4 Date: 2012-10-18 10:49 +0200 http://bitbucket.org/pypy/pypy/changeset/31dfc44554f4/ Log: close to-be-merged branch From noreply at buildbot.pypy.org Thu Oct 18 10:58:31 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 10:58:31 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: hg merge cleanup-llgraph-backend Message-ID: <20121018085831.218251C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58201:0a477b990fba Date: 2012-10-18 10:58 +0200 http://bitbucket.org/pypy/pypy/changeset/0a477b990fba/ Log: hg merge cleanup-llgraph-backend diff too long, truncating to 2000 out of 10084 lines diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py deleted file mode 100644 --- a/pypy/jit/backend/llgraph/llimpl.py +++ /dev/null @@ -1,1984 +0,0 @@ -""" -The non-RPythonic part of the llgraph backend. -This contains all the code that is directly run -when executing on top of the llinterpreter. -""" - -import weakref -from pypy.objspace.flow.model import Variable, Constant -from pypy.annotation import model as annmodel -from pypy.jit.metainterp.history import REF, INT, FLOAT -from pypy.jit.metainterp import history -from pypy.jit.codewriter import heaptracker -from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr, rffi -from pypy.rpython.ootypesystem import ootype -from pypy.rpython.module.support import LLSupport, OOSupport -from pypy.rpython.llinterp import LLException -from pypy.rpython.extregistry import ExtRegistryEntry - -from pypy.jit.metainterp import resoperation -from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.llgraph import symbolic -from pypy.jit.codewriter import longlong -from pypy.jit.codewriter.effectinfo import EffectInfo - -from pypy.rlib.objectmodel import ComputedIntSymbolic, we_are_translated -from pypy.rlib.rarithmetic import ovfcheck -from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint -from pypy.rlib.rtimer import read_timestamp - -import py -from pypy.tool.ansi_print import ansi_log -log = py.log.Producer('runner') -py.log.setconsumer('runner', ansi_log) - -IS_32_BIT = r_ulonglong is not r_uint - - -def _from_opaque(opq): - try: - return opq._obj.externalobj - except AttributeError: - return opq._obj.container - -_TO_OPAQUE = {} - -def _to_opaque(value): - try: - return value._the_opaque_pointer - except AttributeError: - if isinstance(value, Frame): - op = lltype.opaqueptr(llmemory.GCREF.TO, 'frame', - container=value) - else: - op = lltype.opaqueptr(_TO_OPAQUE[value.__class__], 'opaque', - externalobj=value) - value._the_opaque_pointer = op - return op - -def _normalize(value): - if isinstance(value, lltype._ptr): - value = lltype.top_container(value._obj) - return value - -def from_opaque_string(s): - if isinstance(s, str): - return s - elif isinstance(s, ootype._string): - return OOSupport.from_rstr(s) - else: - return LLSupport.from_rstr(s) - -FLOAT_ARRAY_TP = lltype.Ptr(lltype.Array(lltype.Float, hints={"nolength": True})) -def maybe_uncast(TP, array): - if array._TYPE.TO.OF != lltype.Float: - # array._TYPE.TO._hints.get("uncast_on_llgraph"): - array = rffi.cast(TP, array) - return array - -# a list of argtypes of all operations - couldn't find any and it's -# very useful. Note however that the table is half-broken here and -# there, in ways that are sometimes a bit hard to fix; that's why -# it is not "official". -TYPES = { - 'int_add' : (('int', 'int'), 'int'), - 'int_sub' : (('int', 'int'), 'int'), - 'int_mul' : (('int', 'int'), 'int'), - 'int_floordiv' : (('int', 'int'), 'int'), - 'int_mod' : (('int', 'int'), 'int'), - 'int_and' : (('int', 'int'), 'int'), - 'int_or' : (('int', 'int'), 'int'), - 'int_xor' : (('int', 'int'), 'int'), - 'int_lshift' : (('int', 'int'), 'int'), - 'int_rshift' : (('int', 'int'), 'int'), - 'int_lt' : (('int', 'int'), 'bool'), - 'int_gt' : (('int', 'int'), 'bool'), - 'int_ge' : (('int', 'int'), 'bool'), - 'int_le' : (('int', 'int'), 'bool'), - 'int_eq' : (('int', 'int'), 'bool'), - 'int_ne' : (('int', 'int'), 'bool'), - 'int_is_true' : (('int',), 'bool'), - 'int_is_zero' : (('int',), 'bool'), - 'int_neg' : (('int',), 'int'), - 'int_invert' : (('int',), 'int'), - 'int_add_ovf' : (('int', 'int'), 'int'), - 'int_sub_ovf' : (('int', 'int'), 'int'), - 'int_mul_ovf' : (('int', 'int'), 'int'), - 'int_force_ge_zero':(('int',), 'int'), - 'uint_add' : (('int', 'int'), 'int'), - 'uint_sub' : (('int', 'int'), 'int'), - 'uint_mul' : (('int', 'int'), 'int'), - 'uint_lt' : (('int', 'int'), 'bool'), - 'uint_le' : (('int', 'int'), 'bool'), - 'uint_eq' : (('int', 'int'), 'bool'), - 'uint_ne' : (('int', 'int'), 'bool'), - 'uint_gt' : (('int', 'int'), 'bool'), - 'uint_ge' : (('int', 'int'), 'bool'), - 'uint_xor' : (('int', 'int'), 'int'), - 'uint_rshift' : (('int', 'int'), 'int'), - 'uint_floordiv' : (('int', 'int'), 'int'), - 'float_add' : (('float', 'float'), 'float'), - 'float_sub' : (('float', 'float'), 'float'), - 'float_mul' : (('float', 'float'), 'float'), - 'float_truediv' : (('float', 'float'), 'float'), - 'float_lt' : (('float', 'float'), 'bool'), - 'float_le' : (('float', 'float'), 'bool'), - 'float_eq' : (('float', 'float'), 'bool'), - 'float_ne' : (('float', 'float'), 'bool'), - 'float_gt' : (('float', 'float'), 'bool'), - 'float_ge' : (('float', 'float'), 'bool'), - 'float_neg' : (('float',), 'float'), - 'float_abs' : (('float',), 'float'), - 'cast_float_to_int':(('float',), 'int'), - 'cast_int_to_float':(('int',), 'float'), - 'same_as' : (('int',), 'int'), # could also be ptr=>ptr - 'new_with_vtable' : (('ref',), 'ref'), - 'new' : ((), 'ref'), - 'new_array' : (('int',), 'ref'), - 'oois' : (('ref', 'ref'), 'bool'), - 'ooisnot' : (('ref', 'ref'), 'bool'), - 'instanceof' : (('ref',), 'bool'), - 'subclassof' : (('ref', 'ref'), 'bool'), - 'runtimenew' : (('ref',), 'ref'), - 'setfield_gc' : (('ref', 'intorptr'), None), - 'getfield_gc' : (('ref',), 'intorptr'), - 'getfield_gc_pure': (('ref',), 'intorptr'), - 'setfield_raw' : (('ref', 'intorptr'), None), - 'getfield_raw' : (('ref',), 'intorptr'), - 'getfield_raw_pure': (('ref',), 'intorptr'), - 'setarrayitem_gc' : (('ref', 'int', 'intorptr'), None), - 'getarrayitem_gc' : (('ref', 'int'), 'intorptr'), - 'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'), - 'setarrayitem_raw' : (('ref', 'int', 'intorptr'), None), - 'getarrayitem_raw' : (('ref', 'int'), 'intorptr'), - 'getarrayitem_raw_pure' : (('ref', 'int'), 'intorptr'), - 'arraylen_gc' : (('ref',), 'int'), - 'call' : (('ref', 'varargs'), 'intorptr'), - 'call_assembler' : (('varargs',), 'intorptr'), - 'cond_call_gc_wb' : (('ptr', 'ptr'), None), - 'cond_call_gc_wb_array': (('ptr', 'int', 'ptr'), None), - 'oosend' : (('varargs',), 'intorptr'), - 'oosend_pure' : (('varargs',), 'intorptr'), - 'guard_true' : (('bool',), None), - 'guard_false' : (('bool',), None), - 'guard_value' : (('int', 'int'), None), - 'guard_class' : (('ref', 'ref'), None), - 'guard_no_exception' : ((), None), - 'guard_exception' : (('ref',), 'ref'), - 'guard_no_overflow' : ((), None), - 'guard_overflow' : ((), None), - 'guard_nonnull' : (('ref',), None), - 'guard_isnull' : (('ref',), None), - 'guard_nonnull_class' : (('ref', 'ref'), None), - 'newstr' : (('int',), 'ref'), - 'strlen' : (('ref',), 'int'), - 'strgetitem' : (('ref', 'int'), 'int'), - 'strsetitem' : (('ref', 'int', 'int'), None), - 'newunicode' : (('int',), 'ref'), - 'unicodelen' : (('ref',), 'int'), - 'unicodegetitem' : (('ref', 'int'), 'int'), - 'unicodesetitem' : (('ref', 'int', 'int'), 'int'), - 'cast_ptr_to_int' : (('ref',), 'int'), - 'cast_int_to_ptr' : (('int',), 'ref'), - 'debug_merge_point': (('ref', 'int', 'int'), None), - 'jit_frame' : ((), 'ref'), - 'call_may_force' : (('int', 'varargs'), 'intorptr'), - 'guard_not_forced': ((), None), -} - -# ____________________________________________________________ - -class CompiledLoop(object): - has_been_freed = False - invalid = False - - def __init__(self): - self.inputargs = [] - self.operations = [] - - def getargtypes(self): - return [v.concretetype for v in self.inputargs] - - def __repr__(self): - lines = [] - self.as_text(lines, 1) - return 'CompiledLoop %s:\n%s' % (self.inputargs, '\n'.join(lines)) - - def as_text(self, lines, indent): - for op in self.operations: - lines.append('\t'*indent + repr(op)) - -class Operation(object): - result = None - descr = None - jump_target = None - fail_args = None - - def __init__(self, opnum): - self.opnum = opnum - self.args = [] - - def __repr__(self): - if self.result is not None: - sres = repr0(self.result) + ' = ' - else: - sres = '' - return '{%s%s(%s)}' % (sres, self.getopname(), - ', '.join(map(repr0, self.args))) - - def getopname(self): - try: - return resoperation.opname[self.opnum] - except KeyError: - return '<%d>' % self.opnum - - def is_guard(self): - return rop._GUARD_FIRST <= self.opnum <= rop._GUARD_LAST - - def is_final(self): - return rop._FINAL_FIRST <= self.opnum <= rop._FINAL_LAST - -def repr0(x): - if isinstance(x, list): - return '[' + ', '.join(repr0(y) for y in x) + ']' - elif isinstance(x, Constant): - return '(' + repr0(x.value) + ')' - elif isinstance(x, lltype._ptr): - x = llmemory.cast_ptr_to_adr(x) - if x.ptr: - try: - container = x.ptr._obj._normalizedcontainer() - return '* %s' % (container._TYPE._short_name(),) - except AttributeError: - return repr(x) - else: - return 'NULL' - else: - return repr(x) - -def repr_list(lst, types): - res_l = [] - if types and types[-1] == 'varargs': - types = types[:-1] + ('int',) * (len(lst) - len(types) + 1) - assert len(types) == len(lst) - for elem, tp in zip(lst, types): - if isinstance(elem, Constant): - res_l.append('(%s)' % repr1(elem, tp)) - else: - res_l.append(repr1(elem, tp)) - return '[%s]' % (', '.join(res_l)) - -def repr1(x, tp): - if tp == "intorptr": - TYPE = lltype.typeOf(x) - if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc': - tp = "ref" - else: - tp = "int" - if tp == 'int': - return str(x) - elif tp == 'void': - return '---' - elif tp == 'ref': - if not x: - return '(* None)' - if isinstance(x, int): - # XXX normalize? - ptr = str(llmemory.cast_int_to_adr(x)) - elif isinstance(ootype.typeOf(x), ootype.OOType): - return repr(x) - else: - if getattr(x, '_fake', None): - return repr(x) - if lltype.typeOf(x) == llmemory.GCREF: - TP = lltype.Ptr(lltype.typeOf(x._obj.container)) - ptr = lltype.cast_opaque_ptr(TP, x) - else: - ptr = x - try: - container = ptr._obj._normalizedcontainer() - return '(* %s)' % (container._TYPE._short_name(),) - except AttributeError: - return '(%r)' % (ptr,) - elif tp == 'bool': - assert x == 0 or x == 1 - return str(bool(x)) - #elif tp == 'fieldname': - # return str(symbolic.TokenToField[x...][1]) - elif tp == 'float': - return str(x) - else: - raise NotImplementedError("tp = %s" % tp) - -_variables = [] - -def compile_start(): - del _variables[:] - return _to_opaque(CompiledLoop()) - -def mark_as_free(loop): - loop = _from_opaque(loop) - assert not loop.has_been_freed - loop.has_been_freed = True - -def compile_start_int_var(loop): - return compile_start_ref_var(loop, lltype.Signed) - -def compile_start_float_var(loop): - return compile_start_ref_var(loop, longlong.FLOATSTORAGE) - -def compile_start_ref_var(loop, TYPE): - loop = _from_opaque(loop) - assert not loop.operations - v = Variable() - v.concretetype = TYPE - loop.inputargs.append(v) - r = len(_variables) - _variables.append(v) - return r - -def compile_started_vars(clt): - if not hasattr(clt, '_debug_argtypes'): # only when compiling the loop - argtypes = [v.concretetype for v in _variables] - try: - clt._debug_argtypes = argtypes - except AttributeError: # when 'clt' is actually a translated - pass # GcStruct - -def compile_add(loop, opnum): - loop = _from_opaque(loop) - loop.operations.append(Operation(opnum)) - -def compile_add_descr(loop, ofs, type, arg_types, extrainfo, width): - from pypy.jit.backend.llgraph.runner import Descr - loop = _from_opaque(loop) - op = loop.operations[-1] - assert isinstance(type, str) and len(type) == 1 - op.descr = Descr(ofs, type, arg_types=arg_types, extrainfo=extrainfo, width=width) - -def compile_add_descr_arg(loop, ofs, type, arg_types): - from pypy.jit.backend.llgraph.runner import Descr - loop = _from_opaque(loop) - op = loop.operations[-1] - assert isinstance(type, str) and len(type) == 1 - op.args.append(Descr(ofs, type, arg_types=arg_types)) - -def compile_add_loop_token(loop, descr): - if we_are_translated(): - raise ValueError("CALL_ASSEMBLER not supported") - loop = _from_opaque(loop) - op = loop.operations[-1] - op.descr = weakref.ref(descr) - -TARGET_TOKENS = weakref.WeakKeyDictionary() - -def compile_add_target_token(loop, descr, clt): - # here, 'clt' is the compiled_loop_token of the original loop that - # we are compiling - loop = _from_opaque(loop) - op = loop.operations[-1] - descrobj = _normalize(descr) - TARGET_TOKENS[descrobj] = loop, len(loop.operations), op.args, clt - -def compile_add_var(loop, intvar): - loop = _from_opaque(loop) - op = loop.operations[-1] - op.args.append(_variables[intvar]) - -def compile_add_int_const(loop, value): - compile_add_ref_const(loop, value, lltype.Signed) - -def compile_add_float_const(loop, value): - compile_add_ref_const(loop, value, longlong.FLOATSTORAGE) - -def compile_add_ref_const(loop, value, TYPE): - loop = _from_opaque(loop) - const = Constant(value) - const.concretetype = TYPE - op = loop.operations[-1] - op.args.append(const) - -def compile_add_int_result(loop): - return compile_add_ref_result(loop, lltype.Signed) - -def compile_add_float_result(loop): - return compile_add_ref_result(loop, longlong.FLOATSTORAGE) - -def compile_add_ref_result(loop, TYPE): - loop = _from_opaque(loop) - v = Variable() - v.concretetype = TYPE - op = loop.operations[-1] - op.result = v - r = len(_variables) - _variables.append(v) - return r - -def compile_add_jump_target(loop, targettoken, source_clt): - loop = _from_opaque(loop) - descrobj = _normalize(targettoken) - (loop_target, target_opindex, target_inputargs, target_clt - ) = TARGET_TOKENS[descrobj] - # - try: - assert source_clt._debug_argtypes == target_clt._debug_argtypes - except AttributeError: # when translated - pass - # - op = loop.operations[-1] - op.jump_target = loop_target - op.jump_target_opindex = target_opindex - op.jump_target_inputargs = target_inputargs - assert op.opnum == rop.JUMP - assert [v.concretetype for v in op.args] == ( - [v.concretetype for v in target_inputargs]) - # - if loop_target == loop: - log.info("compiling new loop") - else: - log.info("compiling new bridge") - -def compile_add_guard_jump_target(loop, loop_target): - loop = _from_opaque(loop) - loop_target = _from_opaque(loop_target) - op = loop.operations[-1] - assert op.is_guard() - op.jump_target = loop_target - -def compile_add_fail(loop, fail_index): - loop = _from_opaque(loop) - index = len(loop.operations)-1 - op = loop.operations[index] - op.fail_index = fail_index - return index - -def compile_add_fail_arg(loop, intvar): - loop = _from_opaque(loop) - op = loop.operations[-1] - if op.fail_args is None: - op.fail_args = [] - if intvar == -1: - op.fail_args.append(None) - else: - op.fail_args.append(_variables[intvar]) - -def compile_redirect_fail(old_loop, old_index, new_loop): - old_loop = _from_opaque(old_loop) - new_loop = _from_opaque(new_loop) - guard_op = old_loop.operations[old_index] - assert guard_op.is_guard() - guard_op.jump_target = new_loop - # check that the bridge's inputargs are of the correct number and - # kind for the guard - if guard_op.fail_args is not None: - argkinds = [v.concretetype for v in guard_op.fail_args if v] - else: - argkinds = [] - assert argkinds == [v.concretetype for v in new_loop.inputargs] - -# ------------------------------ - -class Frame(object): - _carry_around_for_tests = True - OPHANDLERS = [None] * (rop._LAST+1) - - def __init__(self, cpu): - self.verbose = False - self.cpu = cpu - self.opindex = 1 - self._forced = False - self._may_force = -1 - self._last_exception = None - self._finish_value = None - - def getenv(self, v): - from pypy.jit.backend.llgraph.runner import Descr - if isinstance(v, Constant): - return v.value - elif isinstance(v, Descr): - return v - else: - return self.env[v] - - def _populate_fail_args(self, op, skip=None): - fail_args = [] - if op.fail_args: - for fail_arg in op.fail_args: - if fail_arg is None: - fail_args.append(None) - elif fail_arg is skip: - fail_args.append(fail_arg.concretetype._defl()) - else: - fail_args.append(self.getenv(fail_arg)) - self.fail_args = fail_args - self.fail_index = op.fail_index - - def execute(self): - """Execute all operations in a loop, - possibly following to other loops as well. - """ - assert self._may_force == -1 - assert self._finish_value is None - assert self._last_exception is None, "exception left behind" - verbose = True - self.opindex = 0 - while True: - assert not self.loop.has_been_freed - op = self.loop.operations[self.opindex] - args = [self.getenv(v) for v in op.args] - if not op.is_final(): - try: - result = self.execute_operation(op.opnum, args, op.descr, - verbose) - except GuardFailed: - assert op.is_guard() - _stats.exec_conditional_jumps += 1 - if op.jump_target is not None: - # a patched guard, pointing to further code - if op.fail_args: - args = [self.getenv(v) for v in op.fail_args if v] - else: - args = [] - assert len(op.jump_target.inputargs) == len(args) - self.env = dict(zip(op.jump_target.inputargs, args)) - self.loop = op.jump_target - self.opindex = 0 - continue - else: - self._populate_fail_args(op) - # a non-patched guard - if self.verbose: - log.trace('failed: %s' % ( - ', '.join(map(str, fail_args)),)) - return - #verbose = self.verbose - assert (result is None) == (op.result is None) - if op.result is not None: - RESTYPE = op.result.concretetype - if RESTYPE is lltype.Signed: - x = self.as_int(result) - elif RESTYPE is llmemory.GCREF: - x = self.as_ptr(result) - elif RESTYPE is ootype.Object: - x = self.as_object(result) - elif RESTYPE is longlong.FLOATSTORAGE: - x = self.as_floatstorage(result) - else: - raise Exception("op.result.concretetype is %r" - % (RESTYPE,)) - self.env[op.result] = x - self.opindex += 1 - continue - if op.opnum == rop.JUMP: - inputargs = op.jump_target_inputargs - assert len(inputargs) == len(args) - self.env = dict(zip(inputargs, args)) - self.loop = op.jump_target - self.opindex = op.jump_target_opindex - _stats.exec_jumps += 1 - elif op.opnum == rop.FINISH: - if self.verbose: - log.trace('finished: %s' % ( - ', '.join(map(str, args)),)) - assert len(op.args) <= 1, "FINISH with more than 1 arg" - if len(op.args) == 1: - self._finish_value = self.getenv(op.args[0]) - else: - self._finish_value = "finished, and got no argument" - self.fail_args = op.fail_args - self.fail_index = op.fail_index - self._may_force = self.opindex - return - - else: - assert 0, "unknown final operation %d" % (op.opnum,) - - def execute_operation(self, opnum, values, descr, verbose): - """Execute a single operation. - """ - ophandler = self.OPHANDLERS[opnum] - if ophandler is None: - self._define_impl(opnum) - ophandler = self.OPHANDLERS[opnum] - assert ophandler is not None, "missing impl for op %d" % opnum - opname = resoperation.opname[opnum].lower() - exec_counters = _stats.exec_counters - exec_counters[opname] = exec_counters.get(opname, 0) + 1 - for i in range(len(values)): - if isinstance(values[i], ComputedIntSymbolic): - values[i] = values[i].compute_fn() - res = NotImplemented - try: - res = ophandler(self, descr, *values) - finally: - if 0: # if verbose: - argtypes, restype = TYPES[opname] - if res is None: - resdata = '' - elif res is NotImplemented: - resdata = '*fail*' - else: - resdata = '-> ' + repr1(res, restype) - # fish the types - log.cpu('\t%s %s %s' % (opname, repr_list(values, argtypes), - resdata)) - return res - - def as_int(self, x): - return cast_to_int(x) - - def as_ptr(self, x): - return cast_to_ptr(x) - - def as_object(self, x): - return ootype.cast_to_object(x) - - def as_floatstorage(self, x): - return cast_to_floatstorage(x) - - def log_progress(self): - count = sum(_stats.exec_counters.values()) - count_jumps = _stats.exec_jumps - log.trace('ran %d operations, %d jumps' % (count, count_jumps)) - - def _normalizedcontainer(self, check="ignored"): - return self # for lltype - - # ---------- - - @classmethod - def _define_impl(cls, opnum): - opname = resoperation.opname[opnum] - try: - op = getattr(cls, 'op_' + opname.lower()) # op_guard_true etc. - except AttributeError: - try: - impl = globals()['do_' + opname.lower()] # do_arraylen_gc etc. - def op(self, descr, *args): - if descr is None: - return impl(*args) - else: - return impl(descr, *args) - except KeyError: - op = cls._make_impl_from_blackhole_interp(opname) - cls.OPHANDLERS[opnum] = op - - @classmethod - def _make_impl_from_blackhole_interp(cls, opname): - from pypy.jit.metainterp.blackhole import BlackholeInterpreter - name = 'bhimpl_' + opname.lower() - func = BlackholeInterpreter.__dict__[name] - for argtype in func.argtypes: - assert argtype in ('i', 'r', 'f') - # - def _op_default_implementation(self, descr, *args): - # for all operations implemented in the blackhole interpreter - return func(*args) - # - return _op_default_implementation - - def op_label(self, _, *args): - op = self.loop.operations[self.opindex] - assert op.opnum == rop.LABEL - assert len(op.args) == len(args) - newenv = {} - for v, value in zip(op.args, args): - newenv[v] = value - self.env = newenv - - def op_debug_merge_point(self, _, *args): - from pypy.jit.metainterp.warmspot import get_stats - try: - stats = get_stats() - except AttributeError: - pass - else: - stats.add_merge_point_location(args[1:]) - pass - - def op_guard_true(self, _, value): - if not value: - raise GuardFailed - - def op_guard_false(self, _, value): - if value: - raise GuardFailed - - op_guard_nonnull = op_guard_true - op_guard_isnull = op_guard_false - - def op_guard_class(self, _, value, expected_class): - value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, value) - expected_class = llmemory.cast_adr_to_ptr( - llmemory.cast_int_to_adr(expected_class), - rclass.CLASSTYPE) - if value.typeptr != expected_class: - raise GuardFailed - - def op_guard_nonnull_class(self, _, value, expected_class): - if not value: - raise GuardFailed - self.op_guard_class(_, value, expected_class) - - def op_guard_value(self, _, value, expected_value): - if value != expected_value: - raise GuardFailed - - def op_guard_no_exception(self, _): - if self._last_exception: - raise GuardFailed - - def _check_exception(self, expected_exception): - expected_exception = self._cast_exception(expected_exception) - assert expected_exception - exc = self._last_exception - if exc: - got = exc.args[0] - # exact match! - if got != expected_exception: - return False - return True - else: - return False - - def _cast_exception(self, exception): - return llmemory.cast_adr_to_ptr( - llmemory.cast_int_to_adr(exception), - rclass.CLASSTYPE) - - def _issubclass(self, cls1, cls2): - return rclass.ll_issubclass(cls1, cls2) - - def op_guard_exception(self, _, expected_exception): - if not self._check_exception(expected_exception): - raise GuardFailed - res = self._last_exception[1] - self._last_exception = None - return res - - def op_guard_no_overflow(self, _): - flag = self.overflow_flag - del self.overflow_flag - if flag: - raise GuardFailed - - def op_guard_overflow(self, _): - flag = self.overflow_flag - del self.overflow_flag - if not flag: - raise GuardFailed - - def op_int_add_ovf(self, _, x, y): - try: - z = ovfcheck(x + y) - except OverflowError: - ovf = True - z = 0 - else: - ovf = False - self.overflow_flag = ovf - return z - - def op_int_sub_ovf(self, _, x, y): - try: - z = ovfcheck(x - y) - except OverflowError: - ovf = True - z = 0 - else: - ovf = False - self.overflow_flag = ovf - return z - - def op_int_mul_ovf(self, _, x, y): - try: - z = ovfcheck(x * y) - except OverflowError: - ovf = True - z = 0 - else: - ovf = False - self.overflow_flag = ovf - return z - - # ---------- - # delegating to the builtins do_xxx() (done automatically for simple cases) - - def op_getarrayitem_gc(self, arraydescr, array, index): - if arraydescr.typeinfo == REF: - return do_getarrayitem_gc_ptr(array, index) - elif arraydescr.typeinfo == INT: - return do_getarrayitem_gc_int(array, index) - elif arraydescr.typeinfo == FLOAT: - return do_getarrayitem_gc_float(array, index) - else: - raise NotImplementedError - - op_getarrayitem_gc_pure = op_getarrayitem_gc - - def op_getarrayitem_raw(self, arraydescr, array, index): - if arraydescr.typeinfo == REF: - raise NotImplementedError("getarrayitem_raw -> gcref") - elif arraydescr.typeinfo == INT: - return do_getarrayitem_raw_int(array, index, arraydescr.ofs) - elif arraydescr.typeinfo == FLOAT: - return do_getarrayitem_raw_float(array, index) - else: - raise NotImplementedError - - op_getarrayitem_raw_pure = op_getarrayitem_raw - - def op_getfield_gc(self, fielddescr, struct): - if fielddescr.typeinfo == REF: - return do_getfield_gc_ptr(struct, fielddescr.ofs) - elif fielddescr.typeinfo == INT: - return do_getfield_gc_int(struct, fielddescr.ofs) - elif fielddescr.typeinfo == FLOAT: - return do_getfield_gc_float(struct, fielddescr.ofs) - else: - raise NotImplementedError - - op_getfield_gc_pure = op_getfield_gc - - def op_getfield_raw(self, fielddescr, struct): - if fielddescr.typeinfo == REF: - return do_getfield_raw_ptr(struct, fielddescr.ofs) - elif fielddescr.typeinfo == INT: - return do_getfield_raw_int(struct, fielddescr.ofs) - elif fielddescr.typeinfo == FLOAT: - return do_getfield_raw_float(struct, fielddescr.ofs) - else: - raise NotImplementedError - - op_getfield_raw_pure = op_getfield_raw - - def op_raw_store(self, arraydescr, addr, offset, value): - if arraydescr.typeinfo == REF: - raise AssertionError("cannot store GC pointer in raw storage") - elif arraydescr.typeinfo == INT: - do_raw_store_int(addr, offset, arraydescr.ofs, value) - elif arraydescr.typeinfo == FLOAT: - do_raw_store_float(addr, offset, value) - else: - raise NotImplementedError - - def op_raw_load(self, arraydescr, addr, offset): - if arraydescr.typeinfo == REF: - raise AssertionError("cannot store GC pointer in raw storage") - elif arraydescr.typeinfo == INT: - return do_raw_load_int(addr, offset, arraydescr.ofs) - elif arraydescr.typeinfo == FLOAT: - return do_raw_load_float(addr, offset) - else: - raise NotImplementedError - - def op_new(self, size): - return do_new(size.ofs) - - def op_new_with_vtable(self, descr, vtable): - assert descr is None - descr = heaptracker.vtable2descr(self.cpu, vtable) - result = do_new(descr.ofs) - value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, result) - value.typeptr = cast_from_int(rclass.CLASSTYPE, vtable) - return result - - def op_setarrayitem_gc(self, arraydescr, array, index, newvalue): - if arraydescr.typeinfo == REF: - do_setarrayitem_gc_ptr(array, index, newvalue) - elif arraydescr.typeinfo == INT: - do_setarrayitem_gc_int(array, index, newvalue) - elif arraydescr.typeinfo == FLOAT: - do_setarrayitem_gc_float(array, index, newvalue) - else: - raise NotImplementedError - - def op_setarrayitem_raw(self, arraydescr, array, index, newvalue): - if arraydescr.typeinfo == REF: - raise NotImplementedError("setarrayitem_raw <- gcref") - elif arraydescr.typeinfo == INT: - do_setarrayitem_raw_int(array, index, newvalue, arraydescr.ofs) - elif arraydescr.typeinfo == FLOAT: - do_setarrayitem_raw_float(array, index, newvalue) - else: - raise NotImplementedError - - def op_getinteriorfield_gc(self, descr, array, index): - if descr.typeinfo == REF: - return do_getinteriorfield_gc_ptr(array, index, descr.ofs) - elif descr.typeinfo == INT: - return do_getinteriorfield_gc_int(array, index, descr.ofs) - elif descr.typeinfo == FLOAT: - return do_getinteriorfield_gc_float(array, index, descr.ofs) - else: - raise NotImplementedError - - def op_getinteriorfield_raw(self, descr, array, index): - if descr.typeinfo == REF: - return do_getinteriorfield_raw_ptr(array, index, descr.width, descr.ofs) - elif descr.typeinfo == INT: - return do_getinteriorfield_raw_int(array, index, descr.width, descr.ofs) - elif descr.typeinfo == FLOAT: - return do_getinteriorfield_raw_float(array, index, descr.width, descr.ofs) - else: - raise NotImplementedError - - def op_setinteriorfield_gc(self, descr, array, index, newvalue): - if descr.typeinfo == REF: - return do_setinteriorfield_gc_ptr(array, index, descr.ofs, - newvalue) - elif descr.typeinfo == INT: - return do_setinteriorfield_gc_int(array, index, descr.ofs, - newvalue) - elif descr.typeinfo == FLOAT: - return do_setinteriorfield_gc_float(array, index, descr.ofs, - newvalue) - else: - raise NotImplementedError - - def op_setinteriorfield_raw(self, descr, array, index, newvalue): - if descr.typeinfo == REF: - return do_setinteriorfield_raw_ptr(array, index, newvalue, descr.width, descr.ofs) - elif descr.typeinfo == INT: - return do_setinteriorfield_raw_int(array, index, newvalue, descr.width, descr.ofs) - elif descr.typeinfo == FLOAT: - return do_setinteriorfield_raw_float(array, index, newvalue, descr.width, descr.ofs) - else: - raise NotImplementedError - - def op_setfield_gc(self, fielddescr, struct, newvalue): - if fielddescr.typeinfo == REF: - do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == INT: - do_setfield_gc_int(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == FLOAT: - do_setfield_gc_float(struct, fielddescr.ofs, newvalue) - else: - raise NotImplementedError - - def op_setfield_raw(self, fielddescr, struct, newvalue): - if fielddescr.typeinfo == REF: - do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == INT: - do_setfield_raw_int(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == FLOAT: - do_setfield_raw_float(struct, fielddescr.ofs, newvalue) - else: - raise NotImplementedError - - def op_call(self, calldescr, func, *args): - effectinfo = calldescr.get_extra_info() - if effectinfo is not None and hasattr(effectinfo, 'oopspecindex'): - oopspecindex = effectinfo.oopspecindex - if oopspecindex == EffectInfo.OS_MATH_SQRT: - return do_math_sqrt(args[0]) - return self._do_call(calldescr, func, args, call_with_llptr=False) - - def op_call_release_gil(self, calldescr, func, *args): - return self._do_call(calldescr, func, args, call_with_llptr=True) - - def _do_call(self, calldescr, func, args, call_with_llptr): - assert self._last_exception is None, "exception left behind" - assert _call_args_i == _call_args_r == _call_args_f == [] - args_in_order = [] - for x in args: - T = lltype.typeOf(x) - if T is lltype.Signed: - args_in_order.append('i') - _call_args_i.append(x) - elif T == llmemory.GCREF: - args_in_order.append('r') - _call_args_r.append(x) - elif T is longlong.FLOATSTORAGE: - args_in_order.append('f') - _call_args_f.append(x) - else: - raise TypeError(x) - try: - return _do_call_common(func, args_in_order, calldescr, - call_with_llptr) - except LLException, lle: - self._last_exception = lle - d = {'v': None, - REF: lltype.nullptr(llmemory.GCREF.TO), - INT: 0, - FLOAT: 0.0} - return d[calldescr.typeinfo] - - def op_cond_call_gc_wb(self, descr, a, b): - py.test.skip("cond_call_gc_wb not supported") - - def op_cond_call_gc_wb_array(self, descr, a, b, c): - py.test.skip("cond_call_gc_wb_array not supported") - - def op_oosend(self, descr, obj, *args): - raise NotImplementedError("oosend for lltype backend??") - - op_oosend_pure = op_oosend - - def op_new_array(self, arraydescr, count): - return do_new_array(arraydescr.ofs, count) - - def op_jit_frame(self, descr): - opaque_frame = _to_opaque(self) - return opaque_frame - - def op_read_timestamp(self, descr): - return read_timestamp() - - def op_call_may_force(self, calldescr, func, *args): - assert not self._forced - self._may_force = self.opindex - try: - return self.op_call(calldescr, func, *args) - finally: - self._may_force = -1 - - def op_call_assembler(self, wref_loop_token, *args): - if we_are_translated(): - raise ValueError("CALL_ASSEMBLER not supported") - return self._do_call_assembler(wref_loop_token, *args) - - def _do_call_assembler(self, wref_loop_token, *args): - loop_token = wref_loop_token() - assert loop_token, "CALL_ASSEMBLER to a target that already died" - ctl = loop_token.compiled_loop_token - if hasattr(ctl, 'redirected'): - return self._do_call_assembler(ctl.redirected, *args) - assert not self._forced - self._may_force = self.opindex - try: - inpargs = _from_opaque(ctl.compiled_version).inputargs - assert len(inpargs) == len(args) - for i, inparg in enumerate(inpargs): - TYPE = inparg.concretetype - if TYPE is lltype.Signed: - set_future_value_int(i, args[i]) - elif isinstance(TYPE, lltype.Ptr): - set_future_value_ref(i, args[i]) - elif TYPE is longlong.FLOATSTORAGE: - set_future_value_float(i, args[i]) - else: - raise Exception("Nonsense type %s" % TYPE) - - subframe = self.cpu._execute_token(loop_token) - jd = loop_token.outermost_jitdriver_sd - assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish - assembler_helper = assembler_helper_ptr._obj._callable - try: - return assembler_helper(subframe) - except LLException, lle: - assert self._last_exception is None, "exception left behind" - self._last_exception = lle - # fish op - op = self.loop.operations[self.opindex] - if op.result is not None: - return 0 - finally: - self._may_force = -1 - - def op_guard_not_forced(self, descr): - forced = self._forced - self._forced = False - if forced: - raise GuardFailed - - def op_guard_not_invalidated(self, descr): - if self.loop.invalid: - raise GuardFailed - -class OOFrame(Frame): - - OPHANDLERS = [None] * (rop._LAST+1) - - def op_new_with_vtable(self, descr, vtable): - assert descr is None - typedescr = get_class_size(self.memocast, vtable) - return ootype.cast_to_object(ootype.new(typedescr.TYPE)) - - def op_new_array(self, typedescr, count): - res = ootype.oonewarray(typedescr.ARRAY, count) - return ootype.cast_to_object(res) - - def op_getfield_gc(self, fielddescr, obj): - TYPE = fielddescr.TYPE - fieldname = fielddescr.fieldname - _, T = TYPE._lookup_field(fieldname) - obj = ootype.cast_from_object(TYPE, obj) - res = getattr(obj, fieldname) - if isinstance(T, ootype.OOType): - return ootype.cast_to_object(res) - return res - - op_getfield_gc_pure = op_getfield_gc - - def op_setfield_gc(self, fielddescr, obj, newvalue): - TYPE = fielddescr.TYPE - fieldname = fielddescr.fieldname - _, T = TYPE._lookup_field(fieldname) - obj = ootype.cast_from_object(TYPE, obj) - if isinstance(ootype.typeOf(newvalue), ootype.OOType): - newvalue = ootype.cast_from_object(T, newvalue) - elif isinstance(T, lltype.Primitive): - newvalue = lltype.cast_primitive(T, newvalue) - setattr(obj, fieldname, newvalue) - - def op_getarrayitem_gc(self, typedescr, obj, index): - array = ootype.cast_from_object(typedescr.ARRAY, obj) - res = array.ll_getitem_fast(index) - if isinstance(typedescr.TYPE, ootype.OOType): - return ootype.cast_to_object(res) - return res - - op_getarrayitem_gc_pure = op_getarrayitem_gc - - def op_setarrayitem_gc(self, typedescr, obj, index, objnewvalue): - array = ootype.cast_from_object(typedescr.ARRAY, obj) - if ootype.typeOf(objnewvalue) == ootype.Object: - newvalue = ootype.cast_from_object(typedescr.TYPE, objnewvalue) - else: - newvalue = objnewvalue - array.ll_setitem_fast(index, newvalue) - - def op_arraylen_gc(self, typedescr, obj): - array = ootype.cast_from_object(typedescr.ARRAY, obj) - return array.ll_length() - - def op_call(self, calldescr, func, *args): - sm = ootype.cast_from_object(calldescr.FUNC, func) - newargs = cast_call_args(calldescr.FUNC.ARGS, args) - res = call_maybe_on_top_of_llinterp(sm, newargs) - if isinstance(calldescr.FUNC.RESULT, ootype.OOType): - return ootype.cast_to_object(res) - return res - - def op_oosend(self, descr, obj, *args): - METH = descr.METH - obj = ootype.cast_from_object(descr.SELFTYPE, obj) - meth = getattr(obj, descr.methname) - newargs = cast_call_args(METH.ARGS, args) - res = call_maybe_on_top_of_llinterp(meth, newargs) - if isinstance(METH.RESULT, ootype.OOType): - return ootype.cast_to_object(res) - return res - - op_oosend_pure = op_oosend - - def op_guard_class(self, _, value, expected_class): - value = ootype.cast_from_object(ootype.ROOT, value) - expected_class = ootype.cast_from_object(ootype.Class, expected_class) - if ootype.classof(value) is not expected_class: - raise GuardFailed - - def op_runtimenew(self, _, cls): - cls = ootype.cast_from_object(ootype.Class, cls) - res = ootype.runtimenew(cls) - return ootype.cast_to_object(res) - - def op_instanceof(self, typedescr, obj): - inst = ootype.cast_from_object(ootype.ROOT, obj) - return ootype.instanceof(inst, typedescr.TYPE) - - def op_subclassof(self, _, obj1, obj2): - cls1 = ootype.cast_from_object(ootype.Class, obj1) - cls2 = ootype.cast_from_object(ootype.Class, obj2) - return ootype.subclassof(cls1, cls2) - - def _cast_exception(self, exception): - return ootype.cast_from_object(ootype.Class, exception) - - def _issubclass(self, cls1, cls2): - return ootype.subclassof(cls1, cls2) - -# ____________________________________________________________ - -def cast_to_int(x): - TP = lltype.typeOf(x) - if isinstance(TP, lltype.Ptr): - return heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) - if TP == llmemory.Address: - return heaptracker.adr2int(x) - if TP is lltype.SingleFloat: - return longlong.singlefloat2int(x) - return lltype.cast_primitive(lltype.Signed, x) - -def cast_from_int(TYPE, x): - if isinstance(TYPE, lltype.Ptr): - if isinstance(x, (int, long, llmemory.AddressAsInt)): - x = llmemory.cast_int_to_adr(x) - if TYPE is rffi.VOIDP or ( - hasattr(TYPE.TO, '_hints') and - TYPE.TO._hints.get("uncast_on_llgraph")): - # assume that we want a "C-style" cast, without typechecking the value - return rffi.cast(TYPE, x) - return llmemory.cast_adr_to_ptr(x, TYPE) - elif TYPE == llmemory.Address: - if isinstance(x, (int, long, llmemory.AddressAsInt)): - x = llmemory.cast_int_to_adr(x) - assert lltype.typeOf(x) == llmemory.Address - return x - elif TYPE is lltype.SingleFloat: - assert lltype.typeOf(x) is lltype.Signed - return longlong.int2singlefloat(x) - else: - if lltype.typeOf(x) == llmemory.Address: - x = heaptracker.adr2int(x) - return lltype.cast_primitive(TYPE, x) - -def cast_to_ptr(x): - assert isinstance(lltype.typeOf(x), lltype.Ptr) - return lltype.cast_opaque_ptr(llmemory.GCREF, x) - -def cast_from_ptr(TYPE, x): - return lltype.cast_opaque_ptr(TYPE, x) - -def cast_to_floatstorage(x): - if isinstance(x, float): - return longlong.getfloatstorage(x) # common case - if IS_32_BIT: - assert longlong.supports_longlong - if isinstance(x, r_longlong): - return x - if isinstance(x, r_ulonglong): - return rffi.cast(lltype.SignedLongLong, x) - raise TypeError(type(x)) - -def cast_from_floatstorage(TYPE, x): - assert isinstance(x, longlong.r_float_storage) - if TYPE is lltype.Float: - return longlong.getrealfloat(x) - if longlong.is_longlong(TYPE): - return rffi.cast(TYPE, x) - raise TypeError(TYPE) - - -def new_frame(is_oo, cpu): - if is_oo: - frame = OOFrame(cpu) - else: - frame = Frame(cpu) - return _to_opaque(frame) - -_future_values = [] - -def frame_clear(frame, loop): - frame = _from_opaque(frame) - loop = _from_opaque(loop) - assert len(_future_values) == len(loop.inputargs) - frame.loop = loop - frame.env = {} - for i in range(len(loop.inputargs)): - expected_type = loop.inputargs[i].concretetype - assert lltype.typeOf(_future_values[i]) == expected_type - frame.env[loop.inputargs[i]] = _future_values[i] - del _future_values[:] - -def set_future_value_int(index, value): - assert lltype.typeOf(value) is lltype.Signed - set_future_value_ref(index, value) - -def set_future_value_float(index, value): - assert isinstance(value, longlong.r_float_storage) - set_future_value_ref(index, value) - -def set_future_value_ref(index, value): - del _future_values[index:] - assert len(_future_values) == index - _future_values.append(value) - -def frame_execute(frame): - frame = _from_opaque(frame) - if frame.verbose: - values = [frame.env[v] for v in frame.loop.inputargs] - log.trace('Entering CPU frame <- %r' % (values,)) - try: - result = frame.execute() - if frame.verbose: - log.trace('Leaving CPU frame -> #%d' % (result,)) - frame.log_progress() - except Exception, e: - log.ERROR('%s in CPU frame: %s' % (e.__class__.__name__, e)) - # Only invoke pdb when io capturing is not on otherwise py.io complains. - if py.test.config.option.capture == 'no': - import sys, pdb - pdb.post_mortem(sys.exc_info()[2]) - raise - return result - -def frame_descr_index(frame): - frame = _from_opaque(frame) - op = frame.loop.operations[frame.opindex] - return op.fail_index - -def frame_int_getvalue(frame, num): - frame = _from_opaque(frame) - assert num >= 0 - x = frame.fail_args[num] - assert lltype.typeOf(x) is lltype.Signed - return x - -def frame_float_getvalue(frame, num): - frame = _from_opaque(frame) - assert num >= 0 - x = frame.fail_args[num] - assert lltype.typeOf(x) is longlong.FLOATSTORAGE - return x - -def frame_ptr_getvalue(frame, num): - frame = _from_opaque(frame) - assert num >= 0 - x = frame.fail_args[num] - assert lltype.typeOf(x) == llmemory.GCREF - return x - -def frame_get_value_count(frame): - frame = _from_opaque(frame) - return len(frame.fail_args) - -def finish_value_int(frame): - frame = _from_opaque(frame) - x = frame._finish_value - assert isinstance(x, int) - return x - -def finish_value_float(frame): - frame = _from_opaque(frame) - x = frame._finish_value - assert lltype.typeOf(x) is longlong.FLOATSTORAGE - return x - -def finish_value_ref(frame): - frame = _from_opaque(frame) - x = frame._finish_value - if x is None: - if frame._last_exception is not None: - result = frame._last_exception.args[1] - frame._last_exception = None - return lltype.cast_opaque_ptr(llmemory.GCREF, result) - else: - return lltype.nullptr(llmemory.GCREF.TO) - assert lltype.typeOf(x) == llmemory.GCREF - frame._finish_value = 'deleted by the previous call to finish_value_ref' - return x - -def get_savedata_ref(frame): - frame = _from_opaque(frame) - x = frame._savedata - del frame._savedata - return x - -def set_savedata_ref(frame, value): - frame = _from_opaque(frame) - frame._savedata = value - -##_pseudo_exceptions = {} - -##def _get_error(Class): -## if _llinterp.typer is not None: -## llframe = _llinterp.frame_class(None, None, _llinterp) -## try: -## llframe.make_llexception(Class()) -## except LLException, e: -## return e -## else: -## assert 0, "should have raised" -## else: -## # for tests, a random emulated ll_inst will do -## if Class not in _pseudo_exceptions: -## ll_inst = lltype.malloc(rclass.OBJECT, zero=True) -## ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, -## immortal=True) -## _pseudo_exceptions[Class] = LLException(ll_inst.typeptr, ll_inst) -## return _pseudo_exceptions[Class] - -##def get_overflow_error_value(): -## return lltype.cast_opaque_ptr(llmemory.GCREF, -## _get_error(OverflowError).args[1]) - -def force(opaque_frame): - frame = _from_opaque(opaque_frame) - assert not frame._forced - frame._forced = True - assert frame._may_force >= 0 - call_op = frame.loop.operations[frame._may_force] - opnum = call_op.opnum - if opnum != rop.FINISH: - assert opnum == rop.CALL_MAY_FORCE or opnum == rop.CALL_ASSEMBLER - guard_op = frame.loop.operations[frame._may_force+1] - frame._populate_fail_args(guard_op, skip=call_op.result) - else: - frame._populate_fail_args(call_op) - return frame.fail_index - -##def cast_adr_to_int(memocast, adr): -## # xxx slow -## assert lltype.typeOf(adr) == llmemory.Address -## memocast = _from_opaque(memocast) -## addresses = memocast.addresses -## for i in xrange(len(addresses)-1, -1, -1): -## if addresses[i] == adr: -## return i -## i = len(addresses) -## addresses.append(adr) -## return i - -##def cast_int_to_adr(memocast, int): -## memocast = _from_opaque(memocast) -## assert 0 <= int < len(memocast.addresses) -## return memocast.addresses[int] - -##def get_class_size(memocast, vtable): -## memocast = _from_opaque(memocast) -## return memocast.vtable_to_size[vtable] - -##def set_class_size(memocast, vtable, size): -## memocast = _from_opaque(memocast) -## memocast.vtable_to_size[vtable] = size - -class GuardFailed(Exception): - pass - -# ____________________________________________________________ - - -def do_same_as(x): - return x - -def do_arraylen_gc(arraydescr, array): - array = array._obj.container - return array.getlength() - -def do_strlen(string): - str = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string) - return len(str.chars) - -def do_strgetitem(string, index): - str = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string) - return ord(str.chars[index]) - -def do_unicodelen(string): - uni = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string) - return len(uni.chars) - -def do_unicodegetitem(string, index): - uni = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string) - return ord(uni.chars[index]) - -def do_getarrayitem_gc_int(array, index): - array = array._obj.container - return cast_to_int(array.getitem(index)) - -def do_getarrayitem_raw_int(array, index, itemsize): - array = array.adr.ptr - ITEMTYPE = lltype.typeOf(array).TO.OF - TYPE = symbolic.Size2Type[itemsize] - if TYPE.OF != ITEMTYPE: - array = rffi.cast(lltype.Ptr(TYPE), array) - return cast_to_int(array._obj.getitem(index)) - -def do_getarrayitem_gc_float(array, index): - array = array._obj.container - return cast_to_floatstorage(array.getitem(index)) - -def do_getarrayitem_raw_float(array, index): - array = maybe_uncast(FLOAT_ARRAY_TP, array.adr.ptr) - return cast_to_floatstorage(array._obj.getitem(index)) - -def do_getarrayitem_gc_ptr(array, index): - array = array._obj.container - return cast_to_ptr(array.getitem(index)) - -def _getfield_gc(struct, fieldnum): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), struct) - return getattr(ptr, fieldname) - -def do_getfield_gc_int(struct, fieldnum): - return cast_to_int(_getfield_gc(struct, fieldnum)) - -def do_getfield_gc_float(struct, fieldnum): - return cast_to_floatstorage(_getfield_gc(struct, fieldnum)) - -def do_getfield_gc_ptr(struct, fieldnum): - return cast_to_ptr(_getfield_gc(struct, fieldnum)) - -def _getinteriorfield_gc(struct, fieldnum): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - return getattr(struct, fieldname) - -def do_getinteriorfield_gc_int(array, index, fieldnum): - struct = array._obj.container.getitem(index) - return cast_to_int(_getinteriorfield_gc(struct, fieldnum)) - -def do_getinteriorfield_gc_float(array, index, fieldnum): - struct = array._obj.container.getitem(index) - return cast_to_floatstorage(_getinteriorfield_gc(struct, fieldnum)) - -def do_getinteriorfield_gc_ptr(array, index, fieldnum): - struct = array._obj.container.getitem(index) - return cast_to_ptr(_getinteriorfield_gc(struct, fieldnum)) - -def _getfield_raw(struct, fieldnum): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = cast_from_int(lltype.Ptr(STRUCT), struct) - return getattr(ptr, fieldname) - -def do_getfield_raw_int(struct, fieldnum): - return cast_to_int(_getfield_raw(struct, fieldnum)) - -def do_getfield_raw_float(struct, fieldnum): - return cast_to_floatstorage(_getfield_raw(struct, fieldnum)) - -def do_getfield_raw_ptr(struct, fieldnum): - return cast_to_ptr(_getfield_raw(struct, fieldnum)) - -def do_raw_load_int(struct, offset, descrofs): - TYPE = symbolic.Size2Type[descrofs] - ll_p = rffi.cast(rffi.CCHARP, struct) - ll_p = rffi.cast(lltype.Ptr(TYPE), rffi.ptradd(ll_p, offset)) - value = ll_p[0] - return rffi.cast(lltype.Signed, value) - -def do_raw_load_float(struct, offset): - ll_p = rffi.cast(rffi.CCHARP, struct) - ll_p = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), - rffi.ptradd(ll_p, offset)) - value = ll_p[0] - return value - -def do_raw_store_int(struct, offset, descrofs, value): - TYPE = symbolic.Size2Type[descrofs] - ll_p = rffi.cast(rffi.CCHARP, struct) - ll_p = rffi.cast(lltype.Ptr(TYPE), rffi.ptradd(ll_p, offset)) - ll_p[0] = rffi.cast(TYPE.OF, value) - -def do_raw_store_float(struct, offset, value): - ll_p = rffi.cast(rffi.CCHARP, struct) - ll_p = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), - rffi.ptradd(ll_p, offset)) - ll_p[0] = value - -def do_new(size): - TYPE = symbolic.Size2Type[size] - x = lltype.malloc(TYPE, zero=True) - return cast_to_ptr(x) - -def do_new_array(arraynum, count): - TYPE = symbolic.Size2Type[arraynum] - assert count >= 0 # explode if it's not - x = lltype.malloc(TYPE, count, zero=True) - return cast_to_ptr(x) - -def do_setarrayitem_gc_int(array, index, newvalue): - array = array._obj.container - ITEMTYPE = lltype.typeOf(array).OF - newvalue = cast_from_int(ITEMTYPE, newvalue) - array.setitem(index, newvalue) - -def do_setarrayitem_raw_int(array, index, newvalue, itemsize): - array = array.adr.ptr - ITEMTYPE = lltype.typeOf(array).TO.OF - TYPE = symbolic.Size2Type[itemsize] - if TYPE.OF != ITEMTYPE: - array = rffi.cast(lltype.Ptr(TYPE), array) - newvalue = cast_from_int(TYPE.OF, newvalue) - array._obj.setitem(index, newvalue) - -def do_setarrayitem_gc_float(array, index, newvalue): - array = array._obj.container - ITEMTYPE = lltype.typeOf(array).OF - newvalue = cast_from_floatstorage(ITEMTYPE, newvalue) - array.setitem(index, newvalue) - - -def do_setarrayitem_raw_float(array, index, newvalue): - array = maybe_uncast(FLOAT_ARRAY_TP, array.adr.ptr) - ITEMTYPE = lltype.typeOf(array).TO.OF - newvalue = cast_from_floatstorage(ITEMTYPE, newvalue) - array._obj.setitem(index, newvalue) - -def do_setarrayitem_gc_ptr(array, index, newvalue): - array = array._obj.container - ITEMTYPE = lltype.typeOf(array).OF - newvalue = cast_from_ptr(ITEMTYPE, newvalue) - array.setitem(index, newvalue) - -def new_setfield_gc(cast_func): - def do_setfield_gc(struct, fieldnum, newvalue): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), struct) - FIELDTYPE = getattr(STRUCT, fieldname) - newvalue = cast_func(FIELDTYPE, newvalue) - setattr(ptr, fieldname, newvalue) - return do_setfield_gc -do_setfield_gc_int = new_setfield_gc(cast_from_int) -do_setfield_gc_float = new_setfield_gc(cast_from_floatstorage) -do_setfield_gc_ptr = new_setfield_gc(cast_from_ptr) - -def new_setinteriorfield_gc(cast_func): - def do_setinteriorfield_gc(array, index, fieldnum, newvalue): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - struct = array._obj.container.getitem(index) - FIELDTYPE = getattr(STRUCT, fieldname) - setattr(struct, fieldname, cast_func(FIELDTYPE, newvalue)) - return do_setinteriorfield_gc -do_setinteriorfield_gc_int = new_setinteriorfield_gc(cast_from_int) -do_setinteriorfield_gc_float = new_setinteriorfield_gc(cast_from_floatstorage) -do_setinteriorfield_gc_ptr = new_setinteriorfield_gc(cast_from_ptr) - -def do_setfield_raw_int(struct, fieldnum, newvalue): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = cast_from_int(lltype.Ptr(STRUCT), struct) - FIELDTYPE = getattr(STRUCT, fieldname) - newvalue = cast_from_int(FIELDTYPE, newvalue) - setattr(ptr, fieldname, newvalue) - -def do_setfield_raw_float(struct, fieldnum, newvalue): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = cast_from_int(lltype.Ptr(STRUCT), struct) - FIELDTYPE = getattr(STRUCT, fieldname) - newvalue = cast_from_floatstorage(FIELDTYPE, newvalue) - setattr(ptr, fieldname, newvalue) - -def do_setfield_raw_ptr(struct, fieldnum, newvalue): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = cast_from_int(lltype.Ptr(STRUCT), struct) - FIELDTYPE = getattr(STRUCT, fieldname) - newvalue = cast_from_ptr(FIELDTYPE, newvalue) - setattr(ptr, fieldname, newvalue) - -def do_newstr(length): - x = rstr.mallocstr(length) - return cast_to_ptr(x) - -def do_newunicode(length): - return cast_to_ptr(rstr.mallocunicode(length)) - -def do_strsetitem(string, index, newvalue): - str = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string) - str.chars[index] = chr(newvalue) - -def do_unicodesetitem(string, index, newvalue): - uni = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string) - uni.chars[index] = unichr(newvalue) - -def do_copystrcontent(src, dst, srcstart, dststart, length): - src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), src) - dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), dst) - assert 0 <= srcstart <= srcstart + length <= len(src.chars) - assert 0 <= dststart <= dststart + length <= len(dst.chars) - rstr.copy_string_contents(src, dst, srcstart, dststart, length) - -def do_copyunicodecontent(src, dst, srcstart, dststart, length): - src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), src) - dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst) - assert 0 <= srcstart <= srcstart + length <= len(src.chars) - assert 0 <= dststart <= dststart + length <= len(dst.chars) - rstr.copy_unicode_contents(src, dst, srcstart, dststart, length) - -def do_math_sqrt(value): - import math - y = cast_from_floatstorage(lltype.Float, value) - x = math.sqrt(y) - return cast_to_floatstorage(x) - -# ---------- call ---------- - -_call_args_i = [] -_call_args_r = [] -_call_args_f = [] - -def do_call_pushint(x): - _call_args_i.append(x) - -def do_call_pushptr(x): - _call_args_r.append(x) - -def do_call_pushfloat(x): - _call_args_f.append(x) - -kind2TYPE = { - 'i': lltype.Signed, - 'f': lltype.Float, - 'L': lltype.SignedLongLong, - 'S': lltype.SingleFloat, - 'v': lltype.Void, - } - -def _do_call_common(f, args_in_order=None, calldescr=None, - call_with_llptr=False): - ptr = llmemory.cast_int_to_adr(f).ptr - PTR = lltype.typeOf(ptr) - if PTR == rffi.VOIDP: - # it's a pointer to a C function, so we don't have a precise - # signature: create one from the descr - assert call_with_llptr is True - ARGS = map(kind2TYPE.get, calldescr.arg_types) - RESULT = kind2TYPE[calldescr.typeinfo] - FUNC = lltype.FuncType(ARGS, RESULT) - func_to_call = rffi.cast(lltype.Ptr(FUNC), ptr) - else: - assert call_with_llptr is False - FUNC = PTR.TO - ARGS = FUNC.ARGS - func_to_call = ptr._obj._callable - args = cast_call_args(ARGS, _call_args_i, _call_args_r, _call_args_f, - args_in_order) - del _call_args_i[:] - del _call_args_r[:] - del _call_args_f[:] - assert len(ARGS) == len(args) - if hasattr(ptr._obj, 'graph'): - llinterp = _llinterp # it's a global set here by CPU.__init__() - result = llinterp.eval_graph(ptr._obj.graph, args) - # ^^^ may raise, in which case we get an LLException - else: - result = func_to_call(*args) - return result - -def do_call_void(f): - _do_call_common(f) - -def do_call_int(f): - x = _do_call_common(f) - return cast_to_int(x) - -def do_call_float(f): - x = _do_call_common(f) - return cast_to_floatstorage(x) - -def do_call_ptr(f): - x = _do_call_common(f) - return cast_to_ptr(x) - -def cast_call_args(ARGS, args_i, args_r, args_f, args_in_order=None): - argsiter_i = iter(args_i) - argsiter_r = iter(args_r) - argsiter_f = iter(args_f) - if args_in_order is not None: - orderiter = iter(args_in_order) - args = [] - for TYPE in ARGS: - if TYPE is lltype.Void: - x = None - else: - if isinstance(TYPE, ootype.OOType): - if args_in_order is not None: - n = orderiter.next() - assert n == 'r' - x = argsiter_r.next() - x = ootype.cast_from_object(TYPE, x) - elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc': - if args_in_order is not None: - n = orderiter.next() - assert n == 'r' - x = argsiter_r.next() - x = cast_from_ptr(TYPE, x) - elif TYPE is lltype.Float or longlong.is_longlong(TYPE): - if args_in_order is not None: - n = orderiter.next() - assert n == 'f' - x = argsiter_f.next() - x = cast_from_floatstorage(TYPE, x) - else: - if args_in_order is not None: - n = orderiter.next() - assert n == 'i' - x = argsiter_i.next() - x = cast_from_int(TYPE, x) - args.append(x) - assert list(argsiter_i) == [] - assert list(argsiter_r) == [] - assert list(argsiter_f) == [] - return args - - -# for ootype meth and staticmeth -def call_maybe_on_top_of_llinterp(meth, args): - if isinstance(meth, ootype._bound_meth): - mymethod = meth.meth - myargs = [meth.inst] + list(args) - else: - mymethod = meth - myargs = args - try: - if hasattr(mymethod, 'graph'): - llinterp = _llinterp # it's a global set here by CPU.__init__() - result = llinterp.eval_graph(mymethod.graph, myargs) - else: - result = meth(*args) - except XXX-LLException, e: - self._last_exception = e - result = get_err_result_for_type(mymethod._TYPE.RESULT) - return result - -def get_err_result_for_type(T): - if T is ootype.Void: - return None - elif isinstance(T, ootype.OOType): - return ootype.null(T) - else: - return 0 - -def reset_vable(jd, vable): - xxxxxxxxxxxxx - if jd.index_of_virtualizable != -1: - fielddescr = jd.jit_frame_descr - do_setfield_gc_ptr(vable, fielddescr.ofs, - lltype.nullptr(llmemory.GCREF.TO)) - -def redirect_call_assembler(cpu, oldlooptoken, newlooptoken): - oldclt = oldlooptoken.compiled_loop_token - newclt = newlooptoken.compiled_loop_token - OLD = _from_opaque(oldclt.compiled_version).getargtypes() - NEW = _from_opaque(newclt.compiled_version).getargtypes() - assert OLD == NEW - assert not hasattr(oldclt, 'redirected') - oldclt.redirected = weakref.ref(newlooptoken) - -# ____________________________________________________________ - - -def setannotation(func, annotation, specialize_as_constant=False): - - class Entry(ExtRegistryEntry): - "Annotation and specialization for calls to 'func'." - _about_ = func - - if annotation is None or isinstance(annotation, annmodel.SomeObject): - s_result_annotation = annotation - else: - def compute_result_annotation(self, *args_s): - return annotation(*args_s) - - if specialize_as_constant: - def specialize_call(self, hop): - llvalue = func(hop.args_s[0].const) - hop.exception_cannot_occur() - return hop.inputconst(lltype.typeOf(llvalue), llvalue) - else: - # specialize as direct_call - def specialize_call(self, hop): - ARGS = [r.lowleveltype for r in hop.args_r] - RESULT = hop.r_result.lowleveltype - if hop.rtyper.type_system.name == 'lltypesystem': - FUNCTYPE = lltype.FuncType(ARGS, RESULT) - funcptr = lltype.functionptr(FUNCTYPE, func.__name__, - _callable=func, _debugexc=True) - cfunc = hop.inputconst(lltype.Ptr(FUNCTYPE), funcptr) - else: - FUNCTYPE = ootype.StaticMethod(ARGS, RESULT) - sm = ootype._static_meth(FUNCTYPE, _name=func.__name__, _callable=func) - cfunc = hop.inputconst(FUNCTYPE, sm) - args_v = hop.inputargs(*hop.args_r) - hop.exception_is_here() - return hop.genop('direct_call', [cfunc] + args_v, hop.r_result) - - -COMPILEDLOOP = lltype.Ptr(lltype.OpaqueType("CompiledLoop")) -FRAME = lltype.Ptr(lltype.OpaqueType("Frame")) -OOFRAME = lltype.Ptr(lltype.OpaqueType("OOFrame")) - -_TO_OPAQUE[CompiledLoop] = COMPILEDLOOP.TO -_TO_OPAQUE[Frame] = FRAME.TO -_TO_OPAQUE[OOFrame] = OOFRAME.TO - -s_CompiledLoop = annmodel.SomePtr(COMPILEDLOOP) -s_Frame = annmodel.SomePtr(FRAME) - -if longlong.FLOATSTORAGE is lltype.Float: - s_FloatStorage = annmodel.SomeFloat() -elif longlong.FLOATSTORAGE is lltype.SignedLongLong: - s_FloatStorage = annmodel.SomeInteger(knowntype=longlong.r_float_storage) -else: - assert 0 - -setannotation(compile_start, s_CompiledLoop) -setannotation(compile_start_int_var, annmodel.SomeInteger()) -setannotation(compile_start_ref_var, annmodel.SomeInteger()) -setannotation(compile_start_float_var, annmodel.SomeInteger()) -setannotation(compile_started_vars, annmodel.s_None) -setannotation(compile_add, annmodel.s_None) -setannotation(compile_add_descr, annmodel.s_None) -setannotation(compile_add_descr_arg, annmodel.s_None) -setannotation(compile_add_target_token, annmodel.s_None) -setannotation(compile_add_var, annmodel.s_None) -setannotation(compile_add_int_const, annmodel.s_None) -setannotation(compile_add_ref_const, annmodel.s_None) -setannotation(compile_add_float_const, annmodel.s_None) -setannotation(compile_add_int_result, annmodel.SomeInteger()) -setannotation(compile_add_ref_result, annmodel.SomeInteger()) -setannotation(compile_add_float_result, annmodel.SomeInteger()) -setannotation(compile_add_jump_target, annmodel.s_None) -setannotation(compile_add_guard_jump_target, annmodel.s_None) -setannotation(compile_add_fail, annmodel.SomeInteger()) -setannotation(compile_add_fail_arg, annmodel.s_None) -setannotation(compile_redirect_fail, annmodel.s_None) -setannotation(mark_as_free, annmodel.s_None) - -setannotation(new_frame, s_Frame) -setannotation(frame_clear, annmodel.s_None) -setannotation(set_future_value_int, annmodel.s_None) -setannotation(set_future_value_ref, annmodel.s_None) -setannotation(set_future_value_float, annmodel.s_None) -setannotation(frame_execute, annmodel.SomeInteger()) -setannotation(frame_descr_index, annmodel.SomeInteger()) -setannotation(frame_int_getvalue, annmodel.SomeInteger()) -setannotation(frame_ptr_getvalue, annmodel.SomePtr(llmemory.GCREF)) -setannotation(frame_float_getvalue, s_FloatStorage) -setannotation(frame_get_value_count, annmodel.SomeInteger()) - -setannotation(finish_value_int, annmodel.SomeInteger()) -setannotation(finish_value_float, s_FloatStorage) -setannotation(finish_value_ref, annmodel.SomePtr(llmemory.GCREF)) -setannotation(get_savedata_ref, annmodel.SomePtr(llmemory.GCREF)) -setannotation(set_savedata_ref, annmodel.s_None) -setannotation(force, annmodel.SomeInteger()) - -setannotation(do_arraylen_gc, annmodel.SomeInteger()) -setannotation(do_strlen, annmodel.SomeInteger()) -setannotation(do_strgetitem, annmodel.SomeInteger()) -setannotation(do_unicodelen, annmodel.SomeInteger()) -setannotation(do_unicodegetitem, annmodel.SomeInteger()) -setannotation(do_getarrayitem_gc_int, annmodel.SomeInteger()) -setannotation(do_getarrayitem_gc_ptr, annmodel.SomePtr(llmemory.GCREF)) -setannotation(do_getarrayitem_gc_float, s_FloatStorage) -setannotation(do_getarrayitem_raw_int, annmodel.SomeInteger()) -setannotation(do_getarrayitem_raw_float, s_FloatStorage) -setannotation(do_getfield_gc_int, annmodel.SomeInteger()) -setannotation(do_getfield_gc_ptr, annmodel.SomePtr(llmemory.GCREF)) -setannotation(do_getfield_gc_float, s_FloatStorage) -setannotation(do_getfield_raw_int, annmodel.SomeInteger()) -setannotation(do_getfield_raw_ptr, annmodel.SomePtr(llmemory.GCREF)) -setannotation(do_getfield_raw_float, s_FloatStorage) -setannotation(do_getinteriorfield_gc_int, annmodel.SomeInteger()) -setannotation(do_getinteriorfield_gc_ptr, annmodel.SomePtr(llmemory.GCREF)) -setannotation(do_getinteriorfield_gc_float, s_FloatStorage) -setannotation(do_raw_load_int, annmodel.SomeInteger()) -setannotation(do_new, annmodel.SomePtr(llmemory.GCREF)) -setannotation(do_new_array, annmodel.SomePtr(llmemory.GCREF)) -setannotation(do_setarrayitem_gc_int, annmodel.s_None) -setannotation(do_setarrayitem_gc_ptr, annmodel.s_None) -setannotation(do_setarrayitem_gc_float, annmodel.s_None) -setannotation(do_setarrayitem_raw_int, annmodel.s_None) -setannotation(do_setarrayitem_raw_float, annmodel.s_None) -setannotation(do_setfield_gc_int, annmodel.s_None) -setannotation(do_setfield_gc_ptr, annmodel.s_None) -setannotation(do_setfield_gc_float, annmodel.s_None) -setannotation(do_setfield_raw_int, annmodel.s_None) -setannotation(do_setfield_raw_ptr, annmodel.s_None) -setannotation(do_setfield_raw_float, annmodel.s_None) -setannotation(do_setinteriorfield_gc_int, annmodel.s_None) -setannotation(do_setinteriorfield_gc_ptr, annmodel.s_None) -setannotation(do_setinteriorfield_gc_float, annmodel.s_None) -setannotation(do_raw_store_int, annmodel.s_None) -setannotation(do_newstr, annmodel.SomePtr(llmemory.GCREF)) -setannotation(do_strsetitem, annmodel.s_None) -setannotation(do_newunicode, annmodel.SomePtr(llmemory.GCREF)) -setannotation(do_unicodesetitem, annmodel.s_None) -setannotation(do_call_pushint, annmodel.s_None) -setannotation(do_call_pushptr, annmodel.s_None) -setannotation(do_call_int, annmodel.SomeInteger()) -setannotation(do_call_ptr, annmodel.SomePtr(llmemory.GCREF)) -setannotation(do_call_float, s_FloatStorage) -setannotation(do_call_void, annmodel.s_None) diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -1,927 +1,840 @@ -""" -Minimal-API wrapper around the llinterpreter to run operations. -""" -from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.jit_hooks import LOOP_RUN_CONTAINER From noreply at buildbot.pypy.org Thu Oct 18 11:17:55 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 11:17:55 +0200 (CEST) Subject: [pypy-commit] pypy default: issue1293 fixed: changing func_code must not change the docstring Message-ID: <20121018091755.169B31C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58202:5b2403f92a1e Date: 2012-10-18 11:17 +0200 http://bitbucket.org/pypy/pypy/changeset/5b2403f92a1e/ Log: issue1293 fixed: changing func_code must not change the docstring diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -415,6 +415,7 @@ raise operationerrfmt(space.w_ValueError, "%s() requires a code object with %d free vars, not %d", self.name, closure_len, len(code.co_freevars)) + self.fget_func_doc(space) # see test_issue1293 self.code = code def fget_func_closure(self, space): diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py --- a/pypy/interpreter/test/test_function.py +++ b/pypy/interpreter/test/test_function.py @@ -299,6 +299,12 @@ assert f.__doc__ == u"hi" assert type(f.__doc__) is unicode + def test_issue1293(self): + def f1(): "doc f1" + def f2(): "doc f2" + f1.func_code = f2.func_code + assert f1.__doc__ == "doc f1" + def test_subclassing(self): # cannot subclass 'function' or 'builtin_function' def f(): From noreply at buildbot.pypy.org Thu Oct 18 11:28:43 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 11:28:43 +0200 (CEST) Subject: [pypy-commit] pypy default: issue1292: simplify the repr() of types, now that most built-in types Message-ID: <20121018092843.3C9601C0502@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58203:273ee4e3a74c Date: 2012-10-18 11:28 +0200 http://bitbucket.org/pypy/pypy/changeset/273ee4e3a74c/ Log: issue1292: simplify the repr() of types, now that most built-in types are indeed written in RPython and not in pure Python. We'll need to check this night's lib-python test run to be sure it's correct... diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py --- a/pypy/objspace/std/test/test_typeobject.py +++ b/pypy/objspace/std/test/test_typeobject.py @@ -743,7 +743,13 @@ assert repr(complex) == "" assert repr(property) == "" assert repr(TypeError) == "" - + + def test_repr_issue1292(self): + d = {'object': object} # no __name__ + exec "class A(object): pass\n" in d + assert d['A'].__module__ == '__builtin__' # obscure, follows CPython + assert repr(d['A']) == "" + def test_invalid_mro(self): class A(object): pass 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 @@ -876,8 +876,7 @@ mod = None else: mod = space.str_w(w_mod) - if (not w_obj.is_heaptype() or - (mod == '__builtin__' or mod == 'exceptions')): + if not w_obj.is_heaptype(): kind = 'type' else: kind = 'class' From noreply at buildbot.pypy.org Thu Oct 18 11:30:15 2012 From: noreply at buildbot.pypy.org (anntzer) Date: Thu, 18 Oct 2012 11:30:15 +0200 (CEST) Subject: [pypy-commit] pypy default: Allow unicode for ctypes Structure field names. Message-ID: <20121018093015.7FB821C0502@cobra.cs.uni-duesseldorf.de> Author: Antony Lee Branch: Changeset: r58204:2020097f3291 Date: 2012-10-17 22:24 -0700 http://bitbucket.org/pypy/pypy/changeset/2020097f3291/ Log: Allow unicode for ctypes Structure field names. (Useful e.g. with the unicode_literals future import.) diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py --- a/lib_pypy/_ctypes/structure.py +++ b/lib_pypy/_ctypes/structure.py @@ -69,7 +69,8 @@ resnames.append(name) names = resnames self._names = names - self.__dict__.update(fields) + for name, field in fields.items(): + setattr(self, name, field) class Field(object): def __init__(self, name, offset, size, ctype, num, is_bitfield): diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py +++ b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py @@ -441,6 +441,11 @@ p = pointer(obj) assert p.contents._b_base_ is p + def test_unicode_field_name(self): + # setattr autoconverts field names to bytes + class X(Structure): + _fields_ = [(u"i", c_int)] + class TestPointerMember(BaseCTypesTestChecker): def test_1(self): From noreply at buildbot.pypy.org Thu Oct 18 11:30:16 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 11:30:16 +0200 (CEST) Subject: [pypy-commit] pypy default: Merged in anntzer/pypy (pull request #89) Message-ID: <20121018093016.AD1F01C0502@cobra.cs.uni-duesseldorf.de> Author: arigo Branch: Changeset: r58205:98a9f4ed53bb Date: 2012-10-18 11:30 +0200 http://bitbucket.org/pypy/pypy/changeset/98a9f4ed53bb/ Log: Merged in anntzer/pypy (pull request #89) diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py --- a/lib_pypy/_ctypes/structure.py +++ b/lib_pypy/_ctypes/structure.py @@ -69,7 +69,8 @@ resnames.append(name) names = resnames self._names = names - self.__dict__.update(fields) + for name, field in fields.items(): + setattr(self, name, field) class Field(object): def __init__(self, name, offset, size, ctype, num, is_bitfield): diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py +++ b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py @@ -441,6 +441,11 @@ p = pointer(obj) assert p.contents._b_base_ is p + def test_unicode_field_name(self): + # setattr autoconverts field names to bytes + class X(Structure): + _fields_ = [(u"i", c_int)] + class TestPointerMember(BaseCTypesTestChecker): def test_1(self): From noreply at buildbot.pypy.org Thu Oct 18 13:29:07 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Thu, 18 Oct 2012 13:29:07 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: tweak figure, add layers that show the frame chains Message-ID: <20121018112907.2E8931C00FA@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4871:35f18da6f120 Date: 2012-10-18 09:58 +0200 http://bitbucket.org/pypy/extradoc/changeset/35f18da6f120/ Log: tweak figure, add layers that show the frame chains diff --git a/talk/vmil2012/presentation/figures/framechain1.pdf b/talk/vmil2012/presentation/figures/framechain1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..739545a0285cb335bd79f0276e06c6ae24708fc5 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/framechain2.pdf b/talk/vmil2012/presentation/figures/framechain2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2b173bd9e139a811bd6530ace8387d958e43d570 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/tracing.svg b/talk/vmil2012/presentation/figures/tracing.svg --- a/talk/vmil2012/presentation/figures/tracing.svg +++ b/talk/vmil2012/presentation/figures/tracing.svg @@ -36,17 +36,17 @@ guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:window-width="1280" - inkscape:window-height="776" + inkscape:window-width="1680" + inkscape:window-height="1026" id="namedview24385" showgrid="false" - inkscape:zoom="0.5941137" - inkscape:cx="340.25415" - inkscape:cy="397.92978" + inkscape:zoom="1.6804073" + inkscape:cx="342.18911" + inkscape:cy="336.87906" inkscape:window-x="0" inkscape:window-y="24" inkscape:window-maximized="1" - inkscape:current-layer="layer11" + inkscape:current-layer="layer1" fit-margin-top="2" fit-margin-left="2" fit-margin-right="2" @@ -65,6 +65,44 @@ + + + + + + + + + + + + + + + + + + + + + + + return self.build(n) + + + + + Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4872:ebcb0e96a290 Date: 2012-10-18 09:59 +0200 http://bitbucket.org/pypy/extradoc/changeset/ebcb0e96a290/ Log: interleave example with explanation slides diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -89,23 +89,27 @@ \begin{itemize} \item VM contains both an interpreter and the tracing JIT compiler \item JIT works by observing and logging what the interpreter does - \begin{itemize} - \item for interesting, commonly executed code paths - \item produces a linear list of operations (trace) - \item automatically does (potentially deep) inlining - \end{itemize} - \item trace is optimized and then turned into machine code + \item for interesting, commonly executed code paths + \item produces a linear list of operations (trace) \end{itemize} \end{frame} \begin{frame} + \includegraphics[scale=0.4]{figures/loop01} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop02} +\end{frame} + +\begin{frame} \frametitle{Guards} \begin{itemize} \item Points of control flow divergence are marked with guards \item Operations that check whether conditions are still true \item When a guard fails, execution of the trace stops and continues in the interpreter \pause - \item \emph{This talk:} describe technology and design decisions around guards + \item \emph{This talk:} technology and design decisions of guards \pause \begin{block}{Guard Characteristics} \begin{itemize} @@ -117,6 +121,53 @@ \end{itemize} \end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop03} +\end{frame} + +\begin{frame} + \frametitle{Inlining} + Tracing automatically does (potentially deep) inlining +\end{frame} + + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop04} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop05} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop06} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop07} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop08} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop09} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop10} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop11} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop12} +\end{frame} + % this talk wants to go over a lot of details that are usually glossed over as % "easy" when tracing JITs are introduced. @@ -139,10 +190,6 @@ \end{itemize} \end{frame} -\begin{frame} - \frametitle{Running Example} -\end{frame} - %\section{High-Level} \begin{frame} @@ -156,6 +203,15 @@ \end{frame} \begin{frame} + \includegraphics[scale=0.4]{figures/loop07} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/framechain1} +\end{frame} + + +\begin{frame} \frametitle{Symbolic Frame Compression} \begin{itemize} \item There are \emph{a lot of} guards @@ -169,9 +225,26 @@ \end{frame} \begin{frame} + \includegraphics[scale=0.4]{figures/loop07} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/framechain1} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop08} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/framechain2} +\end{frame} + +\begin{frame} \frametitle{Interaction with Optimization} \begin{itemize} \item Some optimizations make it necessary to store extra information in symbolic frames + \pause \item examples: \begin{itemize} \item allocation removal (need to allocate objects before resuming) @@ -185,9 +258,10 @@ \frametitle{Emitting Guards} Guards are compiled as \begin{itemize} - \item Quick Check if the condition holds + \item quick Check if the condition holds \item and a mapping of machine locations to JIT-variables % indirection using the fail-boxes \end{itemize} + \pause In case of failure \begin{itemize} \item execution jumps to shared compensation code, decodes and stores mapping From noreply at buildbot.pypy.org Thu Oct 18 13:29:09 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Thu, 18 Oct 2012 13:29:09 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: swap slides Message-ID: <20121018112909.720991C00FA@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4873:a9047af3bd5f Date: 2012-10-18 13:28 +0200 http://bitbucket.org/pypy/extradoc/changeset/a9047af3bd5f/ Log: swap slides diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -292,6 +292,28 @@ \includegraphics[width=1\textwidth]{figures/bridge_patched.pdf} \end{figure} \end{frame} + +\begin{frame}[t,fragile] +\pgfplotsset{tick label style={font=\tiny\bfseries}, +label style={font=\small}, +legend style={font=\tiny} +} + \frametitle{Guard Failure Rates / Go Benchmark (29989 Guards)} + \begin{figure} + \centering + \begin{tikzpicture} + \begin{axis}[ + xlabel= Guards by failures, + ylabel=Relative \# of failures, + xtick=\empty, + ytick=\empty, + ] + \input{figures/go_data} + \end{axis} + \end{tikzpicture} + \end{figure} +\end{frame} + \begin{frame}[t,fragile] \pgfplotsset{tick label style={font=\tiny\bfseries}, label style={font=\small}, @@ -312,26 +334,6 @@ \end{tikzpicture} \end{figure} \end{frame} -\begin{frame}[t,fragile] -\pgfplotsset{tick label style={font=\tiny\bfseries}, -label style={font=\small}, -legend style={font=\tiny} -} - \frametitle{Guard Failure Rates / Go Benchmark} - \begin{figure} - \centering - \begin{tikzpicture} - \begin{axis}[ - xlabel= Guards by failures, - ylabel=Relative \# of failures, - xtick=\empty, - ytick=\empty, - ] - \input{figures/go_data} - \end{axis} - \end{tikzpicture} - \end{figure} -\end{frame} %\section{Evaluation} From noreply at buildbot.pypy.org Thu Oct 18 13:29:45 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Thu, 18 Oct 2012 13:29:45 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: tweaks Message-ID: <20121018112945.39CCC1C00FA@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4874:dd7991b6dc35 Date: 2012-10-18 13:29 +0200 http://bitbucket.org/pypy/extradoc/changeset/dd7991b6dc35/ Log: tweaks diff --git a/talk/vmil2012/presentation/figures/tracing.svg b/talk/vmil2012/presentation/figures/tracing.svg --- a/talk/vmil2012/presentation/figures/tracing.svg +++ b/talk/vmil2012/presentation/figures/tracing.svg @@ -36,8 +36,8 @@ guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:window-width="1680" - inkscape:window-height="1026" + inkscape:window-width="1920" + inkscape:window-height="1176" id="namedview24385" showgrid="false" inkscape:zoom="1.6804073" @@ -4275,7 +4275,7 @@ inkscape:groupmode="layer" id="layer2" inkscape:label="Framechain 1" - style="display:none"> + style="display:inline"> + style="display:inline"> Author: Antonio Cuni Branch: py3k Changeset: r58206:bdb58d5150ad Date: 2012-10-18 12:05 +0200 http://bitbucket.org/pypy/pypy/changeset/bdb58d5150ad/ Log: in pypy we simply don't have complex.__floordiv__, but TypeError is raised anyway when trying to // a complex number diff --git a/lib-python/3.2/test/test_complex.py b/lib-python/3.2/test/test_complex.py --- a/lib-python/3.2/test/test_complex.py +++ b/lib-python/3.2/test/test_complex.py @@ -106,8 +106,9 @@ self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j) def test_floordiv(self): - self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 1.5+0j) - self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 0+0j) + import operator + self.assertRaises(TypeError, operator.__floordiv__, 3+0j, 1.5+0j) + self.assertRaises(TypeError, operator.__floordiv__, 3+0j, 0+0j) def test_richcompare(self): self.assertIs(complex.__eq__(1+1j, 1<<10000), False) @@ -153,10 +154,11 @@ check(2 ** 53, range(-100, 0), lambda delta: True) def test_mod(self): + import operator # % is no longer supported on complex numbers - self.assertRaises(TypeError, (1+1j).__mod__, 0+0j) + self.assertRaises(TypeError, operator.__mod__, (1+1j), 0+0j) self.assertRaises(TypeError, lambda: (3.33+4.43j) % 0) - self.assertRaises(TypeError, (1+1j).__mod__, 4.3j) + self.assertRaises(TypeError, operator.__mod__, (1+1j), 4.3j) def test_divmod(self): self.assertRaises(TypeError, divmod, 1+1j, 1+0j) From noreply at buildbot.pypy.org Thu Oct 18 14:23:42 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Thu, 18 Oct 2012 14:23:42 +0200 (CEST) Subject: [pypy-commit] pypy py3k: the fact that complex.__lt__ & co. returns NotImplemented is an impl detail Message-ID: <20121018122342.2A48E1C0502@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58207:8617a5ed3187 Date: 2012-10-18 12:06 +0200 http://bitbucket.org/pypy/pypy/changeset/8617a5ed3187/ Log: the fact that complex.__lt__ & co. returns NotImplemented is an impl detail diff --git a/lib-python/3.2/test/test_complex.py b/lib-python/3.2/test/test_complex.py --- a/lib-python/3.2/test/test_complex.py +++ b/lib-python/3.2/test/test_complex.py @@ -123,10 +123,11 @@ self.assertIs(complex.__ne__(f+0j, f), False) self.assertIs(complex.__eq__(complex(f, f), f), False) self.assertIs(complex.__ne__(complex(f, f), f), True) - self.assertIs(complex.__lt__(1+1j, 2+2j), NotImplemented) - self.assertIs(complex.__le__(1+1j, 2+2j), NotImplemented) - self.assertIs(complex.__gt__(1+1j, 2+2j), NotImplemented) - self.assertIs(complex.__ge__(1+1j, 2+2j), NotImplemented) + if support.check_impl_detail(pypy=False): + self.assertIs(complex.__lt__(1+1j, 2+2j), NotImplemented) + self.assertIs(complex.__le__(1+1j, 2+2j), NotImplemented) + self.assertIs(complex.__gt__(1+1j, 2+2j), NotImplemented) + self.assertIs(complex.__ge__(1+1j, 2+2j), NotImplemented) self.assertRaises(TypeError, operator.lt, 1+1j, 2+2j) self.assertRaises(TypeError, operator.le, 1+1j, 2+2j) self.assertRaises(TypeError, operator.gt, 1+1j, 2+2j) From noreply at buildbot.pypy.org Thu Oct 18 14:23:43 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Thu, 18 Oct 2012 14:23:43 +0200 (CEST) Subject: [pypy-commit] pypy py3k: if a complex number is created by just a negative imaginary part, the real part should be -0.0, not 0.0. Message-ID: <20121018122343.5251F1C0502@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58208:b0ae89b4e3bc Date: 2012-10-18 14:14 +0200 http://bitbucket.org/pypy/pypy/changeset/b0ae89b4e3bc/ Log: if a complex number is created by just a negative imaginary part, the real part should be -0.0, not 0.0. See CPython issue 9011: http://bugs.python.org/issue9011 diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py --- a/pypy/objspace/std/complextype.py +++ b/pypy/objspace/std/complextype.py @@ -71,7 +71,10 @@ imagpart = '-1.0' else: imagpart = s[realstart:newstop] - return '0.0', imagpart + if imagpart[0] == '-': + return '-0.0', imagpart + else: + return '0.0', imagpart else: return s[realstart:realstop], '0.0' diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -45,7 +45,7 @@ test_cparse('(1-6j)', '1', '-6') test_cparse(' ( +3.14-6J )', '+3.14', '-6') test_cparse(' +J', '0.0', '1.0') - test_cparse(' -J', '0.0', '-1.0') + test_cparse(' -J', '-0.0', '-1.0') def test_unpackcomplex(self): space = self.space @@ -572,3 +572,20 @@ def test_complex_two_arguments(self): raises(TypeError, complex, 5, None) + + def test_negated_imaginary_literal(self): + def sign(x): + import math + return math.copysign(1.0, x) + z0 = -0j + z1 = -7j + z2 = -1e1000j + # Note: In versions of Python < 3.2, a negated imaginary literal + # accidentally ended up with real part 0.0 instead of -0.0 + assert sign(z0.real) == -1 + assert sign(z0.imag) == -1 + assert sign(z1.real) == -1 + assert sign(z1.imag) == -1 + assert sign(z2.real) == -1 + assert sign(z2.real) == -1 + From noreply at buildbot.pypy.org Thu Oct 18 14:23:44 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Thu, 18 Oct 2012 14:23:44 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge heads Message-ID: <20121018122344.BC0D71C0502@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58209:5a77344eeda8 Date: 2012-10-18 14:23 +0200 http://bitbucket.org/pypy/pypy/changeset/5a77344eeda8/ Log: merge heads diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -852,7 +852,8 @@ def _getdefaults(self, space): "NOT_RPYTHON" defs_w = [] - for name, defaultval in self._staticdefs: + unwrap_spec = self._code._unwrap_spec[-len(self._staticdefs):] + for i, (name, defaultval) in enumerate(self._staticdefs): if name.startswith('w_'): assert defaultval is None, ( "%s: default value for '%s' can only be None; " @@ -860,7 +861,11 @@ self._code.identifier, name)) defs_w.append(None) else: - defs_w.append(space.wrap(defaultval)) + spec = unwrap_spec[i] + if isinstance(defaultval, str) and spec not in [str]: + defs_w.append(space.wrapbytes(defaultval)) + else: + defs_w.append(space.wrap(defaultval)) if self._code._unwrap_spec: UNDEFINED = object() alldefs_w = [UNDEFINED] * len(self._code.sig[0]) 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 @@ -611,6 +611,16 @@ never_called py.test.raises(AssertionError, space.wrap, gateway.interp2app_temp(g)) + def test_unwrap_spec_default_bytes(self): + space = self.space + @gateway.unwrap_spec(s='bufferstr') + def g(space, s=''): + return space.wrap(type(s) is str) + w_g = space.wrap(gateway.interp2app_temp(g)) + args = argument.Arguments(space, []) + w_res = space.call_args(w_g, args) + assert space.eq_w(w_res, space.w_True) + def test_unwrap_spec_default_applevel_bytes(self): space = self.space @gateway.unwrap_spec(w_x=WrappedDefault('foo')) diff --git a/pypy/module/_collections/test/test_deque.py b/pypy/module/_collections/test/test_deque.py --- a/pypy/module/_collections/test/test_deque.py +++ b/pypy/module/_collections/test/test_deque.py @@ -171,7 +171,7 @@ assert list(d) == list(reversed(range(1000, 1200))) # n = 100 - data = map(str, range(n)) + data = list(map(str, range(n))) for i in range(n): d = deque(data[:i]) r = d.reverse() diff --git a/pypy/objspace/std/specialisedtupleobject.py b/pypy/objspace/std/specialisedtupleobject.py --- a/pypy/objspace/std/specialisedtupleobject.py +++ b/pypy/objspace/std/specialisedtupleobject.py @@ -188,15 +188,26 @@ Cls_ff = make_specialised_class((float, float)) #Cls_ooo = make_specialised_class((object, object, object)) +def is_int_w(space, w_obj): + """Determine if obj can be safely casted to an int_w""" + try: + space.int_w(w_obj) + except OperationError, e: + if not (e.match(space, space.w_OverflowError) or + e.match(space, space.w_TypeError)): + raise + return False + return True + def makespecialisedtuple(space, list_w): if len(list_w) == 2: w_arg1, w_arg2 = list_w w_type1 = space.type(w_arg1) #w_type2 = space.type(w_arg2) # - if w_type1 is space.w_int: + if w_type1 is space.w_int and is_int_w(space, w_arg1): w_type2 = space.type(w_arg2) - if w_type2 is space.w_int: + if w_type2 is space.w_int and is_int_w(space, w_arg2): return Cls_ii(space, w_arg1, w_arg2) #elif w_type2 is space.w_str: # return Cls_is(space, w_arg1, w_arg2) diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py b/pypy/objspace/std/test/test_specialisedtupleobject.py --- a/pypy/objspace/std/test/test_specialisedtupleobject.py +++ b/pypy/objspace/std/test/test_specialisedtupleobject.py @@ -243,6 +243,10 @@ assert a == (1, 2.2,) + b assert not a != (1, 2.2) + b + def test_ovfl_bug(self): + # previously failed + a = (0xffffffffffffffff, 0) + class AppTestAll(test_tupleobject.AppTestW_TupleObject): pass From noreply at buildbot.pypy.org Thu Oct 18 15:28:22 2012 From: noreply at buildbot.pypy.org (Gabriel) Date: Thu, 18 Oct 2012 15:28:22 +0200 (CEST) Subject: [pypy-commit] pypy default: Don't forget the return value, so that ioctl works on int args. Message-ID: <20121018132822.EF6EC1C1CC6@cobra.cs.uni-duesseldorf.de> Author: Gabriel Branch: Changeset: r58210:731e68c58945 Date: 2012-10-12 19:07 +0200 http://bitbucket.org/pypy/pypy/changeset/731e68c58945/ Log: Don't forget the return value, so that ioctl works on int args. 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 @@ -250,6 +250,9 @@ else: intarg = rffi.cast(rffi.INT, intarg) # C long => C int rv = ioctl_int(fd, op, intarg) + if rv < 0: + raise _get_error(space, "ioctl") + return space.wrap(rv) try: arg = space.bufferstr_w(w_arg) From noreply at buildbot.pypy.org Thu Oct 18 15:28:24 2012 From: noreply at buildbot.pypy.org (Gabriel) Date: Thu, 18 Oct 2012 15:28:24 +0200 (CEST) Subject: [pypy-commit] pypy default: Test ioctl with int args Message-ID: <20121018132824.376091C1CC6@cobra.cs.uni-duesseldorf.de> Author: Gabriel Branch: Changeset: r58211:52fe31bb9ef9 Date: 2012-10-12 17:35 +0200 http://bitbucket.org/pypy/pypy/changeset/52fe31bb9ef9/ Log: Test ioctl with int args diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -171,6 +171,17 @@ res = fcntl.ioctl(0, TIOCGPGRP, "\x00\x00") assert res == expected + def test_ioctl_int(self): + import os + import fcntl + #from termios import TCFLSH, TCIOFLUSH + TCFLSH = 0x540b + TCIOFLUSH = 2 + + if not os.isatty(0): + skip("stdin is not a tty") + assert fcntl.ioctl(0, TCFLSH, TCIOFLUSH) == 0 + def test_lockf_with_ex(self): import fcntl f = open(self.tmp, "w") From noreply at buildbot.pypy.org Thu Oct 18 15:28:25 2012 From: noreply at buildbot.pypy.org (Gabriel) Date: Thu, 18 Oct 2012 15:28:25 +0200 (CEST) Subject: [pypy-commit] pypy default: Don't hardcode termios values. Message-ID: <20121018132825.875311C1CC6@cobra.cs.uni-duesseldorf.de> Author: Gabriel Branch: Changeset: r58212:5d789b85d678 Date: 2012-10-18 14:56 +0200 http://bitbucket.org/pypy/pypy/changeset/5d789b85d678/ Log: Don't hardcode termios values. diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -13,7 +13,7 @@ class AppTestFcntl: def setup_class(cls): - space = gettestobjspace(usemodules=('fcntl', 'array', 'struct')) + space = gettestobjspace(usemodules=('fcntl', 'array', 'struct', 'termios')) cls.space = space tmpprefix = str(udir.ensure('test_fcntl', dir=1).join('tmp_')) cls.w_tmp = space.wrap(tmpprefix) @@ -136,11 +136,9 @@ import array import sys, os - if "linux" in sys.platform: - TIOCGPGRP = 0x540f - elif "darwin" in sys.platform or "freebsd" in sys.platform: - TIOCGPGRP = 0x40047477 - else: + try: + from termios import TIOCGPGRP + except ImportError: skip("don't know how to test ioctl() on this platform") raises(TypeError, fcntl.ioctl, "foo") @@ -174,9 +172,11 @@ def test_ioctl_int(self): import os import fcntl - #from termios import TCFLSH, TCIOFLUSH - TCFLSH = 0x540b - TCIOFLUSH = 2 + + try: + from termios import TCFLSH, TCIOFLUSH + except ImportError: + skip("don't know how to test ioctl() on this platform") if not os.isatty(0): skip("stdin is not a tty") From noreply at buildbot.pypy.org Thu Oct 18 15:28:26 2012 From: noreply at buildbot.pypy.org (Gabriel) Date: Thu, 18 Oct 2012 15:28:26 +0200 (CEST) Subject: [pypy-commit] pypy default: Create pseudo-terms so that the ioctl tests can run without a terminal. Message-ID: <20121018132826.C486D1C1CC6@cobra.cs.uni-duesseldorf.de> Author: Gabriel Branch: Changeset: r58213:22bdac404cab Date: 2012-10-18 15:20 +0200 http://bitbucket.org/pypy/pypy/changeset/22bdac404cab/ Log: Create pseudo-terms so that the ioctl tests can run without a terminal. diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -138,6 +138,7 @@ try: from termios import TIOCGPGRP + import pty except ImportError: skip("don't know how to test ioctl() on this platform") @@ -146,28 +147,32 @@ #raises(TypeError, fcntl.ioctl, 0, TIOCGPGRP, float(0)) raises(TypeError, fcntl.ioctl, 0, TIOCGPGRP, 1, "foo") - if not os.isatty(0): - skip("stdin is not a tty") + child_pid, mfd = pty.fork() + if child_pid == 0: + # We're the child + return + try: + buf = array.array('h', [0]) + res = fcntl.ioctl(mfd, TIOCGPGRP, buf, True) + assert res == 0 + assert buf[0] != 0 + expected = buf.tostring() - buf = array.array('h', [0]) - res = fcntl.ioctl(0, TIOCGPGRP, buf, True) - assert res == 0 - assert buf[0] != 0 - expected = buf.tostring() + if '__pypy__' in sys.builtin_module_names or sys.version_info >= (2,5): + buf = array.array('h', [0]) + res = fcntl.ioctl(mfd, TIOCGPGRP, buf) + assert res == 0 + assert buf.tostring() == expected - if '__pypy__' in sys.builtin_module_names or sys.version_info >= (2,5): - buf = array.array('h', [0]) - res = fcntl.ioctl(0, TIOCGPGRP, buf) - assert res == 0 - assert buf.tostring() == expected + res = fcntl.ioctl(mfd, TIOCGPGRP, buf, False) + assert res == expected - res = fcntl.ioctl(0, TIOCGPGRP, buf, False) - assert res == expected + raises(TypeError, fcntl.ioctl, mfd, TIOCGPGRP, "\x00\x00", True) - raises(TypeError, fcntl.ioctl, 0, TIOCGPGRP, "\x00\x00", True) - - res = fcntl.ioctl(0, TIOCGPGRP, "\x00\x00") - assert res == expected + res = fcntl.ioctl(mfd, TIOCGPGRP, "\x00\x00") + assert res == expected + finally: + os.close(mfd) def test_ioctl_int(self): import os @@ -175,12 +180,16 @@ try: from termios import TCFLSH, TCIOFLUSH + import pty except ImportError: skip("don't know how to test ioctl() on this platform") - if not os.isatty(0): - skip("stdin is not a tty") - assert fcntl.ioctl(0, TCFLSH, TCIOFLUSH) == 0 + mfd, sfd = pty.openpty() + try: + assert fcntl.ioctl(mfd, TCFLSH, TCIOFLUSH) == 0 + finally: + os.close(mfd) + os.close(sfd) def test_lockf_with_ex(self): import fcntl From noreply at buildbot.pypy.org Thu Oct 18 16:13:10 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Thu, 18 Oct 2012 16:13:10 +0200 (CEST) Subject: [pypy-commit] buildbot default: don't run pypy-c -A tests on py3k nightly. There is no way they can run in their current form, because we run py.test on top of the translated pypy-c, which means that we will try to import the pypy package no top of pypy3, which will never work of course Message-ID: <20121018141310.D2F9D1C00FA@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r713:0a1aec7ec9a9 Date: 2012-10-18 16:12 +0200 http://bitbucket.org/pypy/buildbot/changeset/0a1aec7ec9a9/ Log: don't run pypy-c -A tests on py3k nightly. There is no way they can run in their current form, because we run py.test on top of the translated pypy-c, which means that we will try to import the pypy package no top of pypy3, which will never work of course diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -66,6 +66,15 @@ app_tests=True, platform='linux64') +# these are like the two above: the only difference is that they only run +# lib-python tests,not -A tests +pypyTranslatedLibPythonTestFactory = pypybuilds.Translated(lib_python=True, + app_tests=False) +pypyTranslatedLibPythonTestFactory64 = pypybuilds.Translated(lib_python=True, + app_tests=False, + platform='linux64') + + pypyTranslatedAppLevelTestFactoryPPC64 = pypybuilds.Translated( lib_python=True, app_tests=True, @@ -218,8 +227,10 @@ APPLVLLINUX64 = "pypy-c-app-level-linux-x86-64" APPLVLLINUXARM = "pypy-c-app-level-linux-armel" APPLVLLINUXPPC64 = "pypy-c-app-level-linux-ppc-64" +APPLVLWIN32 = "pypy-c-app-level-win-x86-32" -APPLVLWIN32 = "pypy-c-app-level-win-x86-32" +LIBPYTHON_LINUX32 = "pypy-c-lib-python-linux-x86-32" +LIBPYTHON_LINUX64 = "pypy-c-lib-python-linux-x86-64" JITLINUX32 = "pypy-c-jit-linux-x86-32" JITLINUX64 = "pypy-c-jit-linux-x86-64" @@ -277,8 +288,8 @@ Nightly("nighly-0-00-py3k", [ LINUX32, LINUX64, - APPLVLLINUX32, - APPLVLLINUX64, + LIBPYTHON_LINUX32, + LIBPYTHON_LINUX64, ], branch='py3k', hour=0, minute=0), # Nightly("nighly-ppc", [ @@ -337,6 +348,20 @@ "category": "linux64", #"locks": [TannitCPU.access('counting')], }, + {"name": LIBPYTHON_LINUX32, + "slavenames": ["allegro32"], + "builddir": LIBPYTHON_LINUX32, + "factory": pypyTranslatedLibPythonTestFactory, + 'category': 'linux32', + #"locks": [TannitCPU.access('counting')], + }, + {"name": LIBPYTHON_LINUX64, + "slavenames": ["allegro64"], + "builddir": LIBPYTHON_LINUX64, + "factory": pypyTranslatedLibPythonTestFactory, + "category": "linux64", + #"locks": [TannitCPU.access('counting')], + }, {"name": OJITLINUX32, "slavenames": ["allegro32"], "builddir": OJITLINUX32, From noreply at buildbot.pypy.org Thu Oct 18 16:14:28 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 16:14:28 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: typo Message-ID: <20121018141428.EBB9B1C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58214:b399a246cd79 Date: 2012-10-18 15:31 +0200 http://bitbucket.org/pypy/pypy/changeset/b399a246cd79/ Log: typo diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -745,7 +745,7 @@ cpu = self.metainterp.cpu descr = cpu.jitframe_get_jfdescr_descr() jfdescrbox = self._opimpl_getfield_gc_any(jfbox, descr) - jfdescrbox = self.implement_guard_value(pc, jfdescrbox) + jfdescrbox = self.implement_guard_value(orgpc, jfdescrbox) jfdescr = jfdescrbox.getref_base() descr = cpu.jitframe_cast_jfdescr_to_descr(jfdescr) if not descr: From noreply at buildbot.pypy.org Thu Oct 18 16:14:30 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 16:14:30 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: fix basics on llgraph backend Message-ID: <20121018141430.26B7D1C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58215:25b339b57cf9 Date: 2012-10-18 15:35 +0200 http://bitbucket.org/pypy/pypy/changeset/25b339b57cf9/ Log: fix basics on llgraph backend diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -146,7 +146,6 @@ model.AbstractCPU.__init__(self) self.rtyper = rtyper self.llinterp = LLInterpreter(rtyper) - self.last_exception = None self.descrs = {} class MiniStats: pass @@ -212,27 +211,32 @@ frame.execute(lltrace) assert False except ExecutionFinished, e: - self.latest_values = e.args - return e.descr + frame.latest_values = e.args + frame.latest_descr = e.descr + return frame except GuardFailed, e: - self.latest_values = e.failargs - return e.descr + frame.latest_values = e.failargs + frame.latest_descr = e.descr + return frame - def get_latest_value_int(self, index): - return self.latest_values[index] + def get_latest_value_int(self, frame, index): + return frame.latest_values[index] get_latest_value_float = get_latest_value_int get_latest_value_ref = get_latest_value_int - def get_latest_value_count(self): - return len(self.latest_values) + def get_latest_value_count(self, frame): + return len(frame.latest_values) + + def get_latest_descr(self, frame): + return frame.latest_descr def clear_latest_values(self, count): del self.latest_values - def grab_exc_value(self): - if self.last_exception is not None: - result = self.last_exception.args[1] - self.last_exception = None + def grab_exc_value(self, frame): + if frame.last_exception is not None: + result = frame.last_exception.args[1] + frame.last_exception = None return lltype.cast_opaque_ptr(llmemory.GCREF, result) else: return lltype.nullptr(llmemory.GCREF.TO) @@ -523,6 +527,7 @@ for box, arg in zip(argboxes, args): self.env[box] = arg self.overflow_flag = False + self.last_exception = None def lookup(self, arg): if isinstance(arg, Const): @@ -638,11 +643,11 @@ self.execute_guard_class(descr, arg, klass) def execute_guard_no_exception(self, descr): - if self.cpu.last_exception is not None: + if self.last_exception is not None: self.fail_guard(descr) def execute_guard_exception(self, descr, excklass): - lle = self.cpu.last_exception + lle = self.last_exception if lle is None: gotklass = lltype.nullptr(rclass.CLASSTYPE.TO) else: @@ -654,7 +659,7 @@ self.fail_guard(descr) # res = lle.args[1] - self.cpu.last_exception = None + self.last_exception = None return support.cast_to_ptr(res) def execute_guard_not_forced(self, descr): @@ -725,9 +730,9 @@ call_args = support.cast_call_args_in_order(TP.ARGS, args) try: res = self.cpu.maybe_on_top_of_llinterp(func, call_args, TP.RESULT) - self.cpu.last_exception = None + self.last_exception = None except LLException, lle: - self.cpu.last_exception = lle + self.last_exception = lle res = _example_res[getkind(TP.RESULT)[0]] return res @@ -767,8 +772,8 @@ try: result = assembler_helper_ptr(failindex, vable) except LLException, lle: - assert self.cpu.last_exception is None, "exception left behind" - self.cpu.last_exception = lle + assert self.last_exception is None, "exception left behind" + self.last_exception = lle if self.current_op.result is not None: return _example_res[self.current_op.result.type] return None From noreply at buildbot.pypy.org Thu Oct 18 16:14:31 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 16:14:31 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (arigo, fijal) fix llgraph backend Message-ID: <20121018141431.6DA5C1C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58216:1b75cd6598b5 Date: 2012-10-18 16:14 +0200 http://bitbucket.org/pypy/pypy/changeset/1b75cd6598b5/ Log: (arigo, fijal) fix llgraph backend diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -142,6 +142,8 @@ supports_singlefloats = True translate_support_code = False + JITFRAMEPTR = llmemory.GCREF + def __init__(self, rtyper, stats=None, *ignored_args, **ignored_kwds): model.AbstractCPU.__init__(self) self.rtyper = rtyper @@ -241,6 +243,16 @@ else: return lltype.nullptr(llmemory.GCREF.TO) + def force(self, frame): + assert not frame._forced + frame._forced = True + guard_op = frame.lltrace.operations[frame.current_index + 1] + call_op = frame.current_op + frame.latest_values = frame._getfailargs(guard_op, call_op.result) + descr = guard_op.getdescr() + frame.latest_descr = descr + return descr + def calldescrof(self, FUNC, ARGS, RESULT, effect_info): key = ('call', getkind(RESULT), tuple([getkind(A) for A in ARGS]), @@ -518,8 +530,10 @@ def bh_read_timestamp(self): return read_timestamp() - class LLFrame(object): + _TYPE = llmemory.GCREF + _forced = False + def __init__(self, cpu, argboxes, args): self.env = {} self.cpu = cpu @@ -546,6 +560,7 @@ continue args = [self.lookup(arg) for arg in op.getarglist()] self.current_op = op # for label + self.current_index = i try: resval = getattr(self, 'execute_' + op.getopname())(op.getdescr(), *args) @@ -582,11 +597,15 @@ assert resval is None i += 1 - def _getfailargs(self): + def _getfailargs(self, op=None, skip=None): + if op is None: + op = self.current_op r = [] - for arg in self.current_op.getfailargs(): + for arg in op.getfailargs(): if arg is None: r.append(None) + elif arg is skip: + r.append(_example_res[skip.type]) else: r.append(self.env[arg]) return r @@ -663,7 +682,8 @@ return support.cast_to_ptr(res) def execute_guard_not_forced(self, descr): - pass # XXX + if self._forced: + self.fail_guard(descr) def execute_guard_not_invalidated(self, descr): if self.lltrace.invalid: @@ -800,9 +820,8 @@ descr = heaptracker.vtable2descr(self.cpu, vtable) return self.cpu.bh_new_with_vtable(vtable, descr) - def execute_force_token(self, _): - import py; py.test.skip("XXX") - + def execute_jit_frame(self, _): + return self def _setup(): def _make_impl_from_blackhole_interp(opname): diff --git a/pypy/jit/backend/llgraph/support.py b/pypy/jit/backend/llgraph/support.py --- a/pypy/jit/backend/llgraph/support.py +++ b/pypy/jit/backend/llgraph/support.py @@ -85,6 +85,8 @@ return lltype.cast_primitive(TYPE, x) def cast_from_ptr(TYPE, x): + if lltype.typeOf(x) == TYPE: + return x return lltype.cast_opaque_ptr(TYPE, x) def cast_arg(TP, x): diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2200,7 +2200,7 @@ def test_force_operations_returning_void(self): values = [] def maybe_force(token, flag): - assert lltype.typeOf(token) == JITFRAMEPTR + assert lltype.typeOf(token) == cpu.JITFRAMEPTR if flag: descr = self.cpu.force(token) values.append(descr) @@ -2208,7 +2208,7 @@ values.append(self.cpu.get_latest_value_int(token, 1)) values.append(token) - FUNC = self.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Void) + FUNC = self.FuncType([self.cpu.JITFRAMEPTR, lltype.Signed], lltype.Void) func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force) funcbox = self.get_funcbox(self.cpu, func_ptr).constbox() calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, @@ -2249,7 +2249,8 @@ values.append(token) return 42 - FUNC = self.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Signed) + FUNC = self.FuncType([self.cpu.JITFRAMEPTR, lltype.Signed], + lltype.Signed) func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force) funcbox = self.get_funcbox(self.cpu, func_ptr).constbox() calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, @@ -2294,7 +2295,7 @@ values.append(token) return 42.5 - FUNC = self.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Float) + FUNC = self.FuncType([self.cpu.JITFRAMEPTR, lltype.Signed], lltype.Float) func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force) funcbox = self.get_funcbox(self.cpu, func_ptr).constbox() calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, @@ -2731,7 +2732,7 @@ called.append(failindex) return 4 + 9 - FUNCPTR = lltype.Ptr(lltype.FuncType([JITFRAMEPTR, llmemory.GCREF], + FUNCPTR = lltype.Ptr(lltype.FuncType([self.cpu.JITFRAMEPTR, llmemory.GCREF], lltype.Signed)) class FakeJitDriverSD: index_of_virtualizable = -1 @@ -2807,7 +2808,7 @@ called.append(failindex) return 13.5 - FUNCPTR = lltype.Ptr(lltype.FuncType([JITFRAMEPTR, llmemory.GCREF], + FUNCPTR = lltype.Ptr(lltype.FuncType([self.cpu.JITFRAMEPTR, llmemory.GCREF], lltype.Float)) class FakeJitDriverSD: index_of_virtualizable = -1 @@ -2903,7 +2904,7 @@ called.append(failindex) return 13.5 - FUNCPTR = lltype.Ptr(lltype.FuncType([JITFRAMEPTR, llmemory.GCREF], + FUNCPTR = lltype.Ptr(lltype.FuncType([self.cpu.JITFRAMEPTR, llmemory.GCREF], lltype.Float)) class FakeJitDriverSD: index_of_virtualizable = -1 @@ -3669,7 +3670,7 @@ values.append(token) return 42 - FUNC = self.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Signed) + FUNC = self.FuncType([self.cpu.JITFRAMEPTR, lltype.Signed], lltype.Signed) func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force) funcbox = self.get_funcbox(self.cpu, func_ptr).constbox() calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, From noreply at buildbot.pypy.org Thu Oct 18 16:26:37 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Thu, 18 Oct 2012 16:26:37 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: play with various different ways to chart this information Message-ID: <20121018142637.B05721C00FA@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4875:35dd000f9dcd Date: 2012-10-18 15:56 +0200 http://bitbucket.org/pypy/extradoc/changeset/35dd000f9dcd/ Log: play with various different ways to chart this information diff --git a/talk/vmil2012/presentation/charts.ods b/talk/vmil2012/presentation/charts.ods index 94300512c367f6ea2553953adde39281e950b27c..7f2bdfee3288646b67dfebc876a7c814e20a8284 GIT binary patch [cut] From noreply at buildbot.pypy.org Thu Oct 18 16:26:38 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Thu, 18 Oct 2012 16:26:38 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: trying to make diagrams, needs lots of steps Message-ID: <20121018142638.D44DB1C00FA@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4876:915024efd777 Date: 2012-10-18 16:26 +0200 http://bitbucket.org/pypy/extradoc/changeset/915024efd777/ Log: trying to make diagrams, needs lots of steps diff --git a/talk/vmil2012/presentation/figures/jit_memory.pdf b/talk/vmil2012/presentation/figures/jit_memory.pdf new file mode 100644 index 0000000000000000000000000000000000000000..760a992c738602fe4decea13cbc78eeac3db15eb GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/op_percentage_after.pdf b/talk/vmil2012/presentation/figures/op_percentage_after.pdf new file mode 100644 index 0000000000000000000000000000000000000000..eb865fb5b5a564aff7817978f38597982b488f3c GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/resume_data_size.pdf b/talk/vmil2012/presentation/figures/resume_data_size.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d964ba5ede9e73040579ca7ab1775d0154cee33d GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -293,6 +293,11 @@ \end{figure} \end{frame} + +\begin{frame} + \includegraphics[scale=0.6]{figures/op_percentage_after} +\end{frame} + \begin{frame}[t,fragile] \pgfplotsset{tick label style={font=\tiny\bfseries}, label style={font=\small}, @@ -335,6 +340,14 @@ \end{figure} \end{frame} +\begin{frame} + \frametitle{JIT memory overhead} + \includegraphics[width=\textwidth]{figures/jit_memory} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.6]{figures/resume_data_size} +\end{frame} %\section{Evaluation} %as in paper From noreply at buildbot.pypy.org Thu Oct 18 16:27:18 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 16:27:18 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Fix half of call_assembler. Fast path needs more thinking. Message-ID: <20121018142718.DBD591C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58217:09931a069bf1 Date: 2012-10-18 16:26 +0200 http://bitbucket.org/pypy/pypy/changeset/09931a069bf1/ Log: Fix half of call_assembler. Fast path needs more thinking. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -766,31 +766,12 @@ return support.cast_result(descr.RESULT, result) def execute_call_assembler(self, descr, *args): - faildescr = self.cpu._execute_token(descr, *args) + frame = self.cpu._execute_token(descr, *args) jd = descr.outermost_jitdriver_sd - if jd.index_of_virtualizable != -1: - vable = args[jd.index_of_virtualizable] - else: - vable = lltype.nullptr(llmemory.GCREF.TO) - # - # Emulate the fast path - failindex = self.cpu.get_fail_descr_number(faildescr) - if failindex == self.cpu.done_with_this_frame_int_v: - self._reset_vable(jd, vable) - return self.cpu.get_latest_value_int(0) - if failindex == self.cpu.done_with_this_frame_ref_v: - self._reset_vable(jd, vable) - return self.cpu.get_latest_value_ref(0) - if failindex == self.cpu.done_with_this_frame_float_v: - self._reset_vable(jd, vable) - return self.cpu.get_latest_value_float(0) - if failindex == self.cpu.done_with_this_frame_void_v: - self._reset_vable(jd, vable) - return None - # + # xxx fast path????? assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish try: - result = assembler_helper_ptr(failindex, vable) + result = assembler_helper_ptr(frame) except LLException, lle: assert self.last_exception is None, "exception left behind" self.last_exception = lle @@ -799,11 +780,6 @@ return None return support.cast_result(lltype.typeOf(result), result) - def _reset_vable(self, jd, vable): - if jd.index_of_virtualizable != -1: - fielddescr = jd.vable_token_descr - self.cpu.bh_setfield_gc_i(vable, 0, fielddescr) - def execute_same_as(self, _, x): return x diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2725,14 +2725,14 @@ def test_assembler_call(self): called = [] - def assembler_helper(jitframe, virtualizable): + def assembler_helper(jitframe): assert self.cpu.get_latest_value_int(jitframe, 0) == 97 - faildescr =self.cpu.get_latest_descr(jitframe) + faildescr =self.cpu.get_latest_descr(jitframe) failindex = self.cpu.get_fail_descr_number(faildescr) called.append(failindex) return 4 + 9 - FUNCPTR = lltype.Ptr(lltype.FuncType([self.cpu.JITFRAMEPTR, llmemory.GCREF], + FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], lltype.Signed)) class FakeJitDriverSD: index_of_virtualizable = -1 From noreply at buildbot.pypy.org Thu Oct 18 16:32:56 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Thu, 18 Oct 2012 16:32:56 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: add absolute guard numbers to diagram Message-ID: <20121018143256.E9C321C00FA@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4877:a1214f707d48 Date: 2012-10-18 16:32 +0200 http://bitbucket.org/pypy/extradoc/changeset/a1214f707d48/ Log: add absolute guard numbers to diagram diff --git a/talk/vmil2012/presentation/charts.ods b/talk/vmil2012/presentation/charts.ods index 7f2bdfee3288646b67dfebc876a7c814e20a8284..4fd468078b9b08ae1d44cfec04c3a39495a85945 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/op_percentage_after.pdf b/talk/vmil2012/presentation/figures/op_percentage_after.pdf index eb865fb5b5a564aff7817978f38597982b488f3c..2524f2189d8e0169494db851efcc73f51696d5fa GIT binary patch [cut] From noreply at buildbot.pypy.org Thu Oct 18 17:00:59 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 17:00:59 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Port to the new model, enough to make test_ajit mostly work Message-ID: <20121018150059.DEF031C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58218:a76a456e0f20 Date: 2012-10-18 17:00 +0200 http://bitbucket.org/pypy/pypy/changeset/a76a456e0f20/ Log: Port to the new model, enough to make test_ajit mostly work diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -27,9 +27,9 @@ self.descr = descr class ExecutionFinished(Exception): - def __init__(self, descr, args): + def __init__(self, descr, arg=None): self.descr = descr - self.args = args + self.arg = arg class Jump(Exception): def __init__(self, descr, args): @@ -213,7 +213,7 @@ frame.execute(lltrace) assert False except ExecutionFinished, e: - frame.latest_values = e.args + frame.finish_value = e.arg frame.latest_descr = e.descr return frame except GuardFailed, e: @@ -232,16 +232,10 @@ def get_latest_descr(self, frame): return frame.latest_descr - def clear_latest_values(self, count): - del self.latest_values - - def grab_exc_value(self, frame): - if frame.last_exception is not None: - result = frame.last_exception.args[1] - frame.last_exception = None - return lltype.cast_opaque_ptr(llmemory.GCREF, result) - else: - return lltype.nullptr(llmemory.GCREF.TO) + def get_finish_value_int(self, frame): + return frame.finish_value + get_finish_value_float = get_finish_value_int + get_finish_value_ref = get_finish_value_int def force(self, frame): assert not frame._forced @@ -619,11 +613,18 @@ # ----------------------------------------------------- - def fail_guard(self, descr): + def fail_guard(self, descr, saveexc=False): + if saveexc: + if self.last_exception is not None: + result = self.last_exception.args[1] + gcref = lltype.cast_opaque_ptr(llmemory.GCREF, result) + else: + gcref = lltype.nullptr(llmemory.GCREF.TO) + self.finish_value = gcref raise GuardFailed(self._getfailargs(), descr) - def execute_finish(self, descr, *args): - raise ExecutionFinished(descr, args) + def execute_finish(self, descr, arg=None): + raise ExecutionFinished(descr, arg) def execute_label(self, descr, *args): argboxes = self.current_op.getarglist() @@ -663,7 +664,7 @@ def execute_guard_no_exception(self, descr): if self.last_exception is not None: - self.fail_guard(descr) + self.fail_guard(descr, saveexc=True) def execute_guard_exception(self, descr, excklass): lle = self.last_exception @@ -675,7 +676,7 @@ llmemory.cast_int_to_adr(excklass), rclass.CLASSTYPE) if gotklass != excklass: - self.fail_guard(descr) + self.fail_guard(descr, saveexc=True) # res = lle.args[1] self.last_exception = None From noreply at buildbot.pypy.org Thu Oct 18 17:21:04 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 17:21:04 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: fix fix fix fix Message-ID: <20121018152104.150BA1C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58219:27c93b400d64 Date: 2012-10-18 17:20 +0200 http://bitbucket.org/pypy/pypy/changeset/27c93b400d64/ Log: fix fix fix fix diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -27,9 +27,10 @@ self.descr = descr class ExecutionFinished(Exception): - def __init__(self, descr, arg=None): + def __init__(self, descr, arg, failargs): self.descr = descr self.arg = arg + self.failargs = failargs class Jump(Exception): def __init__(self, descr, args): @@ -214,6 +215,7 @@ assert False except ExecutionFinished, e: frame.finish_value = e.arg + frame.latest_values = e.failargs frame.latest_descr = e.descr return frame except GuardFailed, e: @@ -624,7 +626,11 @@ raise GuardFailed(self._getfailargs(), descr) def execute_finish(self, descr, arg=None): - raise ExecutionFinished(descr, arg) + if self.current_op.getfailargs() is not None: + failargs = self._getfailargs() + else: + failargs = None # compatibility + raise ExecutionFinished(descr, arg, failargs) def execute_label(self, descr, *args): argboxes = self.current_op.getarglist() diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -63,11 +63,11 @@ else: self.guard_failed = True if result_type == 'int': - return BoxInt(self.cpu.get_latest_value_int(frame, 0)) + return BoxInt(self.cpu.get_finish_value_int(frame)) elif result_type == 'ref': - return BoxPtr(self.cpu.get_latest_value_ref(frame, 0)) + return BoxPtr(self.cpu.get_finish_value_ref(frame)) elif result_type == 'float': - return BoxFloat(self.cpu.get_latest_value_float(frame, 0)) + return BoxFloat(self.cpu.get_finish_value_float(frame)) elif result_type == 'void': return None else: @@ -119,7 +119,7 @@ looptoken = JitCellToken() self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 2) - res = self.cpu.get_latest_value_int(frame, 0) + res = self.cpu.get_finish_value_int(frame) assert res == 3 assert self.cpu.get_latest_descr(frame).identifier == 1 @@ -134,7 +134,7 @@ looptoken = JitCellToken() self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, longlong.getfloatstorage(2.8)) - res = self.cpu.get_latest_value_float(frame, 0) + res = self.cpu.get_finish_value_int(frame) assert longlong.getrealfloat(res) == 5.1 assert self.cpu.get_latest_descr(frame).identifier == 1 @@ -363,7 +363,7 @@ self.cpu.compile_loop([i0], operations, looptoken) frame = self.cpu.execute_token(looptoken, 99) assert self.cpu.get_latest_descr(frame) is faildescr - res = self.cpu.get_latest_value_int(frame, 0) + res = self.cpu.get_finish_value_int(frame) assert res == 99 looptoken = JitCellToken() @@ -373,7 +373,7 @@ self.cpu.compile_loop([], operations, looptoken) frame = self.cpu.execute_token(looptoken) assert self.cpu.get_latest_descr(frame) is faildescr - res = self.cpu.get_latest_value_int(frame, 0) + res = self.cpu.get_finish_value_int(frame) assert res == 42 looptoken = JitCellToken() @@ -394,7 +394,7 @@ value = longlong.getfloatstorage(-61.25) frame = self.cpu.execute_token(looptoken, value) assert self.cpu.get_latest_descr(frame) is faildescr - res = self.cpu.get_latest_value_float(frame, 0) + res = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(res) == -61.25 looptoken = JitCellToken() @@ -404,7 +404,7 @@ self.cpu.compile_loop([], operations, looptoken) frame = self.cpu.execute_token(looptoken) assert self.cpu.get_latest_descr(frame) is faildescr - res = self.cpu.get_latest_value_float(frame, 0) + res = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(res) == 42.5 def test_execute_operations_in_env(self): @@ -492,9 +492,10 @@ else: assert self.cpu.get_latest_descr(frame).identifier == 2 if z != boom: - assert self.cpu.get_latest_value_int(frame, 0) == z - excvalue = self.cpu.grab_exc_value(frame) - assert not excvalue + if not reversed: + assert self.cpu.get_finish_value_int(frame) == z + else: + assert self.cpu.get_latest_value_int(frame, 0) == z def test_ovf_operations_reversed(self): self.test_ovf_operations(reversed=True) @@ -1202,8 +1203,9 @@ retvalues.insert(kk, y) # operations.append( - ResOperation(rop.FINISH, retboxes, None, descr=faildescr) + ResOperation(rop.FINISH, [], None, descr=faildescr) ) + operations[-1].setfailargs(retboxes) print inputargs for op in operations: print op @@ -1326,9 +1328,10 @@ ResOperation(rop.LABEL, fboxes, None, descr=targettoken), ResOperation(rop.FLOAT_LE, [fboxes[0], constfloat(9.2)], i2), ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1), - ResOperation(rop.FINISH, fboxes, None, descr=faildescr2), + ResOperation(rop.FINISH, [], None, descr=faildescr2), ] operations[-2].setfailargs(fboxes) + operations[-1].setfailargs(fboxes) looptoken = JitCellToken() self.cpu.compile_loop(fboxes, operations, looptoken) @@ -1382,8 +1385,9 @@ assert longlong.getrealfloat(f3) == 133.0 bridgeops = [ - ResOperation(rop.FINISH, fboxes, None, descr=faildescr1), + ResOperation(rop.FINISH, [], None, descr=faildescr1), ] + bridgeops[-1].setfailargs(fboxes) self.cpu.compile_bridge(loop.operations[-2].getdescr(), fboxes, bridgeops, looptoken) args = [1, @@ -1976,7 +1980,7 @@ i1 = same_as(1) call(ConstClass(fptr), i0, descr=calldescr) p0 = guard_exception(ConstClass(xtp)) [i1] - finish(0, p0) + finish(p0) ''' FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) fptr = llhelper(FPTR, func) @@ -1997,13 +2001,10 @@ looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) - assert self.cpu.get_latest_value_int(frame, 0) == 0 - assert self.cpu.get_latest_value_ref(frame, 1) == xptr - excvalue = self.cpu.grab_exc_value(frame) - assert not excvalue + assert self.cpu.get_finish_value_ref(frame) == xptr frame = self.cpu.execute_token(looptoken, 0) assert self.cpu.get_latest_value_int(frame, 0) == 1 - excvalue = self.cpu.grab_exc_value(frame) + excvalue = self.cpu.get_finish_value_ref(frame) assert not excvalue ytp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) @@ -2022,9 +2023,8 @@ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_latest_value_int(frame, 0) == 1 - excvalue = self.cpu.grab_exc_value(frame) + excvalue = self.cpu.get_finish_value_ref(frame) assert excvalue == yptr - assert not self.cpu.grab_exc_value(frame) # cleared exc_tp = xtp exc_ptr = xptr @@ -2033,19 +2033,17 @@ i1 = same_as(1) call(ConstClass(fptr), i0, descr=calldescr) guard_no_exception() [i1] - finish(0) + finish(-100) ''' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_latest_value_int(frame, 0) == 1 - excvalue = self.cpu.grab_exc_value(frame) + excvalue = self.cpu.get_finish_value_ref(frame) assert excvalue == xptr frame = self.cpu.execute_token(looptoken, 0) - assert self.cpu.get_latest_value_int(frame, 0) == 0 - excvalue = self.cpu.grab_exc_value(frame) - assert not excvalue + assert self.cpu.get_finish_value_int(frame) == -100 def test_cond_call_gc_wb(self): def func_void(a): @@ -2230,7 +2228,7 @@ self.cpu.compile_loop([i0, i1], ops, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 - assert self.cpu.get_latest_value_int(frame, 0) == 20 + assert self.cpu.get_finish_value_int(frame) == 20 assert values == [] frame = self.cpu.execute_token(looptoken, 10, 1) @@ -2273,7 +2271,7 @@ self.cpu.compile_loop([i0, i1], ops, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 - assert self.cpu.get_latest_value_int(frame, 0) == 42 + assert self.cpu.get_finish_value_int(frame) == 42 assert values == [] frame = self.cpu.execute_token(looptoken, 10, 1) @@ -2318,7 +2316,7 @@ self.cpu.compile_loop([i0, i1], ops, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 - x = self.cpu.get_latest_value_float(frame, 0) + x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 42.5 assert values == [] @@ -2356,7 +2354,7 @@ self.cpu.compile_loop([i1], ops, looptoken) frame = self.cpu.execute_token(looptoken, ord('G')) assert self.cpu.get_latest_descr(frame).identifier == 0 - assert self.cpu.get_latest_value_int(frame, 0) == ord('g') + assert self.cpu.get_finish_value_int(frame) == ord('g') def test_call_to_c_function_with_callback(self): from pypy.rlib.libffi import CDLL, types, ArgChain, clibffi @@ -2471,7 +2469,7 @@ args = [buflen, rffi.cast(lltype.Signed, buffer)] frame = self.cpu.execute_token(looptoken, *args) assert self.cpu.get_latest_descr(frame).identifier == 0 - assert self.cpu.get_latest_value_int(frame, 0) == len(cwd) + assert self.cpu.get_finish_value_int(frame) == len(cwd) assert rffi.charp2strn(buffer, buflen) == cwd lltype.free(buffer, flavor='raw') @@ -2490,7 +2488,7 @@ frame = self.cpu.execute_token(looptoken, -42, 9) assert self.cpu.get_latest_descr(frame).identifier == 0 - assert self.cpu.get_latest_value_int(frame, 0) == -42 + assert self.cpu.get_finish_value_int(frame) == -42 print 'step 1 ok' print '-'*79 @@ -2515,7 +2513,7 @@ frame = self.cpu.execute_token(looptoken, -42, 9) assert self.cpu.get_latest_descr(frame).identifier == 3 - assert self.cpu.get_latest_value_int(frame, 0) == 9 + assert self.cpu.get_finish_value_int(frame) == 9 print 'step 3 ok' print '-'*79 @@ -2554,7 +2552,7 @@ # run: must not be caught in an infinite loop frame = self.cpu.execute_token(looptoken, 16) assert self.cpu.get_latest_descr(frame).identifier == 3 - assert self.cpu.get_latest_value_int(frame, 0) == 333 + assert self.cpu.get_finish_value_int(frame) == 333 # pure do_ / descr features @@ -2726,8 +2724,8 @@ def test_assembler_call(self): called = [] def assembler_helper(jitframe): - assert self.cpu.get_latest_value_int(jitframe, 0) == 97 - faildescr =self.cpu.get_latest_descr(jitframe) + assert self.cpu.get_finish_value_int(jitframe) == 97 + faildescr = self.cpu.get_latest_descr(jitframe) failindex = self.cpu.get_fail_descr_number(faildescr) called.append(failindex) return 4 + 9 @@ -2767,7 +2765,7 @@ EffectInfo.MOST_GENERAL) args = [i+1 for i in range(10)] frame = self.cpu.execute_token(looptoken, *args) - assert self.cpu.get_latest_value_int(frame, 0) == 55 + assert self.cpu.get_finish_value_int(frame) == 55 ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] i10 = int_add(i0, 42) @@ -2780,7 +2778,7 @@ self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [i+1 for i in range(10)] frame = self.cpu.execute_token(othertoken, *args) - assert self.cpu.get_latest_value_int(frame, 0) == 13 + assert self.cpu.get_finish_value_int(frame) == 13 assert called == [done_number] # test the fast path, which should not call assembler_helper() @@ -2791,7 +2789,7 @@ self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [i+1 for i in range(10)] frame = self.cpu.execute_token(othertoken, *args) - assert self.cpu.get_latest_value_int(frame, 0) == 97 + assert self.cpu.get_finish_value_int(frame) == 97 assert not called finally: del self.cpu.done_with_this_frame_int_v @@ -2800,15 +2798,15 @@ if not self.cpu.supports_floats: py.test.skip("requires floats") called = [] - def assembler_helper(jitframe, virtualizable): - x = self.cpu.get_latest_value_float(jitframe, 0) + def assembler_helper(jitframe): + x = self.cpu.get_finish_value_float(jitframe) assert longlong.getrealfloat(x) == 1.2 + 3.2 faildescr =self.cpu.get_latest_descr(jitframe) failindex = self.cpu.get_fail_descr_number(faildescr) called.append(failindex) return 13.5 - FUNCPTR = lltype.Ptr(lltype.FuncType([self.cpu.JITFRAMEPTR, llmemory.GCREF], + FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], lltype.Float)) class FakeJitDriverSD: index_of_virtualizable = -1 @@ -2835,7 +2833,7 @@ args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(2.3)] frame = self.cpu.execute_token(looptoken, *args) - x = self.cpu.get_latest_value_float(frame, 0) + x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 1.2 + 2.3 ops = ''' [f4, f5] @@ -2849,7 +2847,7 @@ args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(3.2)] frame = self.cpu.execute_token(othertoken, *args) - x = self.cpu.get_latest_value_float(frame, 0) + x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 13.5 assert called == [done_number] @@ -2862,7 +2860,7 @@ args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(3.2)] frame = self.cpu.execute_token(othertoken, *args) - x = self.cpu.get_latest_value_float(frame, 0) + x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 1.2 + 3.2 assert not called finally: @@ -2896,15 +2894,15 @@ if not self.cpu.supports_floats: py.test.skip("requires floats") called = [] - def assembler_helper(jitframe, virtualizable): - x = self.cpu.get_latest_value_float(jitframe, 0) + def assembler_helper(jitframe): + x = self.cpu.get_finish_value_float(jitframe) assert longlong.getrealfloat(x) == 1.25 + 3.25 faildescr =self.cpu.get_latest_descr(jitframe) failindex = self.cpu.get_fail_descr_number(faildescr) called.append(failindex) return 13.5 - FUNCPTR = lltype.Ptr(lltype.FuncType([self.cpu.JITFRAMEPTR, llmemory.GCREF], + FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], lltype.Float)) class FakeJitDriverSD: index_of_virtualizable = -1 @@ -2931,7 +2929,7 @@ args = [longlong.getfloatstorage(1.25), longlong.getfloatstorage(2.35)] frame = self.cpu.execute_token(looptoken, *args) - x = self.cpu.get_latest_value_float(frame, 0) + x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 1.25 + 2.35 assert not called @@ -2949,7 +2947,7 @@ args = [longlong.getfloatstorage(1.25), longlong.getfloatstorage(3.25)] frame = self.cpu.execute_token(othertoken, *args) - x = self.cpu.get_latest_value_float(frame, 0) + x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 13.5 assert called == [done_number] del called[:] @@ -2972,7 +2970,7 @@ args = [longlong.getfloatstorage(6.0), longlong.getfloatstorage(1.5)] # 6.0-1.5 == 1.25+3.25 frame = self.cpu.execute_token(othertoken, *args) - x = self.cpu.get_latest_value_float(frame, 0) + x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 13.5 assert called == [done_number] @@ -3405,7 +3403,7 @@ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) for inp, outp in [(2,2), (-3, 0)]: frame = self.cpu.execute_token(looptoken, inp) - assert outp == self.cpu.get_latest_value_int(frame, 0) + assert outp == self.cpu.get_finish_value_int(frame) def test_compile_asmlen(self): from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU @@ -3582,7 +3580,7 @@ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16) - result = self.cpu.get_latest_value_int(frame, 0) + result = self.cpu.get_finish_value_int(frame) assert result == rffi.cast(lltype.Signed, value) rawstorage.free_raw_storage(p) @@ -3607,7 +3605,7 @@ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16) - result = self.cpu.get_latest_value_float(frame, 0) + result = self.cpu.get_finish_value_float(frame) result = longlong.getrealfloat(result) assert result == rffi.cast(lltype.Float, value) rawstorage.free_raw_storage(p) From noreply at buildbot.pypy.org Thu Oct 18 17:41:01 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 17:41:01 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Copy cpython_code_signature() Message-ID: <20121018154101.5E1F31C0F16@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58220:ad5cf022a7b3 Date: 2012-10-17 22:19 +0100 http://bitbucket.org/pypy/pypy/changeset/ad5cf022a7b3/ Log: Copy cpython_code_signature() diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,11 +1,28 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import (BytecodeCorruption, - cpython_code_signature) +from pypy.interpreter.pycode import BytecodeCorruption from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) -from pypy.interpreter.astcompiler.consts import CO_GENERATOR +from pypy.interpreter.astcompiler.consts import (CO_GENERATOR, CO_VARARGS, + CO_VARKEYWORDS) +from pypy.interpreter.argument import Signature + +def cpython_code_signature(code): + "([list-of-arg-names], vararg-name-or-None, kwarg-name-or-None)." + argcount = code.co_argcount + argnames = list(code.co_varnames[:argcount]) + if code.co_flags & CO_VARARGS: + varargname = code.co_varnames[argcount] + argcount += 1 + else: + varargname = None + if code.co_flags & CO_VARKEYWORDS: + kwargname = code.co_varnames[argcount] + argcount += 1 + else: + kwargname = None + return Signature(argnames, varargname, kwargname) class HostCode(object): """ From noreply at buildbot.pypy.org Thu Oct 18 17:41:02 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 17:41:02 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: copy pypy/interpreter/argument.py wholesale into flowspace Message-ID: <20121018154102.A9AFB1C0F16@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58221:dec7915c5171 Date: 2012-10-18 02:10 +0100 http://bitbucket.org/pypy/pypy/changeset/dec7915c5171/ Log: copy pypy/interpreter/argument.py wholesale into flowspace + Use the flowspace version of ArgumentsForTranslation everywhere. diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -16,7 +16,7 @@ from pypy.annotation.dictdef import DictDef from pypy.annotation import description from pypy.annotation.signature import annotationoftype -from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.rlib.objectmodel import r_dict, Symbolic from pypy.tool.algo.unionfind import UnionFind from pypy.rpython.lltypesystem import lltype, llmemory @@ -101,7 +101,7 @@ def consider_list_delitem(self, idx): return self.indexrepr(idx) - + def consider_str_join(self, s): if s.is_constant(): return repr(s.const) @@ -224,7 +224,7 @@ check_no_flags(s_value_or_def.listdef.listitem) elif isinstance(s_value_or_def, SomeDict): check_no_flags(s_value_or_def.dictdef.dictkey) - check_no_flags(s_value_or_def.dictdef.dictvalue) + check_no_flags(s_value_or_def.dictdef.dictvalue) elif isinstance(s_value_or_def, SomeTuple): for s_item in s_value_or_def.items: check_no_flags(s_item) @@ -238,9 +238,9 @@ elif isinstance(s_value_or_def, ListItem): if s_value_or_def in seen: return - seen.add(s_value_or_def) + seen.add(s_value_or_def) check_no_flags(s_value_or_def.s_value) - + for clsdef in self.classdefs: check_no_flags(clsdef) @@ -366,14 +366,14 @@ listdef = ListDef(self, s_ImpossibleValue) for e in x: listdef.generalize(self.immutablevalue(e, False)) - result = SomeList(listdef) + result = SomeList(listdef) elif tp is dict or tp is r_dict: if need_const: key = Constant(x) try: return self.immutable_cache[key] except KeyError: - result = SomeDict(DictDef(self, + result = SomeDict(DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict)) @@ -396,7 +396,7 @@ result.const_box = key return result else: - dictdef = DictDef(self, + dictdef = DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict) @@ -545,7 +545,7 @@ return True else: return False - + def getfrozen(self, pyobj): return description.FrozenDesc(self, pyobj) @@ -566,7 +566,7 @@ key = (x.__class__, x) if key in self.seen_mutable: return - clsdef = self.getuniqueclassdef(x.__class__) + clsdef = self.getuniqueclassdef(x.__class__) self.seen_mutable[key] = True self.event('mutable', x) source = InstanceSource(self, x) @@ -586,7 +586,7 @@ except KeyError: access_sets = map[attrname] = UnionFind(description.ClassAttrFamily) return access_sets - + def pbc_getattr(self, pbc, s_attr): assert s_attr.is_constant() attr = s_attr.const @@ -598,7 +598,7 @@ first = descs[0] if len(descs) == 1: return first.s_read_attribute(attr) - + change = first.mergeattrfamilies(descs[1:], attr) attrfamily = first.getattrfamily(attr) @@ -700,7 +700,7 @@ def ondegenerated(self, what, s_value, where=None, called_from_graph=None): self.annotator.ondegenerated(what, s_value, where=where, called_from_graph=called_from_graph) - + def whereami(self): return self.annotator.whereami(self.position_key) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -1,8 +1,7 @@ import types, py from pypy.objspace.flow.model import Constant, FunctionGraph -from pypy.interpreter.pycode import cpython_code_signature -from pypy.interpreter.argument import rawshape -from pypy.interpreter.argument import ArgErr +from pypy.objspace.flow.bytecode import cpython_code_signature +from pypy.objspace.flow.argument import rawshape, ArgErr from pypy.tool.sourcetools import valid_identifier from pypy.tool.pairtype import extendabletype @@ -181,7 +180,7 @@ name = pyobj.func_name if signature is None: if hasattr(pyobj, '_generator_next_method_of_'): - from pypy.interpreter.argument import Signature + from pypy.objspace.flow.argument import Signature signature = Signature(['entry']) # haaaaaack defaults = () else: @@ -260,7 +259,7 @@ try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: - raise TypeError("signature mismatch: %s() %s" % + raise TypeError("signature mismatch: %s() %s" % (self.name, e.getmsg())) return inputcells diff --git a/pypy/interpreter/argument.py b/pypy/objspace/flow/argument.py copy from pypy/interpreter/argument.py copy to pypy/objspace/flow/argument.py diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -6,7 +6,7 @@ HAVE_ARGUMENT) from pypy.interpreter.astcompiler.consts import (CO_GENERATOR, CO_VARARGS, CO_VARKEYWORDS) -from pypy.interpreter.argument import Signature +from pypy.objspace.flow.argument import Signature def cpython_code_signature(code): "([list-of-arg-names], vararg-name-or-None, kwarg-name-or-None)." diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -8,7 +8,7 @@ from pypy.tool.error import source_lines from pypy.tool.stdlib_opcode import host_bytecode_spec from pypy.interpreter import pyframe -from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.interpreter.pyopcode import BytecodeCorruption from pypy.objspace.flow.model import (Constant, Variable, Block, Link, UnwrapException, c_last_exception) diff --git a/pypy/objspace/flow/generator.py b/pypy/objspace/flow/generator.py --- a/pypy/objspace/flow/generator.py +++ b/pypy/objspace/flow/generator.py @@ -6,7 +6,7 @@ from pypy.translator.unsimplify import split_block from pypy.translator.simplify import eliminate_empty_blocks, simplify_graph from pypy.tool.sourcetools import func_with_new_name -from pypy.interpreter.argument import Signature +from pypy.objspace.flow.argument import Signature class AbstractPosition(object): diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -8,7 +8,7 @@ from inspect import CO_NEWLOCALS from pypy.interpreter.baseobjspace import ObjSpace -from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.objspace.flow.model import (Constant, Variable, WrapException, UnwrapException, checkgraph, SpaceOperation) from pypy.objspace.flow.bytecode import HostCode diff --git a/pypy/rpython/callparse.py b/pypy/rpython/callparse.py --- a/pypy/rpython/callparse.py +++ b/pypy/rpython/callparse.py @@ -1,4 +1,4 @@ -from pypy.interpreter.argument import ArgumentsForTranslation, ArgErr +from pypy.objspace.flow.argument import ArgumentsForTranslation, ArgErr from pypy.annotation import model as annmodel from pypy.rpython import rtuple from pypy.rpython.error import TyperError diff --git a/pypy/rpython/rbuiltin.py b/pypy/rpython/rbuiltin.py --- a/pypy/rpython/rbuiltin.py +++ b/pypy/rpython/rbuiltin.py @@ -44,7 +44,7 @@ def call_args_expand(hop, takes_kwds = True): hop = hop.copy() - from pypy.interpreter.argument import ArgumentsForTranslation + from pypy.objspace.flow.argument import ArgumentsForTranslation arguments = ArgumentsForTranslation.fromshape( None, hop.args_s[1].const, # shape range(hop.nb_args-2)) From noreply at buildbot.pypy.org Thu Oct 18 17:41:03 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 17:41:03 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: copy the tests as well Message-ID: <20121018154103.E07961C0F16@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58222:bc346586e319 Date: 2012-10-18 15:12 +0100 http://bitbucket.org/pypy/pypy/changeset/bc346586e319/ Log: copy the tests as well diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -504,149 +504,6 @@ w_key = keyword_names_w[i - limit] space.setitem(w_kwds, w_key, keywords_w[i]) -class ArgumentsForTranslation(Arguments): - def __init__(self, space, args_w, keywords=None, keywords_w=None, - w_stararg=None, w_starstararg=None): - self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False - Arguments.__init__(self, space, args_w, keywords, keywords_w) - - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - - def prepend(self, w_firstarg): # used often - "Return a new Arguments with a new argument inserted first." - return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - def copy(self): - return ArgumentsForTranslation(self.space, self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - - - def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None, - blindargs=0): - self.combine_if_necessary() - # _match_signature is destructive - return Arguments._match_signature( - self, w_firstarg, scope_w, signature, - defaults_w, blindargs) - - def unpack(self): - self.combine_if_necessary() - return Arguments.unpack(self) - - def match_signature(self, signature, defaults_w): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - return self._parse(None, signature, defaults_w) - - def unmatch_signature(self, signature, data_w): - """kind of inverse of match_signature""" - args_w, kwds_w = self.unpack() - need_cnt = len(args_w) - need_kwds = kwds_w.keys() - space = self.space - argnames, varargname, kwargname = signature - cnt = len(argnames) - data_args_w = data_w[:cnt] - if varargname: - data_w_stararg = data_w[cnt] - cnt += 1 - else: - data_w_stararg = space.newtuple([]) - - unfiltered_kwds_w = {} - if kwargname: - data_w_starargarg = data_w[cnt] - for w_key in space.unpackiterable(data_w_starargarg): - key = space.str_w(w_key) - w_value = space.getitem(data_w_starargarg, w_key) - unfiltered_kwds_w[key] = w_value - cnt += 1 - assert len(data_w) == cnt - - ndata_args_w = len(data_args_w) - if ndata_args_w >= need_cnt: - 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) - else: - stararg_w = space.unpackiterable(data_w_stararg) - datalen = len(data_args_w) - args_w = [None] * (datalen + len(stararg_w)) - for i in range(0, datalen): - args_w[i] = data_args_w[i] - for i in range(0, len(stararg_w)): - args_w[i + datalen] = stararg_w[i] - assert len(args_w) == need_cnt - - keywords = [] - keywords_w = [] - for key in need_kwds: - keywords.append(key) - keywords_w.append(unfiltered_kwds_w[key]) - - return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) - - @staticmethod - def frompacked(space, w_args=None, w_kwds=None): - raise NotImplementedError("go away") - - @staticmethod - def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w): - args_w = data_w[:shape_cnt] - p = end_keys = shape_cnt + len(shape_keys) - if shape_star: - w_star = data_w[p] - p += 1 - else: - w_star = None - if shape_stst: - w_starstar = data_w[p] - p += 1 - else: - w_starstar = None - return ArgumentsForTranslation(space, args_w, list(shape_keys), - data_w[shape_cnt:end_keys], w_star, - w_starstar) - - def flatten(self): - """ Argument <-> list of w_objects together with "shape" information """ - shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape() - data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)] - for key in shape_keys] - if shape_star: - data_w.append(self.w_stararg) - if shape_stst: - data_w.append(self.w_starstararg) - return (shape_cnt, shape_keys, shape_star, shape_stst), data_w - - def _rawshape(self, nextra=0): - assert not self.combine_has_happened - shape_cnt = len(self.arguments_w)+nextra # Number of positional args - if self.keywords: - shape_keys = self.keywords[:] # List of keywords (strings) - shape_keys.sort() - else: - shape_keys = [] - shape_star = self.w_stararg is not None # Flag: presence of *arg - shape_stst = self.w_starstararg is not None # Flag: presence of **kwds - return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted - -def rawshape(args, nextra=0): - return args._rawshape(nextra) - - # # ArgErr family of exceptions raised in case of argument mismatch. # We try to give error messages following CPython's, which are very informative. diff --git a/pypy/interpreter/test/test_argument.py b/pypy/objspace/flow/test/test_argument.py copy from pypy/interpreter/test/test_argument.py copy to pypy/objspace/flow/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/objspace/flow/test/test_argument.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- import py -from pypy.interpreter.argument import (Arguments, ArgumentsForTranslation, +from pypy.objspace.flow.argument import (Arguments, ArgumentsForTranslation, ArgErr, ArgErrUnknownKwds, ArgErrMultipleValues, ArgErrCount, rawshape, Signature) from pypy.interpreter.error import OperationError From noreply at buildbot.pypy.org Thu Oct 18 17:41:05 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 17:41:05 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Kill pypy.interpreter.ArgumentsForTranslation Message-ID: <20121018154105.22BEB1C0F16@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58223:8f834be0f782 Date: 2012-10-18 15:51 +0100 http://bitbucket.org/pypy/pypy/changeset/8f834be0f782/ Log: Kill pypy.interpreter.ArgumentsForTranslation (meh, I accidentally removed it already but left the tests) 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 @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- import py -from pypy.interpreter.argument import (Arguments, ArgumentsForTranslation, - ArgErr, ArgErrUnknownKwds, ArgErrMultipleValues, ArgErrCount, rawshape, - Signature) +from pypy.interpreter.argument import (Arguments, ArgErr, ArgErrUnknownKwds, + ArgErrMultipleValues, ArgErrCount, Signature) from pypy.interpreter.error import OperationError @@ -687,206 +686,3 @@ def f(x): pass e = raises(TypeError, "f(**{u'ü' : 19})") assert "?" in str(e.value) - -def make_arguments_for_translation(space, args_w, keywords_w={}, - w_stararg=None, w_starstararg=None): - return ArgumentsForTranslation(space, args_w, keywords_w.keys(), - keywords_w.values(), w_stararg, - w_starstararg) - -class TestArgumentsForTranslation(object): - - def test_prepend(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ["0"]) - args1 = args.prepend("thingy") - assert args1 is not args - assert args1.arguments_w == ["thingy", "0"] - assert args1.keywords is args.keywords - assert args1.keywords_w is args.keywords_w - - def test_unmatch_signature(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - sig = Signature(['a', 'b', 'c'], 'r', None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - def test_rawshape(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert rawshape(args) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1]) - assert rawshape(args, 2) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert rawshape(args) == (5, (), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert rawshape(args) == (1, ('b', 'c'), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert rawshape(args) == (1, ('c', ), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert rawshape(args) == (1, ('c', 'd'), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert rawshape(args) == (5, ('d', 'e'), False, False) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert rawshape(args) == (0, (), True, True) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert rawshape(args) == (2, ('g', ), True, True) - - def test_copy_and_shape(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ['a'], ['x'], [1], - ['w1'], {'y': 'w2'}) - args1 = args.copy() - args.combine_if_necessary() - assert rawshape(args1) == (1, ('x',), True, True) - - - def test_flatten(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert args.flatten() == ((3, (), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1]) - assert args.flatten() == ((1, (), False, False), [1]) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert args.flatten() == ((5, (), False, False), [1,2,3,4,5]) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert args.flatten() == ((1, ('c', ), False, False), [1, 5]) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7]) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert args.flatten() == ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert args.flatten() == ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - - def test_stararg_flowspace_variable(self): - space = DummySpace() - var = object() - shape = ((2, ('g', ), True, False), [1, 2, 9, var]) - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=var) - assert args.flatten() == shape - - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - - def test_fromshape(self): - space = DummySpace() - shape = ((3, (), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, (), False, False), [1]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, (), False, False), [1,2,3,4,5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('b', 'c'), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', ), False, False), [1, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', 'd'), False, False), [1, 5, 7]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - From noreply at buildbot.pypy.org Thu Oct 18 17:41:06 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 17:41:06 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: kill irrelevant tests Message-ID: <20121018154106.3CD6C1C0F16@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58224:6c24bf4836ee Date: 2012-10-18 16:40 +0100 http://bitbucket.org/pypy/pypy/changeset/6c24bf4836ee/ Log: kill irrelevant tests diff --git a/pypy/objspace/flow/test/test_argument.py b/pypy/objspace/flow/test/test_argument.py --- a/pypy/objspace/flow/test/test_argument.py +++ b/pypy/objspace/flow/test/test_argument.py @@ -1,9 +1,7 @@ # -*- coding: utf-8 -*- import py -from pypy.objspace.flow.argument import (Arguments, ArgumentsForTranslation, - ArgErr, ArgErrUnknownKwds, ArgErrMultipleValues, ArgErrCount, rawshape, +from pypy.objspace.flow.argument import (ArgumentsForTranslation, rawshape, Signature) -from pypy.interpreter.error import OperationError class TestSignature(object): @@ -120,10 +118,7 @@ return issubclass(w_type1, w_type2) def call_method(self, obj, name, *args): - try: - method = getattr(obj, name) - except AttributeError: - raise OperationError(AttributeError, name) + method = getattr(obj, name) return method(*args) def type(self, obj): @@ -139,555 +134,6 @@ w_dict = dict w_str = str -class TestArgumentsNormal(object): - - def test_create(self): - space = DummySpace() - args_w = [] - args = Arguments(space, args_w) - assert args.arguments_w is args_w - assert args.keywords is None - assert args.keywords_w is None - - assert args.firstarg() is None - - args = Arguments(space, args_w, w_stararg=["*"], - w_starstararg={"k": 1}) - assert args.arguments_w == ["*"] - assert args.keywords == ["k"] - assert args.keywords_w == [1] - - assert args.firstarg() == "*" - - def test_prepend(self): - space = DummySpace() - args = Arguments(space, ["0"]) - args1 = args.prepend("thingy") - assert args1 is not args - assert args1.arguments_w == ["thingy", "0"] - assert args1.keywords is args.keywords - assert args1.keywords_w is args.keywords_w - - def test_fixedunpacked(self): - space = DummySpace() - - args = Arguments(space, [], ["k"], [1]) - py.test.raises(ValueError, args.fixedunpack, 1) - - args = Arguments(space, ["a", "b"]) - py.test.raises(ValueError, args.fixedunpack, 0) - py.test.raises(ValueError, args.fixedunpack, 1) - py.test.raises(ValueError, args.fixedunpack, 3) - py.test.raises(ValueError, args.fixedunpack, 4) - - assert args.fixedunpack(2) == ['a', 'b'] - - def test_match0(self): - space = DummySpace() - args = Arguments(space, []) - l = [] - args._match_signature(None, l, Signature([])) - assert len(l) == 0 - l = [None, None] - args = Arguments(space, []) - py.test.raises(ArgErr, args._match_signature, None, l, Signature(["a"])) - args = Arguments(space, []) - py.test.raises(ArgErr, args._match_signature, None, l, Signature(["a"], "*")) - args = Arguments(space, []) - l = [None] - args._match_signature(None, l, Signature(["a"]), defaults_w=[1]) - assert l == [1] - args = Arguments(space, []) - l = [None] - args._match_signature(None, l, Signature([], "*")) - assert l == [()] - args = Arguments(space, []) - l = [None] - args._match_signature(None, l, Signature([], None, "**")) - assert l == [{}] - args = Arguments(space, []) - l = [None, None] - py.test.raises(ArgErr, args._match_signature, 41, l, Signature([])) - args = Arguments(space, []) - l = [None] - args._match_signature(1, l, Signature(["a"])) - assert l == [1] - args = Arguments(space, []) - l = [None] - args._match_signature(1, l, Signature([], "*")) - assert l == [(1,)] - - def test_match4(self): - space = DummySpace() - values = [4, 5, 6, 7] - for havefirstarg in [0, 1]: - for i in range(len(values)-havefirstarg): - arglist = values[havefirstarg:i+havefirstarg] - starargs = tuple(values[i+havefirstarg:]) - if havefirstarg: - firstarg = values[0] - else: - firstarg = None - args = Arguments(space, arglist, w_stararg=starargs) - l = [None, None, None, None] - args._match_signature(firstarg, l, Signature(["a", "b", "c", "d"])) - assert l == [4, 5, 6, 7] - args = Arguments(space, arglist, w_stararg=starargs) - l = [None, None, None, None, None, None] - py.test.raises(ArgErr, args._match_signature, firstarg, l, Signature(["a"])) - args = Arguments(space, arglist, w_stararg=starargs) - l = [None, None, None, None, None, None] - py.test.raises(ArgErr, args._match_signature, firstarg, l, Signature(["a", "b", "c", "d", "e"])) - args = Arguments(space, arglist, w_stararg=starargs) - l = [None, None, None, None, None, None] - py.test.raises(ArgErr, args._match_signature, firstarg, l, Signature(["a", "b", "c", "d", "e"], "*")) - l = [None, None, None, None, None] - args = Arguments(space, arglist, w_stararg=starargs) - args._match_signature(firstarg, l, Signature(["a", "b", "c", "d", "e"]), defaults_w=[1]) - assert l == [4, 5, 6, 7, 1] - for j in range(len(values)): - l = [None] * (j + 1) - args = Arguments(space, arglist, w_stararg=starargs) - args._match_signature(firstarg, l, Signature(["a", "b", "c", "d", "e"][:j], "*")) - assert l == values[:j] + [tuple(values[j:])] - l = [None, None, None, None, None] - args = Arguments(space, arglist, w_stararg=starargs) - args._match_signature(firstarg, l, Signature(["a", "b", "c", "d"], None, "**")) - assert l == [4, 5, 6, 7, {}] - - def test_match_kwds(self): - space = DummySpace() - for i in range(3): - kwds = [("c", 3)] - kwds_w = dict(kwds[:i]) - keywords = kwds_w.keys() - keywords_w = kwds_w.values() - w_kwds = dummy_wrapped_dict(kwds[i:]) - if i == 2: - w_kwds = None - assert len(keywords) == len(keywords_w) - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None] - args._match_signature(None, l, Signature(["a", "b", "c"]), defaults_w=[4]) - assert l == [1, 2, 3] - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None, None] - args._match_signature(None, l, Signature(["a", "b", "b1", "c"]), defaults_w=[4, 5]) - assert l == [1, 2, 4, 3] - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None, None] - args._match_signature(None, l, Signature(["a", "b", "c", "d"]), defaults_w=[4, 5]) - assert l == [1, 2, 3, 5] - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None, None] - py.test.raises(ArgErr, args._match_signature, None, l, - Signature(["c", "b", "a", "d"]), defaults_w=[4, 5]) - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None, None] - py.test.raises(ArgErr, args._match_signature, None, l, - Signature(["a", "b", "c1", "d"]), defaults_w=[4, 5]) - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None] - args._match_signature(None, l, Signature(["a", "b"], None, "**")) - assert l == [1, 2, {'c': 3}] - - def test_match_kwds2(self): - space = DummySpace() - kwds = [("c", 3), ('d', 4)] - for i in range(4): - kwds_w = dict(kwds[:i]) - keywords = kwds_w.keys() - keywords_w = kwds_w.values() - w_kwds = dummy_wrapped_dict(kwds[i:]) - if i == 3: - w_kwds = None - args = Arguments(space, [1, 2], keywords, keywords_w, w_starstararg=w_kwds) - l = [None, None, None, None] - args._match_signature(None, l, Signature(["a", "b", "c"], None, "**")) - assert l == [1, 2, 3, {'d': 4}] - - def test_match_kwds_creates_kwdict(self): - space = DummySpace() - kwds = [("c", 3), ('d', 4)] - for i in range(4): - kwds_w = dict(kwds[:i]) - keywords = kwds_w.keys() - keywords_w = kwds_w.values() - w_kwds = dummy_wrapped_dict(kwds[i:]) - if i == 3: - w_kwds = None - args = Arguments(space, [1, 2], keywords, keywords_w, w_starstararg=w_kwds) - l = [None, None, None, None] - args._match_signature(None, l, Signature(["a", "b", "c"], None, "**")) - assert l == [1, 2, 3, {'d': 4}] - assert isinstance(l[-1], kwargsdict) - - def test_duplicate_kwds(self): - space = DummySpace() - excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"], - [1], w_starstararg={"a": 2}) - assert excinfo.value.w_type is TypeError - - def test_starstararg_wrong_type(self): - space = DummySpace() - excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"], - [1], w_starstararg="hello") - assert excinfo.value.w_type is TypeError - - def test_unwrap_error(self): - space = DummySpace() - valuedummy = object() - def str_w(w): - if w is None: - raise OperationError(TypeError, None) - if w is valuedummy: - raise OperationError(ValueError, None) - return str(w) - space.str_w = str_w - excinfo = py.test.raises(OperationError, Arguments, space, [], - ["a"], [1], w_starstararg={None: 1}) - assert excinfo.value.w_type is TypeError - assert excinfo.value._w_value is not None - excinfo = py.test.raises(OperationError, Arguments, space, [], - ["a"], [1], w_starstararg={valuedummy: 1}) - assert excinfo.value.w_type is ValueError - assert excinfo.value._w_value is None - - - def test_blindargs(self): - space = DummySpace() - kwds = [("a", 3), ('b', 4)] - for i in range(4): - kwds_w = dict(kwds[:i]) - keywords = kwds_w.keys() - keywords_w = kwds_w.values() - w_kwds = dict(kwds[i:]) - if i == 3: - w_kwds = None - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], - w_starstararg=w_kwds) - l = [None, None, None] - args._match_signature(None, l, Signature(["a", "b"], None, "**"), blindargs=2) - assert l == [1, 2, {'a':3, 'b': 4}] - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], - w_starstararg=w_kwds) - l = [None, None, None] - py.test.raises(ArgErrUnknownKwds, args._match_signature, None, l, - Signature(["a", "b"]), blindargs=2) - - def test_args_parsing(self): - space = DummySpace() - args = Arguments(space, []) - - calls = [] - - def _match_signature(w_firstarg, scope_w, signature, - defaults_w=None, blindargs=0): - defaults_w = [] if defaults_w is None else defaults_w - calls.append((w_firstarg, scope_w, signature.argnames, signature.has_vararg(), - signature.has_kwarg(), defaults_w, blindargs)) - args._match_signature = _match_signature - - scope_w = args.parse_obj(None, "foo", Signature(["a", "b"], None, None)) - assert len(calls) == 1 - assert calls[0] == (None, [None, None], ["a", "b"], False, False, - [], 0) - assert calls[0][1] is scope_w - calls = [] - - scope_w = args.parse_obj(None, "foo", Signature(["a", "b"], "args", None), - blindargs=1) - assert len(calls) == 1 - assert calls[0] == (None, [None, None, None], ["a", "b"], True, False, - [], 1) - calls = [] - - scope_w = args.parse_obj(None, "foo", Signature(["a", "b"], "args", "kw"), - defaults_w=['x', 'y']) - assert len(calls) == 1 - assert calls[0] == (None, [None, None, None, None], ["a", "b"], - True, True, - ["x", "y"], 0) - calls = [] - - scope_w = args.parse_obj("obj", "foo", Signature(["a", "b"], "args", "kw"), - defaults_w=['x', 'y'], blindargs=1) - assert len(calls) == 1 - assert calls[0] == ("obj", [None, None, None, None], ["a", "b"], - True, True, - ["x", "y"], 1) - - class FakeArgErr(ArgErr): - - def getmsg(self): - return "msg" - - def _match_signature(*args): - raise FakeArgErr() - args._match_signature = _match_signature - - - excinfo = py.test.raises(OperationError, args.parse_obj, "obj", "foo", - Signature(["a", "b"], None, None)) - assert excinfo.value.w_type is TypeError - assert excinfo.value.get_w_value(space) == "foo() msg" - - - def test_args_parsing_into_scope(self): - space = DummySpace() - args = Arguments(space, []) - - calls = [] - - def _match_signature(w_firstarg, scope_w, signature, - defaults_w=None, blindargs=0): - defaults_w = [] if defaults_w is None else defaults_w - calls.append((w_firstarg, scope_w, signature.argnames, signature.has_vararg(), - signature.has_kwarg(), defaults_w, blindargs)) - args._match_signature = _match_signature - - scope_w = [None, None] - args.parse_into_scope(None, scope_w, "foo", Signature(["a", "b"], None, None)) - assert len(calls) == 1 - assert calls[0] == (None, scope_w, ["a", "b"], False, False, - [], 0) - assert calls[0][1] is scope_w - calls = [] - - scope_w = [None, None, None, None] - args.parse_into_scope(None, scope_w, "foo", Signature(["a", "b"], "args", "kw"), - defaults_w=['x', 'y']) - assert len(calls) == 1 - assert calls[0] == (None, scope_w, ["a", "b"], - True, True, - ["x", "y"], 0) - calls = [] - - scope_w = [None, None, None, None] - args.parse_into_scope("obj", scope_w, "foo", Signature(["a", "b"], - "args", "kw"), - defaults_w=['x', 'y']) - assert len(calls) == 1 - assert calls[0] == ("obj", scope_w, ["a", "b"], - True, True, - ["x", "y"], 0) - - class FakeArgErr(ArgErr): - - def getmsg(self): - return "msg" - - def _match_signature(*args): - raise FakeArgErr() - args._match_signature = _match_signature - - - excinfo = py.test.raises(OperationError, args.parse_into_scope, - "obj", [None, None], "foo", - Signature(["a", "b"], None, None)) - assert excinfo.value.w_type is TypeError - assert excinfo.value.get_w_value(space) == "foo() msg" - - def test_topacked_frompacked(self): - space = DummySpace() - args = Arguments(space, [1], ['a', 'b'], [2, 3]) - w_args, w_kwds = args.topacked() - assert w_args == (1,) - assert w_kwds == {'a': 2, 'b': 3} - args1 = Arguments.frompacked(space, w_args, w_kwds) - assert args.arguments_w == [1] - assert set(args.keywords) == set(['a', 'b']) - assert args.keywords_w[args.keywords.index('a')] == 2 - assert args.keywords_w[args.keywords.index('b')] == 3 - - args = Arguments(space, [1]) - w_args, w_kwds = args.topacked() - assert w_args == (1, ) - assert not w_kwds - - def test_argument_unicode(self): - space = DummySpace() - w_starstar = space.wrap({u'abc': 5}) - args = Arguments(space, [], w_starstararg=w_starstar) - l = [None] - args._match_signature(None, l, Signature(['abc'])) - assert len(l) == 1 - assert l[0] == space.wrap(5) - - def test_starstarargs_special(self): - class kwargs(object): - def __init__(self, k, v): - self.k = k - self.v = v - class MyDummySpace(DummySpace): - def view_as_kwargs(self, kw): - if isinstance(kw, kwargs): - return kw.k, kw.v - return None, None - space = MyDummySpace() - for i in range(3): - kwds = [("c", 3)] - kwds_w = dict(kwds[:i]) - keywords = kwds_w.keys() - keywords_w = kwds_w.values() - rest = dict(kwds[i:]) - w_kwds = kwargs(rest.keys(), rest.values()) - if i == 2: - w_kwds = None - assert len(keywords) == len(keywords_w) - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None] - args._match_signature(None, l, Signature(["a", "b", "c"]), defaults_w=[4]) - assert l == [1, 2, 3] - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None, None] - args._match_signature(None, l, Signature(["a", "b", "b1", "c"]), defaults_w=[4, 5]) - assert l == [1, 2, 4, 3] - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None, None] - args._match_signature(None, l, Signature(["a", "b", "c", "d"]), defaults_w=[4, 5]) - assert l == [1, 2, 3, 5] - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None, None] - py.test.raises(ArgErr, args._match_signature, None, l, - Signature(["c", "b", "a", "d"]), defaults_w=[4, 5]) - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None, None] - py.test.raises(ArgErr, args._match_signature, None, l, - Signature(["a", "b", "c1", "d"]), defaults_w=[4, 5]) - args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds) - l = [None, None, None] - args._match_signature(None, l, Signature(["a", "b"], None, "**")) - assert l == [1, 2, {'c': 3}] - excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"], - [1], w_starstararg=kwargs(["a"], [2])) - assert excinfo.value.w_type is TypeError - - - -class TestErrorHandling(object): - def test_missing_args(self): - # got_nargs, nkwds, expected_nargs, has_vararg, has_kwarg, - # defaults_w, missing_args - sig = Signature([], None, None) - err = ArgErrCount(1, 0, sig, None, 0) - s = err.getmsg() - assert s == "takes no arguments (1 given)" - - sig = Signature(['a'], None, None) - err = ArgErrCount(0, 0, sig, [], 1) - s = err.getmsg() - assert s == "takes exactly 1 argument (0 given)" - - sig = Signature(['a', 'b'], None, None) - err = ArgErrCount(3, 0, sig, [], 0) - s = err.getmsg() - assert s == "takes exactly 2 arguments (3 given)" - err = ArgErrCount(3, 0, sig, ['a'], 0) - s = err.getmsg() - assert s == "takes at most 2 arguments (3 given)" - - sig = Signature(['a', 'b'], '*', None) - err = ArgErrCount(1, 0, sig, [], 1) - s = err.getmsg() - assert s == "takes at least 2 arguments (1 given)" - err = ArgErrCount(0, 1, sig, ['a'], 1) - s = err.getmsg() - assert s == "takes at least 1 non-keyword argument (0 given)" - - sig = Signature(['a'], None, '**') - err = ArgErrCount(2, 1, sig, [], 0) - s = err.getmsg() - assert s == "takes exactly 1 non-keyword argument (2 given)" - err = ArgErrCount(0, 1, sig, [], 1) - s = err.getmsg() - assert s == "takes exactly 1 non-keyword argument (0 given)" - - sig = Signature(['a'], '*', '**') - err = ArgErrCount(0, 1, sig, [], 1) - s = err.getmsg() - assert s == "takes at least 1 non-keyword argument (0 given)" - - sig = Signature(['a'], None, '**') - err = ArgErrCount(2, 1, sig, ['a'], 0) - s = err.getmsg() - assert s == "takes at most 1 non-keyword argument (2 given)" - - def test_bad_type_for_star(self): - space = self.space - try: - Arguments(space, [], w_stararg=space.wrap(42)) - except OperationError, e: - msg = space.str_w(space.str(e.get_w_value(space))) - assert msg == "argument after * must be a sequence, not int" - else: - assert 0, "did not raise" - try: - Arguments(space, [], w_starstararg=space.wrap(42)) - except OperationError, e: - msg = space.str_w(space.str(e.get_w_value(space))) - assert msg == "argument after ** must be a mapping, not int" - else: - assert 0, "did not raise" - - def test_unknown_keywords(self): - space = DummySpace() - err = ArgErrUnknownKwds(space, 1, ['a', 'b'], [0], None) - s = err.getmsg() - assert s == "got an unexpected keyword argument 'b'" - err = ArgErrUnknownKwds(space, 1, ['a', 'b'], [1], None) - s = err.getmsg() - assert s == "got an unexpected keyword argument 'a'" - err = ArgErrUnknownKwds(space, 2, ['a', 'b', 'c'], - [0], None) - s = err.getmsg() - assert s == "got 2 unexpected keyword arguments" - - def test_unknown_unicode_keyword(self): - class DummySpaceUnicode(DummySpace): - class sys: - defaultencoding = 'utf-8' - space = DummySpaceUnicode() - err = ArgErrUnknownKwds(space, 1, ['a', None, 'b', 'c'], - [0, 3, 2], - [unichr(0x1234), u'b', u'c']) - s = err.getmsg() - assert s == "got an unexpected keyword argument '\xe1\x88\xb4'" - - def test_multiple_values(self): - err = ArgErrMultipleValues('bla') - s = err.getmsg() - assert s == "got multiple values for keyword argument 'bla'" - -class AppTestArgument: - def test_error_message(self): - exc = raises(TypeError, (lambda a, b=2: 0), b=3) - assert exc.value.message == "() takes at least 1 non-keyword argument (0 given)" - exc = raises(TypeError, (lambda: 0), b=3) - assert exc.value.message == "() takes no arguments (1 given)" - exc = raises(TypeError, (lambda a, b: 0), 1, 2, 3, a=1) - assert exc.value.message == "() takes exactly 2 arguments (4 given)" - exc = raises(TypeError, (lambda a, b=1: 0), 1, 2, 3, a=1) - assert exc.value.message == "() takes at most 2 non-keyword arguments (3 given)" - exc = raises(TypeError, (lambda a, b=1, **kw: 0), 1, 2, 3) - assert exc.value.message == "() takes at most 2 non-keyword arguments (3 given)" - exc = raises(TypeError, (lambda a, b, c=3, **kw: 0), 1) - assert exc.value.message == "() takes at least 2 arguments (1 given)" - exc = raises(TypeError, (lambda a, b, **kw: 0), 1) - assert exc.value.message == "() takes exactly 2 non-keyword arguments (1 given)" - exc = raises(TypeError, (lambda a, b, c=3, **kw: 0), a=1) - assert exc.value.message == "() takes at least 2 non-keyword arguments (0 given)" - exc = raises(TypeError, (lambda a, b, **kw: 0), a=1) - assert exc.value.message == "() takes exactly 2 non-keyword arguments (0 given)" - - def test_unicode_keywords(self): - def f(**kwargs): - assert kwargs[u"美"] == 42 - f(**{u"美" : 42}) - def f(x): pass - e = raises(TypeError, "f(**{u'ü' : 19})") - assert "?" in str(e.value) - def make_arguments_for_translation(space, args_w, keywords_w={}, w_stararg=None, w_starstararg=None): return ArgumentsForTranslation(space, args_w, keywords_w.keys(), From noreply at buildbot.pypy.org Thu Oct 18 17:41:48 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Thu, 18 Oct 2012 17:41:48 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: extremely minimalistic conclusion Message-ID: <20121018154148.C993D1C0F16@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4878:ffb4a711a6cb Date: 2012-10-18 17:41 +0200 http://bitbucket.org/pypy/extradoc/changeset/ffb4a711a6cb/ Log: extremely minimalistic conclusion diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -348,6 +348,18 @@ \begin{frame} \includegraphics[scale=0.6]{figures/resume_data_size} \end{frame} + +\begin{frame} + \frametitle{Conclusion} + \begin{itemize} + \item Things that sound simple still often need careful engineering + \pause + \item not even any direct performance gains + \item keep memory usage sane + \item allows good bridges + \end{itemize} +\end{frame} + %\section{Evaluation} %as in paper From noreply at buildbot.pypy.org Thu Oct 18 17:47:05 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 17:47:05 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Fix the fast path of call_assembler. Message-ID: <20121018154705.A48211C0F16@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58225:5365a6953d35 Date: 2012-10-18 17:46 +0200 http://bitbucket.org/pypy/pypy/changeset/5365a6953d35/ Log: Fix the fast path of call_assembler. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -217,6 +217,7 @@ frame.finish_value = e.arg frame.latest_values = e.failargs frame.latest_descr = e.descr + frame._execution_finished = True return frame except GuardFailed, e: frame.latest_values = e.failargs @@ -529,6 +530,7 @@ class LLFrame(object): _TYPE = llmemory.GCREF _forced = False + _execution_finished = False def __init__(self, cpu, argboxes, args): self.env = {} @@ -774,8 +776,9 @@ def execute_call_assembler(self, descr, *args): frame = self.cpu._execute_token(descr, *args) + if frame._execution_finished: # fast path + return frame.finish_value jd = descr.outermost_jitdriver_sd - # xxx fast path????? assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish try: result = assembler_helper_ptr(frame) diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -12,11 +12,6 @@ # Boxes and Consts are BoxFloats and ConstFloats. supports_singlefloats = False - done_with_this_frame_void_v = -1 - done_with_this_frame_int_v = -1 - done_with_this_frame_ref_v = -1 - done_with_this_frame_float_v = -1 - propagate_exception_v = -1 total_compiled_loops = 0 total_compiled_bridges = 0 total_freed_loops = 0 diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2724,7 +2724,6 @@ def test_assembler_call(self): called = [] def assembler_helper(jitframe): - assert self.cpu.get_finish_value_int(jitframe) == 97 faildescr = self.cpu.get_latest_descr(jitframe) failindex = self.cpu.get_fail_descr_number(faildescr) called.append(failindex) @@ -2743,7 +2742,8 @@ self.cpu.reserve_some_free_fail_descr_number() ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] - i10 = int_add(i0, i1) + i10 = int_add_ovf(i0, i1) + guard_no_overflow() [] i11 = int_add(i10, i2) i12 = int_add(i11, i3) i13 = int_add(i12, i4) @@ -2756,7 +2756,8 @@ loop = parse(ops) looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() - done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr()) + fail_number = self.cpu.get_fail_descr_number( + loop.operations[1].getdescr()) self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * 10 RES = lltype.Signed @@ -2775,33 +2776,26 @@ ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() + + # test the fast path, which should not call assembler_helper() self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [i+1 for i in range(10)] frame = self.cpu.execute_token(othertoken, *args) + assert self.cpu.get_finish_value_int(frame) == 97 + assert called == [] + + # test the slow path, going via assembler_helper() + args[1] = sys.maxint + frame = self.cpu.execute_token(othertoken, *args) assert self.cpu.get_finish_value_int(frame) == 13 - assert called == [done_number] - - # test the fast path, which should not call assembler_helper() - del called[:] - self.cpu.done_with_this_frame_int_v = done_number - try: - othertoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) - args = [i+1 for i in range(10)] - frame = self.cpu.execute_token(othertoken, *args) - assert self.cpu.get_finish_value_int(frame) == 97 - assert not called - finally: - del self.cpu.done_with_this_frame_int_v + assert called == [fail_number] def test_assembler_call_float(self): if not self.cpu.supports_floats: py.test.skip("requires floats") called = [] def assembler_helper(jitframe): - x = self.cpu.get_finish_value_float(jitframe) - assert longlong.getrealfloat(x) == 1.2 + 3.2 - faildescr =self.cpu.get_latest_descr(jitframe) + faildescr = self.cpu.get_latest_descr(jitframe) failindex = self.cpu.get_fail_descr_number(faildescr) called.append(failindex) return 13.5 @@ -2823,10 +2817,13 @@ self.cpu.reserve_some_free_fail_descr_number() ops = ''' [f0, f1] + i0 = float_eq(f0, -1.0) + guard_false(i0) [] f2 = float_add(f0, f1) finish(f2)''' loop = parse(ops) - done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr()) + fail_number = self.cpu.get_fail_descr_number( + loop.operations[1].getdescr()) looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) @@ -2844,27 +2841,21 @@ loop = parse(ops, namespace=locals()) othertoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + + # test the fast path, which should not call assembler_helper() args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(3.2)] frame = self.cpu.execute_token(othertoken, *args) x = self.cpu.get_finish_value_float(frame) + assert longlong.getrealfloat(x) == 1.2 + 3.2 + assert called == [] + + # test the slow path, going via assembler_helper() + args[0] = longlong.getfloatstorage(-1.0) + frame = self.cpu.execute_token(othertoken, *args) + x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 13.5 - assert called == [done_number] - - # test the fast path, which should not call assembler_helper() - del called[:] - self.cpu.done_with_this_frame_float_v = done_number - try: - othertoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) - args = [longlong.getfloatstorage(1.2), - longlong.getfloatstorage(3.2)] - frame = self.cpu.execute_token(othertoken, *args) - x = self.cpu.get_finish_value_float(frame) - assert longlong.getrealfloat(x) == 1.2 + 3.2 - assert not called - finally: - del self.cpu.done_with_this_frame_float_v + assert called == [fail_number] def test_raw_malloced_getarrayitem(self): ARRAY = rffi.CArray(lltype.Signed) @@ -2895,8 +2886,6 @@ py.test.skip("requires floats") called = [] def assembler_helper(jitframe): - x = self.cpu.get_finish_value_float(jitframe) - assert longlong.getrealfloat(x) == 1.25 + 3.25 faildescr =self.cpu.get_latest_descr(jitframe) failindex = self.cpu.get_fail_descr_number(faildescr) called.append(failindex) @@ -2919,13 +2908,16 @@ self.cpu.reserve_some_free_fail_descr_number() ops = ''' [f0, f1] + i0 = float_eq(f0, -1.0) + guard_false(i0) [] f2 = float_add(f0, f1) finish(f2)''' loop = parse(ops) looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) - done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr()) + fail_number = self.cpu.get_fail_descr_number( + loop.operations[1].getdescr()) args = [longlong.getfloatstorage(1.25), longlong.getfloatstorage(2.35)] frame = self.cpu.execute_token(looptoken, *args) @@ -2948,31 +2940,46 @@ longlong.getfloatstorage(3.25)] frame = self.cpu.execute_token(othertoken, *args) x = self.cpu.get_finish_value_float(frame) + assert longlong.getrealfloat(x) == 1.25 + 3.25 + assert called == [] + + args[0] = longlong.getfloatstorage(-1.0) + frame = self.cpu.execute_token(othertoken, *args) + x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 13.5 - assert called == [done_number] + assert called == [fail_number] del called[:] # compile a replacement ops = ''' [f0, f1] + i0 = float_eq(f0, -2.0) + guard_false(i0) [] f2 = float_sub(f0, f1) finish(f2)''' loop = parse(ops) looptoken2 = JitCellToken() looptoken2.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken2) - done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr()) + fail_number = self.cpu.get_fail_descr_number( + loop.operations[1].getdescr()) # install it self.cpu.redirect_call_assembler(looptoken, looptoken2) # now, our call_assembler should go to looptoken2 - args = [longlong.getfloatstorage(6.0), - longlong.getfloatstorage(1.5)] # 6.0-1.5 == 1.25+3.25 + args = [longlong.getfloatstorage(116.0), + longlong.getfloatstorage(1.5)] + frame = self.cpu.execute_token(othertoken, *args) + x = self.cpu.get_finish_value_float(frame) + assert longlong.getrealfloat(x) == 116.0 - 1.5 + assert called == [] + + args[0] = longlong.getfloatstorage(-2.0) frame = self.cpu.execute_token(othertoken, *args) x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 13.5 - assert called == [done_number] + assert called == [fail_number] def test_short_result_of_getfield_direct(self): # Test that a getfield that returns a CHAR, SHORT or INT, signed From noreply at buildbot.pypy.org Thu Oct 18 18:08:04 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Thu, 18 Oct 2012 18:08:04 +0200 (CEST) Subject: [pypy-commit] pypy py3k: implement isdisjoint for keys/items dict views Message-ID: <20121018160804.AE1FC1C1CE5@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58226:68abca2a460f Date: 2012-10-18 18:07 +0200 http://bitbucket.org/pypy/pypy/changeset/68abca2a460f/ Log: implement isdisjoint for keys/items dict views diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -1052,7 +1052,6 @@ generate_setops() - # ____________________________________________________________ from pypy.objspace.std import dicttype diff --git a/pypy/objspace/std/dicttype.py b/pypy/objspace/std/dicttype.py --- a/pypy/objspace/std/dicttype.py +++ b/pypy/objspace/std/dicttype.py @@ -42,6 +42,7 @@ doc='D.itervalues() -> an iterator over the values of D') dict_reversed = SMM('__reversed__', 1) + def dict_reversed__ANY(space, w_dict): raise OperationError(space.w_TypeError, space.wrap('argument to reversed() must be a sequence')) @@ -192,12 +193,42 @@ # ____________________________________________________________ # Dict views +def descr_dictview_isdisjoin(space, w_self, w_other): + from pypy.objspace.std.dictmultiobject import W_DictViewObject + if w_self is w_other: + if space.len_w(w_self) == 0: + return space.w_True + else: + return space.w_False + + # check whether w_other is a set-like object + if (space.isinstance_w(w_other, space.w_set) or + space.isinstance_w(w_other, space.w_frozenset) or + isinstance(w_other, W_DictViewObject)): + # if w_other is set-like and it's longer, we iterate over w_self + # instead + len_self = space.len_w(w_self) + len_other = space.len_w(w_other) + if len_other > len_self: + w_self, w_other = w_other, w_self + + w_it = space.iter(w_other) + for w_item in space.iteriterable(w_it): + if space.is_true(space.contains(w_self, w_item)): + return space.w_False + return space.w_True + + dict_keys_typedef = StdTypeDef( "dict_keys", + isdisjoint = gateway.interp2app(descr_dictview_isdisjoin), + ) +dict_keys_typedef.registermethods(globals()) dict_items_typedef = StdTypeDef( "dict_items", + isdisjoint = gateway.interp2app(descr_dictview_isdisjoin), ) dict_values_typedef = StdTypeDef( diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -752,6 +752,26 @@ assert d1.keys() - set(d2.keys()) == set('a') assert d1.keys() - set(d3.keys()) == set('ab') + assert not d1.keys().isdisjoint(d1.keys()) + assert not d1.keys().isdisjoint(d2.keys()) + assert not d1.keys().isdisjoint(list(d2.keys())) + assert not d1.keys().isdisjoint(set(d2.keys())) + + assert d1.keys().isdisjoint({'x', 'y', 'z'}) + assert d1.keys().isdisjoint(['x', 'y', 'z']) + assert d1.keys().isdisjoint(set(['x', 'y', 'z'])) + assert d1.keys().isdisjoint(set(['x', 'y'])) + assert d1.keys().isdisjoint(['x', 'y']) + assert d1.keys().isdisjoint({}) + assert d1.keys().isdisjoint(d3.keys()) + + de = {} + assert de.keys().isdisjoint(set()) + assert de.keys().isdisjoint([]) + assert de.keys().isdisjoint(de.keys()) + assert de.keys().isdisjoint([1]) + + def test_items_set_operations(self): d1 = {'a': 1, 'b': 2} d2 = {'a': 2, 'b': 2} @@ -784,6 +804,23 @@ assert d1.items() - d2.items() == set([('a', 1)]) assert d1.items() - d3.items() == set([('a', 1), ('b', 2)]) + assert not d1.items().isdisjoint(d1.items()) + assert not d1.items().isdisjoint(d2.items()) + assert not d1.items().isdisjoint(list(d2.items())) + assert not d1.items().isdisjoint(set(d2.items())) + assert d1.items().isdisjoint({'x', 'y', 'z'}) + assert d1.items().isdisjoint(['x', 'y', 'z']) + assert d1.items().isdisjoint(set(['x', 'y', 'z'])) + assert d1.items().isdisjoint(set(['x', 'y'])) + assert d1.items().isdisjoint({}) + assert d1.items().isdisjoint(d3.items()) + + de = {} + assert de.items().isdisjoint(set()) + assert de.items().isdisjoint([]) + assert de.items().isdisjoint(de.items()) + assert de.items().isdisjoint([1]) + def test_keys_set_operations_any_type(self): d = {1: 'a', 2: 'b', 3: 'c'} assert d.keys() & {1} == {1} From noreply at buildbot.pypy.org Thu Oct 18 18:18:36 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 18 Oct 2012 18:18:36 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Kill test_ztranslation here. Message-ID: <20121018161836.7054F1C1CE7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58227:72336170ced3 Date: 2012-10-18 18:18 +0200 http://bitbucket.org/pypy/pypy/changeset/72336170ced3/ Log: Kill test_ztranslation here. diff --git a/pypy/jit/metainterp/test/test_ztranslation.py b/pypy/jit/metainterp/test/test_ztranslation.py deleted file mode 100644 --- a/pypy/jit/metainterp/test/test_ztranslation.py +++ /dev/null @@ -1,154 +0,0 @@ -import py -from pypy.jit.metainterp.warmspot import rpython_ll_meta_interp, ll_meta_interp -from pypy.jit.backend.llgraph import runner -from pypy.rlib.jit import JitDriver, unroll_parameters, set_param -from pypy.rlib.jit import PARAMETERS, dont_look_inside, hint -from pypy.rlib.jit_hooks import boxint_new, resop_new, resop_getopnum -from pypy.jit.metainterp.jitprof import Profiler -from pypy.jit.metainterp.resoperation import rop -from pypy.rpython.lltypesystem import lltype, llmemory - -class TranslationTest: - - CPUClass = None - type_system = None - - def test_stuff_translates(self): - # this is a basic test that tries to hit a number of features and their - # translation: - # - jitting of loops and bridges - # - virtualizables - # - set_param interface - # - profiler - # - full optimizer - # - jitdriver hooks - # - two JITs - # - string concatenation, slicing and comparison - # - jit hooks interface - - class Frame(object): - _virtualizable2_ = ['l[*]'] - - def __init__(self, i): - self = hint(self, fresh_virtualizable=True, - access_directly=True) - self.l = [i] - - class OtherFrame(object): - _virtualizable2_ = ['i', 'l[*]'] - - def __init__(self, i): - self = hint(self, fresh_virtualizable=True, - access_directly=True) - self.i = i - self.l = [float(i)] - - class JitCellCache: - entry = None - jitcellcache = JitCellCache() - def set_jitcell_at(entry): - jitcellcache.entry = entry - def get_jitcell_at(): - return jitcellcache.entry - def get_printable_location(): - return '(hello world)' - - jitdriver = JitDriver(greens = [], reds = ['total', 'frame'], - virtualizables = ['frame'], - get_jitcell_at=get_jitcell_at, - set_jitcell_at=set_jitcell_at, - get_printable_location=get_printable_location) - def f(i): - for param, defl in unroll_parameters: - set_param(jitdriver, param, defl) - set_param(jitdriver, "threshold", 3) - set_param(jitdriver, "trace_eagerness", 2) - total = 0 - frame = Frame(i) - while frame.l[0] > 3: - jitdriver.can_enter_jit(frame=frame, total=total) - jitdriver.jit_merge_point(frame=frame, total=total) - total += frame.l[0] - if frame.l[0] >= 20: - frame.l[0] -= 2 - frame.l[0] -= 1 - return total * 10 - # - myjitdriver2 = JitDriver(greens = ['g'], - reds = ['m', 's', 'f', 'float_s'], - virtualizables = ['f']) - def f2(g, m, x): - s = "" - f = OtherFrame(x) - float_s = 0.0 - while m > 0: - myjitdriver2.can_enter_jit(g=g, m=m, f=f, s=s, float_s=float_s) - myjitdriver2.jit_merge_point(g=g, m=m, f=f, s=s, - float_s=float_s) - s += 'xy' - if s[:2] == 'yz': - return -666 - m -= 1 - f.i += 3 - float_s += f.l[0] - return f.i - # - def main(i, j): - op = resop_new(rop.INT_ADD, [boxint_new(3), boxint_new(5)], - boxint_new(8)) - return f(i) - f2(i+j, i, j) + resop_getopnum(op) - res = ll_meta_interp(main, [40, 5], CPUClass=self.CPUClass, - type_system=self.type_system, - listops=True) - assert res == main(40, 5) - res = rpython_ll_meta_interp(main, [40, 5], - CPUClass=self.CPUClass, - type_system=self.type_system, - ProfilerClass=Profiler, - listops=True) - assert res == main(40, 5) - - def test_external_exception_handling_translates(self): - jitdriver = JitDriver(greens = [], reds = ['n', 'total']) - - @dont_look_inside - def f(x): - if x > 20: - return 2 - raise ValueError - @dont_look_inside - def g(x): - if x > 15: - raise ValueError - return 2 - def main(i): - set_param(jitdriver, "threshold", 3) - set_param(jitdriver, "trace_eagerness", 2) - total = 0 - n = i - while n > 3: - jitdriver.can_enter_jit(n=n, total=total) - jitdriver.jit_merge_point(n=n, total=total) - try: - total += f(n) - except ValueError: - total += 1 - try: - total += g(n) - except ValueError: - total -= 1 - n -= 1 - return total * 10 - res = ll_meta_interp(main, [40], CPUClass=self.CPUClass, - type_system=self.type_system) - assert res == main(40) - res = rpython_ll_meta_interp(main, [40], CPUClass=self.CPUClass, - type_system=self.type_system, - enable_opts='', - ProfilerClass=Profiler) - assert res == main(40) - -class TestTranslationLLtype(TranslationTest): - - CPUClass = runner.LLtypeCPU - type_system = 'lltype' From noreply at buildbot.pypy.org Thu Oct 18 19:28:27 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 19:28:27 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: inline some Arguments code into ArgsFT Message-ID: <20121018172827.53DCC1C0F16@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58228:92cf20b78c89 Date: 2012-10-18 18:28 +0100 http://bitbucket.org/pypy/pypy/changeset/92cf20b78c89/ Log: inline some Arguments code into ArgsFT diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -93,49 +93,9 @@ ### Construction ### - def __init__(self, space, args_w, keywords=None, keywords_w=None, - w_stararg=None, w_starstararg=None, keyword_names_w=None): - self.space = space - assert isinstance(args_w, list) - self.arguments_w = args_w - self.keywords = keywords - self.keywords_w = keywords_w - self.keyword_names_w = keyword_names_w # matches the tail of .keywords - if keywords is not None: - assert keywords_w is not None - assert len(keywords_w) == len(keywords) - assert (keyword_names_w is None or - len(keyword_names_w) <= len(keywords)) - make_sure_not_resized(self.keywords) - make_sure_not_resized(self.keywords_w) - - make_sure_not_resized(self.arguments_w) - self._combine_wrapped(w_stararg, w_starstararg) - # a flag that specifies whether the JIT can unroll loops that operate - # on the keywords - self._jit_few_keywords = self.keywords is None or jit.isconstant(len(self.keywords)) - - def __repr__(self): - """ NOT_RPYTHON """ - name = self.__class__.__name__ - if not self.keywords: - return '%s(%s)' % (name, self.arguments_w,) - else: - return '%s(%s, %s, %s)' % (name, self.arguments_w, - self.keywords, self.keywords_w) - ### Manipulation ### - @jit.look_inside_iff(lambda self: self._jit_few_keywords) - def unpack(self): # slowish - "Return a ([w1,w2...], {'kw':w3...}) pair." - kwds_w = {} - if self.keywords: - for i in range(len(self.keywords)): - kwds_w[self.keywords[i]] = self.keywords_w[i] - return self.arguments_w, kwds_w - def replace_arguments(self, args_w): "Return a new Arguments with a args_w as positional arguments." return Arguments(self.space, args_w, self.keywords, self.keywords_w, @@ -228,7 +188,192 @@ ### Parsing for function calls ### - @jit.unroll_safe + def parse_into_scope(self, w_firstarg, + scope_w, fnname, signature, defaults_w=None): + """Parse args and kwargs to initialize a frame + according to the signature of code object. + Store the argumentvalues into scope_w. + scope_w must be big enough for signature. + """ + try: + self._match_signature(w_firstarg, + scope_w, signature, defaults_w, 0) + except ArgErr, e: + raise operationerrfmt(self.space.w_TypeError, + "%s() %s", fnname, e.getmsg()) + return signature.scope_length() + + def _parse(self, w_firstarg, signature, defaults_w, blindargs=0): + """Parse args and kwargs according to the signature of a code object, + or raise an ArgErr in case of failure. + """ + scopelen = signature.scope_length() + scope_w = [None] * scopelen + self._match_signature(w_firstarg, scope_w, signature, defaults_w, + blindargs) + return scope_w + + + def parse_obj(self, w_firstarg, + fnname, signature, defaults_w=None, blindargs=0): + """Parse args and kwargs to initialize a frame + according to the signature of code object. + """ + try: + return self._parse(w_firstarg, signature, defaults_w, blindargs) + except ArgErr, e: + raise operationerrfmt(self.space.w_TypeError, + "%s() %s", fnname, e.getmsg()) + + @staticmethod + def frompacked(space, w_args=None, w_kwds=None): + """Convenience static method to build an Arguments + from a wrapped sequence and a wrapped dictionary.""" + return Arguments(space, [], w_stararg=w_args, w_starstararg=w_kwds) + + def topacked(self): + """Express the Argument object as a pair of wrapped w_args, w_kwds.""" + space = self.space + w_args = space.newtuple(self.arguments_w) + w_kwds = space.newdict() + if self.keywords is not None: + limit = len(self.keywords) + if self.keyword_names_w is not None: + limit -= len(self.keyword_names_w) + for i in range(len(self.keywords)): + if i < limit: + w_key = space.wrap(self.keywords[i]) + else: + w_key = self.keyword_names_w[i - limit] + space.setitem(w_kwds, w_key, self.keywords_w[i]) + return w_args, w_kwds + +# JIT helper functions +# these functions contain functionality that the JIT is not always supposed to +# look at. They should not get a self arguments, which makes the amount of +# arguments annoying :-( + +def _check_not_duplicate_kwargs(space, existingkeywords, keywords, keywords_w): + # looks quadratic, but the JIT should remove all of it nicely. + # Also, all the lists should be small + for key in keywords: + for otherkey in existingkeywords: + if otherkey == key: + raise operationerrfmt(space.w_TypeError, + "got multiple values " + "for keyword argument " + "'%s'", key) + +def _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords, + keywords_w, existingkeywords): + i = 0 + for w_key in keys_w: + try: + key = space.str_w(w_key) + except OperationError, e: + if e.match(space, space.w_TypeError): + raise OperationError( + space.w_TypeError, + space.wrap("keywords must be strings")) + if e.match(space, space.w_UnicodeEncodeError): + # Allow this to pass through + key = None + else: + raise + else: + if existingkeywords and key in existingkeywords: + raise operationerrfmt(space.w_TypeError, + "got multiple values " + "for keyword argument " + "'%s'", key) + keywords[i] = key + keywords_w[i] = space.getitem(w_starstararg, w_key) + i += 1 + +def _match_keywords(signature, blindargs, input_argcount, + keywords, kwds_mapping): + # letting JIT unroll the loop is *only* safe if the callsite didn't + # use **args because num_kwds can be arbitrarily large otherwise. + num_kwds = num_remainingkwds = len(keywords) + for i in range(num_kwds): + name = keywords[i] + # If name was not encoded as a string, it could be None. In that + # case, it's definitely not going to be in the signature. + if name is None: + continue + j = signature.find_argname(name) + # if j == -1 nothing happens, because j < input_argcount and + # blindargs > j + if j < input_argcount: + # check that no keyword argument conflicts with these. note + # that for this purpose we ignore the first blindargs, + # which were put into place by prepend(). This way, + # keywords do not conflict with the hidden extra argument + # bound by methods. + if blindargs <= j: + raise ArgErrMultipleValues(name) + else: + kwds_mapping[j - input_argcount] = i # map to the right index + num_remainingkwds -= 1 + return num_remainingkwds + +def _collect_keyword_args(space, keywords, keywords_w, w_kwds, kwds_mapping, + keyword_names_w): + limit = len(keywords) + if keyword_names_w is not None: + limit -= len(keyword_names_w) + for i in range(len(keywords)): + # again a dangerous-looking loop that either the JIT unrolls + # or that is not too bad, because len(kwds_mapping) is small + for j in kwds_mapping: + if i == j: + break + else: + if i < limit: + w_key = space.wrap(keywords[i]) + else: + w_key = keyword_names_w[i - limit] + space.setitem(w_kwds, w_key, keywords_w[i]) + +class ArgumentsForTranslation(Arguments): + def __init__(self, space, args_w, keywords=None, keywords_w=None, + w_stararg=None, w_starstararg=None): + self.w_stararg = w_stararg + self.w_starstararg = w_starstararg + self.combine_has_happened = False + self.space = space + assert isinstance(args_w, list) + self.arguments_w = args_w + self.keywords = keywords + self.keywords_w = keywords_w + self.keyword_names_w = None + + def __repr__(self): + """ NOT_RPYTHON """ + name = self.__class__.__name__ + if not self.keywords: + return '%s(%s)' % (name, self.arguments_w,) + else: + return '%s(%s, %s, %s)' % (name, self.arguments_w, + self.keywords, self.keywords_w) + + def combine_if_necessary(self): + if self.combine_has_happened: + return + self._combine_wrapped(self.w_stararg, self.w_starstararg) + self.combine_has_happened = True + + def prepend(self, w_firstarg): # used often + "Return a new Arguments with a new argument inserted first." + return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, + self.keywords, self.keywords_w, self.w_stararg, + self.w_starstararg) + + def copy(self): + return ArgumentsForTranslation(self.space, self.arguments_w, + self.keywords, self.keywords_w, self.w_stararg, + self.w_starstararg) + def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None, blindargs=0): """Parse args and kwargs according to the signature of a code object, @@ -238,10 +383,7 @@ # args_w = list of the normal actual parameters, wrapped # scope_w = resulting list of wrapped values # - - # some comments about the JIT: it assumes that signature is a constant, - # so all values coming from there can be assumed constant. It assumes - # that the length of the defaults_w does not vary too much. + self.combine_if_necessary() co_argcount = signature.num_argnames() # expected formal arguments, without */** # put the special w_firstarg into the scope, if it exists @@ -311,13 +453,12 @@ # escape num_remainingkwds = _match_keywords( signature, blindargs, input_argcount, keywords, - kwds_mapping, self._jit_few_keywords) + kwds_mapping) if num_remainingkwds: if w_kwds is not None: # collect extra keyword arguments into the **kwarg - _collect_keyword_args( - self.space, keywords, keywords_w, w_kwds, - kwds_mapping, self.keyword_names_w, self._jit_few_keywords) + _collect_keyword_args( self.space, keywords, keywords_w, + w_kwds, kwds_mapping, self.keyword_names_w) else: if co_argcount == 0: raise ArgErrCount(avail, num_kwds, signature, defaults_w, 0) @@ -346,203 +487,16 @@ if missing: raise ArgErrCount(avail, num_kwds, signature, defaults_w, missing) + def unpack(self): + "Return a ([w1,w2...], {'kw':w3...}) pair." + self.combine_if_necessary() + kwds_w = {} + if self.keywords: + for i in range(len(self.keywords)): + kwds_w[self.keywords[i]] = self.keywords_w[i] + return self.arguments_w, kwds_w - def parse_into_scope(self, w_firstarg, - scope_w, fnname, signature, defaults_w=None): - """Parse args and kwargs to initialize a frame - according to the signature of code object. - Store the argumentvalues into scope_w. - scope_w must be big enough for signature. - """ - try: - self._match_signature(w_firstarg, - scope_w, signature, defaults_w, 0) - except ArgErr, e: - raise operationerrfmt(self.space.w_TypeError, - "%s() %s", fnname, e.getmsg()) - return signature.scope_length() - - def _parse(self, w_firstarg, signature, defaults_w, blindargs=0): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - scopelen = signature.scope_length() - scope_w = [None] * scopelen - self._match_signature(w_firstarg, scope_w, signature, defaults_w, - blindargs) - return scope_w - - - def parse_obj(self, w_firstarg, - fnname, signature, defaults_w=None, blindargs=0): - """Parse args and kwargs to initialize a frame - according to the signature of code object. - """ - try: - return self._parse(w_firstarg, signature, defaults_w, blindargs) - except ArgErr, e: - raise operationerrfmt(self.space.w_TypeError, - "%s() %s", fnname, e.getmsg()) - - @staticmethod - def frompacked(space, w_args=None, w_kwds=None): - """Convenience static method to build an Arguments - from a wrapped sequence and a wrapped dictionary.""" - return Arguments(space, [], w_stararg=w_args, w_starstararg=w_kwds) - - def topacked(self): - """Express the Argument object as a pair of wrapped w_args, w_kwds.""" - space = self.space - w_args = space.newtuple(self.arguments_w) - w_kwds = space.newdict() - if self.keywords is not None: - limit = len(self.keywords) - if self.keyword_names_w is not None: - limit -= len(self.keyword_names_w) - for i in range(len(self.keywords)): - if i < limit: - w_key = space.wrap(self.keywords[i]) - else: - w_key = self.keyword_names_w[i - limit] - space.setitem(w_kwds, w_key, self.keywords_w[i]) - return w_args, w_kwds - -# JIT helper functions -# these functions contain functionality that the JIT is not always supposed to -# look at. They should not get a self arguments, which makes the amount of -# arguments annoying :-( - - at jit.look_inside_iff(lambda space, existingkeywords, keywords, keywords_w: - jit.isconstant(len(keywords) and - jit.isconstant(existingkeywords))) -def _check_not_duplicate_kwargs(space, existingkeywords, keywords, keywords_w): - # looks quadratic, but the JIT should remove all of it nicely. - # Also, all the lists should be small - for key in keywords: - for otherkey in existingkeywords: - if otherkey == key: - raise operationerrfmt(space.w_TypeError, - "got multiple values " - "for keyword argument " - "'%s'", key) - -def _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords, - keywords_w, existingkeywords): - i = 0 - for w_key in keys_w: - try: - key = space.str_w(w_key) - except OperationError, e: - if e.match(space, space.w_TypeError): - raise OperationError( - space.w_TypeError, - space.wrap("keywords must be strings")) - if e.match(space, space.w_UnicodeEncodeError): - # Allow this to pass through - key = None - else: - raise - else: - if existingkeywords and key in existingkeywords: - raise operationerrfmt(space.w_TypeError, - "got multiple values " - "for keyword argument " - "'%s'", key) - keywords[i] = key - keywords_w[i] = space.getitem(w_starstararg, w_key) - i += 1 - - at jit.look_inside_iff( - lambda signature, blindargs, input_argcount, - keywords, kwds_mapping, jiton: jiton) -def _match_keywords(signature, blindargs, input_argcount, - keywords, kwds_mapping, _): - # letting JIT unroll the loop is *only* safe if the callsite didn't - # use **args because num_kwds can be arbitrarily large otherwise. - num_kwds = num_remainingkwds = len(keywords) - for i in range(num_kwds): - name = keywords[i] - # If name was not encoded as a string, it could be None. In that - # case, it's definitely not going to be in the signature. - if name is None: - continue - j = signature.find_argname(name) - # if j == -1 nothing happens, because j < input_argcount and - # blindargs > j - if j < input_argcount: - # check that no keyword argument conflicts with these. note - # that for this purpose we ignore the first blindargs, - # which were put into place by prepend(). This way, - # keywords do not conflict with the hidden extra argument - # bound by methods. - if blindargs <= j: - raise ArgErrMultipleValues(name) - else: - kwds_mapping[j - input_argcount] = i # map to the right index - num_remainingkwds -= 1 - return num_remainingkwds - - at jit.look_inside_iff( - lambda space, keywords, keywords_w, w_kwds, kwds_mapping, - keyword_names_w, jiton: jiton) -def _collect_keyword_args(space, keywords, keywords_w, w_kwds, kwds_mapping, - keyword_names_w, _): - limit = len(keywords) - if keyword_names_w is not None: - limit -= len(keyword_names_w) - for i in range(len(keywords)): - # again a dangerous-looking loop that either the JIT unrolls - # or that is not too bad, because len(kwds_mapping) is small - for j in kwds_mapping: - if i == j: - break - else: - if i < limit: - w_key = space.wrap(keywords[i]) - else: - w_key = keyword_names_w[i - limit] - space.setitem(w_kwds, w_key, keywords_w[i]) - -class ArgumentsForTranslation(Arguments): - def __init__(self, space, args_w, keywords=None, keywords_w=None, - w_stararg=None, w_starstararg=None): - self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False - Arguments.__init__(self, space, args_w, keywords, keywords_w) - - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - - def prepend(self, w_firstarg): # used often - "Return a new Arguments with a new argument inserted first." - return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - def copy(self): - return ArgumentsForTranslation(self.space, self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - - - def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None, - blindargs=0): - self.combine_if_necessary() - # _match_signature is destructive - return Arguments._match_signature( - self, w_firstarg, scope_w, signature, - defaults_w, blindargs) - - def unpack(self): - self.combine_if_necessary() - return Arguments.unpack(self) - def match_signature(self, signature, defaults_w): """Parse args and kwargs according to the signature of a code object, or raise an ArgErr in case of failure. From noreply at buildbot.pypy.org Thu Oct 18 20:21:45 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 20:21:45 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: kill unused method parse_into_scope() Message-ID: <20121018182145.78E6C1C00FA@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58229:dd641d483974 Date: 2012-10-18 19:17 +0100 http://bitbucket.org/pypy/pypy/changeset/dd641d483974/ Log: kill unused method parse_into_scope() diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -188,21 +188,6 @@ ### Parsing for function calls ### - def parse_into_scope(self, w_firstarg, - scope_w, fnname, signature, defaults_w=None): - """Parse args and kwargs to initialize a frame - according to the signature of code object. - Store the argumentvalues into scope_w. - scope_w must be big enough for signature. - """ - try: - self._match_signature(w_firstarg, - scope_w, signature, defaults_w, 0) - except ArgErr, e: - raise operationerrfmt(self.space.w_TypeError, - "%s() %s", fnname, e.getmsg()) - return signature.scope_length() - def _parse(self, w_firstarg, signature, defaults_w, blindargs=0): """Parse args and kwargs according to the signature of a code object, or raise an ArgErr in case of failure. From noreply at buildbot.pypy.org Thu Oct 18 20:21:46 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 20:21:46 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Kill unused method parse_obj() Message-ID: <20121018182146.B44AE1C00FA@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58230:86396cfc8f8a Date: 2012-10-18 19:21 +0100 http://bitbucket.org/pypy/pypy/changeset/86396cfc8f8a/ Log: Kill unused method parse_obj() diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -198,18 +198,6 @@ blindargs) return scope_w - - def parse_obj(self, w_firstarg, - fnname, signature, defaults_w=None, blindargs=0): - """Parse args and kwargs to initialize a frame - according to the signature of code object. - """ - try: - return self._parse(w_firstarg, signature, defaults_w, blindargs) - except ArgErr, e: - raise operationerrfmt(self.space.w_TypeError, - "%s() %s", fnname, e.getmsg()) - @staticmethod def frompacked(space, w_args=None, w_kwds=None): """Convenience static method to build an Arguments From noreply at buildbot.pypy.org Thu Oct 18 21:51:56 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 21:51:56 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Inline _parse() Message-ID: <20121018195156.BEA211C1CE2@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58231:3c83368be10b Date: 2012-10-18 19:48 +0100 http://bitbucket.org/pypy/pypy/changeset/3c83368be10b/ Log: Inline _parse() diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -188,16 +188,6 @@ ### Parsing for function calls ### - def _parse(self, w_firstarg, signature, defaults_w, blindargs=0): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - scopelen = signature.scope_length() - scope_w = [None] * scopelen - self._match_signature(w_firstarg, scope_w, signature, defaults_w, - blindargs) - return scope_w - @staticmethod def frompacked(space, w_args=None, w_kwds=None): """Convenience static method to build an Arguments @@ -474,7 +464,10 @@ """Parse args and kwargs according to the signature of a code object, or raise an ArgErr in case of failure. """ - return self._parse(None, signature, defaults_w) + scopelen = signature.scope_length() + scope_w = [None] * scopelen + self._match_signature(None, scope_w, signature, defaults_w, 0) + return scope_w def unmatch_signature(self, signature, data_w): """kind of inverse of match_signature""" From noreply at buildbot.pypy.org Thu Oct 18 21:51:57 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 21:51:57 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Kill useless params and simplify Message-ID: <20121018195157.E10571C1CE2@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58232:daff7cb174a8 Date: 2012-10-18 20:47 +0100 http://bitbucket.org/pypy/pypy/changeset/daff7cb174a8/ Log: Kill useless params and simplify diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -253,8 +253,7 @@ keywords_w[i] = space.getitem(w_starstararg, w_key) i += 1 -def _match_keywords(signature, blindargs, input_argcount, - keywords, kwds_mapping): +def _match_keywords(signature, input_argcount, keywords, kwds_mapping): # letting JIT unroll the loop is *only* safe if the callsite didn't # use **args because num_kwds can be arbitrarily large otherwise. num_kwds = num_remainingkwds = len(keywords) @@ -265,15 +264,10 @@ if name is None: continue j = signature.find_argname(name) - # if j == -1 nothing happens, because j < input_argcount and - # blindargs > j + # if j == -1 nothing happens if j < input_argcount: - # check that no keyword argument conflicts with these. note - # that for this purpose we ignore the first blindargs, - # which were put into place by prepend(). This way, - # keywords do not conflict with the hidden extra argument - # bound by methods. - if blindargs <= j: + # check that no keyword argument conflicts with these. + if j >= 0: raise ArgErrMultipleValues(name) else: kwds_mapping[j - input_argcount] = i # map to the right index @@ -337,61 +331,35 @@ self.keywords, self.keywords_w, self.w_stararg, self.w_starstararg) - def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None, - blindargs=0): + def _match_signature(self, scope_w, signature, defaults_w=None): """Parse args and kwargs according to the signature of a code object, or raise an ArgErr in case of failure. """ - # w_firstarg = a first argument to be inserted (e.g. self) or None # args_w = list of the normal actual parameters, wrapped # scope_w = resulting list of wrapped values # self.combine_if_necessary() co_argcount = signature.num_argnames() # expected formal arguments, without */** - # put the special w_firstarg into the scope, if it exists - if w_firstarg is not None: - upfront = 1 - if co_argcount > 0: - scope_w[0] = w_firstarg - else: - upfront = 0 - args_w = self.arguments_w num_args = len(args_w) - avail = num_args + upfront - - keywords = self.keywords - num_kwds = 0 - if keywords is not None: - num_kwds = len(keywords) - + keywords = self.keywords or [] + num_kwds = len(keywords) # put as many positional input arguments into place as available - input_argcount = upfront - if input_argcount < co_argcount: - take = min(num_args, co_argcount - upfront) - - # letting the JIT unroll this loop is safe, because take is always - # smaller than co_argcount - for i in range(take): - scope_w[i + input_argcount] = args_w[i] - input_argcount += take + take = min(num_args, co_argcount) + scope_w[:take] = args_w[:take] + input_argcount = take # collect extra positional arguments into the *vararg if signature.has_vararg(): - args_left = co_argcount - upfront - if args_left < 0: # check required by rpython - starargs_w = [w_firstarg] - if num_args: - starargs_w = starargs_w + args_w - elif num_args > args_left: - starargs_w = args_w[args_left:] + if num_args > co_argcount: + starargs_w = args_w[co_argcount:] else: starargs_w = [] scope_w[co_argcount] = self.space.newtuple(starargs_w) - elif avail > co_argcount: - raise ArgErrCount(avail, num_kwds, signature, defaults_w, 0) + elif num_args > co_argcount: + raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) # if a **kwargs argument is needed, create the dict w_kwds = None @@ -406,25 +374,21 @@ if num_kwds: # kwds_mapping maps target indexes in the scope (minus input_argcount) # to positions in the keywords_w list - kwds_mapping = [0] * (co_argcount - input_argcount) - # initialize manually, for the JIT :-( - for i in range(len(kwds_mapping)): - kwds_mapping[i] = -1 + kwds_mapping = [-1] * (co_argcount - input_argcount) # match the keywords given at the call site to the argument names # the called function takes # this function must not take a scope_w, to make the scope not # escape - num_remainingkwds = _match_keywords( - signature, blindargs, input_argcount, keywords, - kwds_mapping) + num_remainingkwds = _match_keywords(signature, input_argcount, + keywords, kwds_mapping) if num_remainingkwds: if w_kwds is not None: # collect extra keyword arguments into the **kwarg - _collect_keyword_args( self.space, keywords, keywords_w, + _collect_keyword_args(self.space, keywords, keywords_w, w_kwds, kwds_mapping, self.keyword_names_w) else: if co_argcount == 0: - raise ArgErrCount(avail, num_kwds, signature, defaults_w, 0) + raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords, kwds_mapping, self.keyword_names_w) @@ -448,7 +412,7 @@ else: missing += 1 if missing: - raise ArgErrCount(avail, num_kwds, signature, defaults_w, missing) + raise ArgErrCount(num_args, num_kwds, signature, defaults_w, missing) def unpack(self): "Return a ([w1,w2...], {'kw':w3...}) pair." @@ -466,7 +430,7 @@ """ scopelen = signature.scope_length() scope_w = [None] * scopelen - self._match_signature(None, scope_w, signature, defaults_w, 0) + self._match_signature(scope_w, signature, defaults_w) return scope_w def unmatch_signature(self, signature, data_w): From noreply at buildbot.pypy.org Thu Oct 18 22:09:03 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 22:09:03 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: more tests Message-ID: <20121018200903.D3FE71C0F16@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58233:370f2d98b923 Date: 2012-10-18 21:58 +0200 http://bitbucket.org/pypy/pypy/changeset/370f2d98b923/ Log: more tests diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -243,13 +243,19 @@ def force(self, frame): assert not frame._forced frame._forced = True - guard_op = frame.lltrace.operations[frame.current_index + 1] call_op = frame.current_op + if call_op.getopnum() == rop.FINISH: + guard_op = call_op + else: + guard_op = frame.lltrace.operations[frame.current_index + 1] frame.latest_values = frame._getfailargs(guard_op, call_op.result) descr = guard_op.getdescr() frame.latest_descr = descr return descr + def set_savedata_ref(self, frame, data): + frame.saved_data = data + def calldescrof(self, FUNC, ARGS, RESULT, effect_info): key = ('call', getkind(RESULT), tuple([getkind(A) for A in ARGS]), @@ -529,6 +535,13 @@ class LLFrame(object): _TYPE = llmemory.GCREF + + # some obscure hacks to support comparison with llmemory.GCREF + def __ne__(self, other): + return not self == other + def __eq__(self, other): + return isinstance(other, LLFrame) and self is other + _forced = False _execution_finished = False diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2328,6 +2328,20 @@ assert self.cpu.get_latest_value_int(frame, 2) == 10 assert values == [1, 10, frame] + def test_force_from_finish(self): + loop = parse(''' + [i1, i2] + p0 = jit_frame() + finish(p0, descr=faildescr1) [i1, i2] + ''', namespace={'faildescr1': BasicFailDescr(1)}) + looptoken = JitCellToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + frame = self.cpu.execute_token(looptoken, 20, 0) + descr = self.cpu.force(frame) + assert self.cpu.get_latest_descr(frame) is descr + assert self.cpu.get_latest_value_int(frame, 0) == 20 + assert self.cpu.get_latest_value_int(frame, 1) == 0 + def test_call_to_c_function(self): from pypy.rlib.libffi import CDLL, types, ArgChain, FUNCFLAG_CDECL from pypy.rpython.lltypesystem.ll2ctypes import libc_name diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -2988,7 +2988,7 @@ """ expected = """ [p1] - i0 = force_token() + p0 = jit_frame() jump(p1) """ self.optimize_loop(ops, expected) diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py --- a/pypy/jit/metainterp/test/test_virtualizable.py +++ b/pypy/jit/metainterp/test/test_virtualizable.py @@ -229,7 +229,7 @@ res = self.meta_interp(f, [20]) assert res == 134 self.check_simple_loop(setfield_gc=1, getfield_gc=0) - self.check_resops(setfield_gc=2, getfield_gc=3) + self.check_resops(setfield_gc=2, getfield_gc=4) # ------------------------------ diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -225,7 +225,8 @@ if endnum == -1: raise ParseError("invalid line: %s" % line) args, descr = self.parse_args(opname, line[num + 1:endnum]) - if rop._GUARD_FIRST <= opnum <= rop._GUARD_LAST: + fail_args = None + if rop._GUARD_FIRST <= opnum <= rop._GUARD_LAST or opnum == rop.FINISH: i = line.find('[', endnum) + 1 j = line.find(']', i) if (i <= 0 or j <= 0) and not self.nonstrict: @@ -248,7 +249,6 @@ if hasattr(descr, '_oparser_uses_descr_of_guard'): descr._oparser_uses_descr_of_guard(self, fail_args) else: - fail_args = None if opnum == rop.FINISH: if descr is None and self.invent_fail_descr: descr = self.invent_fail_descr(self.model, fail_args) diff --git a/pypy/jit/tool/test/test_oparser.py b/pypy/jit/tool/test/test_oparser.py --- a/pypy/jit/tool/test/test_oparser.py +++ b/pypy/jit/tool/test/test_oparser.py @@ -7,6 +7,9 @@ from pypy.jit.metainterp.history import AbstractDescr, BoxInt, JitCellToken,\ TargetToken +class FakeDescr(AbstractDescr): + pass + class BaseTestOparser(object): OpParser = None @@ -21,7 +24,7 @@ # a comment i2 = int_add(i0, i1) i3 = int_sub(i2, 3) # another comment - finish() # (tricky) + finish() [] # (tricky) """ loop = self.parse(x) assert len(loop.operations) == 3 @@ -42,6 +45,16 @@ assert loop.operations[0].getdescr() assert loop.operations[0].getfailargs() == [] + def test_failargs_finish(self): + d = FakeDescr() + x = """ + [p0] + finish(descr=f) [p0] + """ + loop = self.parse(x, None, {'f': d}) + assert loop.operations[0].getdescr() is d + assert loop.operations[0].getfailargs() == loop.inputargs + def test_descr(self): class Xyz(AbstractDescr): I_am_a_descr = True # for the mock case From noreply at buildbot.pypy.org Thu Oct 18 22:09:05 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 22:09:05 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: fix this test Message-ID: <20121018200905.2BD781C0F16@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58234:c55b5500d6b8 Date: 2012-10-18 22:01 +0200 http://bitbucket.org/pypy/pypy/changeset/c55b5500d6b8/ Log: fix this test diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -1368,7 +1368,7 @@ force_spill(f1) force_spill(f2) guard_false(i0) [f1, f2, f3] - finish()""" + finish() []""" loop = parse(loopops) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) @@ -1980,7 +1980,7 @@ i1 = same_as(1) call(ConstClass(fptr), i0, descr=calldescr) p0 = guard_exception(ConstClass(xtp)) [i1] - finish(p0) + finish(p0) [] ''' FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) fptr = llhelper(FPTR, func) @@ -2033,7 +2033,7 @@ i1 = same_as(1) call(ConstClass(fptr), i0, descr=calldescr) guard_no_exception() [i1] - finish(-100) + finish(-100) [] ''' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() @@ -2766,7 +2766,7 @@ i16 = int_add(i15, i7) i17 = int_add(i16, i8) i18 = int_add(i17, i9) - finish(i18)''' + finish(i18) []''' loop = parse(ops) looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() @@ -2786,7 +2786,7 @@ i10 = int_add(i0, 42) i11 = call_assembler(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, descr=looptoken) guard_not_forced()[] - finish(i11) + finish(i11) [] ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() @@ -2834,7 +2834,7 @@ i0 = float_eq(f0, -1.0) guard_false(i0) [] f2 = float_add(f0, f1) - finish(f2)''' + finish(f2) []''' loop = parse(ops) fail_number = self.cpu.get_fail_descr_number( loop.operations[1].getdescr()) @@ -2850,7 +2850,7 @@ [f4, f5] f3 = call_assembler(f4, f5, descr=looptoken) guard_not_forced()[] - finish(f3) + finish(f3) [] ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() @@ -2925,7 +2925,7 @@ i0 = float_eq(f0, -1.0) guard_false(i0) [] f2 = float_add(f0, f1) - finish(f2)''' + finish(f2) []''' loop = parse(ops) looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() @@ -2943,7 +2943,7 @@ [f4, f5] f3 = call_assembler(f4, f5, descr=looptoken) guard_not_forced()[] - finish(f3) + finish(f3) [] ''' loop = parse(ops, namespace=locals()) othertoken = JitCellToken() @@ -2970,7 +2970,7 @@ i0 = float_eq(f0, -2.0) guard_false(i0) [] f2 = float_sub(f0, f1) - finish(f2)''' + finish(f2) []''' loop = parse(ops) looptoken2 = JitCellToken() looptoken2.outermost_jitdriver_sd = FakeJitDriverSD() @@ -3416,7 +3416,7 @@ ops = """ [i0] i1 = int_force_ge_zero(i0) # but forced to be in a register - finish(i1, descr=1) + finish(i1, descr=1) [] """ loop = parse(ops, self.cpu, namespace=locals()) descr = loop.operations[-1].getdescr() @@ -3588,7 +3588,7 @@ ops = """ [i0, i1] i2 = raw_load(i0, i1, descr=arraydescr) - finish(i2) + finish(i2) [] """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -3613,7 +3613,7 @@ ops = """ [i0, i1] f2 = raw_load(i0, i1, descr=arraydescr) - finish(f2) + finish(f2) [] """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -3640,7 +3640,7 @@ ops = """ [i0, i1, i2] raw_store(i0, i1, i2, descr=arraydescr) - finish() + finish() [] """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -3664,7 +3664,7 @@ ops = """ [i0, i1, f2] raw_store(i0, i1, f2, descr=arraydescr) - finish() + finish() [] """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) From noreply at buildbot.pypy.org Thu Oct 18 22:09:06 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 18 Oct 2012 22:09:06 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: progress Message-ID: <20121018200906.ADF3C1C0F16@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58235:7e62f1b8a959 Date: 2012-10-18 22:08 +0200 http://bitbucket.org/pypy/pypy/changeset/7e62f1b8a959/ Log: progress diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -256,6 +256,9 @@ def set_savedata_ref(self, frame, data): frame.saved_data = data + def get_savedata_ref(self, frame): + return frame.saved_data + def calldescrof(self, FUNC, ARGS, RESULT, effect_info): key = ('call', getkind(RESULT), tuple([getkind(A) for A in ARGS]), diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py --- a/pypy/jit/metainterp/test/test_virtualizable.py +++ b/pypy/jit/metainterp/test/test_virtualizable.py @@ -410,7 +410,7 @@ res = self.meta_interp(f, [20], enable_opts='') assert res == expected self.check_simple_loop(setarrayitem_gc=1, setfield_gc=0, - getarrayitem_gc=1, arraylen_gc=1, getfield_gc=1) + getarrayitem_gc=1, arraylen_gc=1, getfield_gc=2) # ------------------------------ diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py --- a/pypy/jit/metainterp/warmspot.py +++ b/pypy/jit/metainterp/warmspot.py @@ -441,7 +441,10 @@ def crash_in_jit(e): tb = not we_are_translated() and sys.exc_info()[2] try: - raise e + if we_are_translated(): + raise e + else: + raise except JitException: raise # go through except MemoryError: From noreply at buildbot.pypy.org Thu Oct 18 23:41:07 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 23:41:07 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: kill a few more Arguments methods Message-ID: <20121018214107.83C421C00FA@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58236:2e1769043725 Date: 2012-10-18 22:36 +0100 http://bitbucket.org/pypy/pypy/changeset/2e1769043725/ Log: kill a few more Arguments methods diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -96,15 +96,6 @@ ### Manipulation ### - def replace_arguments(self, args_w): - "Return a new Arguments with a args_w as positional arguments." - return Arguments(self.space, args_w, self.keywords, self.keywords_w, - keyword_names_w = self.keyword_names_w) - - def prepend(self, w_firstarg): - "Return a new Arguments with a new argument inserted first." - return self.replace_arguments([w_firstarg] + self.arguments_w) - def _combine_wrapped(self, w_stararg, w_starstararg): "unpack the *arg and **kwd into arguments_w and keywords_w" if w_stararg is not None: @@ -188,12 +179,6 @@ ### Parsing for function calls ### - @staticmethod - def frompacked(space, w_args=None, w_kwds=None): - """Convenience static method to build an Arguments - from a wrapped sequence and a wrapped dictionary.""" - return Arguments(space, [], w_stararg=w_args, w_starstararg=w_kwds) - def topacked(self): """Express the Argument object as a pair of wrapped w_args, w_kwds.""" space = self.space @@ -483,10 +468,6 @@ return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) @staticmethod - def frompacked(space, w_args=None, w_kwds=None): - raise NotImplementedError("go away") - - @staticmethod def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w): args_w = data_w[:shape_cnt] p = end_keys = shape_cnt + len(shape_keys) From noreply at buildbot.pypy.org Thu Oct 18 23:41:08 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Thu, 18 Oct 2012 23:41:08 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Add test for ArgsFT.fixedunpack() Message-ID: <20121018214108.C6A981C00FA@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58237:4789622b8d7c Date: 2012-10-18 22:40 +0100 http://bitbucket.org/pypy/pypy/changeset/4789622b8d7c/ Log: Add test for ArgsFT.fixedunpack() (it's used in pypy.annotation.description) diff --git a/pypy/objspace/flow/test/test_argument.py b/pypy/objspace/flow/test/test_argument.py --- a/pypy/objspace/flow/test/test_argument.py +++ b/pypy/objspace/flow/test/test_argument.py @@ -151,6 +151,20 @@ assert args1.keywords is args.keywords assert args1.keywords_w is args.keywords_w + def test_fixedunpacked(self): + space = DummySpace() + + args = ArgumentsForTranslation(space, [], ["k"], [1]) + py.test.raises(ValueError, args.fixedunpack, 1) + + args = ArgumentsForTranslation(space, ["a", "b"]) + py.test.raises(ValueError, args.fixedunpack, 0) + py.test.raises(ValueError, args.fixedunpack, 1) + py.test.raises(ValueError, args.fixedunpack, 3) + py.test.raises(ValueError, args.fixedunpack, 4) + + assert args.fixedunpack(2) == ['a', 'b'] + def test_unmatch_signature(self): space = DummySpace() args = make_arguments_for_translation(space, [1,2,3]) From noreply at buildbot.pypy.org Fri Oct 19 03:37:16 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 19 Oct 2012 03:37:16 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Kill unused methods firstarg() and topacked() Message-ID: <20121019013716.B07DC1C00FA@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58238:3a00a97c8f0d Date: 2012-10-18 22:54 +0100 http://bitbucket.org/pypy/pypy/changeset/3a00a97c8f0d/ Log: Kill unused methods firstarg() and topacked() diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -171,31 +171,6 @@ raise ValueError, "not enough arguments (%d expected)" % argcount return self.arguments_w - def firstarg(self): - "Return the first argument for inspection." - if self.arguments_w: - return self.arguments_w[0] - return None - - ### Parsing for function calls ### - - def topacked(self): - """Express the Argument object as a pair of wrapped w_args, w_kwds.""" - space = self.space - w_args = space.newtuple(self.arguments_w) - w_kwds = space.newdict() - if self.keywords is not None: - limit = len(self.keywords) - if self.keyword_names_w is not None: - limit -= len(self.keyword_names_w) - for i in range(len(self.keywords)): - if i < limit: - w_key = space.wrap(self.keywords[i]) - else: - w_key = self.keyword_names_w[i - limit] - space.setitem(w_kwds, w_key, self.keywords_w[i]) - return w_args, w_kwds - # JIT helper functions # these functions contain functionality that the JIT is not always supposed to # look at. They should not get a self arguments, which makes the amount of From noreply at buildbot.pypy.org Fri Oct 19 03:37:17 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 19 Oct 2012 03:37:17 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Get rid of Arguments Message-ID: <20121019013717.DE9781C00FA@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58239:d5f7760b9898 Date: 2012-10-19 01:13 +0100 http://bitbucket.org/pypy/pypy/changeset/d5f7760b9898/ Log: Get rid of Arguments diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -78,99 +78,6 @@ return self.kwargname raise IndexError - - -class Arguments(object): - """ - Collects the arguments of a function call. - - Instances should be considered immutable. - - Some parts of this class are written in a slightly convoluted style to help - the JIT. It is really crucial to get this right, because Python's argument - semantics are complex, but calls occur everywhere. - """ - - ### Construction ### - - - ### Manipulation ### - - def _combine_wrapped(self, w_stararg, w_starstararg): - "unpack the *arg and **kwd into arguments_w and keywords_w" - if w_stararg is not None: - self._combine_starargs_wrapped(w_stararg) - if w_starstararg is not None: - self._combine_starstarargs_wrapped(w_starstararg) - - def _combine_starargs_wrapped(self, w_stararg): - # unpack the * arguments - space = self.space - try: - args_w = space.fixedview(w_stararg) - except OperationError, e: - if e.match(space, space.w_TypeError): - w_type = space.type(w_stararg) - typename = w_type.getname(space) - raise OperationError( - space.w_TypeError, - space.wrap("argument after * must be " - "a sequence, not %s" % (typename,))) - raise - self.arguments_w = self.arguments_w + args_w - - def _combine_starstarargs_wrapped(self, w_starstararg): - # unpack the ** arguments - space = self.space - keywords, values_w = space.view_as_kwargs(w_starstararg) - if keywords is not None: # this path also taken for empty dicts - if self.keywords is None: - self.keywords = keywords - self.keywords_w = values_w - else: - _check_not_duplicate_kwargs( - self.space, self.keywords, keywords, values_w) - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + values_w - return - if space.isinstance_w(w_starstararg, space.w_dict): - keys_w = space.unpackiterable(w_starstararg) - else: - try: - w_keys = space.call_method(w_starstararg, "keys") - except OperationError, e: - if e.match(space, space.w_AttributeError): - w_type = space.type(w_starstararg) - typename = w_type.getname(space) - raise OperationError( - space.w_TypeError, - space.wrap("argument after ** must be " - "a mapping, not %s" % (typename,))) - raise - keys_w = space.unpackiterable(w_keys) - keywords_w = [None] * len(keys_w) - keywords = [None] * len(keys_w) - _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords, keywords_w, self.keywords) - self.keyword_names_w = keys_w - if self.keywords is None: - self.keywords = keywords - self.keywords_w = keywords_w - else: - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + keywords_w - - - def fixedunpack(self, argcount): - """The simplest argument parsing: get the 'argcount' arguments, - or raise a real ValueError if the length is wrong.""" - if self.keywords: - raise ValueError, "no keyword arguments expected" - if len(self.arguments_w) > argcount: - raise ValueError, "too many arguments (%d expected)" % argcount - elif len(self.arguments_w) < argcount: - raise ValueError, "not enough arguments (%d expected)" % argcount - return self.arguments_w - # JIT helper functions # these functions contain functionality that the JIT is not always supposed to # look at. They should not get a self arguments, which makes the amount of @@ -252,7 +159,7 @@ w_key = keyword_names_w[i - limit] space.setitem(w_kwds, w_key, keywords_w[i]) -class ArgumentsForTranslation(Arguments): +class ArgumentsForTranslation(object): def __init__(self, space, args_w, keywords=None, keywords_w=None, w_stararg=None, w_starstararg=None): self.w_stararg = w_stararg @@ -274,6 +181,81 @@ return '%s(%s, %s, %s)' % (name, self.arguments_w, self.keywords, self.keywords_w) + def _combine_wrapped(self, w_stararg, w_starstararg): + "unpack the *arg and **kwd into arguments_w and keywords_w" + if w_stararg is not None: + self._combine_starargs_wrapped(w_stararg) + if w_starstararg is not None: + self._combine_starstarargs_wrapped(w_starstararg) + + def _combine_starargs_wrapped(self, w_stararg): + # unpack the * arguments + space = self.space + try: + args_w = space.fixedview(w_stararg) + except OperationError, e: + if e.match(space, space.w_TypeError): + w_type = space.type(w_stararg) + typename = w_type.getname(space) + raise OperationError( + space.w_TypeError, + space.wrap("argument after * must be " + "a sequence, not %s" % (typename,))) + raise + self.arguments_w = self.arguments_w + args_w + + def _combine_starstarargs_wrapped(self, w_starstararg): + # unpack the ** arguments + space = self.space + keywords, values_w = space.view_as_kwargs(w_starstararg) + if keywords is not None: # this path also taken for empty dicts + if self.keywords is None: + self.keywords = keywords + self.keywords_w = values_w + else: + _check_not_duplicate_kwargs( + self.space, self.keywords, keywords, values_w) + self.keywords = self.keywords + keywords + self.keywords_w = self.keywords_w + values_w + return + if space.isinstance_w(w_starstararg, space.w_dict): + keys_w = space.unpackiterable(w_starstararg) + else: + try: + w_keys = space.call_method(w_starstararg, "keys") + except OperationError, e: + if e.match(space, space.w_AttributeError): + w_type = space.type(w_starstararg) + typename = w_type.getname(space) + raise OperationError( + space.w_TypeError, + space.wrap("argument after ** must be " + "a mapping, not %s" % (typename,))) + raise + keys_w = space.unpackiterable(w_keys) + keywords_w = [None] * len(keys_w) + keywords = [None] * len(keys_w) + _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords, keywords_w, self.keywords) + self.keyword_names_w = keys_w + if self.keywords is None: + self.keywords = keywords + self.keywords_w = keywords_w + else: + self.keywords = self.keywords + keywords + self.keywords_w = self.keywords_w + keywords_w + + + def fixedunpack(self, argcount): + """The simplest argument parsing: get the 'argcount' arguments, + or raise a real ValueError if the length is wrong.""" + if self.keywords: + raise ValueError, "no keyword arguments expected" + if len(self.arguments_w) > argcount: + raise ValueError, "too many arguments (%d expected)" % argcount + elif len(self.arguments_w) < argcount: + raise ValueError, "not enough arguments (%d expected)" % argcount + return self.arguments_w + def combine_if_necessary(self): if self.combine_has_happened: return From noreply at buildbot.pypy.org Fri Oct 19 10:19:48 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Fri, 19 Oct 2012 10:19:48 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: cpython support Message-ID: <20121019081948.DAEE71C04C6@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: extradoc Changeset: r4879:a0f33334684c Date: 2012-10-19 09:54 +0200 http://bitbucket.org/pypy/extradoc/changeset/a0f33334684c/ Log: cpython support diff --git a/talk/dls2012/demo/demo.py b/talk/dls2012/demo/demo.py --- a/talk/dls2012/demo/demo.py +++ b/talk/dls2012/demo/demo.py @@ -227,7 +227,7 @@ vim.type('44ggodef renumber(self):ll = list(set(self.labels))ll.sort()if ll[0] != 0:ll.insert(0, 0)for x, y in self.labels.indexes():self.labels[x, y] = ll.index(self.labels[x, y])self.last_label = len(ll) - 1:w', 0.01) pause("Now, lets find a boudningbox for each segment,") - vim.type("G75ggOclass BoundingBox(object):def __init__(self):self.maxx = self.maxy = float('-Inf')self.minx = self.miny = float('Inf')def add(self, x, y):self.maxx = max(self.maxx, x)self.maxy = max(self.maxy, y)self.minx = min(self.minx, x)self.miny = min(self.miny, y)def extract_boxes(labels):boxes = [BoundingBox() for i in xrange(max(labels))]for x, y in labels.indexes():l = labels[x, y]if l:boxes[int(l-1)].add(x, y)return boxes", 0.01) + vim.type("G75ggOclass BoundingBox(object):def __init__(self):self.maxx = self.maxy = float('-Inf')self.minx = self.miny = float('Inf')def add(self, x, y):self.maxx = max(self.maxx, x)self.maxy = max(self.maxy, y)self.minx = min(self.minx, x)self.miny = min(self.miny, y)def extract_boxes(labels):boxes = [BoundingBox() for i in xrange(int(max(labels)))]for x, y in labels.indexes():l = labels[x, y]if l:boxes[int(l-1)].add(x, y)return boxes", 0.01) vim.type("G98ggOboxes = extract_boxes(labels):w", 0.01) pause("and draw that boudning box.") diff --git a/talk/dls2012/demo/detect.py b/talk/dls2012/demo/detect.py --- a/talk/dls2012/demo/detect.py +++ b/talk/dls2012/demo/detect.py @@ -97,7 +97,7 @@ def extract_boxes(labels): - boxes = [BoundingBox() for i in xrange(max(labels))] + boxes = [BoundingBox() for i in xrange(int(max(labels)))] for x, y in labels.indexes(): l = labels[x, y] if l: From noreply at buildbot.pypy.org Fri Oct 19 10:19:50 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Fri, 19 Oct 2012 10:19:50 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: key for skipping to end of demo Message-ID: <20121019081950.0C2201C04CF@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: extradoc Changeset: r4880:8c1a7728e420 Date: 2012-10-19 10:16 +0200 http://bitbucket.org/pypy/extradoc/changeset/8c1a7728e420/ Log: key for skipping to end of demo diff --git a/talk/dls2012/demo/demo.py b/talk/dls2012/demo/demo.py --- a/talk/dls2012/demo/demo.py +++ b/talk/dls2012/demo/demo.py @@ -38,10 +38,16 @@ def __del__(self): self.close() + +class SkipToEnd(Exception): + pass + def pause(msg=''): print "\n" print msg - raw_input('Press ENTER\n') + res = raw_input('Press ENTER (s)\n') + if res == 's': + raise SkipToEnd def demo(skip1=False): if not skip1: @@ -57,10 +63,14 @@ runner = Popen([sys.executable, 'run.py', 'demo.avi']) vim = Vim('analytics.py') - if not skip1: - part1(vim) - part2(vim, skip1) + try: + if not skip1: + part1(vim) + part2(vim, skip1) + except SkipToEnd: + os.system('hg revert analytics.py background.py detect.py foreground.py') + pause("That's all! Feel free to make your own adjustments or (to quit),") runner.kill() vim.close() @@ -246,7 +256,6 @@ vim.send('>=') vim.type(' minarea]:w', 0.01) - pause("That's all! Feel free to make your own adjustments or (to quit),") if __name__ == '__main__': From noreply at buildbot.pypy.org Fri Oct 19 10:19:51 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Fri, 19 Oct 2012 10:19:51 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: compare to cpython Message-ID: <20121019081951.265B71C0723@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: extradoc Changeset: r4881:d8fdddadb27e Date: 2012-10-19 10:19 +0200 http://bitbucket.org/pypy/extradoc/changeset/d8fdddadb27e/ Log: compare to cpython diff --git a/talk/dls2012/demo/demo.py b/talk/dls2012/demo/demo.py --- a/talk/dls2012/demo/demo.py +++ b/talk/dls2012/demo/demo.py @@ -70,8 +70,11 @@ except SkipToEnd: os.system('hg revert analytics.py background.py detect.py foreground.py') + pause("New lets compare this with cpython.") + runner2 = Popen(["python", 'run.py', 'demo.avi']) pause("That's all! Feel free to make your own adjustments or (to quit),") runner.kill() + runner2.kill() vim.close() def part1(vim): From noreply at buildbot.pypy.org Fri Oct 19 10:39:48 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Fri, 19 Oct 2012 10:39:48 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: place and size vim window Message-ID: <20121019083948.5CA221C0012@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: extradoc Changeset: r4882:f6423e067479 Date: 2012-10-19 10:39 +0200 http://bitbucket.org/pypy/extradoc/changeset/f6423e067479/ Log: place and size vim window diff --git a/talk/dls2012/demo/demo.py b/talk/dls2012/demo/demo.py --- a/talk/dls2012/demo/demo.py +++ b/talk/dls2012/demo/demo.py @@ -60,8 +60,10 @@ def update(self, frame): view(frame) """ + vim = Vim('analytics.py') + vim.send(':winpos 0 30:winsize 75 30') + time.sleep(0.5) runner = Popen([sys.executable, 'run.py', 'demo.avi']) - vim = Vim('analytics.py') try: if not skip1: From noreply at buildbot.pypy.org Fri Oct 19 11:06:10 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Fri, 19 Oct 2012 11:06:10 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: limit max framerate a bit Message-ID: <20121019090610.8C2DC1C00FA@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: extradoc Changeset: r4883:583d5cbd8c58 Date: 2012-10-19 11:05 +0200 http://bitbucket.org/pypy/extradoc/changeset/583d5cbd8c58/ Log: limit max framerate a bit diff --git a/talk/dls2012/demo/io.py b/talk/dls2012/demo/io.py --- a/talk/dls2012/demo/io.py +++ b/talk/dls2012/demo/io.py @@ -47,7 +47,7 @@ img = out if not self.width: w, h = img.width, img.height - self.mplayer = Popen(['mplayer', '-', '-benchmark', + self.mplayer = Popen(['mplayer', '-', '-fps', '200', #'-benchmark', '-demuxer', 'rawvideo', '-rawvideo', 'w=%d:h=%d:format=y8' % (w, h), '-really-quiet'], From noreply at buildbot.pypy.org Fri Oct 19 11:49:53 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Fri, 19 Oct 2012 11:49:53 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: part2 back Message-ID: <20121019094953.177431C0012@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: extradoc Changeset: r4884:1c0e3f5da4b8 Date: 2012-10-19 11:49 +0200 http://bitbucket.org/pypy/extradoc/changeset/1c0e3f5da4b8/ Log: part2 back diff --git a/talk/dls2012/demo/analytics.py b/talk/dls2012/demo/analytics.py --- a/talk/dls2012/demo/analytics.py +++ b/talk/dls2012/demo/analytics.py @@ -18,3 +18,4 @@ #view(self.background.image) #view(255 * fg) + diff --git a/talk/dls2012/demo/demo.py b/talk/dls2012/demo/demo.py --- a/talk/dls2012/demo/demo.py +++ b/talk/dls2012/demo/demo.py @@ -50,8 +50,8 @@ raise SkipToEnd def demo(skip1=False): - if not skip1: - with open('analytics.py', 'w') as fd: + with open('analytics.py', 'w') as fd: + if not skip1: print >>fd, """ from reloader import ReloadHack from io import view @@ -60,7 +60,29 @@ def update(self, frame): view(frame) """ + else: + print >>fd, """ +from reloader import ReloadHack +from io import view +from background import Background +from foreground import foreground +from detect import find_objects + +class Tracker(ReloadHack): + def __init__(self): + self.background = Background() + + def update(self, frame): + self.background.update(frame) + fg = foreground(frame, self.background.image) + find_objects(fg) + #view(self.background.image) + view(255 * fg) + +""" + vim = Vim('analytics.py') + time.sleep(0.1) vim.send(':winpos 0 30:winsize 75 30') time.sleep(0.5) runner = Popen([sys.executable, 'run.py', 'demo.avi']) @@ -186,7 +208,7 @@ pause("That's a bit slow, but this operation is separable, let's see\n"+ "if it is faster with two passes.") vim.send(':e detect.py') - vim.type('7ggix9ggixjddOfor dx in xrange(-r, r+1):') + vim.type('7ggix9ggixjddkofor dx in xrange(-r, r+1):') vim.type('11ggix9wix13wxxx', 0.2) vim.type('VkkkkyP5jx', 0.2) vim.type('14ggx7wcwxres') @@ -226,15 +248,15 @@ vim.type('51ggA.labels:w') pause("It still seems to work as before. Now lets add the second pass") - vim.type('Ofor x, y in reversed(seg.indexes()):if seg[x, y]:ll = [labels[x, y], labels[x+1, y], labels[x-1, y+1],labels[x, y+1], labels[x+1, y+1]]labels.update(x, y, ll):w', 0.01) + vim.type('OjOfor x, y in reversed(seg.indexes()):if seg[x, y]:ll = [labels[x, y], labels[x+1, y], labels[x-1, y+1],labels[x, y+1], labels[x+1, y+1]]labels.update(x, y, ll):w', 0.01) pause("That's starting to look good, but in complicated cases we can still\n" + "get multiple lables per segment, so we need to repeat until convergance") vim.type('56ggVkkkkkkkkkk', 0.2) vim.send('>') - vim.type('Owhile not labels.done:labels.done = True') + vim.type('kowhile not labels.done:labels.done = True') vim.type('28ggoself.done = False') - vim.type('43gg39ggOif self.labels[x, y] != l:self.done = False:w') + vim.type('43gg39ggOif self.labels[x, y] != l:self.done = False:w') pause("As a final touch, lets renumber the labels be consecutative\n" + "integers.") diff --git a/talk/dls2012/demo/detect.py b/talk/dls2012/demo/detect.py --- a/talk/dls2012/demo/detect.py +++ b/talk/dls2012/demo/detect.py @@ -60,13 +60,13 @@ for x, y in seg.indexes(): if seg[x, y]: ll = [labels[x, y], labels[x-1, y], labels[x-1, y-1], - labels[x, y-1], labels[x+1, y-1]] + labels[x, y-1], labels[x+1, y-1]] labels.update(x, y, ll) for x, y in reversed(seg.indexes()): if seg[x, y]: ll = [labels[x, y], labels[x+1, y], labels[x-1, y+1], - labels[x, y+1], labels[x+1, y+1]] + labels[x, y+1], labels[x+1, y+1]] labels.update(x, y, ll) labels.renumber() From noreply at buildbot.pypy.org Fri Oct 19 12:59:13 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Fri, 19 Oct 2012 12:59:13 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: more general Message-ID: <20121019105913.A651F1C0012@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: extradoc Changeset: r4885:a1b4b82ad5a3 Date: 2012-10-19 12:58 +0200 http://bitbucket.org/pypy/extradoc/changeset/a1b4b82ad5a3/ Log: more general diff --git a/talk/dls2012/demo/demo.py b/talk/dls2012/demo/demo.py --- a/talk/dls2012/demo/demo.py +++ b/talk/dls2012/demo/demo.py @@ -256,7 +256,7 @@ vim.send('>') vim.type('kowhile not labels.done:labels.done = True') vim.type('28ggoself.done = False') - vim.type('43gg39ggOif self.labels[x, y] != l:self.done = False:w') + vim.type('43gg39ggIkaif self.labels[x, y] != l:self.done = False:w') pause("As a final touch, lets renumber the labels be consecutative\n" + "integers.") diff --git a/talk/dls2012/demo/detect.py b/talk/dls2012/demo/detect.py --- a/talk/dls2012/demo/detect.py +++ b/talk/dls2012/demo/detect.py @@ -60,13 +60,13 @@ for x, y in seg.indexes(): if seg[x, y]: ll = [labels[x, y], labels[x-1, y], labels[x-1, y-1], - labels[x, y-1], labels[x+1, y-1]] + labels[x, y-1], labels[x+1, y-1]] labels.update(x, y, ll) for x, y in reversed(seg.indexes()): if seg[x, y]: ll = [labels[x, y], labels[x+1, y], labels[x-1, y+1], - labels[x, y+1], labels[x+1, y+1]] + labels[x, y+1], labels[x+1, y+1]] labels.update(x, y, ll) labels.renumber() From noreply at buildbot.pypy.org Fri Oct 19 13:39:50 2012 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 19 Oct 2012 13:39:50 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: merge default into branch Message-ID: <20121019113950.A1C101C0012@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-problems Changeset: r58240:e85a4b405f1a Date: 2012-10-18 20:01 +0200 http://bitbucket.org/pypy/pypy/changeset/e85a4b405f1a/ Log: merge default into branch diff too long, truncating to 2000 out of 2833 lines diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py --- a/lib_pypy/_ctypes/structure.py +++ b/lib_pypy/_ctypes/structure.py @@ -69,7 +69,8 @@ resnames.append(name) names = resnames self._names = names - self.__dict__.update(fields) + for name, field in fields.items(): + setattr(self, name, field) class Field(object): def __init__(self, name, offset, size, ctype, num, is_bitfield): diff --git a/lib_pypy/pypy_test/test_ctypes_support.py b/lib_pypy/pypy_test/test_ctypes_support.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_ctypes_support.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import absolute_import - -import py -from ctypes import * -try: - from ctypes_support import standard_c_lib, get_errno, set_errno -except ImportError: # on top of cpython - from lib_pypy.ctypes_support import standard_c_lib, get_errno, set_errno - - -def test_stdlib_and_errno(): - py.test.skip("this is expected on top of pypy, we need to fix ctypes in a way that is now in 2.6 in order to make this reliable") - write = standard_c_lib.write - write.argtypes = [c_int, c_char_p, c_size_t] - write.restype = c_size_t - # clear errno first - set_errno(0) - assert get_errno() == 0 - write(-345, "abc", 3) - assert get_errno() != 0 - set_errno(0) - assert get_errno() == 0 - -def test_argument_conversion_and_checks(): - strlen = standard_c_lib.strlen - strlen.argtypes = [c_char_p] - strlen.restype = c_size_t - assert strlen("eggs") == 4 - - # Should raise ArgumentError, not segfault - py.test.raises(ArgumentError, strlen, False) - diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -17,12 +17,6 @@ projects, or anything else in PyPy, pop up on IRC or write to us on the `mailing list`_. -Make big integers faster -------------------------- - -PyPy's implementation of the Python ``long`` type is slower than CPython's. -Find out why and optimize them. **UPDATE:** this was done (thanks stian). - Make bytearray type fast ------------------------ @@ -81,14 +75,6 @@ * Allow separate compilation of extension modules. -Work on some of other languages -------------------------------- - -There are various languages implemented using the RPython translation toolchain. -One of the most interesting is the `JavaScript implementation`_, but there -are others like scheme or prolog. An interesting project would be to improve -the jittability of those or to experiment with various optimizations. - Various GCs ----------- @@ -144,8 +130,6 @@ * `hg` -* `sympy` - Experiment (again) with LLVM backend for RPython compilation ------------------------------------------------------------ @@ -191,4 +175,3 @@ .. _`issue tracker`: http://bugs.pypy.org .. _`mailing list`: http://mail.python.org/mailman/listinfo/pypy-dev .. _`jitviewer`: http://bitbucket.org/pypy/jitviewer -.. _`JavaScript implementation`: https://bitbucket.org/pypy/lang-js/overview diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py --- a/pypy/interpreter/astcompiler/consts.py +++ b/pypy/interpreter/astcompiler/consts.py @@ -9,13 +9,14 @@ CO_NESTED = 0x0010 CO_GENERATOR = 0x0020 CO_NOFREE = 0x0040 -CO_CONTAINSGLOBALS = 0x0800 CO_GENERATOR_ALLOWED = 0x1000 CO_FUTURE_DIVISION = 0x2000 CO_FUTURE_ABSOLUTE_IMPORT = 0x4000 CO_FUTURE_WITH_STATEMENT = 0x8000 CO_FUTURE_PRINT_FUNCTION = 0x10000 CO_FUTURE_UNICODE_LITERALS = 0x20000 +CO_CONTAINSGLOBALS = 0x80000 # pypy-specific: need to check that it's not used + # by any other flag PyCF_SOURCE_IS_UTF8 = 0x0100 PyCF_DONT_IMPLY_DEDENT = 0x0200 diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -415,6 +415,7 @@ raise operationerrfmt(space.w_ValueError, "%s() requires a code object with %d free vars, not %d", self.name, closure_len, len(code.co_freevars)) + self.fget_func_doc(space) # see test_issue1293 self.code = code def fget_func_closure(self, space): diff --git a/pypy/interpreter/test/test_code.py b/pypy/interpreter/test/test_code.py --- a/pypy/interpreter/test/test_code.py +++ b/pypy/interpreter/test/test_code.py @@ -1,5 +1,6 @@ from pypy.conftest import gettestobjspace from pypy.interpreter import gateway +from pypy.interpreter.astcompiler import consts import py class AppTestCodeIntrospection: @@ -11,6 +12,7 @@ filename = filename[:-1] cls.w_file = space.wrap(filename) + cls.w_CO_CONTAINSGLOBALS = space.wrap(consts.CO_CONTAINSGLOBALS) def test_attributes(self): def f(): pass @@ -185,7 +187,7 @@ assert f(4).func_code.co_flags & 0x10 assert f.func_code.co_flags & 0x10 == 0 # check for CO_CONTAINSGLOBALS - assert not f.func_code.co_flags & 0x0800 + assert not f.func_code.co_flags & self.CO_CONTAINSGLOBALS exec """if 1: @@ -197,8 +199,8 @@ """ # check for CO_CONTAINSGLOBALS - assert f.func_code.co_flags & 0x0800 - assert not g.func_code.co_flags & 0x0800 + assert f.func_code.co_flags & self.CO_CONTAINSGLOBALS + assert not g.func_code.co_flags & self.CO_CONTAINSGLOBALS exec """if 1: b = 2 @@ -207,4 +209,4 @@ return a + b + x """ # check for CO_CONTAINSGLOBALS - assert f.func_code.co_flags & 0x0800 + assert f.func_code.co_flags & self.CO_CONTAINSGLOBALS diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py --- a/pypy/interpreter/test/test_function.py +++ b/pypy/interpreter/test/test_function.py @@ -299,6 +299,12 @@ assert f.__doc__ == u"hi" assert type(f.__doc__) is unicode + def test_issue1293(self): + def f1(): "doc f1" + def f2(): "doc f2" + f1.func_code = f2.func_code + assert f1.__doc__ == "doc f1" + def test_subclassing(self): # cannot subclass 'function' or 'builtin_function' def f(): diff --git a/pypy/jit/backend/llvm/__init__.py b/pypy/jit/backend/llvm/__init__.py deleted file mode 100644 diff --git a/pypy/jit/backend/llvm/compile.py b/pypy/jit/backend/llvm/compile.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/compile.py +++ /dev/null @@ -1,732 +0,0 @@ -import py -from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp.history import Const, INT -from pypy.jit.backend.llvm import llvm_rffi -from pypy.jit.metainterp import resoperation -from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.llsupport import symbolic -from pypy.jit.backend.llvm.runner import SizeDescr, CallDescr -from pypy.jit.backend.llvm.runner import FieldDescr, ArrayDescr - -# ____________________________________________________________ - -class LLVMJITCompiler(object): - FUNC = lltype.FuncType([], lltype.Signed) - lastovf = lltype.nullptr(llvm_rffi.LLVMValueRef.TO) - - def __init__(self, cpu, loop): - self.cpu = cpu - self.loop = loop - - def compile(self): - self.start_generating_function() - self.generate_initial_arguments_load() - self.generate_loop_body() - self.close_phi_nodes() - self.done_generating_function() - - def start_generating_function(self): - func = llvm_rffi.LLVMAddFunction(self.cpu.module, "", self.cpu.ty_func) - self.compiling_func = func - self.builder = llvm_rffi.LLVMCreateBuilder() - self.vars = {} - - def generate_initial_arguments_load(self): - loop = self.loop - func = self.compiling_func - bb_entry = llvm_rffi.LLVMAppendBasicBlock(func, "entry") - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_entry) - self.cpu._ensure_in_args(len(loop.inputargs)) - self.phi_incoming_blocks = [bb_entry] - self.phi_incoming_values = [] - for i in range(len(loop.inputargs)): - ty = self.cpu._get_pointer_type(loop.inputargs[i]) - llvmconstptr = self.cpu._make_const(self.cpu.in_out_args[i], ty) - res = llvm_rffi.LLVMBuildLoad(self.builder, llvmconstptr, "") - self.phi_incoming_values.append([res]) - self.bb_start = llvm_rffi.LLVMAppendBasicBlock(func, "") - llvm_rffi.LLVMBuildBr(self.builder, self.bb_start) - # - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, self.bb_start) - for v in loop.inputargs: - ty = self.cpu._get_var_type(v) - phi = llvm_rffi.LLVMBuildPhi(self.builder, ty, "") - self.vars[v] = phi - - def generate_loop_body(self): - func = self.compiling_func - self.pending_blocks = [(self.loop.operations, self.bb_start, False)] - while self.pending_blocks: - operations, bb, exc = self.pending_blocks.pop() - self._generate_branch(operations, bb, exc) - self.bb_start = lltype.nullptr(llvm_rffi.LLVMBasicBlockRef.TO) - - def close_phi_nodes(self): - incoming_blocks = lltype.malloc( - rffi.CArray(llvm_rffi.LLVMBasicBlockRef), - len(self.phi_incoming_blocks), flavor='raw') - incoming_values = lltype.malloc( - rffi.CArray(llvm_rffi.LLVMValueRef), - len(self.phi_incoming_blocks), flavor='raw') - for j in range(len(self.phi_incoming_blocks)): - incoming_blocks[j] = self.phi_incoming_blocks[j] - loop = self.loop - for i in range(len(loop.inputargs)): - phi = self.vars[loop.inputargs[i]] - incoming = self.phi_incoming_values[i] - for j in range(len(self.phi_incoming_blocks)): - incoming_values[j] = incoming[j] - llvm_rffi.LLVMAddIncoming(phi, incoming_values, incoming_blocks, - len(self.phi_incoming_blocks)) - lltype.free(incoming_values, flavor='raw') - lltype.free(incoming_blocks, flavor='raw') - - def done_generating_function(self): - llvm_rffi.LLVMDisposeBuilder(self.builder) - llvm_rffi.LLVMDumpValue(self.compiling_func) # xxx for debugging - # - func_addr = llvm_rffi.LLVM_EE_getPointerToFunction(self.cpu.ee, - self.compiling_func) - if not we_are_translated(): - print '--- function is at %r ---' % (func_addr,) - # - func_ptr = rffi.cast(lltype.Ptr(self.FUNC), func_addr) - index = self.loop._llvm_compiled_index - if index < 0: - self.loop._llvm_compiled_index = len(self.cpu.compiled_functions) - self.cpu.compiled_functions.append(func_ptr) - else: - self.cpu.compiled_functions[index] = func_ptr - - def _generate_branch(self, operations, basicblock, exc): - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, basicblock) - # The flag 'exc' is set to True if we are a branch handling a - # GUARD_EXCEPTION or GUARD_NO_EXCEPTION. In this case, we have to - # store away the exception into self.backup_exc_xxx, *unless* the - # branch starts with a further GUARD_EXCEPTION/GUARD_NO_EXCEPTION. - if exc: - opnum = operations[0].getopnum() - if opnum not in (rop.GUARD_EXCEPTION, rop.GUARD_NO_EXCEPTION): - self._store_away_exception() - # Normal handling of the operations follows. - for op in operations: - self._generate_op(op) - - def _generate_op(self, op): - opnum = op.getopnum() - for i, name in all_operations: - if opnum == i: - meth = getattr(self, name) - meth(op) - return - else: - raise MissingOperation(resoperation.opname[opnum]) - - def _store_away_exception(self): - # etype, evalue: ty_char_ptr - etype = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_type, "") - llvm_rffi.LLVMBuildStore(self.builder, - self.cpu.const_null_charptr, - self.cpu.const_exc_type) - llvm_rffi.LLVMBuildStore(self.builder, - etype, - self.cpu.const_backup_exc_type) - evalue = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_value, "") - llvm_rffi.LLVMBuildStore(self.builder, - self.cpu.const_null_charptr, - self.cpu.const_exc_value) - llvm_rffi.LLVMBuildStore(self.builder, - evalue, - self.cpu.const_backup_exc_value) - - def getintarg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_int(v.getint()) - else: - return self._cast_to_int(value_ref) - - def _cast_to_int(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_int: - return value_ref - else: - return llvm_rffi.LLVMBuildZExt(self.builder, value_ref, - self.cpu.ty_int, "") - - def getbitarg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_bit(v.getint()) - else: - return self._cast_to_bit(value_ref) - - def _cast_to_bit(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_bit: - return value_ref - else: - return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref, - self.cpu.ty_bit, "") - - def getchararg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_char(v.getint()) - else: - return self._cast_to_char(value_ref) - - def _cast_to_char(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_char: - return value_ref - elif ty == self.cpu.ty_int or ty == self.cpu.ty_unichar: - return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref, - self.cpu.ty_char, "") - elif ty == self.cpu.ty_bit: - return llvm_rffi.LLVMBuildZExt(self.builder, value_ref, - self.cpu.ty_char, "") - else: - raise AssertionError("type is not an int nor a bit") - - def getunichararg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_unichar(v.getint()) - else: - return self._cast_to_unichar(value_ref) - - def _cast_to_unichar(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_unichar: - return value_ref - elif ty == self.cpu.ty_int: - return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref, - self.cpu.ty_char, "") - elif ty == self.cpu.ty_bit or ty == self.cpu.ty_char: - return llvm_rffi.LLVMBuildZExt(self.builder, value_ref, - self.cpu.ty_char, "") - else: - raise AssertionError("type is not an int nor a bit") - - def getptrarg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - return self.cpu._make_const(v.getaddr(self.cpu), - self.cpu.ty_char_ptr) - else: - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_int: - value_ref = llvm_rffi.LLVMBuildIntToPtr(self.builder, - value_ref, - self.cpu.ty_char_ptr, - "") - else: - assert (ty != self.cpu.ty_bit and - ty != self.cpu.ty_char and - ty != self.cpu.ty_unichar) - return value_ref - - for _opname, _llvmname in [('INT_ADD', 'Add'), - ('INT_SUB', 'Sub'), - ('INT_MUL', 'Mul'), - ('INT_FLOORDIV', 'SDiv'), - ('INT_MOD', 'SRem'), - ('INT_LSHIFT', 'Shl'), - ('INT_RSHIFT', 'AShr'), - ('UINT_RSHIFT', 'LShr'), - ('INT_AND', 'And'), - ('INT_OR', 'Or'), - ('INT_XOR', 'Xor'), - ]: - exec py.code.Source(''' - def generate_%s(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuild%s( - self.builder, - self.getintarg(op.args[0]), - self.getintarg(op.args[1]), - "") - ''' % (_opname, _llvmname)).compile() - - for _opname, _predicate in [('INT_LT', llvm_rffi.Predicate.SLT), - ('INT_LE', llvm_rffi.Predicate.SLE), - ('INT_EQ', llvm_rffi.Predicate.EQ), - ('INT_NE', llvm_rffi.Predicate.NE), - ('INT_GT', llvm_rffi.Predicate.SGT), - ('INT_GE', llvm_rffi.Predicate.SGE), - ('UINT_LT', llvm_rffi.Predicate.ULT), - ('UINT_LE', llvm_rffi.Predicate.ULE), - ('UINT_GT', llvm_rffi.Predicate.UGT), - ('UINT_GE', llvm_rffi.Predicate.UGE)]: - exec py.code.Source(''' - def generate_%s(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, - %d, - self.getintarg(op.args[0]), - self.getintarg(op.args[1]), - "") - ''' % (_opname, _predicate)).compile() - - def generate_INT_NEG(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildNeg(self.builder, - self.getintarg(op.args[0]), - "") - - def generate_INT_INVERT(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildNot(self.builder, - self.getintarg(op.args[0]), - "") - - def generate_INT_IS_TRUE(self, op): - v = op.args[0] - try: - value_ref = self.vars[v] - if llvm_rffi.LLVMTypeOf(value_ref) != self.cpu.ty_bit: - raise KeyError - except KeyError: - res = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.NE, - self.getintarg(op.args[0]), - self.cpu.const_zero, - "") - else: - res = value_ref # value_ref: ty_bit. this is a no-op - self.vars[op.result] = res - - def generate_BOOL_NOT(self, op): - v = op.args[0] - try: - value_ref = self.vars[v] - if llvm_rffi.LLVMTypeOf(value_ref) != self.cpu.ty_bit: - raise KeyError - except KeyError: - res = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - self.getintarg(op.args[0]), - self.cpu.const_zero, - "") - else: - # value_ref: ty_bit - res = llvm_rffi.LLVMBuildNot(self.builder, value_ref, "") - self.vars[op.result] = res - - def generate_INT_ADD_OVF(self, op): - self._generate_ovf_op(op, self.cpu.f_add_ovf) - - def generate_INT_SUB_OVF(self, op): - self._generate_ovf_op(op, self.cpu.f_sub_ovf) - - def generate_INT_MUL_OVF(self, op): - self._generate_ovf_op(op, self.cpu.f_mul_ovf) - - def _generate_ovf_op(self, op, f_intrinsic): - self._generate_ovf_test(f_intrinsic, - self.getintarg(op.args[0]), - self.getintarg(op.args[1]), - op.result) - - def _generate_ovf_test(self, f_intrinsic, arg0, arg1, result): - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 2, - flavor='raw') - arglist[0] = arg0 - arglist[1] = arg1 - tmp = llvm_rffi.LLVMBuildCall(self.builder, f_intrinsic, - arglist, 2, "") - lltype.free(arglist, flavor='raw') - self.vars[result] = llvm_rffi.LLVMBuildExtractValue(self.builder, - tmp, 0, "") - self.lastovf = llvm_rffi.LLVMBuildExtractValue(self.builder, tmp, 1, - "") - - def generate_GUARD_FALSE(self, op): - self._generate_guard(op, self.getbitarg(op.args[0]), True) - - def generate_GUARD_TRUE(self, op): - self._generate_guard(op, self.getbitarg(op.args[0]), False) - - def generate_GUARD_VALUE(self, op): - if op.args[0].type == INT: - arg0 = self.getintarg(op.args[0]) - arg1 = self.getintarg(op.args[1]) - else: - arg0 = self.getptrarg(op.args[0]) - arg1 = self.getptrarg(op.args[1]) - equal = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - arg0, arg1, "") - self._generate_guard(op, equal, False) - - def generate_GUARD_CLASS(self, op): - loc = self._generate_field_gep(op.args[0], self.cpu.fielddescr_vtable) - cls = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - equal = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - cls, - self.getintarg(op.args[1]), "") - self._generate_guard(op, equal, False) - - def generate_GUARD_NO_EXCEPTION(self, op): - # etype: ty_char_ptr - etype = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_type, "") - eisnull = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - etype, - self.cpu.const_null_charptr, "") - self._generate_guard(op, eisnull, False, exc=True) - - def generate_GUARD_EXCEPTION(self, op): - v = op.args[0] - assert isinstance(v, Const) - # etype, expectedtype: ty_char_ptr - expectedtype = self.cpu._make_const(v.getint(), self.cpu.ty_char_ptr) - etype = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_type, "") - eisequal = llvm_rffi.LLVMBuildICmp(self.builder, - llvm_rffi.Predicate.EQ, - etype, - expectedtype, "") - self._generate_guard(op, eisequal, False, exc=True) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_value, - "") - - def generate_GUARD_NO_OVERFLOW(self, op): - self._generate_guard(op, self.lastovf, True) - - def generate_GUARD_OVERFLOW(self, op): - self._generate_guard(op, self.lastovf, False) - - def _generate_guard(self, op, verify_condition, reversed, exc=False): - func = self.compiling_func - bb_on_track = llvm_rffi.LLVMAppendBasicBlock(func, "") - bb_off_track = llvm_rffi.LLVMAppendBasicBlock(func, "") - llvm_rffi.LLVMBuildCondBr(self.builder, verify_condition, - bb_on_track, bb_off_track) - if reversed: - bb_on_track, bb_off_track = bb_off_track, bb_on_track - # generate the on-track part first, and the off-track part later - self.pending_blocks.append((op.suboperations, bb_off_track, exc)) - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_on_track) - - def generate_JUMP(self, op): - if op.jump_target is self.loop: - basicblock = llvm_rffi.LLVMGetInsertBlock(self.builder) - self.phi_incoming_blocks.append(basicblock) - for i in range(len(op.args)): - incoming = self.phi_incoming_values[i] - v = op.args[i] - if v.type == INT: - value_ref = self.getintarg(v) - else: - value_ref = self.getptrarg(v) - incoming.append(value_ref) - llvm_rffi.LLVMBuildBr(self.builder, self.bb_start) - else: - index = op.jump_target._llvm_compiled_index - assert index >= 0 - self._generate_fail(op.args, index) - - def generate_FAIL(self, op): - i = len(self.cpu.fail_ops) - self.cpu.fail_ops.append(op) - self._generate_fail(op.args, ~i) - - def _generate_fail(self, args, index): - self.cpu._ensure_out_args(len(args)) - for i in range(len(args)): - v = args[i] - if v.type == INT: - value_ref = self.getintarg(v) - ty = self.cpu.ty_int_ptr - else: - value_ref = self.getptrarg(v) - ty = self.cpu.ty_char_ptr_ptr - llvmconstptr = self.cpu._make_const(self.cpu.in_out_args[i], ty) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, - llvmconstptr) - llvm_rffi.LLVMBuildRet(self.builder, self.cpu._make_const_int(index)) - - def _generate_field_gep(self, v_structure, fielddescr): - assert isinstance(fielddescr, FieldDescr) - indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 1, - flavor='raw') - indices[0] = self.cpu._make_const_int(fielddescr.offset) - location = llvm_rffi.LLVMBuildGEP(self.builder, - self.getptrarg(v_structure), - indices, 1, "") - lltype.free(indices, flavor='raw') - ty = self.cpu.types_ptr_by_index[fielddescr.size_index] - location = llvm_rffi.LLVMBuildBitCast(self.builder, location, ty, "") - return location - - def generate_GETFIELD_GC(self, op): - loc = self._generate_field_gep(op.args[0], op.getdescr()) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - generate_GETFIELD_GC_PURE = generate_GETFIELD_GC - generate_GETFIELD_RAW = generate_GETFIELD_GC - generate_GETFIELD_RAW_PURE = generate_GETFIELD_GC - - def generate_SETFIELD_GC(self, op): - fielddescr = op.getdescr() - loc = self._generate_field_gep(op.args[0], fielddescr) - assert isinstance(fielddescr, FieldDescr) - getarg = self.cpu.getarg_by_index[fielddescr.size_index] - value_ref = getarg(self, op.args[1]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def generate_CALL(self, op): - calldescr = op.getdescr() - assert isinstance(calldescr, CallDescr) - ty_function_ptr = self.cpu.get_calldescr_ty_function_ptr(calldescr) - v = op.args[0] - if isinstance(v, Const): - func = self.cpu._make_const(v.getint(), ty_function_ptr) - else: - func = self.getintarg(v) - func = llvm_rffi.LLVMBuildIntToPtr(self.builder, - func, - ty_function_ptr, "") - nb_args = len(op.args) - 1 - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), nb_args, - flavor='raw') - for i in range(nb_args): - v = op.args[1 + i] - index = calldescr.args_indices[i] - getarg = self.cpu.getarg_by_index[index] - value_ref = getarg(self, v) - arglist[i] = value_ref - res = llvm_rffi.LLVMBuildCall(self.builder, - func, arglist, nb_args, "") - lltype.free(arglist, flavor='raw') - if op.result is not None: - assert calldescr.res_index >= 0 - self.vars[op.result] = res - - generate_CALL_PURE = generate_CALL - - def generate_CAST_PTR_TO_INT(self, op): - res = llvm_rffi.LLVMBuildPtrToInt(self.builder, - self.getptrarg(op.args[0]), - self.cpu.ty_int, "") - self.vars[op.result] = res - - def generate_CAST_INT_TO_PTR(self, op): - res = llvm_rffi.LLVMBuildIntToPtr(self.builder, - self.getintarg(op.args[0]), - self.cpu.ty_char_ptr, "") - self.vars[op.result] = res - - def generate_OOIS(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.EQ, - self.getptrarg(op.args[0]), - self.getptrarg(op.args[1]), "") - - def generate_OOISNOT(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.NE, - self.getptrarg(op.args[0]), - self.getptrarg(op.args[1]), "") - - def generate_OOISNULL(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.EQ, - self.getptrarg(op.args[0]), - self.cpu.const_null_charptr, "") - - def generate_OONONNULL(self, op): - self.vars[op.result] = llvm_rffi.LLVMBuildICmp( - self.builder, llvm_rffi.Predicate.NE, - self.getptrarg(op.args[0]), - self.cpu.const_null_charptr, "") - - def generate_SAME_AS(self, op): - if op.args[0].type == INT: - self.vars[op.result] = self.getintarg(op.args[0]) - else: - self.vars[op.result] = self.getptrarg(op.args[0]) - - def _generate_len_gep(self, array_ref, ty, const_index_length): - array = llvm_rffi.LLVMBuildBitCast(self.builder, - array_ref, ty, "") - indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 2, - flavor='raw') - indices[0] = self.cpu.const_zero - indices[1] = const_index_length - loc = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 2, "") - lltype.free(indices, flavor='raw') - return loc - - def _generate_len(self, op, ty, const_index_length): - loc = self._generate_len_gep(self.getptrarg(op.args[0]), - ty, const_index_length) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - def generate_ARRAYLEN_GC(self, op): - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - self._generate_len(op, arraydescr.ty_array_ptr, - self.cpu.const_array_index_length) - - def _generate_gep(self, op, ty, const_index_array): - array = llvm_rffi.LLVMBuildBitCast(self.builder, - self.getptrarg(op.args[0]), - ty, "") - indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 3, - flavor='raw') - indices[0] = self.cpu.const_zero - indices[1] = const_index_array - indices[2] = self.getintarg(op.args[1]) - location = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 3, "") - lltype.free(indices, flavor='raw') - return location - - def _generate_array_gep(self, op): - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - location = self._generate_gep(op, arraydescr.ty_array_ptr, - self.cpu.const_array_index_array) - return location - - def generate_GETARRAYITEM_GC(self, op): - loc = self._generate_array_gep(op) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - generate_GETARRAYITEM_GC_PURE = generate_GETARRAYITEM_GC - - def generate_SETARRAYITEM_GC(self, op): - loc = self._generate_array_gep(op) - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - getarg = self.cpu.getarg_by_index[arraydescr.itemsize_index] - value_ref = getarg(self, op.args[2]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def generate_STRLEN(self, op): - self._generate_len(op, self.cpu.ty_string_ptr, - self.cpu.const_string_index_length) - - def generate_UNICODELEN(self, op): - self._generate_len(op, self.cpu.ty_unicode_ptr, - self.cpu.const_unicode_index_length) - - def generate_STRGETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_string_ptr, - self.cpu.const_string_index_array) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - def generate_UNICODEGETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_unicode_ptr, - self.cpu.const_unicode_index_array) - self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "") - - def generate_STRSETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_string_ptr, - self.cpu.const_string_index_array) - value_ref = self.getchararg(op.args[2]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def generate_UNICODESETITEM(self, op): - loc = self._generate_gep(op, self.cpu.ty_unicode_ptr, - self.cpu.const_unicode_index_array) - value_ref = self.getunichararg(op.args[2]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def _generate_new(self, size_ref): - malloc_func = self.cpu._make_const(self.cpu.malloc_fn_ptr, - self.cpu.ty_malloc_fn) - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 1, - flavor='raw') - arglist[0] = size_ref - res = llvm_rffi.LLVMBuildCall(self.builder, malloc_func, - arglist, 1, "") - lltype.free(arglist, flavor='raw') - return res - - def generate_NEW(self, op): - sizedescr = op.getdescr() - assert isinstance(sizedescr, SizeDescr) - res = self._generate_new(self.cpu._make_const_int(sizedescr.size)) - self.vars[op.result] = res - - def generate_NEW_WITH_VTABLE(self, op): - sizedescr = self.cpu.class_sizes[op.args[0].getint()] - res = self._generate_new(self.cpu._make_const_int(sizedescr.size)) - self.vars[op.result] = res - loc = self._generate_field_gep(op.result, self.cpu.vtable_descr) - value_ref = self.getintarg(op.args[0]) - llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "") - - def _generate_new_array(self, op, ty_array, const_item_size, - const_index_array, const_index_length): - length_ref = self.getintarg(op.args[0]) - if const_item_size == self.cpu.const_one: - arraysize_ref = length_ref - else: - arraysize_ref = llvm_rffi.LLVMBuildMul(self.builder, - length_ref, - const_item_size, - "") - size_ref = llvm_rffi.LLVMBuildAdd(self.builder, - const_index_array, - arraysize_ref, - "") - res = self._generate_new(size_ref) - loc = self._generate_len_gep(res, ty_array, const_index_length) - llvm_rffi.LLVMBuildStore(self.builder, - length_ref, - loc, "") - self.vars[op.result] = res - - def generate_NEW_ARRAY(self, op): - arraydescr = op.getdescr() - assert isinstance(arraydescr, ArrayDescr) - self._generate_new_array(op, arraydescr.ty_array_ptr, - self.cpu._make_const_int(arraydescr.itemsize), - self.cpu.const_array_index_array, - self.cpu.const_array_index_length) - - def generate_NEWSTR(self, op): - self._generate_new_array(op, self.cpu.ty_string_ptr, - self.cpu.const_one, - self.cpu.const_string_index_array, - self.cpu.const_string_index_length) - - def generate_NEWUNICODE(self, op): - self._generate_new_array(op, self.cpu.ty_unicode_ptr, - self.cpu._make_const_int(self.cpu.size_of_unicode), - self.cpu.const_unicode_index_array, - self.cpu.const_unicode_index_length) - - def generate_DEBUG_MERGE_POINT(self, op): - pass - -# ____________________________________________________________ - -class MissingOperation(Exception): - pass - -all_operations = {} -for _key, _value in rop.__dict__.items(): - if 'A' <= _key <= 'Z': - assert _value not in all_operations - methname = 'generate_' + _key - if hasattr(LLVMJITCompiler, methname): - all_operations[_value] = methname -all_operations = unrolling_iterable(all_operations.items()) diff --git a/pypy/jit/backend/llvm/demo1.c b/pypy/jit/backend/llvm/demo1.c deleted file mode 100644 --- a/pypy/jit/backend/llvm/demo1.c +++ /dev/null @@ -1,17 +0,0 @@ -/* LLVM includes */ -#include "llvm-c/Analysis.h" -#include "llvm-c/Transforms/Scalar.h" -#include "llvm-c/ExecutionEngine.h" -#include "demo2.h" - -/* The following list of functions seems to be necessary to force the - * functions to be included in pypy_cache_llvm.so. The list is never - * used. Actually, any single function seems to be enough... - */ -void* llvm_c_functions[] = { - (void*) LLVMModuleCreateWithName, - (void*) _LLVM_EE_getPointerToFunction, - (void*) _LLVM_Intrinsic_add_ovf, - (void*) _LLVM_Intrinsic_sub_ovf, - (void*) _LLVM_Intrinsic_mul_ovf -}; diff --git a/pypy/jit/backend/llvm/demo2.cpp b/pypy/jit/backend/llvm/demo2.cpp deleted file mode 100644 --- a/pypy/jit/backend/llvm/demo2.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* LLVM includes */ -#include -#include "llvm-c/ExecutionEngine.h" -#include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Intrinsics.h" -#include "demo2.h" - -using namespace llvm; - - -/* Set the flag to true. - */ -void _LLVM_SetFlags(void) -{ - //PerformTailCallOpt = true; -} - -/* This piece of code regroups conveniently a part of the initialization. - */ -LLVMExecutionEngineRef _LLVM_EE_Create(LLVMModuleRef M) -{ - LLVMModuleProviderRef mp = LLVMCreateModuleProviderForExistingModule(M); - LLVMExecutionEngineRef ee; - char* errormsg; - int error = LLVMCreateJITCompiler(&ee, mp, 0 /*Fast*/, &errormsg); - if (error) - { - fprintf(stderr, "Error creating the JIT compiler:\n%s", errormsg); - abort(); - } - return ee; -} - -/* Missing pieces of the C interface... - */ -void *_LLVM_EE_getPointerToFunction(LLVMExecutionEngineRef EE, - LLVMValueRef F) -{ - return unwrap(EE)->getPointerToFunction(unwrap(F)); -} - -static LLVMValueRef _LLVM_Intrinsic_ovf(LLVMModuleRef M, LLVMTypeRef Ty, - Intrinsic::ID num) -{ - const Type *array_of_types[1]; - Function *F; - array_of_types[0] = unwrap(Ty); - F = Intrinsic::getDeclaration(unwrap(M), num, array_of_types, 1); - return wrap(F); -} - -LLVMValueRef _LLVM_Intrinsic_add_ovf(LLVMModuleRef M, LLVMTypeRef Ty) -{ - return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::sadd_with_overflow); -} - -LLVMValueRef _LLVM_Intrinsic_sub_ovf(LLVMModuleRef M, LLVMTypeRef Ty) -{ - return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::ssub_with_overflow); -} - -LLVMValueRef _LLVM_Intrinsic_mul_ovf(LLVMModuleRef M, LLVMTypeRef Ty) -{ - return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::smul_with_overflow); -} diff --git a/pypy/jit/backend/llvm/demo2.h b/pypy/jit/backend/llvm/demo2.h deleted file mode 100644 --- a/pypy/jit/backend/llvm/demo2.h +++ /dev/null @@ -1,16 +0,0 @@ - -#ifdef __cplusplus -extern "C" { -#endif - -void _LLVM_SetFlags(void); -LLVMExecutionEngineRef _LLVM_EE_Create(LLVMModuleRef M); -void *_LLVM_EE_getPointerToFunction(LLVMExecutionEngineRef EE, - LLVMValueRef F); -LLVMValueRef _LLVM_Intrinsic_add_ovf(LLVMModuleRef M, LLVMTypeRef Ty); -LLVMValueRef _LLVM_Intrinsic_sub_ovf(LLVMModuleRef M, LLVMTypeRef Ty); -LLVMValueRef _LLVM_Intrinsic_mul_ovf(LLVMModuleRef M, LLVMTypeRef Ty); - -#ifdef __cplusplus -} -#endif diff --git a/pypy/jit/backend/llvm/llvm_rffi.py b/pypy/jit/backend/llvm/llvm_rffi.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/llvm_rffi.py +++ /dev/null @@ -1,371 +0,0 @@ -import py, os, sys -import pypy -from pypy.rpython.lltypesystem import lltype, rffi -from pypy.translator.tool.cbuild import ExternalCompilationInfo, log - -if not sys.platform.startswith('linux'): - py.test.skip("Linux only for now") - -# ____________________________________________________________ - -llvm_config = 'llvm-config' -cachename = os.path.join(os.path.dirname(pypy.__file__), '_cache') -dirname = os.path.join(cachename, 'libs') -libname = os.path.join(dirname, 'pypy_cache_llvm.so') -cname = os.path.join(os.path.dirname(__file__), 'demo1.c') -cppname = os.path.join(os.path.dirname(__file__), 'demo2.cpp') -o1name = os.path.join(dirname, 'demo1.o') -o2name = os.path.join(dirname, 'demo2.o') - -if (not os.path.isfile(libname) or - os.path.getmtime(cname) > os.path.getmtime(libname) or - os.path.getmtime(cppname) > os.path.getmtime(libname)): - g = os.popen('%s --version' % llvm_config, 'r') - data = g.read() - g.close() - if not data.startswith('2.'): - py.test.skip("llvm (version 2) is required") - - if not os.path.isdir(dirname): - if not os.path.isdir(cachename): - os.mkdir(cachename) - os.mkdir(dirname) - - def do(cmdline): - log(cmdline) - err = os.system(cmdline) - if err: - raise Exception("gcc command failed") - - do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cname, o1name, llvm_config)) - do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cppname, o2name, llvm_config)) - do("g++ -g -shared '%s' '%s' -o '%s'" % (o1name, o2name, libname) + - " `%s --cflags --ldflags --libs jit engine`" % llvm_config) - -ctypes_compilation_info = ExternalCompilationInfo( - library_dirs = [dirname], - libraries = ['pypy_cache_llvm'], -) - -compilation_info = ExternalCompilationInfo.from_linker_flags( - os.popen("%s --ldflags --libs jit engine" % llvm_config, 'r').read()) - -compilation_info = compilation_info.merge(ExternalCompilationInfo( - link_extra = [o1name, o2name], - use_cpp_linker = True, - )) - -compilation_info._with_ctypes = ctypes_compilation_info - -_teardown = None - -def set_teardown_function(fn): - global _teardown - _teardown = fn - -def teardown_now(): - global _teardown - fn = _teardown - _teardown = None - if fn is not None: - fn() - -# ____________________________________________________________ - -Debug = True - -def llexternal(name, args, result, **kwds): - ll = rffi.llexternal(name, args, result, - compilation_info=compilation_info, - **kwds) - if Debug: - def func(*args): - print name - res = ll(*args) - print '\t->', res - return res - return func - else: - return ll - -def opaqueptr(name): - return rffi.VOIDP # lltype.Ptr(rffi.COpaque(name)) - -LLVMModuleRef = opaqueptr('struct LLVMOpaqueModule') -LLVMTypeRef = opaqueptr('struct LLVMOpaqueType') -LLVMValueRef = opaqueptr('struct LLVMOpaqueValue') -LLVMBasicBlockRef = opaqueptr('struct LLVMOpaqueBasicBlock') -LLVMBuilderRef = opaqueptr('struct LLVMOpaqueBuilder') -LLVMModuleProviderRef = opaqueptr('struct LLVMOpaqueModuleProvider') -LLVMGenericValueRef = opaqueptr('struct LLVMOpaqueGenericValue') -LLVMExecutionEngineRef = opaqueptr('struct LLVMOpaqueExecutionEngine') - -class Predicate: - EQ = 32 # equal - NE = 33 # not equal - UGT = 34 # unsigned greater than - UGE = 35 # unsigned greater or equal - ULT = 36 # unsigned less than - ULE = 37 # unsigned less or equal - SGT = 38 # signed greater than - SGE = 39 # signed greater or equal - SLT = 40 # signed less than - SLE = 41 # signed less or equal - -class CallConv: - C = 0 - Fast = 8 - Cold = 9 - X86Stdcall = 64 - X86Fastcall = 65 - -# ____________________________________________________________ - -LLVMDisposeMessage = llexternal('LLVMDisposeMessage', [rffi.CCHARP], - lltype.Void) - -LLVMModuleCreateWithName = llexternal('LLVMModuleCreateWithName', - [rffi.CCHARP], - LLVMModuleRef) -LLVMDumpModule = llexternal('LLVMDumpModule', [LLVMModuleRef], lltype.Void) - -LLVMInt1Type = llexternal('LLVMInt1Type', [], LLVMTypeRef) -LLVMInt8Type = llexternal('LLVMInt8Type', [], LLVMTypeRef) -LLVMInt16Type = llexternal('LLVMInt16Type', [], LLVMTypeRef) -LLVMInt32Type = llexternal('LLVMInt32Type', [], LLVMTypeRef) -LLVMInt64Type = llexternal('LLVMInt64Type', [], LLVMTypeRef) -LLVMFunctionType = llexternal('LLVMFunctionType', - [LLVMTypeRef, # return type - rffi.CArrayPtr(LLVMTypeRef), # param types - rffi.UINT, # param count - rffi.INT], # flag: is_vararg - LLVMTypeRef) -LLVMStructType = llexternal('LLVMStructType', - [rffi.CArrayPtr(LLVMTypeRef), # element types - rffi.UINT, # element count - rffi.INT], # flag: packed - LLVMTypeRef) -LLVMArrayType = llexternal('LLVMArrayType', [LLVMTypeRef, # element type - rffi.UINT], # element count - LLVMTypeRef) -LLVMPointerType = llexternal('LLVMPointerType', [LLVMTypeRef, # element type - rffi.UINT], # address space - LLVMTypeRef) -LLVMVoidType = llexternal('LLVMVoidType', [], LLVMTypeRef) - -LLVMTypeOf = llexternal('LLVMTypeOf', [LLVMValueRef], LLVMTypeRef) -LLVMDumpValue = llexternal('LLVMDumpValue', [LLVMValueRef], lltype.Void) -LLVMConstNull = llexternal('LLVMConstNull', [LLVMTypeRef], LLVMValueRef) -LLVMConstInt = llexternal('LLVMConstInt', [LLVMTypeRef, # type - rffi.ULONGLONG, # value - rffi.INT], # flag: is_signed - LLVMValueRef) -LLVMConstIntToPtr = llexternal('LLVMConstIntToPtr', - [LLVMValueRef, # constant integer value - LLVMTypeRef], # type of the result - LLVMValueRef) - -LLVMAddFunction = llexternal('LLVMAddFunction', - [LLVMModuleRef, # module - rffi.CCHARP, # name - LLVMTypeRef], # function type - LLVMValueRef) -LLVMSetFunctionCallConv = llexternal('LLVMSetFunctionCallConv', - [LLVMValueRef, # function - rffi.UINT], # new call conv - lltype.Void) -LLVMGetParam = llexternal('LLVMGetParam', - [LLVMValueRef, # function - rffi.UINT], # index - LLVMValueRef) - -LLVMAppendBasicBlock = llexternal('LLVMAppendBasicBlock', - [LLVMValueRef, # function - rffi.CCHARP], # name - LLVMBasicBlockRef) - -LLVMSetInstructionCallConv = llexternal('LLVMSetInstructionCallConv', - [LLVMValueRef, # call instruction - rffi.UINT], # new call conv - lltype.Void) -LLVMSetTailCall = llexternal('LLVMSetTailCall', - [LLVMValueRef, # call instruction - rffi.INT], # flag: is_tail - lltype.Void) -LLVMAddIncoming = llexternal('LLVMAddIncoming', - [LLVMValueRef, # phi node - rffi.CArrayPtr(LLVMValueRef), # incoming values - rffi.CArrayPtr(LLVMBasicBlockRef), # incom.blocks - rffi.UINT], # count - lltype.Void) -LLVMCreateBuilder = llexternal('LLVMCreateBuilder', [], LLVMBuilderRef) -LLVMPositionBuilderAtEnd = llexternal('LLVMPositionBuilderAtEnd', - [LLVMBuilderRef, # builder - LLVMBasicBlockRef], # block - lltype.Void) -LLVMGetInsertBlock = llexternal('LLVMGetInsertBlock', [LLVMBuilderRef], - LLVMBasicBlockRef) -LLVMDisposeBuilder = llexternal('LLVMDisposeBuilder', [LLVMBuilderRef], - lltype.Void) - -LLVMBuildRet = llexternal('LLVMBuildRet', [LLVMBuilderRef, # builder, - LLVMValueRef], # result - LLVMValueRef) -LLVMBuildBr = llexternal('LLVMBuildBr', [LLVMBuilderRef, # builder, - LLVMBasicBlockRef],# destination block - LLVMValueRef) -LLVMBuildCondBr = llexternal('LLVMBuildCondBr', - [LLVMBuilderRef, # builder - LLVMValueRef, # condition - LLVMBasicBlockRef, # block if true - LLVMBasicBlockRef], # block if false - LLVMValueRef) - -for _name in ['Add', 'Sub', 'Mul', 'SDiv', 'SRem', 'Shl', 'LShr', 'AShr', - 'And', 'Or', 'Xor']: - globals()['LLVMBuild' + _name] = llexternal('LLVMBuild' + _name, - [LLVMBuilderRef, # builder - LLVMValueRef, # left-hand side - LLVMValueRef, # right-hand side - rffi.CCHARP], # name of result - LLVMValueRef) - -for _name in ['Neg', 'Not']: - globals()['LLVMBuild' + _name] = llexternal('LLVMBuild' + _name, - [LLVMBuilderRef, # builder - LLVMValueRef, # argument - rffi.CCHARP], # name of result - LLVMValueRef) - -LLVMBuildLoad = llexternal('LLVMBuildLoad', - [LLVMBuilderRef, # builder - LLVMValueRef, # pointer location - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildStore = llexternal('LLVMBuildStore', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMValueRef], # pointer location - LLVMValueRef) -LLVMBuildGEP = llexternal('LLVMBuildGEP', # GEP = 'getelementptr' - [LLVMBuilderRef, # builder - LLVMValueRef, # base pointer - rffi.CArrayPtr(LLVMValueRef), # indices - rffi.UINT, # num indices - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildTrunc = llexternal('LLVMBuildTrunc', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildZExt = llexternal('LLVMBuildZExt', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildPtrToInt = llexternal('LLVMBuildPtrToInt', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildIntToPtr = llexternal('LLVMBuildIntToPtr', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildBitCast = llexternal('LLVMBuildBitCast', - [LLVMBuilderRef, # builder - LLVMValueRef, # value - LLVMTypeRef, # destination type - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildICmp = llexternal('LLVMBuildICmp', - [LLVMBuilderRef, # builder - rffi.INT, # predicate (see Predicate above) - LLVMValueRef, # left-hand side - LLVMValueRef, # right-hand side - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildPhi = llexternal('LLVMBuildPhi', - [LLVMBuilderRef, # builder - LLVMTypeRef, # type of value - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildCall = llexternal('LLVMBuildCall', - [LLVMBuilderRef, # builder - LLVMValueRef, # function - rffi.CArrayPtr(LLVMValueRef), # arguments - rffi.UINT, # argument count - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildSelect = llexternal('LLVMBuildSelect', - [LLVMBuilderRef, # builder - LLVMValueRef, # if - LLVMValueRef, # then - LLVMValueRef, # else - rffi.CCHARP], # name of result - LLVMValueRef) -LLVMBuildExtractValue = llexternal('LLVMBuildExtractValue', - [LLVMBuilderRef, # builder - LLVMValueRef, # aggregated value - rffi.UINT, # index - rffi.CCHARP], # name of result - LLVMValueRef) - -LLVMCreateModuleProviderForExistingModule = llexternal( - 'LLVMCreateModuleProviderForExistingModule', [LLVMModuleRef], - LLVMModuleProviderRef) - -# ____________________________________________________________ - -LLVMCreateGenericValueOfInt = llexternal('LLVMCreateGenericValueOfInt', - [LLVMTypeRef, # type - rffi.ULONGLONG, # value - rffi.INT], # flag: is_signed - LLVMGenericValueRef) -LLVMDisposeGenericValue = llexternal('LLVMDisposeGenericValue', - [LLVMGenericValueRef], lltype.Void) - -LLVMGenericValueToInt = llexternal('LLVMGenericValueToInt', - [LLVMGenericValueRef, - rffi.INT], # flag: is_signed - rffi.ULONGLONG) - -LLVMCreateJITCompiler = llexternal('LLVMCreateJITCompiler', - [rffi.CArrayPtr(LLVMExecutionEngineRef), - LLVMModuleProviderRef, - rffi.INT, # "fast" - rffi.CArrayPtr(rffi.CCHARP)], # -> error - rffi.INT) -LLVMDisposeExecutionEngine = llexternal('LLVMDisposeExecutionEngine', - [LLVMExecutionEngineRef], - lltype.Void) - -LLVMRunFunction = llexternal('LLVMRunFunction', - [LLVMExecutionEngineRef, - LLVMValueRef, # function - rffi.UINT, # num args - rffi.CArrayPtr(LLVMGenericValueRef)], # args - LLVMGenericValueRef) # return value - -LLVM_SetFlags = llexternal('_LLVM_SetFlags', [], lltype.Void) -LLVM_EE_Create = llexternal('_LLVM_EE_Create', [LLVMModuleRef], - LLVMExecutionEngineRef) -LLVM_EE_getPointerToFunction = llexternal('_LLVM_EE_getPointerToFunction', - [LLVMExecutionEngineRef, - LLVMValueRef], # function - rffi.VOIDP) -LLVM_Intrinsic_add_ovf = llexternal('_LLVM_Intrinsic_add_ovf', - [LLVMModuleRef, LLVMTypeRef], - LLVMValueRef) -LLVM_Intrinsic_sub_ovf = llexternal('_LLVM_Intrinsic_sub_ovf', - [LLVMModuleRef, LLVMTypeRef], - LLVMValueRef) -LLVM_Intrinsic_mul_ovf = llexternal('_LLVM_Intrinsic_mul_ovf', - [LLVMModuleRef, LLVMTypeRef], - LLVMValueRef) diff --git a/pypy/jit/backend/llvm/runner.py b/pypy/jit/backend/llvm/runner.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/runner.py +++ /dev/null @@ -1,731 +0,0 @@ -import sys -from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr -from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rlib.objectmodel import we_are_translated, specialize -from pypy.rlib import runicode -from pypy.jit.metainterp.history import AbstractDescr, INT -from pypy.jit.metainterp.history import BoxInt, BoxPtr -from pypy.jit.backend.model import AbstractCPU -from pypy.jit.backend.llvm import llvm_rffi -from pypy.jit.metainterp import history -from pypy.jit.metainterp.resoperation import rop, ResOperation -from pypy.jit.backend.llsupport import symbolic -from pypy.jit.metainterp.typesystem import llhelper - -history.TreeLoop._llvm_compiled_index = -1 - - -class LLVMCPU(object): - ts = llhelper - RAW_VALUE = rffi.CFixedArray(rffi.ULONGLONG, 1) - SIGNED_VALUE = rffi.CFixedArray(lltype.Signed, 1) - POINTER_VALUE = rffi.CFixedArray(llmemory.GCREF, 1) - - SIZE_GCPTR = 0 - SIZE_INT = 1 - SIZE_CHAR = 2 - SIZE_UNICHAR = 3 - - def __init__(self, rtyper, stats=None, translate_support_code=False, - annmixlevel=None, gcdescr=None): - self.rtyper = rtyper - self.translate_support_code = translate_support_code - self.compiled_functions = [] - self.fail_ops = [] - self.in_out_args = [] - if translate_support_code: - get_size = llmemory.sizeof - else: - get_size = rffi.sizeof - self._arraydescrs = [ - ArrayDescr(get_size(llmemory.GCREF), self.SIZE_GCPTR), # 0 - ArrayDescr(get_size(lltype.Signed), self.SIZE_INT), # 1 - ArrayDescr(get_size(lltype.Char), self.SIZE_CHAR), # 2 - ArrayDescr(get_size(lltype.UniChar), self.SIZE_UNICHAR), # 3 - ] - self._descr_caches = {} - self.fielddescr_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr') - if sys.maxint == 2147483647: - self.size_of_int = 4 - else: - self.size_of_int = 8 - if runicode.MAXUNICODE > 0xffff: - self.size_of_unicode = 4 - else: - self.size_of_unicode = 2 - self.gcarray_gcref = lltype.GcArray(llmemory.GCREF) - self.gcarray_signed = lltype.GcArray(lltype.Signed) - self.gcarray_char = lltype.GcArray(lltype.Char) - self.gcarray_unichar = lltype.GcArray(lltype.UniChar) - basesize, _, ofs_length = symbolic.get_array_token( - self.gcarray_signed, self.translate_support_code) - self.array_index_array = basesize - self.array_index_length = ofs_length - basesize, _, ofs_length = symbolic.get_array_token( - rstr.STR, self.translate_support_code) - self.string_index_array = basesize - self.string_index_length = ofs_length - basesize, _, ofs_length = symbolic.get_array_token( - rstr.UNICODE, self.translate_support_code) - self.unicode_index_array = basesize - self.unicode_index_length = ofs_length - self.vtable_descr = self.fielddescrof(rclass.OBJECT, 'typeptr') - self._ovf_error_instance = self._get_prebuilt_error(OverflowError) - self._zer_error_instance = self._get_prebuilt_error(ZeroDivisionError) - # - # temporary (Boehm only) - from pypy.translator.tool.cbuild import ExternalCompilationInfo - compilation_info = ExternalCompilationInfo(libraries=['gc']) - self.malloc_fn_ptr = rffi.llexternal("GC_malloc", - [rffi.SIZE_T], - llmemory.GCREF, - compilation_info=compilation_info, - sandboxsafe=True, - _nowrapper=True) - assert rffi.sizeof(rffi.SIZE_T) == self.size_of_int - - def set_class_sizes(self, class_sizes): - self.class_sizes = class_sizes - - def setup_once(self): - if not we_are_translated(): - llvm_rffi.teardown_now() - llvm_rffi.LLVM_SetFlags() - self.module = llvm_rffi.LLVMModuleCreateWithName("pypyjit") - if self.size_of_int == 4: - self.ty_int = llvm_rffi.LLVMInt32Type() - else: - self.ty_int = llvm_rffi.LLVMInt64Type() - if self.size_of_unicode == 2: - self.ty_unichar = llvm_rffi.LLVMInt16Type() - else: - self.ty_unichar = llvm_rffi.LLVMInt32Type() - self.ty_void = llvm_rffi.LLVMVoidType() - self.ty_bit = llvm_rffi.LLVMInt1Type() - self.ty_char = llvm_rffi.LLVMInt8Type() - self.ty_char_ptr = llvm_rffi.LLVMPointerType(self.ty_char, 0) - self.ty_char_ptr_ptr = llvm_rffi.LLVMPointerType(self.ty_char_ptr, 0) - self.ty_int_ptr = llvm_rffi.LLVMPointerType(self.ty_int, 0) - self.ty_int_ptr_ptr = llvm_rffi.LLVMPointerType(self.ty_int_ptr, 0) - self.ty_unichar_ptr = llvm_rffi.LLVMPointerType(self.ty_unichar, 0) - self.const_zero = self._make_const_int(0) - self.const_one = self._make_const_int(1) - self.const_null_charptr = self._make_const(0, self.ty_char_ptr) - # - from pypy.jit.backend.llvm.compile import LLVMJITCompiler - self.types_by_index = [self.ty_char_ptr, # SIZE_GCPTR - self.ty_int, # SIZE_INT - self.ty_char, # SIZE_CHAR - self.ty_unichar] # SIZE_UNICHAR - self.types_ptr_by_index = [self.ty_char_ptr_ptr, # SIZE_GCPTR - self.ty_int_ptr, # SIZE_INT - self.ty_char_ptr, # SIZE_CHAR - self.ty_unichar_ptr] # SIZE_UNICHAR - self.getarg_by_index = [LLVMJITCompiler.getptrarg, # SIZE_GCPTR - LLVMJITCompiler.getintarg, # SIZE_INT - LLVMJITCompiler.getchararg, # SIZE_CHAR - LLVMJITCompiler.getunichararg] # SIZE_UNICHAR - for i in range(len(self.types_by_index)): - arraydescr = self._arraydescrs[i] - (arraydescr.ty_array_ptr, - self.const_array_index_length, - self.const_array_index_array) = \ - self._build_ty_array_ptr(self.array_index_array, - self.types_by_index[i], - self.array_index_length) - (self.ty_string_ptr, - self.const_string_index_length, - self.const_string_index_array) = \ - self._build_ty_array_ptr(self.string_index_array, - self.ty_char, - self.string_index_length) - (self.ty_unicode_ptr, - self.const_unicode_index_length, - self.const_unicode_index_array) = \ - self._build_ty_array_ptr(self.unicode_index_array, - self.ty_unichar, - self.unicode_index_length) - # - arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), 0, - flavor='raw') - self.ty_func = llvm_rffi.LLVMFunctionType(self.ty_int, arglist, 0, - False) - lltype.free(arglist, flavor='raw') - # - self.f_add_ovf = llvm_rffi.LLVM_Intrinsic_add_ovf(self.module, - self.ty_int) - self.f_sub_ovf = llvm_rffi.LLVM_Intrinsic_sub_ovf(self.module, - self.ty_int) - self.f_mul_ovf = llvm_rffi.LLVM_Intrinsic_mul_ovf(self.module, - self.ty_int) - if we_are_translated(): - addr = llop.get_exception_addr(llmemory.Address) - self.exc_type = rffi.cast(rffi.CArrayPtr(lltype.Signed), addr) - addr = llop.get_exc_value_addr(llmemory.Address) - self.exc_value = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), addr) - else: - self.exc_type = lltype.malloc(rffi.CArray(lltype.Signed), 1, - zero=True, flavor='raw') - self.exc_value = lltype.malloc(rffi.CArray(llmemory.GCREF), 1, - zero=True, flavor='raw') - self.backup_exc_type = lltype.malloc(rffi.CArray(lltype.Signed), 1, - zero=True, flavor='raw') - self.backup_exc_value = lltype.malloc(rffi.CArray(llmemory.GCREF), 1, - zero=True, flavor='raw') - self.const_exc_type = self._make_const(self.exc_type, - self.ty_char_ptr_ptr) - self.const_exc_value = self._make_const(self.exc_value, - self.ty_char_ptr_ptr) - self.const_backup_exc_type = self._make_const(self.backup_exc_type, - self.ty_char_ptr_ptr) - self.const_backup_exc_value = self._make_const(self.backup_exc_value, - self.ty_char_ptr_ptr) - # - self._setup_prebuilt_error('ovf') - self._setup_prebuilt_error('zer') - # - # temporary (Boehm only) - param_types = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), 1, - flavor='raw') - param_types[0] = self.ty_int - self.ty_malloc_fn = llvm_rffi.LLVMPointerType( - llvm_rffi.LLVMFunctionType(self.ty_char_ptr, param_types, 1, 0), - 0) - lltype.free(param_types, flavor='raw') - # - self.ee = llvm_rffi.LLVM_EE_Create(self.module) - if not we_are_translated(): - llvm_rffi.set_teardown_function(self._teardown) - - def _teardown(self): - llvm_rffi.LLVMDisposeExecutionEngine(self.ee) - - def _get_prebuilt_error(self, Class): - "NOT_RPYTHON" - if self.rtyper is not None: # normal case - bk = self.rtyper.annotator.bookkeeper - clsdef = bk.getuniqueclassdef(Class) - ll_inst = self.rtyper.exceptiondata.get_standard_ll_exc_instance( - self.rtyper, clsdef) - else: - # for tests, a random emulated ll_inst will do - ll_inst = lltype.malloc(rclass.OBJECT) - ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, - immortal=True) - return ll_inst - - @specialize.arg(1) - def _setup_prebuilt_error(self, prefix): - ll_inst = getattr(self, '_' + prefix + '_error_instance') - setattr(self, '_' + prefix + '_error_type', - rffi.cast(lltype.Signed, ll_inst.typeptr)) - setattr(self, '_' + prefix + '_error_value', - lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst)) - setattr(self, 'const_' + prefix + '_error_type', - self._make_const(ll_inst.typeptr, self.ty_char_ptr)) - setattr(self, 'const_' + prefix + '_error_value', - self._make_const(ll_inst, self.ty_char_ptr)) - - def _build_ty_array_ptr(self, basesize, ty_item, ofs_length): - pad1 = ofs_length - pad2 = basesize - ofs_length - self.size_of_int - assert pad1 >= 0 and pad2 >= 0 - const_index_length = self._make_const_int(pad1) - const_index_array = self._make_const_int(pad1 + 1 + pad2) - # build the type "struct{pad1.., length, pad2.., array{type}}" - typeslist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), - pad1+pad2+2, flavor='raw') - # add the first padding - for n in range(pad1): - typeslist[n] = self.ty_char - # add the length field - typeslist[pad1] = self.ty_int - # add the second padding - for n in range(pad1+1, pad1+1+pad2): - typeslist[n] = self.ty_char - # add the array field - typeslist[pad1+1+pad2] = llvm_rffi.LLVMArrayType(ty_item, 0) - # done - ty_array = llvm_rffi.LLVMStructType(typeslist, - pad1+pad2+2, - 1) - lltype.free(typeslist, flavor='raw') - ty_array_ptr = llvm_rffi.LLVMPointerType(ty_array, 0) - return (ty_array_ptr, const_index_length, const_index_array) - - # ------------------------------ - # Compilation - - def compile_operations(self, loop, _guard_op=None): - from pypy.jit.backend.llvm.compile import LLVMJITCompiler - compiler = LLVMJITCompiler(self, loop) - compiler.compile() - - def _ensure_in_args(self, count): - while len(self.in_out_args) < count: - self.in_out_args.append(lltype.malloc(self.RAW_VALUE, flavor='raw')) - - _ensure_out_args = _ensure_in_args - - def _make_const_int(self, value): - return llvm_rffi.LLVMConstInt(self.ty_int, value, True) - - def _make_const_char(self, value): - assert (value & ~255) == 0, "value is not in range(256)" - return llvm_rffi.LLVMConstInt(self.ty_char, value, True) - - def _make_const_unichar(self, value): - #xxx assert something about 'value' - return llvm_rffi.LLVMConstInt(self.ty_unichar, value, True) - - def _make_const_bit(self, value): - assert (value & ~1) == 0, "value is not 0 or 1" - return llvm_rffi.LLVMConstInt(self.ty_bit, value, True) - - @specialize.arglltype(1) - def _make_const(self, value, ty_result): - value_as_signed = rffi.cast(lltype.Signed, value) - llvmconstint = self._make_const_int(value_as_signed) - llvmconstptr = llvm_rffi.LLVMConstIntToPtr(llvmconstint, ty_result) - return llvmconstptr - - def _get_var_type(self, v): - if v.type == INT: - return self.ty_int - else: - return self.ty_char_ptr - - def _get_pointer_type(self, v): - if v.type == INT: - return self.ty_int_ptr - else: - return self.ty_char_ptr_ptr - - # ------------------------------ - # Execution - - def set_future_value_int(self, index, intvalue): - p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index]) - p[0] = intvalue - - def set_future_value_ref(self, index, ptrvalue): - p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index]) - p[0] = ptrvalue - - def execute_operations(self, loop): - index = loop._llvm_compiled_index - assert index >= 0 - while True: - func_ptr = self.compiled_functions[index] - print 'execute_operations: %d (at 0x%x)' % ( - index, rffi.cast(lltype.Signed, func_ptr)) - index = func_ptr() - print '\t--->', index - if index < 0: - break - return self.fail_ops[~index] - - def get_latest_value_int(self, index): - p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index]) - return p[0] - - def get_latest_value_ref(self, index): - p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index]) - return p[0] - - def get_exception(self): - return self.backup_exc_type[0] - - def get_exc_value(self): - return self.backup_exc_value[0] - - def clear_exception(self): - self.backup_exc_type[0] = 0 - self.backup_exc_value[0] = lltype.nullptr(llmemory.GCREF.TO) - - # XXX wrong, but untested - - def set_overflow_error(self): - self.backup_exc_type[0] = self._ovf_error_type - self.backup_exc_value[0] = self._ovf_error_value - - def set_zero_division_error(self): - self.backup_exc_type[0] = self._zer_error_type - self.backup_exc_value[0] = self._zer_error_value - - @staticmethod - def cast_adr_to_int(x): - return rffi.cast(lltype.Signed, x) - - @staticmethod - def cast_int_to_adr(x): - assert x == 0 or x > (1<<20) or x < (-1<<20) - if we_are_translated(): - return rffi.cast(llmemory.Address, x) - else: - # indirect casting because the above doesn't work with ll2ctypes - return llmemory.cast_ptr_to_adr(rffi.cast(llmemory.GCREF, x)) - - def _get_size_index(self, TYPE): - if isinstance(TYPE, lltype.Ptr): - if TYPE.TO._gckind == 'gc': - return self.SIZE_GCPTR - else: - return self.SIZE_INT - else: - if TYPE == lltype.Signed or TYPE == lltype.Unsigned: - return self.SIZE_INT - elif TYPE == lltype.Char or TYPE == lltype.Bool: - return self.SIZE_CHAR - elif TYPE == lltype.UniChar: - return self.SIZE_UNICHAR - else: - raise BadSizeError(TYPE) - - def sizeof(self, S): - try: - return self._descr_caches['size', S] - except KeyError: - pass - descr = SizeDescr(symbolic.get_size(S, self.translate_support_code)) - self._descr_caches['size', S] = descr - return descr - - def fielddescrof(self, S, fieldname): - try: - return self._descr_caches['field', S, fieldname] - except KeyError: - pass - ofs, _ = symbolic.get_field_token(S, fieldname, - self.translate_support_code) - size_index = self._get_size_index(getattr(S, fieldname)) - descr = FieldDescr(ofs, size_index) - self._descr_caches['field', S, fieldname] = descr - return descr - - def arraydescrof(self, A): - basesize, _, ofs_length = symbolic.get_array_token(A, - self.translate_support_code) - if isinstance(basesize, int): # else Symbolics, can't be compared... - assert self.array_index_array == basesize - assert self.array_index_length == ofs_length - itemsize_index = self._get_size_index(A.OF) - return self._arraydescrs[itemsize_index] - - def calldescrof(self, FUNC, ARGS, RESULT): - args_indices = [self._get_size_index(ARG) for ARG in ARGS] - if RESULT is lltype.Void: - res_index = -1 - else: - res_index = self._get_size_index(RESULT) - # - key = ('call', tuple(args_indices), res_index) - try: - descr = self._descr_caches[key] - except KeyError: - descr = CallDescr(args_indices, res_index) - self._descr_caches[key] = descr - return descr - - def get_calldescr_ty_function_ptr(self, calldescr): - if not calldescr.ty_function_ptr: - # - args_indices = calldescr.args_indices - param_types = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), - len(args_indices), flavor='raw') - for i in range(len(args_indices)): - param_types[i] = self.types_by_index[args_indices[i]] - # - res_index = calldescr.res_index - if res_index < 0: - ty_result = self.ty_void - else: - ty_result = self.types_by_index[res_index] - # - ty_func = llvm_rffi.LLVMFunctionType(ty_result, param_types, - len(args_indices), 0) - lltype.free(param_types, flavor='raw') - ty_funcptr = llvm_rffi.LLVMPointerType(ty_func, 0) - calldescr.ty_function_ptr = ty_funcptr - # - return calldescr.ty_function_ptr - - # ------------------------------ - # do_xxx methods - - def do_arraylen_gc(self, args, arraydescr): - array = args[0].getref_base() - p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) - res = len(p) - return BoxInt(res) - - def do_strlen(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) - res = len(p.chars) - return BoxInt(res) - - def do_strgetitem(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s) - res = ord(p.chars[args[1].getint()]) - return BoxInt(res) - - def do_unicodelen(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) - res = len(p.chars) - return BoxInt(res) - - def do_unicodegetitem(self, args, descr=None): - s = args[0].getref_base() - p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s) - res = ord(p.chars[args[1].getint()]) - return BoxInt(res) - - def do_getarrayitem_gc(self, args, arraydescr): - array = args[0].getref_base() - index = args[1].getint() - assert isinstance(arraydescr, ArrayDescr) - itemsize_index = arraydescr.itemsize_index - if itemsize_index == self.SIZE_GCPTR: - p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) - res = p[index] - return BoxPtr(res) - elif itemsize_index == self.SIZE_INT: - p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) - res = p[index] - elif itemsize_index == self.SIZE_CHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_char), array) - res = ord(p[index]) - elif itemsize_index == self.SIZE_UNICHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_unichar), array) - res = ord(p[index]) - else: - raise BadSizeError - return BoxInt(res) - - @specialize.argtype(1) - def _do_getfield(self, struct, fielddescr): - assert isinstance(fielddescr, FieldDescr) - size_index = fielddescr.size_index - if size_index == self.SIZE_GCPTR: - p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct) - res = p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] - return BoxPtr(res) - elif size_index == self.SIZE_INT: - p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct) - res = p[fielddescr.offset / rffi.sizeof(lltype.Signed)] - elif size_index == self.SIZE_CHAR: - p = rffi.cast(rffi.CArrayPtr(lltype.Char), struct) - res = ord(p[fielddescr.offset / rffi.sizeof(lltype.Char)]) - elif size_index == self.SIZE_UNICHAR: - p = rffi.cast(rffi.CArrayPtr(lltype.UniChar), struct) - res = ord(p[fielddescr.offset / rffi.sizeof(lltype.UniChar)]) - else: - raise BadSizeError - return BoxInt(res) - - def do_getfield_gc(self, args, fielddescr): - struct = args[0].getref_base() - return self._do_getfield(struct, fielddescr) - - def do_getfield_raw(self, args, fielddescr): - struct = args[0].getaddr(self) - return self._do_getfield(struct, fielddescr) - - def do_new(self, args, sizedescr): - assert isinstance(sizedescr, SizeDescr) - res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, sizedescr.size)) - return BoxPtr(res) - - def do_new_with_vtable(self, args, descr=None): - assert descr is None - sizedescr = self.class_sizes[args[0].getint()] - res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, sizedescr.size)) - self._do_setfield(res, args[0], self.vtable_descr) - return BoxPtr(res) - - def _allocate_new_array(self, args, item_size, index_array, index_length): - length = args[0].getint() - #try: - size = index_array + length * item_size - #except OverflowError: - # ... - res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, size)) - p = rffi.cast(rffi.CArrayPtr(lltype.Signed), res) - p[index_length / rffi.sizeof(lltype.Signed)] = length - return BoxPtr(res) - - def do_new_array(self, args, arraydescr): - assert isinstance(arraydescr, ArrayDescr) - return self._allocate_new_array(args, arraydescr.itemsize, - self.array_index_array, - self.array_index_length) - - def do_setarrayitem_gc(self, args, arraydescr): - array = args[0].getref_base() - index = args[1].getint() - assert isinstance(arraydescr, ArrayDescr) - itemsize_index = arraydescr.itemsize_index - if itemsize_index == self.SIZE_GCPTR: - p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array) - res = args[2].getref_base() - p[index] = res - elif itemsize_index == self.SIZE_INT: - p = rffi.cast(lltype.Ptr(self.gcarray_signed), array) - res = args[2].getint() - p[index] = res - elif itemsize_index == self.SIZE_CHAR: - p = rffi.cast(lltype.Ptr(self.gcarray_char), array) From noreply at buildbot.pypy.org Fri Oct 19 13:39:51 2012 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 19 Oct 2012 13:39:51 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: disallow ufuncs, binfuncs, operators on flexible types, start to test repr() Message-ID: <20121019113951.C48701C0012@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-problems Changeset: r58241:45b875bca4f1 Date: 2012-10-19 11:42 +0200 http://bitbucket.org/pypy/pypy/changeset/45b875bca4f1/ Log: disallow ufuncs, binfuncs, operators on flexible types, start to test repr() diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -62,6 +62,7 @@ 'flexible': 'interp_boxes.W_FlexibleBox', 'character': 'interp_boxes.W_CharacterBox', 'str_': 'interp_boxes.W_StringBox', + 'string_': 'interp_boxes.W_StringBox', 'unicode_': 'interp_boxes.W_UnicodeBox', 'void': 'interp_boxes.W_VoidBox', 'complexfloating': 'interp_boxes.W_ComplexFloatingBox', 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 @@ -143,6 +143,9 @@ def is_record_type(self): return self.fields is not None + def is_flexible_type(self): + return (self.num == 18 or self.num == 19 or self.num == 20) + def __repr__(self): if self.fields is not None: return '' % self.fields 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 @@ -150,6 +150,9 @@ "supported for binary functions")) assert isinstance(self, W_Ufunc2) obj = convert_to_array(space, w_obj) + if obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('cannot perform reduce for flexible type')) obj_shape = obj.get_shape() if obj.is_scalar(): return obj.get_scalar_value() @@ -235,6 +238,9 @@ if space.is_w(out, space.w_None): out = None w_obj = convert_to_array(space, w_obj) + if w_obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('Not implemented for this type')) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -301,6 +307,10 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) + if w_lhs.get_dtype().is_flexible_type() or \ + w_rhs.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('unsupported operand types')) calc_dtype = find_binop_result_dtype(space, w_lhs.get_dtype(), w_rhs.get_dtype(), int_only=self.int_only, 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 @@ -2249,18 +2249,30 @@ def test_stringarray(self): from _numpypy import array a = array(['abc'],'S3') - assert repr(a) == "array(['abc'])" assert str(a.dtype) == '|S3' a = array(['abc']) - assert repr(a) == "array(['abc'])" assert str(a.dtype) == '|S3' a = array(['abc','defg','ab']) assert str(a.dtype) == '|S4' assert a[0] == 'abc' assert a[1] == 'defg' assert a[2] == 'ab' - assert repr(a) == "array(['abc', 'defg', 'ab'])" + raises(TypeError, a, 'sum') + raises(TypeError, 'a+a') + def test_flexible_repr(self): + # import overrides str(), repr() for array + from numpypy.core import arrayprint + from _numpypy import array + a = array(['abc'],'S3') + s = repr(a) + # simplify \n in repr + assert s.replace('\n', '') == "array(['abc'], dtype='|S3')" + a = array(['abc','defg','ab']) + s = repr(a) + assert s.replace('\n', '') == \ + "array(['abc', 'defg', 'ab'], dtype='|S4')" + class AppTestPyPy(BaseNumpyAppTest): def setup_class(cls): From noreply at buildbot.pypy.org Fri Oct 19 13:39:52 2012 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 19 Oct 2012 13:39:52 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: test, fix repr() for StringArray Message-ID: <20121019113952.F103B1C0012@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-problems Changeset: r58242:cfa9c1076990 Date: 2012-10-19 13:09 +0200 http://bitbucket.org/pypy/pypy/changeset/cfa9c1076990/ Log: test, fix repr() for StringArray diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,5 +1,5 @@ -from _numpypy import array, ndarray, int_, float_, bool_ #, complex_# , longlong +from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math @@ -200,7 +200,7 @@ typename = "'%s'" % typename lf = '' - if 0: # or issubclass(arr.dtype.type, flexible): + if issubclass(arr.dtype.type, flexible): if arr.dtype.names: typename = "%s" % str(arr.dtype) else: 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 @@ -2247,7 +2247,7 @@ assert a[0]['x'] == 'a' def test_stringarray(self): - from _numpypy import array + from _numpypy import array, flexible a = array(['abc'],'S3') assert str(a.dtype) == '|S3' a = array(['abc']) @@ -2266,8 +2266,10 @@ from _numpypy import array a = array(['abc'],'S3') s = repr(a) - # simplify \n in repr + # simplify test for \n in repr assert s.replace('\n', '') == "array(['abc'], dtype='|S3')" + # but make sure it exists + assert s.find('\n') == 15 a = array(['abc','defg','ab']) s = repr(a) assert s.replace('\n', '') == \ From noreply at buildbot.pypy.org Fri Oct 19 14:05:31 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Fri, 19 Oct 2012 14:05:31 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: intro to demo Message-ID: <20121019120531.B032C1C00FA@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: extradoc Changeset: r4886:a5576fd34d4f Date: 2012-10-19 14:05 +0200 http://bitbucket.org/pypy/extradoc/changeset/a5576fd34d4f/ Log: intro to demo diff --git a/talk/dls2012/presentation/talk.tex b/talk/dls2012/presentation/talk.tex --- a/talk/dls2012/presentation/talk.tex +++ b/talk/dls2012/presentation/talk.tex @@ -17,11 +17,32 @@ \usepackage[english]{babel} +\usepackage{fancyvrb} \usepackage{listings} \usepackage{ulem} \usepackage{color} \usepackage{alltt} + +\usepackage[T1]{fontenc} +\usepackage{setspace} +\usepackage[scaled=0.81]{beramono} +\definecolor{gray}{rgb}{0.3,0.3,0.3} + +\lstset{ + basicstyle=\setstretch{1.05}\ttfamily\footnotesize, + language=Python, + keywordstyle=\bfseries, + stringstyle=\color{blue}, + commentstyle=\color{gray}\textit, + fancyvrb=true, + showstringspaces=false, + %keywords={def,while,if,elif,return,class,get,set,new,guard_class} + numberstyle = \tiny, + numbersep = -20pt, +} + + \usepackage[utf8x]{inputenc} @@ -140,5 +161,68 @@ \end{itemize} \end{frame} +\begin{frame} + \frametitle{Demo} + \vfill + \begin{itemize} + \item Video analytics research example + \item Experimenten driven + \item Custom loops over the pixels + \item Good enough performace + \end{itemize} + \vfill + \begin{itemize} + \item Image class with task specific features + \begin{itemize} + \item Zero-padded + \item Clips updates within border + \end{itemize} + \item @autoreload decorator reloading functions on code change + \item ReloadHack class reloads and reinstanciates on code change + \end{itemize} + \vfill +\end{frame} + +\begin{frame}[fragile] + \frametitle{Image class} +\begin{lstlisting}[mathescape,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] +class Image(object): + def __getitem__(self, (x, y)): + if 0 <= x < self.width and 0 <= y < self.height: + return self.data[y * self.width + x] + return 0 + + def __setitem__(self, (x, y), value): + if 0 <= x < self.width and 0 <= y < self.height: + self.data[y * self.width + x] = value + + __add__ = binop(float.__add__) + __sub__ = binop(float.__sub__) + __mul__ = binop(float.__mul__) + __div__ = binop(float.__div__) + __pow__ = binop(float.__pow__) + + ... +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Image class} +\begin{lstlisting}[mathescape,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] +def binop(op): + def f(a, b): + if not isinstance(a, Image): + a = ConstantImage(b.width, b.height, a) + if not isinstance(b, Image): + b = ConstantImage(a.width, a.height, b) + + out = a.new(typecode='d') + for x, y in a.indexes(): + out[x, y] = op(float(a[x, y]), float(b[x, y])) + + return out + return f +\end{lstlisting} +\end{frame} \end{document} From noreply at buildbot.pypy.org Fri Oct 19 14:20:12 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Fri, 19 Oct 2012 14:20:12 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: clenaups Message-ID: <20121019122012.684FA1C00FA@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: extradoc Changeset: r4887:52354174c76a Date: 2012-10-19 14:20 +0200 http://bitbucket.org/pypy/extradoc/changeset/52354174c76a/ Log: clenaups diff --git a/talk/dls2012/presentation/talk.tex b/talk/dls2012/presentation/talk.tex --- a/talk/dls2012/presentation/talk.tex +++ b/talk/dls2012/presentation/talk.tex @@ -166,7 +166,7 @@ \vfill \begin{itemize} \item Video analytics research example - \item Experimenten driven + \item Experimenten driven - prototyping \item Custom loops over the pixels \item Good enough performace \end{itemize} @@ -175,7 +175,7 @@ \item Image class with task specific features \begin{itemize} \item Zero-padded - \item Clips updates within border + \item Clips updates outside border \end{itemize} \item @autoreload decorator reloading functions on code change \item ReloadHack class reloads and reinstanciates on code change From noreply at buildbot.pypy.org Fri Oct 19 15:51:15 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 19 Oct 2012 15:51:15 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix for the warning "exceptblock is not completely sane". Message-ID: <20121019135115.49FC01C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58243:7df4e80ad524 Date: 2012-10-19 15:50 +0200 http://bitbucket.org/pypy/pypy/changeset/7df4e80ad524/ Log: Fix for the warning "exceptblock is not completely sane". diff --git a/pypy/translator/goal/query.py b/pypy/translator/goal/query.py --- a/pypy/translator/goal/query.py +++ b/pypy/translator/goal/query.py @@ -49,7 +49,7 @@ s_ev = annotator.binding(ev, None) if s_et: if s_et.knowntype == type: - if s_et.__class__ == annmodel.SomeObject: + if s_et.__class__ == annmodel.SomeType: if hasattr(s_et, 'is_type_of') and s_et.is_type_of == [ev]: continue else: From noreply at buildbot.pypy.org Fri Oct 19 17:04:13 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 19 Oct 2012 17:04:13 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Fixes Message-ID: <20121019150413.0DC7C1C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58244:c88aa317024c Date: 2012-10-19 16:39 +0200 http://bitbucket.org/pypy/pypy/changeset/c88aa317024c/ Log: Fixes diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -236,10 +236,21 @@ return frame.latest_descr def get_finish_value_int(self, frame): - return frame.finish_value + res = frame.finish_value + del frame.finish_value + return res get_finish_value_float = get_finish_value_int get_finish_value_ref = get_finish_value_int + def grab_exc_value(self, frame): + if frame.last_exception is not None: + result = frame.last_exception.args[1] + gcref = lltype.cast_opaque_ptr(llmemory.GCREF, result) + else: + gcref = lltype.nullptr(llmemory.GCREF.TO) + frame.last_exception = None + return gcref + def force(self, frame): assert not frame._forced frame._forced = True @@ -547,6 +558,7 @@ _forced = False _execution_finished = False + finish_value = None def __init__(self, cpu, argboxes, args): self.env = {} @@ -633,14 +645,7 @@ # ----------------------------------------------------- - def fail_guard(self, descr, saveexc=False): - if saveexc: - if self.last_exception is not None: - result = self.last_exception.args[1] - gcref = lltype.cast_opaque_ptr(llmemory.GCREF, result) - else: - gcref = lltype.nullptr(llmemory.GCREF.TO) - self.finish_value = gcref + def fail_guard(self, descr): raise GuardFailed(self._getfailargs(), descr) def execute_finish(self, descr, arg=None): @@ -688,7 +693,7 @@ def execute_guard_no_exception(self, descr): if self.last_exception is not None: - self.fail_guard(descr, saveexc=True) + self.fail_guard(descr) def execute_guard_exception(self, descr, excklass): lle = self.last_exception @@ -700,7 +705,7 @@ llmemory.cast_int_to_adr(excklass), rclass.CLASSTYPE) if gotklass != excklass: - self.fail_guard(descr, saveexc=True) + self.fail_guard(descr) # res = lle.args[1] self.last_exception = None diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -1419,7 +1419,7 @@ opnum == rop.GUARD_EXCEPTION or opnum == rop.GUARD_NOT_FORCED): return lltype.cast_opaque_ptr(rclass.OBJECTPTR, - self.cpu.get_finish_value_ref(jitframe)) + self.cpu.grab_exc_value(jitframe)) # elif opnum == rop.GUARD_NO_OVERFLOW: # Produced by int_xxx_ovf(). The pc is just after the opcode. diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -2109,7 +2109,7 @@ opnum == rop.GUARD_NONNULL_CLASS): pass # the pc is already set to the *start* of the opcode elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION: - exception = self.cpu.get_finish_value_ref(jitframe) + exception = self.cpu.grab_exc_value(jitframe) if exception: self.execute_ll_raised(lltype.cast_opaque_ptr(rclass.OBJECTPTR, exception)) From noreply at buildbot.pypy.org Fri Oct 19 17:04:14 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 19 Oct 2012 17:04:14 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (arigo, fijal) Fix. Armin says "the x86 backend will require hacks straight Message-ID: <20121019150414.362A31C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58245:6c873fb3754b Date: 2012-10-19 17:03 +0200 http://bitbucket.org/pypy/pypy/changeset/6c873fb3754b/ Log: (arigo, fijal) Fix. Armin says "the x86 backend will require hacks straight from the 80s" diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -217,7 +217,7 @@ frame.finish_value = e.arg frame.latest_values = e.failargs frame.latest_descr = e.descr - frame._execution_finished = True + frame._execution_finished_normally = e.descr.fast_path_done return frame except GuardFailed, e: frame.latest_values = e.failargs @@ -557,7 +557,7 @@ return isinstance(other, LLFrame) and self is other _forced = False - _execution_finished = False + _execution_finished_normally = False finish_value = None def __init__(self, cpu, argboxes, args): @@ -797,7 +797,7 @@ def execute_call_assembler(self, descr, *args): frame = self.cpu._execute_token(descr, *args) - if frame._execution_finished: # fast path + if frame._execution_finished_normally: # fast path return frame.finish_value jd = descr.outermost_jitdriver_sd assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -734,15 +734,19 @@ metainterp_sd.stats.add_jitcell_token(jitcell_token) -_DoneWithThisFrameDescr = ResumeGuardForcedDescr # XXX replace me +_DoneWithThisFrameDescr = ResumeGuardForcedDescr # XXX class DoneWithThisFrameDescrVoid(_DoneWithThisFrameDescr): + fast_path_done = True + def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): assert jitdriver_sd is self.jitdriver_sd assert jitdriver_sd.result_type == history.VOID raise metainterp_sd.DoneWithThisFrameVoid() class DoneWithThisFrameDescrInt(_DoneWithThisFrameDescr): + fast_path_done = True + def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): assert jitdriver_sd is self.jitdriver_sd assert jitdriver_sd.result_type == history.INT @@ -750,6 +754,8 @@ raise metainterp_sd.DoneWithThisFrameInt(result) class DoneWithThisFrameDescrRef(_DoneWithThisFrameDescr): + fast_path_done = True + def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): assert jitdriver_sd is self.jitdriver_sd assert jitdriver_sd.result_type == history.REF @@ -758,6 +764,8 @@ raise metainterp_sd.DoneWithThisFrameRef(cpu, result) class DoneWithThisFrameDescrFloat(_DoneWithThisFrameDescr): + fast_path_done = True + def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): assert jitdriver_sd is self.jitdriver_sd assert jitdriver_sd.result_type == history.FLOAT diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py --- a/pypy/jit/metainterp/history.py +++ b/pypy/jit/metainterp/history.py @@ -140,6 +140,8 @@ class AbstractDescr(AbstractValue): __slots__ = () + fast_path_done = False + def repr_of_descr(self): return '%r' % (self,) From noreply at buildbot.pypy.org Fri Oct 19 17:14:01 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 19 Oct 2012 17:14:01 +0200 (CEST) Subject: [pypy-commit] pypy py3k: revert 8617a5ed3187 and fix it by actually returning NotImplemented from complex.__lt__&co. Not sure this is the 100% right way to do it, but it seems to do the job Message-ID: <20121019151401.C24D41C0012@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58246:dd6debeadbe9 Date: 2012-10-19 17:13 +0200 http://bitbucket.org/pypy/pypy/changeset/dd6debeadbe9/ Log: revert 8617a5ed3187 and fix it by actually returning NotImplemented from complex.__lt__&co. Not sure this is the 100% right way to do it, but it seems to do the job diff --git a/lib-python/3.2/test/test_complex.py b/lib-python/3.2/test/test_complex.py --- a/lib-python/3.2/test/test_complex.py +++ b/lib-python/3.2/test/test_complex.py @@ -123,11 +123,10 @@ self.assertIs(complex.__ne__(f+0j, f), False) self.assertIs(complex.__eq__(complex(f, f), f), False) self.assertIs(complex.__ne__(complex(f, f), f), True) - if support.check_impl_detail(pypy=False): - self.assertIs(complex.__lt__(1+1j, 2+2j), NotImplemented) - self.assertIs(complex.__le__(1+1j, 2+2j), NotImplemented) - self.assertIs(complex.__gt__(1+1j, 2+2j), NotImplemented) - self.assertIs(complex.__ge__(1+1j, 2+2j), NotImplemented) + self.assertIs(complex.__lt__(1+1j, 2+2j), NotImplemented) + self.assertIs(complex.__le__(1+1j, 2+2j), NotImplemented) + self.assertIs(complex.__gt__(1+1j, 2+2j), NotImplemented) + self.assertIs(complex.__ge__(1+1j, 2+2j), NotImplemented) self.assertRaises(TypeError, operator.lt, 1+1j, 2+2j) self.assertRaises(TypeError, operator.le, 1+1j, 2+2j) self.assertRaises(TypeError, operator.gt, 1+1j, 2+2j) diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -201,7 +201,8 @@ return ne__Complex_Long(space, w_complex2, w_long1) def lt__Complex_Complex(space, w_complex1, w_complex2): - raise OperationError(space.w_TypeError, space.wrap('cannot compare complex numbers using <, <=, >, >=')) + from pypy.objspace.std.model import FailedToImplement + raise FailedToImplement gt__Complex_Complex = lt__Complex_Complex ge__Complex_Complex = lt__Complex_Complex diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -169,15 +169,20 @@ raises(TypeError, "3+0j // 0+0j") def test_richcompare(self): + import operator assert complex.__lt__(1+1j, None) is NotImplemented assert complex.__eq__(1+1j, 2+2j) is False assert complex.__eq__(1+1j, 1+1j) is True assert complex.__ne__(1+1j, 1+1j) is False assert complex.__ne__(1+1j, 2+2j) is True - raises(TypeError, complex.__lt__, 1+1j, 2+2j) - raises(TypeError, complex.__le__, 1+1j, 2+2j) - raises(TypeError, complex.__gt__, 1+1j, 2+2j) - raises(TypeError, complex.__ge__, 1+1j, 2+2j) + assert complex.__lt__(1+1j, 2+2j) is NotImplemented + assert complex.__le__(1+1j, 2+2j) is NotImplemented + assert complex.__gt__(1+1j, 2+2j) is NotImplemented + assert complex.__ge__(1+1j, 2+2j) is NotImplemented + raises(TypeError, operator.lt, 1+1j, 2+2j) + raises(TypeError, operator.le, 1+1j, 2+2j) + raises(TypeError, operator.gt, 1+1j, 2+2j) + raises(TypeError, operator.ge, 1+1j, 2+2j) large = 1 << 10000 assert not (5+0j) == large assert not large == (5+0j) From noreply at buildbot.pypy.org Fri Oct 19 17:23:24 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 19 Oct 2012 17:23:24 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Don't bother with OperationError Message-ID: <20121019152324.D3A991C0012@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58247:78e064874855 Date: 2012-10-19 03:14 +0100 http://bitbucket.org/pypy/pypy/changeset/78e064874855/ Log: Don't bother with OperationError None of the relevant objspaces raise or catch them so just let exceptions and raise real ones when needed. + cleanup JIT leftovers diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -2,11 +2,6 @@ Arguments objects. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.rlib.debug import make_sure_not_resized -from pypy.rlib import jit - - class Signature(object): _immutable_ = True _immutable_fields_ = ["argnames[*]"] @@ -17,7 +12,6 @@ self.varargname = varargname self.kwargname = kwargname - @jit.elidable def find_argname(self, name): try: return self.argnames.index(name) @@ -84,41 +78,18 @@ # arguments annoying :-( def _check_not_duplicate_kwargs(space, existingkeywords, keywords, keywords_w): - # looks quadratic, but the JIT should remove all of it nicely. - # Also, all the lists should be small for key in keywords: - for otherkey in existingkeywords: - if otherkey == key: - raise operationerrfmt(space.w_TypeError, - "got multiple values " - "for keyword argument " - "'%s'", key) + if key in existingkeywords: + raise TypeError("got multiple values for keyword argument '%s'", key) def _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords, keywords_w, existingkeywords): - i = 0 - for w_key in keys_w: - try: - key = space.str_w(w_key) - except OperationError, e: - if e.match(space, space.w_TypeError): - raise OperationError( - space.w_TypeError, - space.wrap("keywords must be strings")) - if e.match(space, space.w_UnicodeEncodeError): - # Allow this to pass through - key = None - else: - raise - else: - if existingkeywords and key in existingkeywords: - raise operationerrfmt(space.w_TypeError, - "got multiple values " - "for keyword argument " - "'%s'", key) + for i, w_key in enumerate(keys_w): + key = space.str_w(w_key) + if existingkeywords and key in existingkeywords: + raise TypeError("got multiple values for keyword argument '%s'" % key) keywords[i] = key keywords_w[i] = space.getitem(w_starstararg, w_key) - i += 1 def _match_keywords(signature, input_argcount, keywords, kwds_mapping): # letting JIT unroll the loop is *only* safe if the callsite didn't @@ -191,17 +162,7 @@ def _combine_starargs_wrapped(self, w_stararg): # unpack the * arguments space = self.space - try: - args_w = space.fixedview(w_stararg) - except OperationError, e: - if e.match(space, space.w_TypeError): - w_type = space.type(w_stararg) - typename = w_type.getname(space) - raise OperationError( - space.w_TypeError, - space.wrap("argument after * must be " - "a sequence, not %s" % (typename,))) - raise + args_w = space.fixedview(w_stararg) self.arguments_w = self.arguments_w + args_w def _combine_starstarargs_wrapped(self, w_starstararg): @@ -221,21 +182,12 @@ if space.isinstance_w(w_starstararg, space.w_dict): keys_w = space.unpackiterable(w_starstararg) else: - try: - w_keys = space.call_method(w_starstararg, "keys") - except OperationError, e: - if e.match(space, space.w_AttributeError): - w_type = space.type(w_starstararg) - typename = w_type.getname(space) - raise OperationError( - space.w_TypeError, - space.wrap("argument after ** must be " - "a mapping, not %s" % (typename,))) - raise + w_keys = space.call_method(w_starstararg, "keys") keys_w = space.unpackiterable(w_keys) keywords_w = [None] * len(keys_w) keywords = [None] * len(keys_w) - _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords, keywords_w, self.keywords) + _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, + keywords, keywords_w, self.keywords) self.keyword_names_w = keys_w if self.keywords is None: self.keywords = keywords From noreply at buildbot.pypy.org Fri Oct 19 17:23:26 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 19 Oct 2012 17:23:26 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Inline 2 helpers Message-ID: <20121019152326.1005C1C0012@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58248:c2825f821cd1 Date: 2012-10-19 03:28 +0100 http://bitbucket.org/pypy/pypy/changeset/c2825f821cd1/ Log: Inline 2 helpers diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -77,20 +77,6 @@ # look at. They should not get a self arguments, which makes the amount of # arguments annoying :-( -def _check_not_duplicate_kwargs(space, existingkeywords, keywords, keywords_w): - for key in keywords: - if key in existingkeywords: - raise TypeError("got multiple values for keyword argument '%s'", key) - -def _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords, - keywords_w, existingkeywords): - for i, w_key in enumerate(keys_w): - key = space.str_w(w_key) - if existingkeywords and key in existingkeywords: - raise TypeError("got multiple values for keyword argument '%s'" % key) - keywords[i] = key - keywords_w[i] = space.getitem(w_starstararg, w_key) - def _match_keywords(signature, input_argcount, keywords, kwds_mapping): # letting JIT unroll the loop is *only* safe if the callsite didn't # use **args because num_kwds can be arbitrarily large otherwise. @@ -174,8 +160,8 @@ self.keywords = keywords self.keywords_w = values_w else: - _check_not_duplicate_kwargs( - self.space, self.keywords, keywords, values_w) + if set(keywords) & set(self.keywords): + raise TypeError("got multiple values for keyword argument '%s'", key) self.keywords = self.keywords + keywords self.keywords_w = self.keywords_w + values_w return @@ -186,8 +172,12 @@ keys_w = space.unpackiterable(w_keys) keywords_w = [None] * len(keys_w) keywords = [None] * len(keys_w) - _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, - keywords, keywords_w, self.keywords) + for i, w_key in enumerate(keys_w): + key = space.str_w(w_key) + if key in self.keywords: + raise TypeError("got multiple values for keyword argument '%s'" % key) + keywords[i] = key + keywords_w[i] = space.getitem(w_starstararg, w_key) self.keyword_names_w = keys_w if self.keywords is None: self.keywords = keywords From noreply at buildbot.pypy.org Fri Oct 19 17:23:27 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 19 Oct 2012 17:23:27 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Inline remaining helpers (don't hide away the side-effects) Message-ID: <20121019152327.317FC1C0012@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58249:9a05448ca146 Date: 2012-10-19 03:49 +0100 http://bitbucket.org/pypy/pypy/changeset/9a05448ca146/ Log: Inline remaining helpers (don't hide away the side-effects) diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -72,50 +72,6 @@ return self.kwargname raise IndexError -# JIT helper functions -# these functions contain functionality that the JIT is not always supposed to -# look at. They should not get a self arguments, which makes the amount of -# arguments annoying :-( - -def _match_keywords(signature, input_argcount, keywords, kwds_mapping): - # letting JIT unroll the loop is *only* safe if the callsite didn't - # use **args because num_kwds can be arbitrarily large otherwise. - num_kwds = num_remainingkwds = len(keywords) - for i in range(num_kwds): - name = keywords[i] - # If name was not encoded as a string, it could be None. In that - # case, it's definitely not going to be in the signature. - if name is None: - continue - j = signature.find_argname(name) - # if j == -1 nothing happens - if j < input_argcount: - # check that no keyword argument conflicts with these. - if j >= 0: - raise ArgErrMultipleValues(name) - else: - kwds_mapping[j - input_argcount] = i # map to the right index - num_remainingkwds -= 1 - return num_remainingkwds - -def _collect_keyword_args(space, keywords, keywords_w, w_kwds, kwds_mapping, - keyword_names_w): - limit = len(keywords) - if keyword_names_w is not None: - limit -= len(keyword_names_w) - for i in range(len(keywords)): - # again a dangerous-looking loop that either the JIT unrolls - # or that is not too bad, because len(kwds_mapping) is small - for j in kwds_mapping: - if i == j: - break - else: - if i < limit: - w_key = space.wrap(keywords[i]) - else: - w_key = keyword_names_w[i - limit] - space.setitem(w_kwds, w_key, keywords_w[i]) - class ArgumentsForTranslation(object): def __init__(self, space, args_w, keywords=None, keywords_w=None, w_stararg=None, w_starstararg=None): @@ -263,13 +219,36 @@ # the called function takes # this function must not take a scope_w, to make the scope not # escape - num_remainingkwds = _match_keywords(signature, input_argcount, - keywords, kwds_mapping) + num_remainingkwds = len(keywords) + for i, name in enumerate(keywords): + # If name was not encoded as a string, it could be None. In that + # case, it's definitely not going to be in the signature. + if name is None: + continue + j = signature.find_argname(name) + # if j == -1 nothing happens + if j < input_argcount: + # check that no keyword argument conflicts with these. + if j >= 0: + raise ArgErrMultipleValues(name) + else: + kwds_mapping[j - input_argcount] = i # map to the right index + num_remainingkwds -= 1 + if num_remainingkwds: if w_kwds is not None: # collect extra keyword arguments into the **kwarg - _collect_keyword_args(self.space, keywords, keywords_w, - w_kwds, kwds_mapping, self.keyword_names_w) + limit = len(keywords) + if self.keyword_names_w is not None: + limit -= len(self.keyword_names_w) + for i in range(len(keywords)): + if i in kwds_mapping: + continue + if i < limit: + w_key = self.space.wrap(keywords[i]) + else: + w_key = self.keyword_names_w[i - limit] + self.space.setitem(w_kwds, w_key, keywords_w[i]) else: if co_argcount == 0: raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) From noreply at buildbot.pypy.org Fri Oct 19 17:31:21 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 19 Oct 2012 17:31:21 +0200 (CEST) Subject: [pypy-commit] cffi default: FILE limited support Message-ID: <20121019153121.7E8761C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r998:246ee2ad7b58 Date: 2012-10-19 17:31 +0200 http://bitbucket.org/cffi/cffi/changeset/246ee2ad7b58/ Log: FILE limited support diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1695,8 +1695,9 @@ return ct_int; } -static PyObject * -_prepare_pointer_call_argument(CTypeDescrObject *ctptr, PyObject *init) +static int +_prepare_pointer_call_argument(CTypeDescrObject *ctptr, PyObject *init, + char **output_data) { /* 'ctptr' is here a pointer type 'ITEM *'. Accept as argument an initializer for an array 'ITEM[]'. This includes the case of @@ -1712,11 +1713,11 @@ We assume that the C code won't modify the 'char *' data. */ if ((ctitem->ct_flags & CT_PRIMITIVE_CHAR) && (ctitem->ct_size == sizeof(char))) { - Py_INCREF(init); - return init; + output_data[0] = PyBytes_AS_STRING(init); + return 1; } else - return Py_None; + return 0; } else if (PyList_Check(init) || PyTuple_Check(init)) { length = PySequence_Fast_GET_SIZE(init); @@ -1725,32 +1726,44 @@ /* from a unicode, we add the null terminator */ length = _my_PyUnicode_SizeAsWideChar(init) + 1; } + else if (PyFile_Check(init)) { + if (strcmp(ctptr->ct_itemdescr->ct_name, "struct _IO_FILE") != 0) { + PyErr_Format(PyExc_TypeError, + "FILE object passed to a '%s' argument", + ctptr->ct_name); + return -1; + } + output_data[0] = (char *)PyFile_AsFile(init); + return 1; + } else { /* refuse to receive just an integer (and interpret it as the array size) */ - return Py_None; + return 0; } if (ctitem->ct_size <= 0) - return Py_None; + return 0; datasize = length * ctitem->ct_size; if ((datasize / ctitem->ct_size) != length) { PyErr_SetString(PyExc_OverflowError, "array size would overflow a Py_ssize_t"); - return NULL; + return -1; } result = PyBytes_FromStringAndSize(NULL, datasize); if (result == NULL) - return NULL; + return -1; data = PyBytes_AS_STRING(result); memset(data, 0, datasize); if (convert_array_from_object(data, ctptr, init) < 0) { Py_DECREF(result); - return NULL; + return -1; } - return result; + output_data[0] = data; + output_data[1] = (char *)result; + return 1; } static PyObject* @@ -1870,20 +1883,19 @@ argtype = (CTypeDescrObject *)PyTuple_GET_ITEM(fvarargs, i); if (argtype->ct_flags & CT_POINTER) { - PyObject *string; + ((char **)data)[1] = NULL; + if (!CData_Check(obj)) { - string = _prepare_pointer_call_argument(argtype, obj); - if (string != Py_None) { - if (string == NULL) + int res = _prepare_pointer_call_argument(argtype, obj, + (char **)data); + if (res != 0) { + if (res < 0) goto error; - ((char **)data)[0] = PyBytes_AS_STRING(string); - ((char **)data)[1] = (char *)string; assert(i < nargs_declared); /* otherwise, obj is a CData */ free_me_until = i + 1; continue; } } - ((char **)data)[1] = NULL; } if (convert_from_object(data, argtype, obj) < 0) goto error; @@ -1928,8 +1940,8 @@ argtype = (CTypeDescrObject *)PyTuple_GET_ITEM(signature, 2 + i); if (argtype->ct_flags & CT_POINTER) { char *data = buffer + cif_descr->exchange_offset_arg[1 + i]; - PyObject *string_or_null = (PyObject *)(((char **)data)[1]); - Py_XDECREF(string_or_null); + PyObject *tmpobj_or_null = (PyObject *)(((char **)data)[1]); + Py_XDECREF(tmpobj_or_null); } } if (buffer) diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2215,3 +2215,55 @@ buffer(p)[:] = bytearray(b"foo\x00") assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] + +def test_FILE(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fscanf = ll.load_function(BFunc2, "fscanf") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.close() + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"hello" + fr1.close() + +def test_FILE_only_for_FILE_arg(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + B_NOT_FILE = new_struct_type("NOT_FILE") + B_NOT_FILEP = new_pointer_type(B_NOT_FILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value) == ("FILE object passed to a 'struct NOT_FILE *' " + "argument") diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -59,7 +59,7 @@ if name.startswith('RTLD_'): setattr(self, name, getattr(backend, name)) # - lines = [] + lines = ['typedef struct _IO_FILE FILE;'] by_size = {} for cname in ['long long', 'long', 'int', 'short', 'char']: by_size[self.sizeof(cname)] = cname diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -397,7 +397,12 @@ some headers declare a different type (e.g. an enum) and also call it ``bool``. +* *New in version 0.4:* FILE. Limited support: just enough to declare C + functions taking a ``FILE *`` argument and calling them with a Python + file object. + .. "versionadded:: 0.4": bool +.. "versionadded:: 0.4": FILE As we will see on `the verification step`_ below, the declarations can also contain "``...``" at various places; these are placeholders that will diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -2,6 +2,7 @@ from cffi import FFI import math, os, sys from cffi.backend_ctypes import CTypesBackend +from testing.udir import udir try: from StringIO import StringIO @@ -295,3 +296,20 @@ m = ffi.dlopen("m") x = m.sin(1.23) assert x == math.sin(1.23) + + def test_fputs_custom_FILE(self): + if self.Backend is CTypesBackend: + py.test.skip("FILE not supported with the ctypes backend") + filename = str(udir.join('fputs_custom_FILE')) + ffi = FFI(backend=self.Backend()) + ffi.cdef("int fputs(const char *, FILE *);") + C = ffi.dlopen(None) + with open(filename, 'wb') as f: + f.write(b'[') + C.fputs(b"hello from custom file", f) + f.write(b'][') + C.fputs(b"some more output", f) + f.write(b']') + with open(filename, 'rb') as f: + res = f.read() + assert res == b'[hello from custom file][some more output]' From noreply at buildbot.pypy.org Fri Oct 19 17:32:16 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 19 Oct 2012 17:32:16 +0200 (CEST) Subject: [pypy-commit] cffi default: Fix hyperlink Message-ID: <20121019153216.8DC591C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r999:3436a0eec188 Date: 2012-10-19 17:32 +0200 http://bitbucket.org/cffi/cffi/changeset/3436a0eec188/ Log: Fix hyperlink diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -667,7 +667,7 @@ would not fit nicely in the model, and it does not seem to be needed here). But see ``ffi.addressof()`` below__. -__ Miscellaneous_ +__ `Misc methods on ffi`_ Any operation that would in C return a pointer or array or struct type gives you a fresh cdata object. Unlike the "original" one, these fresh From noreply at buildbot.pypy.org Fri Oct 19 18:11:04 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 19 Oct 2012 18:11:04 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (arigo, fijal) slow progress on restoring the virtualizable Message-ID: <20121019161104.A3FF71C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58250:794269d9494a Date: 2012-10-19 18:10 +0200 http://bitbucket.org/pypy/pypy/changeset/794269d9494a/ Log: (arigo, fijal) slow progress on restoring the virtualizable diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -131,6 +131,10 @@ def is_float_field(self): return getkind(self.FIELD) == 'float' +class JFDescrDescr(AbstractDescr): + def is_pointer_field(self): + return True + _example_res = {'v': None, 'r': lltype.nullptr(llmemory.GCREF.TO), 'i': 0, @@ -270,6 +274,14 @@ def get_savedata_ref(self, frame): return frame.saved_data + def jitframe_get_jfdescr_descr(self): + return JFDescrDescr() + + def jitframe_cast_jfdescr_to_descr(self, descr): + return descr + + # ------------------------------------------------------------ + def calldescrof(self, FUNC, ARGS, RESULT, effect_info): key = ('call', getkind(RESULT), tuple([getkind(A) for A in ARGS]), @@ -368,6 +380,9 @@ bh_call_v = _do_call def bh_getfield_gc(self, p, descr): + if isinstance(descr, JFDescrDescr): + p.latest_descr._TYPE = llmemory.GCREF # HACK + return p.latest_descr p = support.cast_arg(lltype.Ptr(descr.S), p) return support.cast_result(descr.FIELD, getattr(p, descr.fieldname)) diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -232,6 +232,11 @@ def typedescrof(self, TYPE): raise NotImplementedError + def jitframe_get_jfdescr_descr(self): + """ Return a descr that can be used to read the XXX field + """ + raise NotImplementedError + # ---------- the backend-dependent operations ---------- # lltype specific operations diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -750,8 +750,8 @@ descr = cpu.jitframe_cast_jfdescr_to_descr(jfdescr) if not descr: return - import pdb; pdb.set_trace() - xxx + resume.rebuild_virtualizable_from_resumedata(self.metainterp, descr, + vinfo, box) def _get_virtualizable_field_index(self, fielddescr): # Get the index of a fielddescr. Must only be called for diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py --- a/pypy/jit/metainterp/resume.py +++ b/pypy/jit/metainterp/resume.py @@ -694,9 +694,8 @@ virtuals_cache = None virtual_default = None - def _init(self, cpu, jitframe, storage): + def _init(self, cpu, storage): self.cpu = cpu - self.jitframe = jitframe self.cur_numb = storage.rd_numb self.consts = storage.rd_consts @@ -798,7 +797,8 @@ unique_id = lambda: None def __init__(self, jitframe, storage, metainterp): - self._init(metainterp.cpu, jitframe, storage) + self._init(metainterp.cpu, storage) + self.jitframe = jitframe self.metainterp = metainterp count = metainterp.cpu.get_latest_value_count(jitframe) self.liveboxes = [None] * count @@ -1004,6 +1004,22 @@ def write_a_float(self, index, box): self.boxes_f[index] = box +def rebuild_virtualizable_from_resumedata(metainterp, storage, + virtualizable_info, vable_box): + resumereader = ResumeDataForceVirtualizableReader(storage, metainterp, + vable_box) + resumereader.consume_vref_and_vable_boxes(virtualizable_info, + None) + +class ResumeDataForceVirtualizableReader(ResumeDataBoxReader): + def __init__(self, storage, metainterp, vable_box): + self.metainterp = metainterp + self._init(metainterp.cpu, storage) + self.liveboxes = [None] * xxx + + def load_box_from_cpu(self, num, kind): + xxx + # ---------- when resuming for blackholing, get direct values ---------- def blackhole_from_resumedata(blackholeinterpbuilder, jitdriver_sd, @@ -1064,7 +1080,8 @@ # 2: resuming from the GUARD_NOT_FORCED def __init__(self, metainterp_sd, jitframe, storage, all_virtuals=None): - self._init(metainterp_sd.cpu, jitframe, storage) + self._init(metainterp_sd.cpu, storage) + self.jitframe = jitframe self.callinfocollection = metainterp_sd.callinfocollection if all_virtuals is None: # common case self._prepare(storage) From noreply at buildbot.pypy.org Fri Oct 19 18:52:39 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 19 Oct 2012 18:52:39 +0200 (CEST) Subject: [pypy-commit] pypy default: push fromfloat failure categorization down into rbigint Message-ID: <20121019165239.B755B1C00FA@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r58251:ffd5545e9972 Date: 2012-10-19 09:53 -0700 http://bitbucket.org/pypy/pypy/changeset/ffd5545e9972/ Log: push fromfloat failure categorization down into rbigint diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -98,12 +98,13 @@ try: return W_LongObject.fromfloat(space, w_floatobj.floatval) except OverflowError: - if isnan(w_floatobj.floatval): - raise OperationError( - space.w_ValueError, - space.wrap("cannot convert float NaN to integer")) - raise OperationError(space.w_OverflowError, - space.wrap("cannot convert float infinity to long")) + raise OperationError( + space.w_OverflowError, + space.wrap("cannot convert float infinity to integer")) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("cannot convert float NaN to integer")) + def trunc__Float(space, w_floatobj): whole = math.modf(w_floatobj.floatval)[1] try: @@ -308,7 +309,7 @@ # Convert to long and use its hash. try: w_lval = W_LongObject.fromfloat(space, v) - except OverflowError: + except (OverflowError, ValueError): # can't convert to long int -- arbitrary if v < 0: return -271828 diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -1,7 +1,7 @@ from pypy.rlib.rarithmetic import LONG_BIT, intmask, longlongmask, r_uint, r_ulonglong, r_longlonglong from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen, is_valid_int from pypy.rlib.rarithmetic import most_neg_value_of_same_type -from pypy.rlib.rfloat import isfinite +from pypy.rlib.rfloat import isinf, isnan from pypy.rlib.debug import make_sure_not_resized, check_regular_int from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.rlib import jit @@ -207,10 +207,11 @@ def fromfloat(dval): """ Create a new bigint object from a float """ # This function is not marked as pure because it can raise - if isfinite(dval): - return rbigint._fromfloat_finite(dval) - else: - raise OverflowError + if isinf(dval): + raise OverflowError("cannot convert float infinity to integer") + if isnan(dval): + raise ValueError("cannot convert float NaN to integer") + return rbigint._fromfloat_finite(dval) @staticmethod @jit.elidable diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -4,6 +4,7 @@ from random import random, randint, sample from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF from pypy.rlib.rbigint import _store_digit, _mask_digit +from pypy.rlib.rfloat import NAN from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask from pypy.rpython.test.test_llinterp import interpret @@ -266,6 +267,7 @@ x = 12345.6789e200 x *= x assert raises(OverflowError, rbigint.fromfloat, x) + assert raises(ValueError, rbigint.fromfloat, NAN) # f1 = rbigint.fromfloat(9007199254740991.0) assert f1.tolong() == 9007199254740991 From noreply at buildbot.pypy.org Fri Oct 19 19:14:13 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 19 Oct 2012 19:14:13 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Enough to pass the test and another one about virtualizables with arrays. Message-ID: <20121019171413.9ADE01C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58252:f476428da6ef Date: 2012-10-19 19:14 +0200 http://bitbucket.org/pypy/pypy/changeset/f476428da6ef/ Log: Enough to pass the test and another one about virtualizables with arrays. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -135,6 +135,14 @@ def is_pointer_field(self): return True +class JFValueDescr(AbstractDescr): + def __init__(self, kind): + self.kind = kind + def is_pointer_field(self): + return self.kind == 'ref' + def is_float_field(self): + return self.kind == 'float' + _example_res = {'v': None, 'r': lltype.nullptr(llmemory.GCREF.TO), 'i': 0, @@ -149,6 +157,10 @@ JITFRAMEPTR = llmemory.GCREF + jfdescr_for_int = JFValueDescr('int') + jfdescr_for_ref = JFValueDescr('ref') + jfdescr_for_float = JFValueDescr('float') + def __init__(self, rtyper, stats=None, *ignored_args, **ignored_kwds): model.AbstractCPU.__init__(self) self.rtyper = rtyper @@ -381,7 +393,11 @@ def bh_getfield_gc(self, p, descr): if isinstance(descr, JFDescrDescr): - p.latest_descr._TYPE = llmemory.GCREF # HACK + result = p.latest_descr + # HACK + result._TYPE = llmemory.GCREF + result._identityhash = lambda: hash(result) # for rd_hash() + # return p.latest_descr p = support.cast_arg(lltype.Ptr(descr.S), p) return support.cast_result(descr.FIELD, getattr(p, descr.fieldname)) @@ -445,6 +461,9 @@ bh_setarrayitem_raw_f = bh_setarrayitem_raw def bh_getinteriorfield_gc(self, a, index, descr): + if isinstance(descr, JFValueDescr): + assert isinstance(a, LLFrame) + return a.latest_values[index] array = a._obj.container return support.cast_result(descr.FIELD, getattr(array.getitem(index), descr.fieldname)) diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -595,6 +595,14 @@ self.metainterp_sd = metainterp_sd self.jitdriver_sd = jitdriver_sd + def store_final_boxes(self, guard_op, boxes): + # override this method to also store the length on 'self' + ResumeGuardDescr.store_final_boxes(self, guard_op, boxes) + self.latest_value_count = len(boxes) + + def get_latest_value_count(self): + return self.latest_value_count + def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe): # Failures of a GUARD_NOT_FORCED are never compiled, but # always just blackholed. First fish for the data saved when diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -751,7 +751,7 @@ if not descr: return resume.rebuild_virtualizable_from_resumedata(self.metainterp, descr, - vinfo, box) + vinfo, box, jfbox) def _get_virtualizable_field_index(self, fielddescr): # Get the index of a fielddescr. Must only be called for diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py --- a/pypy/jit/metainterp/resume.py +++ b/pypy/jit/metainterp/resume.py @@ -1004,21 +1004,58 @@ def write_a_float(self, index, box): self.boxes_f[index] = box -def rebuild_virtualizable_from_resumedata(metainterp, storage, - virtualizable_info, vable_box): +def rebuild_virtualizable_from_resumedata(metainterp, storage, vinfo, + vable_box, jfbox): resumereader = ResumeDataForceVirtualizableReader(storage, metainterp, - vable_box) - resumereader.consume_vref_and_vable_boxes(virtualizable_info, - None) + jfbox) + numb = resumereader.cur_numb + virtualizable = vinfo.unwrap_virtualizable_box(vable_box) + boxes = vinfo.load_list_of_boxes(virtualizable, resumereader, numb) + # + for i in range(len(vinfo.static_field_descrs)): + descr = vinfo.static_field_descrs[i] + metainterp.execute_and_record(rop.SETFIELD_GC, descr, + vable_box, boxes[i]) + srcindex = len(vinfo.static_field_descrs) + for array_index in range(len(vinfo.array_field_descrs)): + length = vinfo.get_array_length(virtualizable, array_index) + box_array = metainterp.execute_and_record(rop.GETFIELD_GC, + vinfo.array_field_descrs[array_index], vable_box) + array_descr = vinfo.array_descrs[array_index] + for i in range(length): + metainterp.execute_and_record(rop.SETARRAYITEM_GC, array_descr, + box_array, ConstInt(i), + boxes[srcindex]) + srcindex += 1 + assert srcindex + 1 == len(boxes) class ResumeDataForceVirtualizableReader(ResumeDataBoxReader): - def __init__(self, storage, metainterp, vable_box): + def __init__(self, storage, metainterp, jfbox): self.metainterp = metainterp self._init(metainterp.cpu, storage) - self.liveboxes = [None] * xxx + count = storage.get_latest_value_count() + self.liveboxes = [None] * count + self.jfbox = jfbox + self._prepare_virtuals(storage.rd_virtuals) def load_box_from_cpu(self, num, kind): - xxx + if num < 0: + num += len(self.liveboxes) + assert num >= 0 + cpu = self.metainterp.cpu + if kind == INT: + descr = cpu.jfdescr_for_int + elif kind == REF: + descr = cpu.jfdescr_for_ref + elif kind == FLOAT: + descr = cpu.jfdescr_for_float + else: + assert 0, "bad kind: %d" % ord(kind) + box = self.metainterp.execute_and_record(rop.GETINTERIORFIELD_GC, + descr, self.jfbox, + ConstInt(num)) + self.liveboxes[num] = box + return box # ---------- when resuming for blackholing, get direct values ---------- diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -867,6 +867,9 @@ self.l = l self.s = s + class Oups(Exception): + pass + def main(codeno, n, a): frame = Frame([a, a+1, a+2, a+3], 0) return f(codeno, n, a, frame) @@ -886,11 +889,14 @@ if codeno == 0: subframe = Frame([n, n+1, n+2, n+3], 0) x += f(1, 10, 1, subframe) + if subframe.l[3] != 42: + raise Oups s = frame.s assert s >= 0 x += frame.l[s] x += len(frame.l) frame.s -= 1 + frame.l[3] = 42 return x res = self.meta_interp(main, [0, 10, 1], listops=True, inline=True) From noreply at buildbot.pypy.org Fri Oct 19 19:33:06 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 19 Oct 2012 19:33:06 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: A failing test Message-ID: <20121019173306.D20861C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58253:92643ca9b8f6 Date: 2012-10-19 19:32 +0200 http://bitbucket.org/pypy/pypy/changeset/92643ca9b8f6/ Log: A failing test diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -783,6 +783,10 @@ portal(codeno, frame) return frame.thing.val + @dont_look_inside + def escaping(f, t1): + assert f.thing is t1 + def portal(codeno, frame): i = 0 while i < 10: @@ -793,8 +797,10 @@ subframe = Frame() subframe.thing = Thing(nextval) nextval = portal(1, subframe) - if subframe.thing.val != nextval: + t1 = subframe.thing + if t1.val != nextval: raise Oups + escaping(subframe, t1) frame.thing = Thing(nextval + 1) i += 1 return frame.thing.val From noreply at buildbot.pypy.org Fri Oct 19 19:53:51 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 19 Oct 2012 19:53:51 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: C&P some missing opcodes Message-ID: <20121019175351.464091C0012@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58254:181050fb370b Date: 2012-10-19 16:38 +0100 http://bitbucket.org/pypy/pypy/changeset/181050fb370b/ Log: C&P some missing opcodes diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -669,6 +669,41 @@ def PRINT_NEWLINE(self, oparg, next_instr): self.space.appcall(rpython_print_newline) + def JUMP_FORWARD(self, jumpby, next_instr): + next_instr += jumpby + return next_instr + + def POP_JUMP_IF_FALSE(self, target, next_instr): + w_value = self.popvalue() + if not self.space.is_true(w_value): + return target + return next_instr + + def POP_JUMP_IF_TRUE(self, target, next_instr): + w_value = self.popvalue() + if self.space.is_true(w_value): + return target + return next_instr + + def JUMP_IF_FALSE_OR_POP(self, target, next_instr): + w_value = self.peekvalue() + if not self.space.is_true(w_value): + return target + self.popvalue() + return next_instr + + def JUMP_IF_TRUE_OR_POP(self, target, next_instr): + w_value = self.peekvalue() + if self.space.is_true(w_value): + return target + self.popvalue() + return next_instr + + def GET_ITER(self, oparg, next_instr): + w_iterable = self.popvalue() + w_iterator = self.space.iter(w_iterable) + self.pushvalue(w_iterator) + def FOR_ITER(self, jumpby, next_instr): w_iterator = self.peekvalue() try: From noreply at buildbot.pypy.org Fri Oct 19 19:53:52 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 19 Oct 2012 19:53:52 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Add popvalues() Message-ID: <20121019175352.60C9D1C0012@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58255:6d9f1823fbe4 Date: 2012-10-19 17:20 +0100 http://bitbucket.org/pypy/pypy/changeset/6d9f1823fbe4/ Log: Add popvalues() diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -287,6 +287,11 @@ "settop past the bottom of the stack") self.locals_stack_w[index] = w_object + def popvalues(self, n): + values_w = [self.popvalue() for i in range(n)] + values_w.reverse() + return values_w + def peekvalues(self, n): values_w = [None] * n base = self.valuestackdepth - n From noreply at buildbot.pypy.org Fri Oct 19 19:53:53 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Fri, 19 Oct 2012 19:53:53 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Copy stack manipulation opcodes Message-ID: <20121019175353.7BB981C0012@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58256:6782b68bd09b Date: 2012-10-19 18:53 +0100 http://bitbucket.org/pypy/pypy/changeset/6782b68bd09b/ Log: Copy stack manipulation opcodes diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -804,6 +804,40 @@ raise FlowingError(self, "Attempting to modify global variable %r." % (varname)) + def POP_TOP(self, oparg, next_instr): + self.popvalue() + + def ROT_TWO(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_2) + + def ROT_THREE(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + w_3 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_3) + self.pushvalue(w_2) + + def ROT_FOUR(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + w_3 = self.popvalue() + w_4 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_4) + self.pushvalue(w_3) + self.pushvalue(w_2) + + def DUP_TOP(self, oparg, next_instr): + w_1 = self.peekvalue() + self.pushvalue(w_1) + + def DUP_TOPX(self, itemcount, next_instr): + self.dupvalues(itemcount) + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. From noreply at buildbot.pypy.org Fri Oct 19 19:58:43 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 19 Oct 2012 19:58:43 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (arigo, fijal) fix for a test Message-ID: <20121019175843.88E9D1C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58257:27d724f93837 Date: 2012-10-19 19:41 +0200 http://bitbucket.org/pypy/pypy/changeset/27d724f93837/ Log: (arigo, fijal) fix for a test diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -752,6 +752,8 @@ return resume.rebuild_virtualizable_from_resumedata(self.metainterp, descr, vinfo, box, jfbox) + self._opimpl_setfield_gc_any(box, vinfo.jit_frame_descr, + history.CONST_NULL) def _get_virtualizable_field_index(self, fielddescr): # Get the index of a fielddescr. Must only be called for From noreply at buildbot.pypy.org Fri Oct 19 19:58:44 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 19 Oct 2012 19:58:44 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: one more test, that doesn't do exactly what I wanted, but still explodes Message-ID: <20121019175844.C0F0C1C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58258:2f3784367953 Date: 2012-10-19 19:58 +0200 http://bitbucket.org/pypy/pypy/changeset/2f3784367953/ Log: one more test, that doesn't do exactly what I wanted, but still explodes diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -958,6 +958,36 @@ policy=StopAtXPolicy(change)) assert res == main(0) + def test_call_assembler_two_virtualizables(self): + class Frame(object): + _virtualizable2_ = ['thing'] + + def __init__(self, thing): + self.thing = thing + + driver = JitDriver(greens = ['codeno'], + reds = ['i', 'frame', 'parent_frame'], + virtualizables = ['frame']) + + def portal(codeno, parent_frame): + i = 0 + frame = Frame(codeno) + while i < 10: + driver.jit_merge_point(i=i, frame=frame, codeno=codeno, + parent_frame=parent_frame) + frame.thing = frame.thing + parent_frame.thing + if codeno == 0: + portal((i % 2) + 1, frame) + i += 1 + return frame.thing + + def main(): + frame = Frame(0) + return portal(0, frame) + + res = self.meta_interp(main, [], inline=True) + assert res == main() + def test_assembler_call_red_args(self): driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], get_printable_location = lambda codeno : str(codeno)) From noreply at buildbot.pypy.org Fri Oct 19 20:25:47 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 19 Oct 2012 20:25:47 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20121019182547.AD3861C0012@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58259:760a976a876f Date: 2012-10-19 11:26 -0700 http://bitbucket.org/pypy/pypy/changeset/760a976a876f/ Log: merge default diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py --- a/lib_pypy/_ctypes/structure.py +++ b/lib_pypy/_ctypes/structure.py @@ -69,7 +69,8 @@ resnames.append(name) names = resnames self._names = names - self.__dict__.update(fields) + for name, field in fields.items(): + setattr(self, name, field) class Field(object): def __init__(self, name, offset, size, ctype, num, is_bitfield): diff --git a/lib_pypy/pypy_test/test_ctypes_support.py b/lib_pypy/pypy_test/test_ctypes_support.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_ctypes_support.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import absolute_import - -import py -from ctypes import * -try: - from ctypes_support import standard_c_lib, get_errno, set_errno -except ImportError: # on top of cpython - from lib_pypy.ctypes_support import standard_c_lib, get_errno, set_errno - - -def test_stdlib_and_errno(): - py.test.skip("this is expected on top of pypy, we need to fix ctypes in a way that is now in 2.6 in order to make this reliable") - write = standard_c_lib.write - write.argtypes = [c_int, c_char_p, c_size_t] - write.restype = c_size_t - # clear errno first - set_errno(0) - assert get_errno() == 0 - write(-345, "abc", 3) - assert get_errno() != 0 - set_errno(0) - assert get_errno() == 0 - -def test_argument_conversion_and_checks(): - strlen = standard_c_lib.strlen - strlen.argtypes = [c_char_p] - strlen.restype = c_size_t - assert strlen("eggs") == 4 - - # Should raise ArgumentError, not segfault - py.test.raises(ArgumentError, strlen, False) - diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -434,6 +434,7 @@ raise operationerrfmt(space.w_ValueError, "%s() requires a code object with %d free vars, not %d", self.name, closure_len, len(code.co_freevars)) + self.fget_func_doc(space) # see test_issue1293 self.code = code def fget_func_closure(self, space): diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py --- a/pypy/interpreter/test/test_function.py +++ b/pypy/interpreter/test/test_function.py @@ -322,6 +322,12 @@ assert f.__doc__ == "hi" assert type(f.__doc__) is str + def test_issue1293(self): + def f1(): "doc f1" + def f2(): "doc f2" + f1.__code__ = f2.__code__ + assert f1.__doc__ == "doc f1" + def test_subclassing(self): # cannot subclass 'function' or 'builtin_function' def f(): 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 @@ -255,6 +255,9 @@ else: intarg = rffi.cast(rffi.INT, intarg) # C long => C int rv = ioctl_int(fd, op, intarg) + if rv < 0: + raise _get_error(space, "ioctl") + return space.wrap(rv) try: arg = space.bufferstr_w(w_arg) diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -13,7 +13,7 @@ class AppTestFcntl: def setup_class(cls): - space = gettestobjspace(usemodules=('fcntl', 'array', 'struct')) + space = gettestobjspace(usemodules=('fcntl', 'array', 'struct', 'termios')) cls.space = space tmpprefix = str(udir.ensure('test_fcntl', dir=1).join('tmp_')) cls.w_tmp = space.wrap(tmpprefix) @@ -136,11 +136,10 @@ import array import sys, os - if "linux" in sys.platform: - TIOCGPGRP = 0x540f - elif "darwin" in sys.platform or "freebsd" in sys.platform: - TIOCGPGRP = 0x40047477 - else: + try: + from termios import TIOCGPGRP + import pty + except ImportError: skip("don't know how to test ioctl() on this platform") raises(TypeError, fcntl.ioctl, "foo") @@ -148,28 +147,49 @@ #raises(TypeError, fcntl.ioctl, 0, TIOCGPGRP, float(0)) raises(TypeError, fcntl.ioctl, 0, TIOCGPGRP, 1, "foo") - if not os.isatty(0): - skip("stdin is not a tty") + child_pid, mfd = pty.fork() + if child_pid == 0: + # We're the child + return + try: + buf = array.array('h', [0]) + res = fcntl.ioctl(mfd, TIOCGPGRP, buf, True) + assert res == 0 + assert buf[0] != 0 + expected = buf.tostring() - buf = array.array('h', [0]) - res = fcntl.ioctl(0, TIOCGPGRP, buf, True) - assert res == 0 - assert buf[0] != 0 - expected = buf.tostring() + if '__pypy__' in sys.builtin_module_names or sys.version_info >= (2,5): + buf = array.array('h', [0]) + res = fcntl.ioctl(mfd, TIOCGPGRP, buf) + assert res == 0 + assert buf.tostring() == expected - if '__pypy__' in sys.builtin_module_names or sys.version_info >= (2,5): - buf = array.array('h', [0]) - res = fcntl.ioctl(0, TIOCGPGRP, buf) - assert res == 0 - assert buf.tostring() == expected + res = fcntl.ioctl(mfd, TIOCGPGRP, buf, False) + assert res == expected - res = fcntl.ioctl(0, TIOCGPGRP, buf, False) - assert res == expected + raises(TypeError, fcntl.ioctl, mfd, TIOCGPGRP, "\x00\x00", True) - raises(TypeError, fcntl.ioctl, 0, TIOCGPGRP, "\x00\x00", True) + res = fcntl.ioctl(mfd, TIOCGPGRP, "\x00\x00") + assert res == expected + finally: + os.close(mfd) - res = fcntl.ioctl(0, TIOCGPGRP, "\x00\x00") - assert res == expected + def test_ioctl_int(self): + import os + import fcntl + + try: + from termios import TCFLSH, TCIOFLUSH + import pty + except ImportError: + skip("don't know how to test ioctl() on this platform") + + mfd, sfd = pty.openpty() + try: + assert fcntl.ioctl(mfd, TCFLSH, TCIOFLUSH) == 0 + finally: + os.close(mfd) + os.close(sfd) def test_lockf_with_ex(self): import fcntl diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py b/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py +++ b/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py @@ -462,6 +462,17 @@ callback = proto(callback) raises(ArgumentError, lambda: callback((1, 2, 3, 4), POINT())) + def test_argument_conversion_and_checks(self): + py.test.skip("XXX currently broken on PyPy, sorry") + strlen = dll.my_strchr + strlen.argtypes = [c_char_p, c_int] + strlen.restype = c_char_p + assert strlen("eggs", ord("g")) == "ggs" + + # Should raise ArgumentError, not segfault + py.test.raises(ArgumentError, strlen, 0, 0) + py.test.raises(ArgumentError, strlen, False, 0) + def test_union_as_passed_value(self): class UN(Union): _fields_ = [("x", c_short), @@ -545,3 +556,5 @@ res = test_errno() n = get_errno() assert (res, n) == (42, 43) + set_errno(0) + assert get_errno() == 0 diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py +++ b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py @@ -441,6 +441,11 @@ p = pointer(obj) assert p.contents._b_base_ is p + def test_unicode_field_name(self): + # setattr autoconverts field names to bytes + class X(Structure): + _fields_ = [(u"i", c_int)] + class TestPointerMember(BaseCTypesTestChecker): def test_1(self): diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -97,12 +97,13 @@ try: return W_LongObject.fromfloat(space, w_value.floatval) except OverflowError: - if isnan(w_value.floatval): - raise OperationError( - space.w_ValueError, - space.wrap("cannot convert float NaN to integer")) - raise OperationError(space.w_OverflowError, - space.wrap("cannot convert float infinity to long")) + raise OperationError( + space.w_OverflowError, + space.wrap("cannot convert float infinity to integer")) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("cannot convert float NaN to integer")) + def trunc__Float(space, w_floatobj): whole = math.modf(w_floatobj.floatval)[1] try: @@ -307,7 +308,7 @@ # Convert to long and use its hash. try: w_lval = W_LongObject.fromfloat(space, v) - except OverflowError: + except (OverflowError, ValueError): # can't convert to long int -- arbitrary if v < 0: return -HASH_INF diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py --- a/pypy/objspace/std/test/test_typeobject.py +++ b/pypy/objspace/std/test/test_typeobject.py @@ -718,6 +718,12 @@ assert repr(property) == "" assert repr(TypeError) == "" + def test_repr_issue1292(self): + d = {'object': object} # no __name__ + exec("class A(object): pass\n", d) + assert d['A'].__module__ == 'builtins' # obscure, follows CPython + assert repr(d['A']) == "" + def test_invalid_mro(self): class A(object): pass diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -1,7 +1,7 @@ from pypy.rlib.rarithmetic import LONG_BIT, intmask, longlongmask, r_uint, r_ulonglong, r_longlonglong from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen, is_valid_int from pypy.rlib.rarithmetic import most_neg_value_of_same_type -from pypy.rlib.rfloat import isfinite +from pypy.rlib.rfloat import isinf, isnan from pypy.rlib.debug import make_sure_not_resized, check_regular_int from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.rlib import jit @@ -207,10 +207,11 @@ def fromfloat(dval): """ Create a new bigint object from a float """ # This function is not marked as pure because it can raise - if isfinite(dval): - return rbigint._fromfloat_finite(dval) - else: - raise OverflowError + if isinf(dval): + raise OverflowError("cannot convert float infinity to integer") + if isnan(dval): + raise ValueError("cannot convert float NaN to integer") + return rbigint._fromfloat_finite(dval) @staticmethod @jit.elidable diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -4,6 +4,7 @@ from random import random, randint, sample from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF from pypy.rlib.rbigint import _store_digit, _mask_digit +from pypy.rlib.rfloat import NAN from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask from pypy.rpython.test.test_llinterp import interpret @@ -266,6 +267,7 @@ x = 12345.6789e200 x *= x assert raises(OverflowError, rbigint.fromfloat, x) + assert raises(ValueError, rbigint.fromfloat, NAN) # f1 = rbigint.fromfloat(9007199254740991.0) assert f1.tolong() == 9007199254740991 diff --git a/pypy/translator/goal/query.py b/pypy/translator/goal/query.py --- a/pypy/translator/goal/query.py +++ b/pypy/translator/goal/query.py @@ -49,7 +49,7 @@ s_ev = annotator.binding(ev, None) if s_et: if s_et.knowntype == type: - if s_et.__class__ == annmodel.SomeObject: + if s_et.__class__ == annmodel.SomeType: if hasattr(s_et, 'is_type_of') and s_et.is_type_of == [ev]: continue else: From noreply at buildbot.pypy.org Fri Oct 19 20:55:33 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 19 Oct 2012 20:55:33 +0200 (CEST) Subject: [pypy-commit] pypy py3k: py3 round Message-ID: <20121019185533.60A6E1C00FA@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58260:5460b861cac5 Date: 2012-10-19 11:52 -0700 http://bitbucket.org/pypy/pypy/changeset/5460b861cac5/ Log: py3 round diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -3,11 +3,9 @@ """ from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.rlib.runicode import UNICHR -from pypy.rlib.rfloat import isnan, isinf, round_double -from pypy.rlib import rfloat import __builtin__ def abs(space, w_val): @@ -102,40 +100,22 @@ # ____________________________________________________________ -# Here 0.30103 is an upper bound for log10(2) -NDIGITS_MAX = int((rfloat.DBL_MANT_DIG - rfloat.DBL_MIN_EXP) * 0.30103) -NDIGITS_MIN = -int((rfloat.DBL_MAX_EXP + 1) * 0.30103) - - at unwrap_spec(number=float, w_ndigits = WrappedDefault(0)) -def round(space, number, w_ndigits): - """round(number[, ndigits]) -> floating point number + at unwrap_spec(w_ndigits=WrappedDefault(None)) +def round(space, w_number, w_ndigits=None): + """round(number[, ndigits]) -> number Round a number to a given precision in decimal digits (default 0 digits). -This always returns a floating point number. Precision may be negative.""" - # Algorithm copied directly from CPython - - # interpret 2nd argument as a Py_ssize_t; clip on overflow - ndigits = space.getindex_w(w_ndigits, None) - - # nans, infinities and zeros round to themselves - if number == 0 or isinf(number) or isnan(number): - return space.wrap(number) - - # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x - # always rounds to itself. For ndigits < NDIGITS_MIN, x always - # rounds to +-0.0. - if ndigits > NDIGITS_MAX: - return space.wrap(number) - elif ndigits < NDIGITS_MIN: - # return 0.0, but with sign of x - return space.wrap(0.0 * number) - - # finite x, and ndigits is not unreasonably large - z = round_double(number, ndigits) - if isinf(z): - raise OperationError(space.w_OverflowError, - space.wrap("rounded value too large to represent")) - return space.wrap(z) +This returns an int when called with one argument, otherwise the +same type as the number. ndigits may be negative.""" + round = space.lookup(w_number, '__round__') + if round is None: + raise operationerrfmt(space.w_TypeError, + "type %s doesn't define __round__ method", + space.type(w_number).getname(space)) + if space.is_none(w_ndigits): + return space.get_and_call_function(round, w_number) + else: + return space.get_and_call_function(round, w_number, w_ndigits) # ____________________________________________________________ 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 @@ -642,6 +642,77 @@ assert round(562949953421312.5, 1) == 562949953421312.5 assert round(56294995342131.5, 3) == 56294995342131.5 + assert round(0.0) == 0.0 + assert type(round(0.0)) == int + assert round(1.0) == 1.0 + assert round(10.0) == 10.0 + assert round(1000000000.0) == 1000000000.0 + assert round(1e20) == 1e20 + + assert round(-1.0) == -1.0 + assert round(-10.0) == -10.0 + assert round(-1000000000.0) == -1000000000.0 + assert round(-1e20) == -1e20 + + assert round(0.1) == 0.0 + assert round(1.1) == 1.0 + assert round(10.1) == 10.0 + assert round(1000000000.1) == 1000000000.0 + + assert round(-1.1) == -1.0 + assert round(-10.1) == -10.0 + assert round(-1000000000.1) == -1000000000.0 + + assert round(0.9) == 1.0 + assert round(9.9) == 10.0 + assert round(999999999.9) == 1000000000.0 + + assert round(-0.9) == -1.0 + assert round(-9.9) == -10.0 + assert round(-999999999.9) == -1000000000.0 + + assert round(-8.0, -1) == -10.0 + assert type(round(-8.0, -1)) == float + + assert type(round(-8.0, 0)) == float + assert type(round(-8.0, 1)) == float + + # Check even / odd rounding behaviour + assert round(5.5) == 6 + assert round(6.5) == 6 + assert round(-5.5) == -6 + assert round(-6.5) == -6 + + # Check behavior on ints + assert round(0) == 0 + assert round(8) == 8 + assert round(-8) == -8 + assert type(round(0)) == int + assert type(round(-8, -1)) == int + assert type(round(-8, 0)) == int + assert type(round(-8, 1)) == int + + assert round(number=-8.0, ndigits=-1) == -10.0 + raises(TypeError, round) + + # test generic rounding delegation for reals + class TestRound: + def __round__(self): + return 23 + + class TestNoRound: + pass + + assert round(TestRound()) == 23 + + raises(TypeError, round, 1, 2, 3) + raises(TypeError, round, TestNoRound()) + + t = TestNoRound() + t.__round__ = lambda *args: args + raises(TypeError, round, t) + raises(TypeError, round, t, 0) + def test_vars_obscure_case(self): class C_get_vars(object): def getDict(self): diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py --- a/pypy/objspace/std/floattype.py +++ b/pypy/objspace/std/floattype.py @@ -263,6 +263,58 @@ def descr_get_imag(space, w_obj): return space.wrap(0.0) +# Here 0.30103 is an upper bound for log10(2) +NDIGITS_MAX = int((rfloat.DBL_MANT_DIG - rfloat.DBL_MIN_EXP) * 0.30103) +NDIGITS_MIN = -int((rfloat.DBL_MAX_EXP + 1) * 0.30103) + + at unwrap_spec(w_ndigits=WrappedDefault(None)) +def descr___round__(space, w_float, w_ndigits=None): + # Algorithm copied directly from CPython + from pypy.objspace.std.floatobject import W_FloatObject + from pypy.objspace.std.longobject import W_LongObject + assert isinstance(w_float, W_FloatObject) + x = w_float.floatval + + if space.is_none(w_ndigits): + # single-argument round: round to nearest integer + rounded = rfloat.round_away(x) + if math.fabs(x - rounded) == 0.5: + # halfway case: round to even + rounded = 2.0 * rfloat.round_away(x / 2.0) + try: + return W_LongObject.fromfloat(space, rounded) + except OverflowError: + raise OperationError( + space.w_OverflowError, + space.wrap("cannot convert float infinity to integer")) + except ValueError: + raise OperationError( + space.w_ValueError, + space.wrap("cannot convert float NaN to integer")) + + # interpret 2nd argument as a Py_ssize_t; clip on overflow + ndigits = space.getindex_w(w_ndigits, None) + + # nans and infinities round to themselves + if rfloat.isinf(x) or rfloat.isnan(x): + return space.wrap(x) + + # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x + # always rounds to itself. For ndigits < NDIGITS_MIN, x always + # rounds to +-0.0 + if ndigits > NDIGITS_MAX: + return space.wrap(x) + elif ndigits < NDIGITS_MIN: + # return 0.0, but with sign of x + return space.wrap(0.0 * x) + + # finite x, and ndigits is not unreasonably large + z = rfloat.round_double(x, ndigits) + if rfloat.isinf(z): + raise OperationError(space.w_OverflowError, + space.wrap("overflow occurred during round")) + return space.wrap(z) + # ____________________________________________________________ float_typedef = StdTypeDef("float", @@ -271,6 +323,7 @@ Convert a string or number to a floating point number, if possible.''', __new__ = interp2app(descr__new__), __getformat__ = interp2app(descr___getformat__, as_classmethod=True), + __round__ = interp2app(descr___round__), fromhex = interp2app(descr_fromhex, as_classmethod=True), conjugate = interp2app(descr_conjugate), real = typedef.GetSetProperty(descr_get_real), diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py --- a/pypy/objspace/std/longtype.py +++ b/pypy/objspace/std/longtype.py @@ -1,9 +1,11 @@ from pypy.interpreter.error import OperationError from pypy.interpreter import typedef -from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault +from pypy.interpreter.gateway import (applevel, interp2app, unwrap_spec, + WrappedDefault) from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.strutil import string_to_bigint, ParseStringError +from pypy.rlib.rbigint import rbigint def descr_conjugate(space, w_int): return space.int(w_int) @@ -12,7 +14,6 @@ @unwrap_spec(w_x = WrappedDefault(0)) def descr__new__(space, w_longtype, w_x, w_base=None): from pypy.objspace.std.longobject import W_LongObject - from pypy.rlib.rbigint import rbigint if space.config.objspace.std.withsmalllong: from pypy.objspace.std.smalllongobject import W_SmallLongObject else: @@ -120,13 +121,64 @@ @unwrap_spec(s='bufferstr', byteorder=str) def descr_from_bytes(space, w_cls, s, byteorder): - from pypy.rlib.rbigint import rbigint bigint = rbigint.frombytes(s) from pypy.objspace.std.longobject import W_LongObject w_obj = space.allocate_instance(W_LongObject, w_cls) W_LongObject.__init__(w_obj, bigint) return w_obj +divmod_near = applevel(''' + def divmod_near(a, b): + """Return a pair (q, r) such that a = b * q + r, and abs(r) + <= abs(b)/2, with equality possible only if q is even. In + other words, q == a / b, rounded to the nearest integer using + round-half-to-even.""" + q, r = divmod(a, b) + # round up if either r / b > 0.5, or r / b == 0.5 and q is + # odd. The expression r / b > 0.5 is equivalent to 2 * r > b + # if b is positive, 2 * r < b if b negative. + greater_than_half = 2*r > b if b > 0 else 2*r < b + exactly_half = 2*r == b + if greater_than_half or exactly_half and q % 2 == 1: + q += 1 + r -= b + return q, r +''', filename=__file__).interphook('divmod_near') + + at unwrap_spec(w_ndigits=WrappedDefault(None)) +def descr___round__(space, w_long, w_ndigits=None): + """To round an integer m to the nearest 10**n (n positive), we make + use of the divmod_near operation, defined by: + + divmod_near(a, b) = (q, r) + + where q is the nearest integer to the quotient a / b (the + nearest even integer in the case of a tie) and r == a - q * b. + Hence q * b = a - r is the nearest multiple of b to a, + preferring even multiples in the case of a tie. + + So the nearest multiple of 10**n to m is: + + m - divmod_near(m, 10**n)[1] + + """ + from pypy.objspace.std.longobject import W_AbstractIntObject, newlong + assert isinstance(w_long, W_AbstractIntObject) + + if space.is_none(w_ndigits): + return space.int(w_long) + + ndigits = space.bigint_w(space.index(w_ndigits)) + # if ndigits >= 0 then no rounding is necessary; return self unchanged + if ndigits.ge(rbigint.fromint(0)): + return space.int(w_long) + + # result = self - divmod_near(self, 10 ** -ndigits)[1] + right = rbigint.fromint(10).pow(ndigits.neg()) + w_temp = divmod_near(space, w_long, newlong(space, right)) + w_temp2 = space.getitem(w_temp, space.wrap(1)) + return space.sub(w_long, w_temp2) + # ____________________________________________________________ long_typedef = StdTypeDef("int", @@ -138,6 +190,7 @@ string, use the optional base. It is an error to supply a base when converting a non-string.''', __new__ = interp2app(descr__new__), + __round__ = interp2app(descr___round__), conjugate = interp2app(descr_conjugate), numerator = typedef.GetSetProperty(descr_get_numerator), denominator = typedef.GetSetProperty(descr_get_denominator), From noreply at buildbot.pypy.org Fri Oct 19 21:56:19 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 19 Oct 2012 21:56:19 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: progress Message-ID: <20121019195619.C76451C0448@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58261:3297b303f4c2 Date: 2012-10-19 21:56 +0200 http://bitbucket.org/pypy/pypy/changeset/3297b303f4c2/ Log: progress diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -169,6 +169,7 @@ class MiniStats: pass self.stats = stats or MiniStats() + self.TOKEN_TRACING_RESCALL = NotAFrame() def compile_loop(self, inputargs, operations, looptoken, log=True, name=''): clt = model.CompiledLoopToken(self, looptoken.number) @@ -394,11 +395,13 @@ def bh_getfield_gc(self, p, descr): if isinstance(descr, JFDescrDescr): result = p.latest_descr + if result is None: + return lltype.nullptr(llmemory.GCREF.TO) # HACK result._TYPE = llmemory.GCREF result._identityhash = lambda: hash(result) # for rd_hash() # - return p.latest_descr + return result p = support.cast_arg(lltype.Ptr(descr.S), p) return support.cast_result(descr.FIELD, getattr(p, descr.fieldname)) @@ -581,8 +584,20 @@ def bh_read_timestamp(self): return read_timestamp() +class NotAFrame(object): + _TYPE = llmemory.GCREF + + class latest_descr: + pass + + def __eq__(self, other): + return isinstance(other, NotAFrame) + def __ne__(self, other): + return not (self == other) + class LLFrame(object): _TYPE = llmemory.GCREF + latest_descr = None # some obscure hacks to support comparison with llmemory.GCREF def __ne__(self, other): diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -743,6 +743,10 @@ if not self._establish_nullity(jfbox, orgpc): return # jfbox is NULL cpu = self.metainterp.cpu + if jfbox.getref_base() == cpu.TOKEN_TRACING_RESCALL: + # we're trying to force a virtualizable that is being traced, + # abort as bad loop + raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) descr = cpu.jitframe_get_jfdescr_descr() jfdescrbox = self._opimpl_getfield_gc_any(jfbox, descr) jfdescrbox = self.implement_guard_value(orgpc, jfdescrbox) diff --git a/pypy/jit/metainterp/virtualizable.py b/pypy/jit/metainterp/virtualizable.py --- a/pypy/jit/metainterp/virtualizable.py +++ b/pypy/jit/metainterp/virtualizable.py @@ -16,6 +16,7 @@ def __init__(self, warmrunnerdesc, VTYPEPTR): self.warmrunnerdesc = warmrunnerdesc cpu = warmrunnerdesc.cpu + self.TOKEN_TRACING_RESCALL = cpu.TOKEN_TRACING_RESCALL if cpu.ts.name == 'ootype': import py py.test.skip("ootype: fix virtualizables") @@ -230,7 +231,7 @@ def tracing_before_residual_call(virtualizable): virtualizable = cast_gcref_to_vtype(virtualizable) assert virtualizable.jit_frame == jitframe.TOKEN_NONE - virtualizable.jit_frame = jitframe.TOKEN_TRACING_RESCALL + virtualizable.jit_frame = self.TOKEN_TRACING_RESCALL self.tracing_before_residual_call = tracing_before_residual_call def tracing_after_residual_call(virtualizable): @@ -238,7 +239,7 @@ if virtualizable.jit_frame != jitframe.TOKEN_NONE: # not modified by the residual call; assert that it is still # set to TOKEN_TRACING_RESCALL and clear it. - assert virtualizable.jit_frame == jitframe.TOKEN_TRACING_RESCALL + assert virtualizable.jit_frame == self.TOKEN_TRACING_RESCALL virtualizable.jit_frame = jitframe.TOKEN_NONE return False else: @@ -248,7 +249,7 @@ def force_now(virtualizable): token = virtualizable.jit_frame - if token == jitframe.TOKEN_TRACING_RESCALL: + if token == self.TOKEN_TRACING_RESCALL: # The values in the virtualizable are always correct during # tracing. We only need to reset jit_frame to TOKEN_NONE # as a marker for the tracing, to tell it that this diff --git a/pypy/jit/metainterp/virtualref.py b/pypy/jit/metainterp/virtualref.py --- a/pypy/jit/metainterp/virtualref.py +++ b/pypy/jit/metainterp/virtualref.py @@ -9,6 +9,7 @@ def __init__(self, warmrunnerdesc): self.warmrunnerdesc = warmrunnerdesc self.cpu = warmrunnerdesc.cpu + self.TOKEN_TRACING_RESCALL = self.cpu.TOKEN_TRACING_RESCALL # we make the low-level type of an RPython class directly self.JIT_VIRTUAL_REF = lltype.GcStruct('JitVirtualRef', ('super', rclass.OBJECT), @@ -86,7 +87,7 @@ return vref = lltype.cast_opaque_ptr(lltype.Ptr(self.JIT_VIRTUAL_REF), gcref) assert vref.jit_frame == jitframe.TOKEN_NONE - vref.jit_frame = jitframe.TOKEN_TRACING_RESCALL + vref.jit_frame = self.TOKEN_TRACING_RESCALL def tracing_after_residual_call(self, gcref): if not self.is_virtual_ref(gcref): @@ -96,7 +97,7 @@ if vref.jit_frame != jitframe.TOKEN_NONE: # not modified by the residual call; assert that it is still # set to TOKEN_TRACING_RESCALL and clear it. - assert vref.jit_frame == jitframe.TOKEN_TRACING_RESCALL + assert vref.jit_frame == self.TOKEN_TRACING_RESCALL vref.jit_frame = jitframe.TOKEN_NONE return False else: @@ -108,7 +109,7 @@ return assert real_object vref = lltype.cast_opaque_ptr(lltype.Ptr(self.JIT_VIRTUAL_REF), gcref) - assert vref.jit_frame != jitframe.TOKEN_TRACING_RESCALL + assert vref.jit_frame != self.TOKEN_TRACING_RESCALL vref.jit_frame = jitframe.TOKEN_NONE vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object) @@ -142,7 +143,7 @@ vref = lltype.cast_pointer(lltype.Ptr(self.JIT_VIRTUAL_REF), inst) token = vref.jit_frame if token != jitframe.TOKEN_NONE: - if token == jitframe.TOKEN_TRACING_RESCALL: + if token == self.TOKEN_TRACING_RESCALL: # The "virtual" is not a virtual at all during tracing. # We only need to reset jit_frame to TOKEN_NONE # as a marker for the tracing, to tell it that this From noreply at buildbot.pypy.org Fri Oct 19 22:08:42 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 19 Oct 2012 22:08:42 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: leave a comment here, next step Message-ID: <20121019200842.D987C1C04C6@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58262:ca1ea67f544f Date: 2012-10-19 22:08 +0200 http://bitbucket.org/pypy/pypy/changeset/ca1ea67f544f/ Log: leave a comment here, next step diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -753,7 +753,8 @@ jfdescr = jfdescrbox.getref_base() descr = cpu.jitframe_cast_jfdescr_to_descr(jfdescr) if not descr: - return + XXX # shall we simply force and abort here??? this is an equivalent + # of sys._getframe() resume.rebuild_virtualizable_from_resumedata(self.metainterp, descr, vinfo, box, jfbox) self._opimpl_setfield_gc_any(box, vinfo.jit_frame_descr, From noreply at buildbot.pypy.org Fri Oct 19 22:15:31 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 19 Oct 2012 22:15:31 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: a failing test and I *think* a correct behavior Message-ID: <20121019201531.69F6F1C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58263:ee7e755c20c7 Date: 2012-10-19 22:15 +0200 http://bitbucket.org/pypy/pypy/changeset/ee7e755c20c7/ Log: a failing test and I *think* a correct behavior diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -753,8 +753,7 @@ jfdescr = jfdescrbox.getref_base() descr = cpu.jitframe_cast_jfdescr_to_descr(jfdescr) if not descr: - XXX # shall we simply force and abort here??? this is an equivalent - # of sys._getframe() + raise SwitchToBlackhole(Counters.ABORT_ESCAPE) resume.rebuild_virtualizable_from_resumedata(self.metainterp, descr, vinfo, box, jfbox) self._opimpl_setfield_gc_any(box, vinfo.jit_frame_descr, diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -958,7 +958,7 @@ policy=StopAtXPolicy(change)) assert res == main(0) - def test_call_assembler_two_virtualizables(self): + def test_call_assembler_force_from_inside(self): class Frame(object): _virtualizable2_ = ['thing'] @@ -988,6 +988,37 @@ res = self.meta_interp(main, [], inline=True) assert res == main() + def test_call_assembler_two_virtualizables(self): + class Frame(object): + _virtualizable2_ = ['thing'] + + def __init__(self, thing): + self.thing = thing + + driver = JitDriver(greens = ['codeno'], + reds = ['i', 'frame', 'frames'], + virtualizables = ['frame']) + + def portal(codeno, frame, frames): + i = 0 + while i < 10: + driver.jit_merge_point(i=i, frame=frame, codeno=codeno, + frames=frames) + frame.thing = frame.thing + 1 + if codeno == 0: + no = (i % 2) + newframe = frames[no] + frame.thing += portal(no + 1, newframe, None) + i += 1 + return frame.thing + + def main(): + frames = [Frame(1), Frame(2)] + return portal(0, Frame(0), frames) + + res = self.meta_interp(main, [], inline=True) + assert res == main() + def test_assembler_call_red_args(self): driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], get_printable_location = lambda codeno : str(codeno)) From noreply at buildbot.pypy.org Fri Oct 19 22:36:55 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 19 Oct 2012 22:36:55 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: a non-working fix, maybe I missed something Message-ID: <20121019203655.2403F1C04CF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58264:d38c50226d4b Date: 2012-10-19 22:36 +0200 http://bitbucket.org/pypy/pypy/changeset/d38c50226d4b/ Log: a non-working fix, maybe I missed something diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -2540,6 +2540,10 @@ args = arglist[num_green_args+1:] assert len(args) == targetjitdriver_sd.num_red_args warmrunnerstate = targetjitdriver_sd.warmstate + if targetjitdriver_sd.virtualizable_info is not None: + vbox = args[targetjitdriver_sd.index_of_virtualizable] + frame = self.framestack[-1] + frame._force_virtualizable_if_necessary(vbox, frame.pc) token = warmrunnerstate.get_assembler_token(greenargs) op = op.copy_and_change(rop.CALL_ASSEMBLER, args=args, descr=token) self.history.operations.append(op) From noreply at buildbot.pypy.org Fri Oct 19 23:16:33 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 19 Oct 2012 23:16:33 +0200 (CEST) Subject: [pypy-commit] pypy py3k: utilize isfinite Message-ID: <20121019211633.F35B81C00FA@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58265:813f5fbdbc7b Date: 2012-10-19 14:12 -0700 http://bitbucket.org/pypy/pypy/changeset/813f5fbdbc7b/ Log: utilize isfinite diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py --- a/pypy/objspace/std/floattype.py +++ b/pypy/objspace/std/floattype.py @@ -296,7 +296,7 @@ ndigits = space.getindex_w(w_ndigits, None) # nans and infinities round to themselves - if rfloat.isinf(x) or rfloat.isnan(x): + if not rfloat.isfinite(x): return space.wrap(x) # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x From noreply at buildbot.pypy.org Sat Oct 20 07:00:30 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 07:00:30 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Context manager for mmap. Message-ID: <20121020050030.4C3AC1C029E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58266:055710da332e Date: 2012-10-20 06:59 +0200 http://bitbucket.org/pypy/pypy/changeset/055710da332e/ Log: Context manager for mmap. diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -1,6 +1,6 @@ from pypy.interpreter.error import OperationError, wrap_oserror from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.rlib import rmmap, rarithmetic from pypy.rlib.rmmap import RValueError, RTypeError @@ -132,6 +132,13 @@ def __len__(self): return self.space.wrap(self.mmap.size) + def closed_get(self, space): + try: + self.mmap.check_valid() + except RValueError: + return space.w_True + return space.w_False + def check_valid(self): try: self.mmap.check_valid() @@ -199,6 +206,14 @@ space = self.space return space.wrap(StringLikeBuffer(space, space.wrap(self))) + def descr_enter(self, space): + self.check_valid() + return space.wrap(self) + + def descr_exit(self, space, __args__): + self.close() + + if rmmap._POSIX: @unwrap_spec(fileno=int, length=int, flags=int, @@ -260,6 +275,10 @@ __getitem__ = interp2app(W_MMap.descr_getitem), __setitem__ = interp2app(W_MMap.descr_setitem), __buffer__ = interp2app(W_MMap.descr_buffer), + __enter__ = interp2app(W_MMap.descr_enter), + __exit__ = interp2app(W_MMap.descr_exit), + + closed = GetSetProperty(W_MMap.closed_get), ) constants = rmmap.constants diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -622,6 +622,12 @@ finally: m.close() + def test_context_manager(self): + import mmap + with mmap.mmap(-1, 10) as m: + assert not m.closed + assert m.closed + def test_all(self): # this is a global test, ported from test_mmap.py import mmap From noreply at buildbot.pypy.org Sat Oct 20 10:20:54 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 20 Oct 2012 10:20:54 +0200 (CEST) Subject: [pypy-commit] cffi default: Standardize the error message. Message-ID: <20121020082054.B45C91C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1000:77df9afbe082 Date: 2012-10-20 09:38 +0200 http://bitbucket.org/cffi/cffi/changeset/77df9afbe082/ Log: Standardize the error message. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1727,12 +1727,8 @@ length = _my_PyUnicode_SizeAsWideChar(init) + 1; } else if (PyFile_Check(init)) { - if (strcmp(ctptr->ct_itemdescr->ct_name, "struct _IO_FILE") != 0) { - PyErr_Format(PyExc_TypeError, - "FILE object passed to a '%s' argument", - ctptr->ct_name); - return -1; - } + if (strcmp(ctptr->ct_itemdescr->ct_name, "struct _IO_FILE") != 0) + return 0; output_data[0] = (char *)PyFile_AsFile(init); return 1; } diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2265,5 +2265,5 @@ fw1 = posix.fdopen(fdw, 'w') # e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value) == ("FILE object passed to a 'struct NOT_FILE *' " - "argument") + assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not file") From noreply at buildbot.pypy.org Sat Oct 20 10:21:45 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 20 Oct 2012 10:21:45 +0200 (CEST) Subject: [pypy-commit] pypy default: Port the test. Not passing so far. Message-ID: <20121020082145.D49591C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58267:146ebe66c0b0 Date: 2012-10-20 09:47 +0200 http://bitbucket.org/pypy/pypy/changeset/146ebe66c0b0/ Log: Port the test. Not passing so far. 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 @@ -157,7 +157,7 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - raise self._convert_error("compatible pointer", w_ob) + raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): from pypy.module._cffi_backend import ctypearray 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 @@ -2211,3 +2211,55 @@ buffer(p)[:] = bytearray(b"foo\x00") assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] + +def test_FILE(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fscanf = ll.load_function(BFunc2, "fscanf") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.close() + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"hello" + fr1.close() + +def test_FILE_only_for_FILE_arg(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + B_NOT_FILE = new_struct_type("NOT_FILE") + B_NOT_FILEP = new_pointer_type(B_NOT_FILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not file") From noreply at buildbot.pypy.org Sat Oct 20 10:21:47 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 20 Oct 2012 10:21:47 +0200 (CEST) Subject: [pypy-commit] pypy default: Passing file arguments. Message-ID: <20121020082147.038391C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58268:235d902b48ba Date: 2012-10-20 10:21 +0200 http://bitbucket.org/pypy/pypy/changeset/235d902b48ba/ Log: Passing file arguments. diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -147,9 +147,13 @@ argtype = self.fargs[i] if isinstance(argtype, W_CTypePointer): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) - if get_mustfree_flag(data): + flag = get_mustfree_flag(data) + if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') + elif flag == 2: + file = rffi.cast(rffi.CCHARPP, data)[0] + rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -164,6 +168,26 @@ assert isinstance(abi, int) return space.wrap(abi) +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +def prepare_file_call_argument(fileobj): + import os + space = fileobj.space + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(self.space.w_ValueError, + self.space.wrap("file has no OS file descriptor")) + try: + fd2 = os.dup(fd) + f = rffi_fdopen(fd2, fileobj.mode) + if not f: + os.close(fd2) + raise OSError(rposix.get_errno(), "fdopen failed") + except OSError, e: + raise wrap_oserror(space, e) + return f + # ____________________________________________________________ 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 @@ -177,7 +177,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = [] + _attrs_ = ['is_file'] + _immutable_fields_ = ['is_file'] def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -186,6 +187,7 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" + self.is_file = (ctitem.name == "struct _IO_FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -234,7 +236,7 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) - def _prepare_pointer_call_argument(self, w_init): + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): @@ -242,10 +244,19 @@ elif space.isinstance_w(w_init, space.w_basestring): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 + elif self.is_file: + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = space.interpclass_w(w_init) + if isinstance(ob, W_File): + result = ctypefunc.prepare_file_call_argument(ob) + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 2 + return 0 else: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 if self.ctitem.size <= 0: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 try: datasize = ovfcheck(length * self.ctitem.size) except OverflowError: @@ -258,25 +269,19 @@ except Exception: lltype.free(result, flavor='raw') raise - return result + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 1 def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag space = self.space ob = space.interpclass_w(w_ob) - if isinstance(ob, cdataobj.W_CData): - buffer = lltype.nullptr(rffi.CCHARP.TO) - else: - buffer = self._prepare_pointer_call_argument(w_ob) - # - if buffer: - rffi.cast(rffi.CCHARPP, cdata)[0] = buffer - set_mustfree_flag(cdata, True) - return True - else: - set_mustfree_flag(cdata, False) + result = (not isinstance(ob, cdataobj.W_CData) and + self._prepare_pointer_call_argument(w_ob, cdata)) + if result == 0: self.convert_from_object(cdata, w_ob) - return False + set_mustfree_flag(cdata, result) + return result def getcfield(self, attr): return self.ctitem.getcfield(attr) From noreply at buildbot.pypy.org Sat Oct 20 10:38:11 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 20 Oct 2012 10:38:11 +0200 (CEST) Subject: [pypy-commit] cffi default: Test for buffering issues in PyPy. Message-ID: <20121020083811.0E5FC1C029E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1001:3c18741f1708 Date: 2012-10-20 10:37 +0200 http://bitbucket.org/cffi/cffi/changeset/3c18741f1708/ Log: Test for buffering issues in PyPy. diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2233,9 +2233,10 @@ # import posix fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r') - fw1 = posix.fdopen(fdw, 'w') + fr1 = posix.fdopen(fdr, 'r', 256) + fw1 = posix.fdopen(fdw, 'w', 256) # + fw1.write(b"X") res = fputs(b"hello world\n", fw1) assert res >= 0 fw1.close() @@ -2243,7 +2244,7 @@ p = newp(new_array_type(BCharP, 100), None) res = fscanf(fr1, b"%s\n", p) assert res == 1 - assert string(p) == b"hello" + assert string(p) == b"Xhello" fr1.close() def test_FILE_only_for_FILE_arg(): From noreply at buildbot.pypy.org Sat Oct 20 10:38:32 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 20 Oct 2012 10:38:32 +0200 (CEST) Subject: [pypy-commit] pypy default: Test and fix for buffering issues. Message-ID: <20121020083832.0E4E71C029E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58269:d5b4f3649b81 Date: 2012-10-20 10:38 +0200 http://bitbucket.org/pypy/pypy/changeset/d5b4f3649b81/ Log: Test and fix for buffering issues. diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -174,6 +174,7 @@ def prepare_file_call_argument(fileobj): import os space = fileobj.space + fileobj.direct_flush() fd = fileobj.direct_fileno() if fd < 0: raise OperationError(self.space.w_ValueError, 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 @@ -2229,9 +2229,10 @@ # import posix fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r') - fw1 = posix.fdopen(fdw, 'w') + fr1 = posix.fdopen(fdr, 'r', 256) + fw1 = posix.fdopen(fdw, 'w', 256) # + fw1.write(b"X") res = fputs(b"hello world\n", fw1) assert res >= 0 fw1.close() @@ -2239,7 +2240,7 @@ p = newp(new_array_type(BCharP, 100), None) res = fscanf(fr1, b"%s\n", p) assert res == 1 - assert string(p) == b"hello" + assert string(p) == b"Xhello" fr1.close() def test_FILE_only_for_FILE_arg(): From noreply at buildbot.pypy.org Sat Oct 20 10:45:58 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 20 Oct 2012 10:45:58 +0200 (CEST) Subject: [pypy-commit] cffi default: Missing quote. Message-ID: <20121020084559.007CF1C0129@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1002:5b20c98735f9 Date: 2012-10-20 10:45 +0200 http://bitbucket.org/cffi/cffi/changeset/5b20c98735f9/ Log: Missing quote. diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -523,7 +523,7 @@ you would use "``typedef struct { ...; } foo_t;``". * array lengths: when used as structure fields, arrays can have an - unspecified length, as in "``int n[];``" or "``int n[...];``. + unspecified length, as in "``int n[];``" or "``int n[...];``". The length is completed by the C compiler. * enums: if you don't know the exact order (or values) of the declared From noreply at buildbot.pypy.org Sat Oct 20 14:40:57 2012 From: noreply at buildbot.pypy.org (jerith) Date: Sat, 20 Oct 2012 14:40:57 +0200 (CEST) Subject: [pypy-commit] pypy default: Some ctypefunc bugfixes. Message-ID: <20121020124057.8F39E1C0012@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: Changeset: r58270:6234e2653575 Date: 2012-10-20 14:40 +0200 http://bitbucket.org/pypy/pypy/changeset/6234e2653575/ Log: Some ctypefunc bugfixes. diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,8 +4,9 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi +from pypy.rlib import jit, clibffi, jit_libffi, rposix from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -177,8 +178,8 @@ fileobj.direct_flush() fd = fileobj.direct_fileno() if fd < 0: - raise OperationError(self.space.w_ValueError, - self.space.wrap("file has no OS file descriptor")) + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) try: fd2 = os.dup(fd) f = rffi_fdopen(fd2, fileobj.mode) From noreply at buildbot.pypy.org Sat Oct 20 20:13:38 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 20 Oct 2012 20:13:38 +0200 (CEST) Subject: [pypy-commit] pypy default: some random cleanups, including removing a totally dead function Message-ID: <20121020181338.36DDF1C1D2A@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r58271:b4e11a2ce755 Date: 2012-10-20 11:12 -0700 http://bitbucket.org/pypy/pypy/changeset/b4e11a2ce755/ Log: some random cleanups, including removing a totally dead function diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py --- a/pypy/rpython/lltypesystem/rstr.py +++ b/pypy/rpython/lltypesystem/rstr.py @@ -1,5 +1,4 @@ from weakref import WeakValueDictionary -from pypy.tool.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.rpython.error import TyperError from pypy.rlib.objectmodel import malloc_zero_filled, we_are_translated @@ -9,9 +8,9 @@ from pypy.rlib import jit from pypy.rlib.rarithmetic import ovfcheck from pypy.rpython.rmodel import inputconst, IntegerRepr -from pypy.rpython.rstr import AbstractStringRepr,AbstractCharRepr,\ - AbstractUniCharRepr, AbstractStringIteratorRepr,\ - AbstractLLHelpers, AbstractUnicodeRepr +from pypy.rpython.rstr import (AbstractStringRepr, AbstractCharRepr, + AbstractUniCharRepr, AbstractStringIteratorRepr, + AbstractLLHelpers, AbstractUnicodeRepr) from pypy.rpython.lltypesystem import ll_str from pypy.rpython.lltypesystem.lltype import \ GcStruct, Signed, Array, Char, UniChar, Ptr, malloc, \ @@ -20,7 +19,6 @@ from pypy.rpython.rmodel import Repr from pypy.rpython.lltypesystem import llmemory from pypy.tool.sourcetools import func_with_new_name -from pypy.rpython.lltypesystem.lloperation import llop # ____________________________________________________________ # @@ -84,7 +82,6 @@ copy_string_contents = _new_copy_contents_fun(STR, Char, 'string') copy_unicode_contents = _new_copy_contents_fun(UNICODE, UniChar, 'unicode') -SIGNED_ARRAY = GcArray(Signed) CONST_STR_CACHE = WeakValueDictionary() CONST_UNICODE_CACHE = WeakValueDictionary() @@ -201,28 +198,6 @@ # get flowed and annotated, mostly with SomePtr. # -def ll_construct_restart_positions(s, l): - # Construct the array of possible restarting positions - # T = Array_of_ints [-1..len2] - # T[-1] = -1 s2.chars[-1] is supposed to be unequal to everything else - T = malloc( SIGNED_ARRAY, l) - T[0] = 0 - i = 1 - j = 0 - while i0: - j = T[j-1] - else: - T[i] = 0 - i += 1 - j = 0 - return T - - FAST_COUNT = 0 FAST_FIND = 1 FAST_RFIND = 2 @@ -234,6 +209,7 @@ def bloom_add(mask, c): return mask | (1 << (ord(c) & (BLOOM_WIDTH - 1))) + def bloom(mask, c): return mask & (1 << (ord(c) & (BLOOM_WIDTH - 1))) @@ -284,8 +260,8 @@ def ll_stritem_nonneg(s, i): chars = s.chars - ll_assert(i>=0, "negative str getitem index") - ll_assert(i= 0, "negative str getitem index") + ll_assert(i < len(chars), "str getitem index out of bound") return chars[i] ll_stritem_nonneg._annenforceargs_ = [None, int] @@ -632,9 +608,9 @@ i = start - 1 while i + 1 <= start + w: i += 1 - if s1.chars[i+m-1] == s2.chars[m-1]: + if s1.chars[i + m - 1] == s2.chars[m - 1]: for j in range(mlast): - if s1.chars[i+j] != s2.chars[j]: + if s1.chars[i + j] != s2.chars[j]: break else: if mode != FAST_COUNT: @@ -670,16 +646,16 @@ i -= 1 if s1.chars[i] == s2.chars[0]: for j in xrange(mlast, 0, -1): - if s1.chars[i+j] != s2.chars[j]: + if s1.chars[i + j] != s2.chars[j]: break else: return i - if i-1 >= 0 and not bloom(mask, s1.chars[i-1]): + if i - 1 >= 0 and not bloom(mask, s1.chars[i - 1]): i -= m else: i -= skip else: - if i-1 >= 0 and not bloom(mask, s1.chars[i-1]): + if i - 1 >= 0 and not bloom(mask, s1.chars[i - 1]): i -= m if mode != FAST_COUNT: @@ -710,7 +686,6 @@ malloc = mallocunicode copy_contents = copy_unicode_contents result = malloc(itemslen) - res_chars = result.chars res_index = 0 i = 0 while i < num_items: @@ -886,7 +861,7 @@ sign = -1 i += 1 elif chars[i] == '+': - i += 1; + i += 1 # skip whitespaces between sign and digits while i < strlen and chars[i] == ' ': i += 1 @@ -990,7 +965,7 @@ vchunk = hop.gendirectcall(ll_str.ll_int2oct, vitem, inputconst(Bool, False)) else: - raise TyperError, "%%%s is not RPython" % (code, ) + raise TyperError("%%%s is not RPython" % (code,)) else: from pypy.rpython.lltypesystem.rstr import string_repr, unicode_repr if is_unicode: From noreply at buildbot.pypy.org Sat Oct 20 20:13:39 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 20 Oct 2012 20:13:39 +0200 (CEST) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20121020181339.9E12F1C1D2A@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r58272:73639025b26e Date: 2012-10-20 11:13 -0700 http://bitbucket.org/pypy/pypy/changeset/73639025b26e/ Log: merged upstream diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,8 +4,9 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi +from pypy.rlib import jit, clibffi, jit_libffi, rposix from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -147,9 +148,13 @@ argtype = self.fargs[i] if isinstance(argtype, W_CTypePointer): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) - if get_mustfree_flag(data): + flag = get_mustfree_flag(data) + if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') + elif flag == 2: + file = rffi.cast(rffi.CCHARPP, data)[0] + rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -164,6 +169,27 @@ assert isinstance(abi, int) return space.wrap(abi) +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +def prepare_file_call_argument(fileobj): + import os + space = fileobj.space + fileobj.direct_flush() + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fd2 = os.dup(fd) + f = rffi_fdopen(fd2, fileobj.mode) + if not f: + os.close(fd2) + raise OSError(rposix.get_errno(), "fdopen failed") + except OSError, e: + raise wrap_oserror(space, e) + return f + # ____________________________________________________________ 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 @@ -157,7 +157,7 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - raise self._convert_error("compatible pointer", w_ob) + raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): from pypy.module._cffi_backend import ctypearray @@ -177,7 +177,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = [] + _attrs_ = ['is_file'] + _immutable_fields_ = ['is_file'] def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -186,6 +187,7 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" + self.is_file = (ctitem.name == "struct _IO_FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -234,7 +236,7 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) - def _prepare_pointer_call_argument(self, w_init): + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): @@ -242,10 +244,19 @@ elif space.isinstance_w(w_init, space.w_basestring): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 + elif self.is_file: + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = space.interpclass_w(w_init) + if isinstance(ob, W_File): + result = ctypefunc.prepare_file_call_argument(ob) + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 2 + return 0 else: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 if self.ctitem.size <= 0: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 try: datasize = ovfcheck(length * self.ctitem.size) except OverflowError: @@ -258,25 +269,19 @@ except Exception: lltype.free(result, flavor='raw') raise - return result + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 1 def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag space = self.space ob = space.interpclass_w(w_ob) - if isinstance(ob, cdataobj.W_CData): - buffer = lltype.nullptr(rffi.CCHARP.TO) - else: - buffer = self._prepare_pointer_call_argument(w_ob) - # - if buffer: - rffi.cast(rffi.CCHARPP, cdata)[0] = buffer - set_mustfree_flag(cdata, True) - return True - else: - set_mustfree_flag(cdata, False) + result = (not isinstance(ob, cdataobj.W_CData) and + self._prepare_pointer_call_argument(w_ob, cdata)) + if result == 0: self.convert_from_object(cdata, w_ob) - return False + set_mustfree_flag(cdata, result) + return result def getcfield(self, attr): return self.ctitem.getcfield(attr) 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 @@ -2211,3 +2211,56 @@ buffer(p)[:] = bytearray(b"foo\x00") assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] + +def test_FILE(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fscanf = ll.load_function(BFunc2, "fscanf") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r', 256) + fw1 = posix.fdopen(fdw, 'w', 256) + # + fw1.write(b"X") + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.close() + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"Xhello" + fr1.close() + +def test_FILE_only_for_FILE_arg(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + B_NOT_FILE = new_struct_type("NOT_FILE") + B_NOT_FILEP = new_pointer_type(B_NOT_FILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not file") diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -98,12 +98,13 @@ try: return W_LongObject.fromfloat(space, w_floatobj.floatval) except OverflowError: - if isnan(w_floatobj.floatval): - raise OperationError( - space.w_ValueError, - space.wrap("cannot convert float NaN to integer")) - raise OperationError(space.w_OverflowError, - space.wrap("cannot convert float infinity to long")) + raise OperationError( + space.w_OverflowError, + space.wrap("cannot convert float infinity to integer")) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("cannot convert float NaN to integer")) + def trunc__Float(space, w_floatobj): whole = math.modf(w_floatobj.floatval)[1] try: @@ -308,7 +309,7 @@ # Convert to long and use its hash. try: w_lval = W_LongObject.fromfloat(space, v) - except OverflowError: + except (OverflowError, ValueError): # can't convert to long int -- arbitrary if v < 0: return -271828 diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -1,7 +1,7 @@ from pypy.rlib.rarithmetic import LONG_BIT, intmask, longlongmask, r_uint, r_ulonglong, r_longlonglong from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen, is_valid_int from pypy.rlib.rarithmetic import most_neg_value_of_same_type -from pypy.rlib.rfloat import isfinite +from pypy.rlib.rfloat import isinf, isnan from pypy.rlib.debug import make_sure_not_resized, check_regular_int from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.rlib import jit @@ -207,10 +207,11 @@ def fromfloat(dval): """ Create a new bigint object from a float """ # This function is not marked as pure because it can raise - if isfinite(dval): - return rbigint._fromfloat_finite(dval) - else: - raise OverflowError + if isinf(dval): + raise OverflowError("cannot convert float infinity to integer") + if isnan(dval): + raise ValueError("cannot convert float NaN to integer") + return rbigint._fromfloat_finite(dval) @staticmethod @jit.elidable diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -4,6 +4,7 @@ from random import random, randint, sample from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF from pypy.rlib.rbigint import _store_digit, _mask_digit +from pypy.rlib.rfloat import NAN from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask from pypy.rpython.test.test_llinterp import interpret @@ -266,6 +267,7 @@ x = 12345.6789e200 x *= x assert raises(OverflowError, rbigint.fromfloat, x) + assert raises(ValueError, rbigint.fromfloat, NAN) # f1 = rbigint.fromfloat(9007199254740991.0) assert f1.tolong() == 9007199254740991 diff --git a/pypy/translator/goal/query.py b/pypy/translator/goal/query.py --- a/pypy/translator/goal/query.py +++ b/pypy/translator/goal/query.py @@ -49,7 +49,7 @@ s_ev = annotator.binding(ev, None) if s_et: if s_et.knowntype == type: - if s_et.__class__ == annmodel.SomeObject: + if s_et.__class__ == annmodel.SomeType: if hasattr(s_et, 'is_type_of') and s_et.is_type_of == [ev]: continue else: From noreply at buildbot.pypy.org Sat Oct 20 20:37:10 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 20:37:10 +0200 (CEST) Subject: [pypy-commit] pypy default: Rewrite _sre tests in a way more friendly for the py3k branch Message-ID: <20121020183710.110061C1DB3@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r58273:e7f1252eef3e Date: 2012-10-20 16:59 +0200 http://bitbucket.org/pypy/pypy/changeset/e7f1252eef3e/ Log: Rewrite _sre tests in a way more friendly for the py3k branch diff --git a/pypy/module/_sre/test/test_app_sre.py b/pypy/module/_sre/test/test_app_sre.py --- a/pypy/module/_sre/test/test_app_sre.py +++ b/pypy/module/_sre/test/test_app_sre.py @@ -5,17 +5,20 @@ from pypy.interpreter.gateway import app2interp_temp from pypy.conftest import gettestobjspace, option -def init_globals_hack(space): - space.appexec([space.wrap(autopath.this_dir)], """(this_dir): - import __builtin__ as b - import sys, os.path - # Uh-oh, ugly hack - sys.path.insert(0, this_dir) - import support_test_app_sre - b.s = support_test_app_sre - sys.path.pop(0) +def init_app_test(cls, space): + cls.w_s = space.appexec([space.wrap(autopath.this_dir)], + """(this_dir): + import sys + # Uh-oh, ugly hack + sys.path.insert(0, this_dir) + try: + import support_test_app_sre + return support_test_app_sre + finally: + sys.path.pop(0) """) + class AppTestSrePy: def test_magic(self): @@ -326,7 +329,7 @@ def test_scanner_zero_width_match(self): import re, sys if sys.version_info[:2] == (2, 3): - return + skip("2.3 is different here") p = re.compile(".*").scanner("bla") assert ("bla", "") == (p.search().group(0), p.search().group(0)) assert None == p.search() @@ -340,7 +343,7 @@ cls.space = gettestobjspace(usemodules=('_locale',)) except py.test.skip.Exception: cls.space = gettestobjspace(usemodules=('_rawffi',)) - init_globals_hack(cls.space) + init_app_test(cls, cls.space) def setup_method(self, method): import locale @@ -351,11 +354,13 @@ locale.setlocale(locale.LC_ALL, (None, None)) def test_getlower_no_flags(self): + s = self.s UPPER_AE = "\xc4" s.assert_lower_equal([("a", "a"), ("A", "a"), (UPPER_AE, UPPER_AE), (u"\u00c4", u"\u00c4"), (u"\u4444", u"\u4444")], 0) def test_getlower_locale(self): + s = self.s import locale, sre_constants UPPER_AE = "\xc4" LOWER_AE = "\xe4" @@ -370,6 +375,7 @@ skip("unsupported locale de_DE") def test_getlower_unicode(self): + s = self.s import sre_constants UPPER_AE = "\xc4" LOWER_AE = "\xe4" @@ -596,34 +602,41 @@ class AppTestOpcodes: def setup_class(cls): + if option.runappdirect: + py.test.skip("can only be run on py.py: _sre opcodes don't match") try: cls.space = gettestobjspace(usemodules=('_locale',)) except py.test.skip.Exception: cls.space = gettestobjspace(usemodules=('_rawffi',)) # This imports support_test_sre as the global "s" - init_globals_hack(cls.space) + init_app_test(cls, cls.space) def test_length_optimization(self): + s = self.s pattern = "bla" opcodes = [s.OPCODES["info"], 3, 3, len(pattern)] \ + s.encode_literal(pattern) + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["b", "bl", "ab"]) def test_literal(self): + s = self.s opcodes = s.encode_literal("bla") + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["bl", "blu"]) s.assert_match(opcodes, ["bla", "blab", "cbla", "bbla"]) def test_not_literal(self): + s = self.s opcodes = s.encode_literal("b") \ + [s.OPCODES["not_literal"], ord("a"), s.OPCODES["success"]] s.assert_match(opcodes, ["bx", "ababy"]) s.assert_no_match(opcodes, ["ba", "jabadu"]) def test_unknown(self): + s = self.s raises(RuntimeError, s.search, [55555], "b") def test_at_beginning(self): + s = self.s for atname in ["at_beginning", "at_beginning_string"]: opcodes = [s.OPCODES["at"], s.ATCODES[atname]] \ + s.encode_literal("bla") + [s.OPCODES["success"]] @@ -631,30 +644,35 @@ s.assert_no_match(opcodes, "abla") def test_at_beginning_line(self): + s = self.s opcodes = [s.OPCODES["at"], s.ATCODES["at_beginning_line"]] \ + s.encode_literal("bla") + [s.OPCODES["success"]] s.assert_match(opcodes, ["bla", "x\nbla"]) s.assert_no_match(opcodes, ["abla", "abla\nubla"]) def test_at_end(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end"], s.OPCODES["success"]] s.assert_match(opcodes, ["bla", "bla\n"]) s.assert_no_match(opcodes, ["blau", "abla\nblau"]) def test_at_end_line(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end_line"], s.OPCODES["success"]] s.assert_match(opcodes, ["bla\n", "bla\nx", "bla"]) s.assert_no_match(opcodes, ["blau"]) def test_at_end_string(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end_string"], s.OPCODES["success"]] s.assert_match(opcodes, "bla") s.assert_no_match(opcodes, ["blau", "bla\n"]) def test_at_boundary(self): + s = self.s for atname in "at_boundary", "at_loc_boundary", "at_uni_boundary": opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES[atname], s.OPCODES["success"]] @@ -666,6 +684,7 @@ s.assert_no_match(opcodes, "") def test_at_non_boundary(self): + s = self.s for atname in "at_non_boundary", "at_loc_non_boundary", "at_uni_non_boundary": opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES[atname], s.OPCODES["success"]] @@ -673,6 +692,7 @@ s.assert_no_match(opcodes, ["bla ja", "bla"]) def test_at_loc_boundary(self): + s = self.s import locale try: s.void_locale() @@ -692,6 +712,7 @@ skip("locale error") def test_at_uni_boundary(self): + s = self.s UPPER_PI = u"\u03a0" LOWER_PI = u"\u03c0" opcodes = s.encode_literal("bl") + [s.OPCODES["any"], s.OPCODES["at"], @@ -703,6 +724,7 @@ s.assert_match(opcodes, ["blaha", u"bl%sja" % UPPER_PI]) def test_category_loc_word(self): + s = self.s import locale try: s.void_locale() @@ -723,23 +745,27 @@ skip("locale error") def test_any(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["any"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_match(opcodes, ["b a", "bla", "bboas"]) s.assert_no_match(opcodes, ["b\na", "oba", "b"]) def test_any_all(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["any_all"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_match(opcodes, ["b a", "bla", "bboas", "b\na"]) s.assert_no_match(opcodes, ["oba", "b"]) def test_in_failure(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 2, s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["ba", "bla"]) def test_in_literal(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 7] \ + s.encode_literal("la") + [s.OPCODES["failure"], s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -747,6 +773,7 @@ s.assert_no_match(opcodes, ["ba", "bja", "blla"]) def test_in_category(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 6, s.OPCODES["category"], s.CHCODES["category_digit"], s.OPCODES["category"], s.CHCODES["category_space"], s.OPCODES["failure"]] + s.encode_literal("a") + [s.OPCODES["success"]] @@ -757,6 +784,7 @@ import _sre if _sre.CODESIZE != 2: return + s = self.s # charset bitmap for characters "l" and "h" bitmap = 6 * [0] + [4352] + 9 * [0] opcodes = s.encode_literal("b") + [s.OPCODES["in"], 19, s.OPCODES["charset"]] \ @@ -768,6 +796,7 @@ # disabled because this actually only works on big-endian machines if _sre.CODESIZE != 2: return + s = self.s # constructing bigcharset for lowercase pi (\u03c0) UPPER_PI = u"\u03a0" LOWER_PI = u"\u03c0" @@ -783,6 +812,7 @@ # XXX bigcharset test for ucs4 missing here def test_in_range(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 5, s.OPCODES["range"], ord("1"), ord("9"), s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -790,6 +820,7 @@ s.assert_no_match(opcodes, ["baa", "b5"]) def test_in_negate(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 7, s.OPCODES["negate"]] \ + s.encode_literal("la") + [s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -797,12 +828,14 @@ s.assert_no_match(opcodes, ["bla", "baa", "blbla"]) def test_literal_ignore(self): + s = self.s opcodes = s.encode_literal("b") \ + [s.OPCODES["literal_ignore"], ord("a"), s.OPCODES["success"]] s.assert_match(opcodes, ["ba", "bA"]) s.assert_no_match(opcodes, ["bb", "bu"]) def test_not_literal_ignore(self): + s = self.s UPPER_PI = u"\u03a0" opcodes = s.encode_literal("b") \ + [s.OPCODES["not_literal_ignore"], ord("a"), s.OPCODES["success"]] @@ -810,6 +843,7 @@ s.assert_no_match(opcodes, ["ba", "bA"]) def test_in_ignore(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in_ignore"], 8] \ + s.encode_literal("abc") + [s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -817,6 +851,7 @@ s.assert_no_match(opcodes, ["ba", "bja", "blla"]) def test_in_jump_info(self): + s = self.s for opname in "jump", "info": opcodes = s.encode_literal("b") \ + [s.OPCODES[opname], 3, s.OPCODES["failure"], s.OPCODES["failure"]] \ @@ -824,6 +859,7 @@ s.assert_match(opcodes, "ba") def _test_mark(self): + s = self.s # XXX need to rewrite this implementation-independent opcodes = s.encode_literal("a") + [s.OPCODES["mark"], 0] \ + s.encode_literal("b") + [s.OPCODES["mark"], 1, s.OPCODES["success"]] @@ -835,6 +871,7 @@ assert [1, 2] == state.marks def test_branch(self): + s = self.s opcodes = [s.OPCODES["branch"], 7] + s.encode_literal("ab") \ + [s.OPCODES["jump"], 9, 7] + s.encode_literal("cd") \ + [s.OPCODES["jump"], 2, s.OPCODES["failure"], s.OPCODES["success"]] @@ -842,18 +879,21 @@ s.assert_no_match(opcodes, ["aacas", "ac", "bla"]) def test_repeat_one(self): + s = self.s opcodes = [s.OPCODES["repeat_one"], 6, 1, 65535] + s.encode_literal("a") \ + [s.OPCODES["success"]] + s.encode_literal("ab") + [s.OPCODES["success"]] s.assert_match(opcodes, ["aab", "aaaab"]) s.assert_no_match(opcodes, ["ab", "a"]) def test_min_repeat_one(self): + s = self.s opcodes = [s.OPCODES["min_repeat_one"], 5, 1, 65535, s.OPCODES["any"]] \ + [s.OPCODES["success"]] + s.encode_literal("b") + [s.OPCODES["success"]] s.assert_match(opcodes, ["aab", "ardb", "bb"]) s.assert_no_match(opcodes, ["b"]) def test_repeat_maximizing(self): + s = self.s opcodes = [s.OPCODES["repeat"], 5, 1, 65535] + s.encode_literal("a") \ + [s.OPCODES["max_until"]] + s.encode_literal("b") + [s.OPCODES["success"]] s.assert_match(opcodes, ["ab", "aaaab", "baabb"]) @@ -865,6 +905,7 @@ # CPython 2.3 fails with a recursion limit exceeded error here. import sys if not sys.version_info[:2] == (2, 3): + s = self.s opcodes = [s.OPCODES["repeat"], 10, 1, 65535, s.OPCODES["repeat_one"], 6, 0, 65535] + s.encode_literal("a") + [s.OPCODES["success"], s.OPCODES["max_until"], s.OPCODES["success"]] @@ -872,6 +913,7 @@ assert "" == s.search(opcodes, "bb").group(0) def test_repeat_minimizing(self): + s = self.s opcodes = [s.OPCODES["repeat"], 4, 1, 65535, s.OPCODES["any"], s.OPCODES["min_until"]] + s.encode_literal("b") + [s.OPCODES["success"]] s.assert_match(opcodes, ["ab", "aaaab", "baabb"]) @@ -879,24 +921,28 @@ assert "aab" == s.search(opcodes, "aabb").group(0) def test_groupref(self): + s = self.s opcodes = [s.OPCODES["mark"], 0, s.OPCODES["any"], s.OPCODES["mark"], 1] \ + s.encode_literal("a") + [s.OPCODES["groupref"], 0, s.OPCODES["success"]] s.assert_match(opcodes, ["bab", "aaa", "dad"]) s.assert_no_match(opcodes, ["ba", "bad", "baad"]) def test_groupref_ignore(self): + s = self.s opcodes = [s.OPCODES["mark"], 0, s.OPCODES["any"], s.OPCODES["mark"], 1] \ + s.encode_literal("a") + [s.OPCODES["groupref_ignore"], 0, s.OPCODES["success"]] s.assert_match(opcodes, ["bab", "baB", "Dad"]) s.assert_no_match(opcodes, ["ba", "bad", "baad"]) def test_assert(self): + s = self.s opcodes = s.encode_literal("a") + [s.OPCODES["assert"], 4, 0] \ + s.encode_literal("b") + [s.OPCODES["success"], s.OPCODES["success"]] assert "a" == s.search(opcodes, "ab").group(0) s.assert_no_match(opcodes, ["a", "aa"]) def test_assert_not(self): + s = self.s opcodes = s.encode_literal("a") + [s.OPCODES["assert_not"], 4, 0] \ + s.encode_literal("b") + [s.OPCODES["success"], s.OPCODES["success"]] assert "a" == s.search(opcodes, "ac").group(0) From noreply at buildbot.pypy.org Sat Oct 20 20:37:11 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 20:37:11 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121020183711.4BB421C1DB3@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r58274:a3fc44987dc2 Date: 2012-10-20 20:36 +0200 http://bitbucket.org/pypy/pypy/changeset/a3fc44987dc2/ Log: merge heads diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py --- a/pypy/rpython/lltypesystem/rstr.py +++ b/pypy/rpython/lltypesystem/rstr.py @@ -1,5 +1,4 @@ from weakref import WeakValueDictionary -from pypy.tool.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.rpython.error import TyperError from pypy.rlib.objectmodel import malloc_zero_filled, we_are_translated @@ -9,9 +8,9 @@ from pypy.rlib import jit from pypy.rlib.rarithmetic import ovfcheck from pypy.rpython.rmodel import inputconst, IntegerRepr -from pypy.rpython.rstr import AbstractStringRepr,AbstractCharRepr,\ - AbstractUniCharRepr, AbstractStringIteratorRepr,\ - AbstractLLHelpers, AbstractUnicodeRepr +from pypy.rpython.rstr import (AbstractStringRepr, AbstractCharRepr, + AbstractUniCharRepr, AbstractStringIteratorRepr, + AbstractLLHelpers, AbstractUnicodeRepr) from pypy.rpython.lltypesystem import ll_str from pypy.rpython.lltypesystem.lltype import \ GcStruct, Signed, Array, Char, UniChar, Ptr, malloc, \ @@ -20,7 +19,6 @@ from pypy.rpython.rmodel import Repr from pypy.rpython.lltypesystem import llmemory from pypy.tool.sourcetools import func_with_new_name -from pypy.rpython.lltypesystem.lloperation import llop # ____________________________________________________________ # @@ -84,7 +82,6 @@ copy_string_contents = _new_copy_contents_fun(STR, Char, 'string') copy_unicode_contents = _new_copy_contents_fun(UNICODE, UniChar, 'unicode') -SIGNED_ARRAY = GcArray(Signed) CONST_STR_CACHE = WeakValueDictionary() CONST_UNICODE_CACHE = WeakValueDictionary() @@ -201,28 +198,6 @@ # get flowed and annotated, mostly with SomePtr. # -def ll_construct_restart_positions(s, l): - # Construct the array of possible restarting positions - # T = Array_of_ints [-1..len2] - # T[-1] = -1 s2.chars[-1] is supposed to be unequal to everything else - T = malloc( SIGNED_ARRAY, l) - T[0] = 0 - i = 1 - j = 0 - while i0: - j = T[j-1] - else: - T[i] = 0 - i += 1 - j = 0 - return T - - FAST_COUNT = 0 FAST_FIND = 1 FAST_RFIND = 2 @@ -234,6 +209,7 @@ def bloom_add(mask, c): return mask | (1 << (ord(c) & (BLOOM_WIDTH - 1))) + def bloom(mask, c): return mask & (1 << (ord(c) & (BLOOM_WIDTH - 1))) @@ -284,8 +260,8 @@ def ll_stritem_nonneg(s, i): chars = s.chars - ll_assert(i>=0, "negative str getitem index") - ll_assert(i= 0, "negative str getitem index") + ll_assert(i < len(chars), "str getitem index out of bound") return chars[i] ll_stritem_nonneg._annenforceargs_ = [None, int] @@ -632,9 +608,9 @@ i = start - 1 while i + 1 <= start + w: i += 1 - if s1.chars[i+m-1] == s2.chars[m-1]: + if s1.chars[i + m - 1] == s2.chars[m - 1]: for j in range(mlast): - if s1.chars[i+j] != s2.chars[j]: + if s1.chars[i + j] != s2.chars[j]: break else: if mode != FAST_COUNT: @@ -670,16 +646,16 @@ i -= 1 if s1.chars[i] == s2.chars[0]: for j in xrange(mlast, 0, -1): - if s1.chars[i+j] != s2.chars[j]: + if s1.chars[i + j] != s2.chars[j]: break else: return i - if i-1 >= 0 and not bloom(mask, s1.chars[i-1]): + if i - 1 >= 0 and not bloom(mask, s1.chars[i - 1]): i -= m else: i -= skip else: - if i-1 >= 0 and not bloom(mask, s1.chars[i-1]): + if i - 1 >= 0 and not bloom(mask, s1.chars[i - 1]): i -= m if mode != FAST_COUNT: @@ -710,7 +686,6 @@ malloc = mallocunicode copy_contents = copy_unicode_contents result = malloc(itemslen) - res_chars = result.chars res_index = 0 i = 0 while i < num_items: @@ -886,7 +861,7 @@ sign = -1 i += 1 elif chars[i] == '+': - i += 1; + i += 1 # skip whitespaces between sign and digits while i < strlen and chars[i] == ' ': i += 1 @@ -990,7 +965,7 @@ vchunk = hop.gendirectcall(ll_str.ll_int2oct, vitem, inputconst(Bool, False)) else: - raise TyperError, "%%%s is not RPython" % (code, ) + raise TyperError("%%%s is not RPython" % (code,)) else: from pypy.rpython.lltypesystem.rstr import string_repr, unicode_repr if is_unicode: From noreply at buildbot.pypy.org Sat Oct 20 20:37:40 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 20:37:40 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Skip an implementation detail about unitialized module.__dict__ Message-ID: <20121020183740.D94261C1DB3@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58275:5ce4ecaaa057 Date: 2012-10-20 07:27 +0200 http://bitbucket.org/pypy/pypy/changeset/5ce4ecaaa057/ Log: Skip an implementation detail about unitialized module.__dict__ (same change as for 2.7) diff --git a/lib-python/3.2/test/test_module.py b/lib-python/3.2/test/test_module.py --- a/lib-python/3.2/test/test_module.py +++ b/lib-python/3.2/test/test_module.py @@ -1,6 +1,6 @@ # Test the module type import unittest -from test.support import run_unittest, gc_collect +from test.support import run_unittest, gc_collect, check_impl_detail import sys ModuleType = type(sys) @@ -10,8 +10,10 @@ # An uninitialized module has no __dict__ or __name__, # and __doc__ is None foo = ModuleType.__new__(ModuleType) - self.assertTrue(foo.__dict__ is None) - self.assertRaises(SystemError, dir, foo) + self.assertFalse(foo.__dict__) + if check_impl_detail(): + self.assertTrue(foo.__dict__ is None) + self.assertRaises(SystemError, dir, foo) try: s = foo.__name__ self.fail("__name__ = %s" % repr(s)) From noreply at buildbot.pypy.org Sat Oct 20 20:37:42 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 20:37:42 +0200 (CEST) Subject: [pypy-commit] pypy py3k: hg merge default Message-ID: <20121020183742.25F5A1C1DB3@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58276:76608832a8d1 Date: 2012-10-20 17:03 +0200 http://bitbucket.org/pypy/pypy/changeset/76608832a8d1/ Log: hg merge default diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,8 +4,9 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi +from pypy.rlib import jit, clibffi, jit_libffi, rposix from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -147,9 +148,13 @@ argtype = self.fargs[i] if isinstance(argtype, W_CTypePointer): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) - if get_mustfree_flag(data): + flag = get_mustfree_flag(data) + if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') + elif flag == 2: + file = rffi.cast(rffi.CCHARPP, data)[0] + rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -164,6 +169,27 @@ assert isinstance(abi, int) return space.wrap(abi) +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +def prepare_file_call_argument(fileobj): + import os + space = fileobj.space + fileobj.direct_flush() + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fd2 = os.dup(fd) + f = rffi_fdopen(fd2, fileobj.mode) + if not f: + os.close(fd2) + raise OSError(rposix.get_errno(), "fdopen failed") + except OSError, e: + raise wrap_oserror(space, e) + return f + # ____________________________________________________________ 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 @@ -157,7 +157,7 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - raise self._convert_error("compatible pointer", w_ob) + raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): from pypy.module._cffi_backend import ctypearray @@ -177,7 +177,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = [] + _attrs_ = ['is_file'] + _immutable_fields_ = ['is_file'] def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -186,6 +187,7 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" + self.is_file = (ctitem.name == "struct _IO_FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -234,7 +236,7 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) - def _prepare_pointer_call_argument(self, w_init): + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): @@ -243,10 +245,19 @@ space.isinstance_w(w_init, space.w_bytes)): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 + elif self.is_file: + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = space.interpclass_w(w_init) + if isinstance(ob, W_File): + result = ctypefunc.prepare_file_call_argument(ob) + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 2 + return 0 else: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 if self.ctitem.size <= 0: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 try: datasize = ovfcheck(length * self.ctitem.size) except OverflowError: @@ -259,25 +270,19 @@ except Exception: lltype.free(result, flavor='raw') raise - return result + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 1 def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag space = self.space ob = space.interpclass_w(w_ob) - if isinstance(ob, cdataobj.W_CData): - buffer = lltype.nullptr(rffi.CCHARP.TO) - else: - buffer = self._prepare_pointer_call_argument(w_ob) - # - if buffer: - rffi.cast(rffi.CCHARPP, cdata)[0] = buffer - set_mustfree_flag(cdata, True) - return True - else: - set_mustfree_flag(cdata, False) + result = (not isinstance(ob, cdataobj.W_CData) and + self._prepare_pointer_call_argument(w_ob, cdata)) + if result == 0: self.convert_from_object(cdata, w_ob) - return False + set_mustfree_flag(cdata, result) + return result def getcfield(self, attr): return self.ctitem.getcfield(attr) 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 @@ -2211,3 +2211,56 @@ buffer(p)[:] = bytearray(b"foo\x00") assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] + +def test_FILE(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fscanf = ll.load_function(BFunc2, "fscanf") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r', 256) + fw1 = posix.fdopen(fdw, 'w', 256) + # + fw1.write(b"X") + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.close() + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"Xhello" + fr1.close() + +def test_FILE_only_for_FILE_arg(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + B_NOT_FILE = new_struct_type("NOT_FILE") + B_NOT_FILEP = new_pointer_type(B_NOT_FILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not file") diff --git a/pypy/module/_sre/test/test_app_sre.py b/pypy/module/_sre/test/test_app_sre.py --- a/pypy/module/_sre/test/test_app_sre.py +++ b/pypy/module/_sre/test/test_app_sre.py @@ -5,17 +5,20 @@ from pypy.interpreter.gateway import app2interp_temp from pypy.conftest import gettestobjspace, option -def init_globals_hack(space): - space.appexec([space.wrap(autopath.this_dir)], """(this_dir): - import builtins as b - import sys, os.path - # Uh-oh, ugly hack - sys.path.insert(0, this_dir) - import support_test_app_sre - b.s = support_test_app_sre - sys.path.pop(0) +def init_app_test(cls, space): + cls.w_s = space.appexec([space.wrap(autopath.this_dir)], + """(this_dir): + import sys + # Uh-oh, ugly hack + sys.path.insert(0, this_dir) + try: + import support_test_app_sre + return support_test_app_sre + finally: + sys.path.pop(0) """) + class AppTestSrePy: def test_magic(self): @@ -315,7 +318,7 @@ def test_scanner_zero_width_match(self): import re, sys if sys.version_info[:2] == (2, 3): - return + skip("2.3 is different here") p = re.compile(".*").scanner("bla") assert ("bla", "") == (p.search().group(0), p.search().group(0)) assert None == p.search() @@ -329,7 +332,7 @@ cls.space = gettestobjspace(usemodules=('_locale',)) except py.test.skip.Exception: cls.space = gettestobjspace(usemodules=('_rawffi',)) - init_globals_hack(cls.space) + init_app_test(cls, cls.space) def setup_method(self, method): import locale @@ -340,11 +343,13 @@ locale.setlocale(locale.LC_ALL, (None, None)) def test_getlower_no_flags(self): + s = self.s UPPER_AE = "\xc4" s.assert_lower_equal([("a", "a"), ("A", "a"), (UPPER_AE, UPPER_AE), ("\u00c4", "\u00c4"), ("\u4444", "\u4444")], 0) def test_getlower_locale(self): + s = self.s import locale, sre_constants UPPER_AE = "\xc4" LOWER_AE = "\xe4" @@ -359,6 +364,7 @@ skip("unsupported locale de_DE") def test_getlower_unicode(self): + s = self.s import sre_constants UPPER_AE = "\xc4" LOWER_AE = "\xe4" @@ -587,34 +593,41 @@ class AppTestOpcodes: def setup_class(cls): + if option.runappdirect: + py.test.skip("can only be run on py.py: _sre opcodes don't match") try: cls.space = gettestobjspace(usemodules=('_locale',)) except py.test.skip.Exception: cls.space = gettestobjspace(usemodules=('_rawffi',)) # This imports support_test_sre as the global "s" - init_globals_hack(cls.space) + init_app_test(cls, cls.space) def test_length_optimization(self): + s = self.s pattern = "bla" opcodes = [s.OPCODES["info"], 3, 3, len(pattern)] \ + s.encode_literal(pattern) + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["b", "bl", "ab"]) def test_literal(self): + s = self.s opcodes = s.encode_literal("bla") + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["bl", "blu"]) s.assert_match(opcodes, ["bla", "blab", "cbla", "bbla"]) def test_not_literal(self): + s = self.s opcodes = s.encode_literal("b") \ + [s.OPCODES["not_literal"], ord("a"), s.OPCODES["success"]] s.assert_match(opcodes, ["bx", "ababy"]) s.assert_no_match(opcodes, ["ba", "jabadu"]) def test_unknown(self): + s = self.s raises(RuntimeError, s.search, [55555], "b") def test_at_beginning(self): + s = self.s for atname in ["at_beginning", "at_beginning_string"]: opcodes = [s.OPCODES["at"], s.ATCODES[atname]] \ + s.encode_literal("bla") + [s.OPCODES["success"]] @@ -622,30 +635,35 @@ s.assert_no_match(opcodes, "abla") def test_at_beginning_line(self): + s = self.s opcodes = [s.OPCODES["at"], s.ATCODES["at_beginning_line"]] \ + s.encode_literal("bla") + [s.OPCODES["success"]] s.assert_match(opcodes, ["bla", "x\nbla"]) s.assert_no_match(opcodes, ["abla", "abla\nubla"]) def test_at_end(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end"], s.OPCODES["success"]] s.assert_match(opcodes, ["bla", "bla\n"]) s.assert_no_match(opcodes, ["blau", "abla\nblau"]) def test_at_end_line(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end_line"], s.OPCODES["success"]] s.assert_match(opcodes, ["bla\n", "bla\nx", "bla"]) s.assert_no_match(opcodes, ["blau"]) def test_at_end_string(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end_string"], s.OPCODES["success"]] s.assert_match(opcodes, "bla") s.assert_no_match(opcodes, ["blau", "bla\n"]) def test_at_boundary(self): + s = self.s for atname in "at_boundary", "at_loc_boundary", "at_uni_boundary": opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES[atname], s.OPCODES["success"]] @@ -657,6 +675,7 @@ s.assert_no_match(opcodes, "") def test_at_non_boundary(self): + s = self.s for atname in "at_non_boundary", "at_loc_non_boundary", "at_uni_non_boundary": opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES[atname], s.OPCODES["success"]] @@ -664,6 +683,7 @@ s.assert_no_match(opcodes, ["bla ja", "bla"]) def test_at_loc_boundary(self): + s = self.s import locale try: s.void_locale() @@ -683,6 +703,7 @@ skip("locale error") def test_at_uni_boundary(self): + s = self.s UPPER_PI = "\u03a0" LOWER_PI = "\u03c0" opcodes = s.encode_literal("bl") + [s.OPCODES["any"], s.OPCODES["at"], @@ -694,6 +715,7 @@ s.assert_match(opcodes, ["blaha", "bl%sja" % UPPER_PI]) def test_category_loc_word(self): + s = self.s import locale try: s.void_locale() @@ -714,23 +736,27 @@ skip("locale error") def test_any(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["any"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_match(opcodes, ["b a", "bla", "bboas"]) s.assert_no_match(opcodes, ["b\na", "oba", "b"]) def test_any_all(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["any_all"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_match(opcodes, ["b a", "bla", "bboas", "b\na"]) s.assert_no_match(opcodes, ["oba", "b"]) def test_in_failure(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 2, s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["ba", "bla"]) def test_in_literal(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 7] \ + s.encode_literal("la") + [s.OPCODES["failure"], s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -738,6 +764,7 @@ s.assert_no_match(opcodes, ["ba", "bja", "blla"]) def test_in_category(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 6, s.OPCODES["category"], s.CHCODES["category_digit"], s.OPCODES["category"], s.CHCODES["category_space"], s.OPCODES["failure"]] + s.encode_literal("a") + [s.OPCODES["success"]] @@ -748,6 +775,7 @@ import _sre if _sre.CODESIZE != 2: return + s = self.s # charset bitmap for characters "l" and "h" bitmap = 6 * [0] + [4352] + 9 * [0] opcodes = s.encode_literal("b") + [s.OPCODES["in"], 19, s.OPCODES["charset"]] \ @@ -759,6 +787,7 @@ # disabled because this actually only works on big-endian machines if _sre.CODESIZE != 2: return + s = self.s # constructing bigcharset for lowercase pi (\u03c0) UPPER_PI = u"\u03a0" LOWER_PI = u"\u03c0" @@ -774,6 +803,7 @@ # XXX bigcharset test for ucs4 missing here def test_in_range(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 5, s.OPCODES["range"], ord("1"), ord("9"), s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -781,6 +811,7 @@ s.assert_no_match(opcodes, ["baa", "b5"]) def test_in_negate(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 7, s.OPCODES["negate"]] \ + s.encode_literal("la") + [s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -788,12 +819,14 @@ s.assert_no_match(opcodes, ["bla", "baa", "blbla"]) def test_literal_ignore(self): + s = self.s opcodes = s.encode_literal("b") \ + [s.OPCODES["literal_ignore"], ord("a"), s.OPCODES["success"]] s.assert_match(opcodes, ["ba", "bA"]) s.assert_no_match(opcodes, ["bb", "bu"]) def test_not_literal_ignore(self): + s = self.s UPPER_PI = "\u03a0" opcodes = s.encode_literal("b") \ + [s.OPCODES["not_literal_ignore"], ord("a"), s.OPCODES["success"]] @@ -801,6 +834,7 @@ s.assert_no_match(opcodes, ["ba", "bA"]) def test_in_ignore(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in_ignore"], 8] \ + s.encode_literal("abc") + [s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -808,6 +842,7 @@ s.assert_no_match(opcodes, ["ba", "bja", "blla"]) def test_in_jump_info(self): + s = self.s for opname in "jump", "info": opcodes = s.encode_literal("b") \ + [s.OPCODES[opname], 3, s.OPCODES["failure"], s.OPCODES["failure"]] \ @@ -815,6 +850,7 @@ s.assert_match(opcodes, "ba") def _test_mark(self): + s = self.s # XXX need to rewrite this implementation-independent opcodes = s.encode_literal("a") + [s.OPCODES["mark"], 0] \ + s.encode_literal("b") + [s.OPCODES["mark"], 1, s.OPCODES["success"]] @@ -826,6 +862,7 @@ assert [1, 2] == state.marks def test_branch(self): + s = self.s opcodes = [s.OPCODES["branch"], 7] + s.encode_literal("ab") \ + [s.OPCODES["jump"], 9, 7] + s.encode_literal("cd") \ + [s.OPCODES["jump"], 2, s.OPCODES["failure"], s.OPCODES["success"]] @@ -833,18 +870,21 @@ s.assert_no_match(opcodes, ["aacas", "ac", "bla"]) def test_repeat_one(self): + s = self.s opcodes = [s.OPCODES["repeat_one"], 6, 1, 65535] + s.encode_literal("a") \ + [s.OPCODES["success"]] + s.encode_literal("ab") + [s.OPCODES["success"]] s.assert_match(opcodes, ["aab", "aaaab"]) s.assert_no_match(opcodes, ["ab", "a"]) def test_min_repeat_one(self): + s = self.s opcodes = [s.OPCODES["min_repeat_one"], 5, 1, 65535, s.OPCODES["any"]] \ + [s.OPCODES["success"]] + s.encode_literal("b") + [s.OPCODES["success"]] s.assert_match(opcodes, ["aab", "ardb", "bb"]) s.assert_no_match(opcodes, ["b"]) def test_repeat_maximizing(self): + s = self.s opcodes = [s.OPCODES["repeat"], 5, 1, 65535] + s.encode_literal("a") \ + [s.OPCODES["max_until"]] + s.encode_literal("b") + [s.OPCODES["success"]] s.assert_match(opcodes, ["ab", "aaaab", "baabb"]) @@ -856,6 +896,7 @@ # CPython 2.3 fails with a recursion limit exceeded error here. import sys if not sys.version_info[:2] == (2, 3): + s = self.s opcodes = [s.OPCODES["repeat"], 10, 1, 65535, s.OPCODES["repeat_one"], 6, 0, 65535] + s.encode_literal("a") + [s.OPCODES["success"], s.OPCODES["max_until"], s.OPCODES["success"]] @@ -863,6 +904,7 @@ assert "" == s.search(opcodes, "bb").group(0) def test_repeat_minimizing(self): + s = self.s opcodes = [s.OPCODES["repeat"], 4, 1, 65535, s.OPCODES["any"], s.OPCODES["min_until"]] + s.encode_literal("b") + [s.OPCODES["success"]] s.assert_match(opcodes, ["ab", "aaaab", "baabb"]) @@ -870,24 +912,28 @@ assert "aab" == s.search(opcodes, "aabb").group(0) def test_groupref(self): + s = self.s opcodes = [s.OPCODES["mark"], 0, s.OPCODES["any"], s.OPCODES["mark"], 1] \ + s.encode_literal("a") + [s.OPCODES["groupref"], 0, s.OPCODES["success"]] s.assert_match(opcodes, ["bab", "aaa", "dad"]) s.assert_no_match(opcodes, ["ba", "bad", "baad"]) def test_groupref_ignore(self): + s = self.s opcodes = [s.OPCODES["mark"], 0, s.OPCODES["any"], s.OPCODES["mark"], 1] \ + s.encode_literal("a") + [s.OPCODES["groupref_ignore"], 0, s.OPCODES["success"]] s.assert_match(opcodes, ["bab", "baB", "Dad"]) s.assert_no_match(opcodes, ["ba", "bad", "baad"]) def test_assert(self): + s = self.s opcodes = s.encode_literal("a") + [s.OPCODES["assert"], 4, 0] \ + s.encode_literal("b") + [s.OPCODES["success"], s.OPCODES["success"]] assert "a" == s.search(opcodes, "ab").group(0) s.assert_no_match(opcodes, ["a", "aa"]) def test_assert_not(self): + s = self.s opcodes = s.encode_literal("a") + [s.OPCODES["assert_not"], 4, 0] \ + s.encode_literal("b") + [s.OPCODES["success"], s.OPCODES["success"]] assert "a" == s.search(opcodes, "ac").group(0) From noreply at buildbot.pypy.org Sat Oct 20 20:37:43 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 20:37:43 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Found a way to have space.appexec() work with the -A option. Message-ID: <20121020183743.6130F1C1DB3@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58277:c134365a2913 Date: 2012-10-20 17:06 +0200 http://bitbucket.org/pypy/pypy/changeset/c134365a2913/ Log: Found a way to have space.appexec() work with the -A option. diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -158,9 +158,7 @@ body = body.lstrip() assert body.startswith('(') src = py.code.Source("def anonymous" + body) - d = {} - exec src.compile() in d - return d['anonymous'](*args) + return (src, args) def wrap(self, obj): return obj @@ -208,7 +206,7 @@ if option.runappdirect: py.test.skip("translation test, skipped for appdirect") -def run_with_python(python, target): +def run_with_python(python, target, **definitions): if python is None: py.test.skip("Cannot find the default python3 interpreter to run with -A") # we assume that the source of target is in utf-8. Unfortunately, we don't @@ -239,10 +237,18 @@ return res else: raise AssertionError("DID NOT RAISE") + class Test: + pass + self = Test() """ + defs = [] + for symbol, (code, args) in definitions.items(): + defs.append(str(code)) + args = ','.join(repr(arg) for arg in args) + defs.append("self.%s = anonymous(%s)\n" % (symbol, args)) source = py.code.Source(target)[1:].deindent() pyfile = udir.join('src.py') - source = helpers + str(source) + source = helpers + '\n'.join(defs) + str(source) with pyfile.open('w') as f: f.write(source) res, stdout, stderr = runsubprocess.run_subprocess( @@ -504,9 +510,11 @@ def runtest(self): target = self.obj src = extract_docstring_if_empty_function(target.im_func) + space = target.im_self.space if self.config.option.runappdirect: - return run_with_python(self.config.option.python, src) - space = target.im_self.space + appexec_definitions = self.parent.obj.__dict__ + return run_with_python(self.config.option.python, src, + **appexec_definitions) filename = self._getdynfilename(target) func = app2interp_temp(src, filename=filename) w_instance = self.parent.w_instance From noreply at buildbot.pypy.org Sat Oct 20 20:37:44 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 20:37:44 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix test_app_sre when run with -A Message-ID: <20121020183744.9819A1C1DB3@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58278:25dd33767b04 Date: 2012-10-20 20:31 +0200 http://bitbucket.org/pypy/pypy/changeset/25dd33767b04/ Log: Fix test_app_sre when run with -A diff --git a/pypy/module/_sre/test/test_app_sre.py b/pypy/module/_sre/test/test_app_sre.py --- a/pypy/module/_sre/test/test_app_sre.py +++ b/pypy/module/_sre/test/test_app_sre.py @@ -197,8 +197,8 @@ # which (if interpreted literally, as CPython does) gives the # following strangeish rules: assert isinstance(re.sub("a", "b", "diwoiioamoi"), str) - assert isinstance(re.sub("a", "b", b"diwoiiobmoi"), bytes) - assert isinstance(re.sub('x', b'y', b'x'), bytes) + raises(TypeError, re.sub, "a", "b", b"diwoiiobmoi") + raises(TypeError, re.sub, 'x', b'y', b'x') def test_sub_callable(self): import re From noreply at buildbot.pypy.org Sat Oct 20 20:37:45 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 20:37:45 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix test: don't mix unicode and byte strings in regexp search/replace. Message-ID: <20121020183745.BF38C1C1DB3@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58279:071daa233191 Date: 2012-10-20 20:34 +0200 http://bitbucket.org/pypy/pypy/changeset/071daa233191/ Log: Fix test: don't mix unicode and byte strings in regexp search/replace. diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -113,12 +113,18 @@ if endpos < pos: endpos = pos if space.is_true(space.isinstance(w_string, space.w_unicode)): unicodestr = space.unicode_w(w_string) + if not space.isinstance_w(self.w_pattern, space.w_unicode): + raise OperationError(space.w_TypeError, space.wrap( + "can't use a string pattern on a bytes-like object")) if pos > len(unicodestr): pos = len(unicodestr) if endpos > len(unicodestr): endpos = len(unicodestr) return rsre_core.UnicodeMatchContext(self.code, unicodestr, pos, endpos, self.flags) else: str = space.bufferstr_w(w_string) + if space.isinstance_w(self.w_pattern, space.w_unicode): + raise OperationError(space.w_TypeError, space.wrap( + "can't use a bytes pattern on a string-like object")) if pos > len(str): pos = len(str) if endpos > len(str): endpos = len(str) return rsre_core.StrMatchContext(self.code, str, From noreply at buildbot.pypy.org Sat Oct 20 21:17:07 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 21:17:07 +0200 (CEST) Subject: [pypy-commit] pypy default: cpyext: add PyErr_Display Message-ID: <20121020191707.A4F6B1C0012@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r58280:075b5c1e232b Date: 2012-10-20 21:15 +0200 http://bitbucket.org/pypy/pypy/changeset/075b5c1e232b/ Log: cpyext: add PyErr_Display diff --git a/pypy/module/cpyext/pyerrors.py b/pypy/module/cpyext/pyerrors.py --- a/pypy/module/cpyext/pyerrors.py +++ b/pypy/module/cpyext/pyerrors.py @@ -284,6 +284,20 @@ """Alias for PyErr_PrintEx(1).""" PyErr_PrintEx(space, 1) + at cpython_api([PyObject, PyObject, PyObject], lltype.Void) +def PyErr_Display(space, w_type, w_value, tb): + if tb: + w_tb = from_ref(space, tb) + else: + w_tb = space.w_None + try: + space.call_function(space.sys.get("excepthook"), + w_type, w_value, w_tb) + except OperationError: + # Like CPython: This is wrong, but too many callers rely on + # this behavior. + pass + @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) def PyTraceBack_Print(space, w_tb, w_file): space.call_method(w_file, "write", space.wrap( diff --git a/pypy/module/cpyext/test/test_pyerrors.py b/pypy/module/cpyext/test/test_pyerrors.py --- a/pypy/module/cpyext/test/test_pyerrors.py +++ b/pypy/module/cpyext/test/test_pyerrors.py @@ -219,6 +219,31 @@ assert e.errno == errno.EBADF assert e.strerror == os.strerror(errno.EBADF) + def test_PyErr_Display(self): + module = self.import_extension('foo', [ + ("display_error", "METH_VARARGS", + r''' + PyObject *type, *val, *tb; + PyErr_GetExcInfo(&type, &val, &tb); + PyErr_Display(type, val, tb); + Py_XDECREF(type); + Py_XDECREF(val); + Py_XDECREF(tb); + Py_RETURN_NONE; + '''), + ]) + import sys, StringIO + sys.stderr = StringIO.StringIO() + try: + 1 / 0 + except ZeroDivisionError: + module.display_error() + finally: + output = sys.stderr.getvalue() + sys.stderr = sys.__stderr__ + assert "in test_PyErr_Display\n" in output + assert "ZeroDivisionError" in output + def test_GetSetExcInfo(self): import sys module = self.import_extension('foo', [ From noreply at buildbot.pypy.org Sat Oct 20 23:30:15 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 23:30:15 +0200 (CEST) Subject: [pypy-commit] pypy py3k: pyexpat: add mappings for error messages. Message-ID: <20121020213015.E34641C1CE6@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58281:45e1d87468c3 Date: 2012-10-20 22:35 +0200 http://bitbucket.org/pypy/pypy/changeset/45e1d87468c3/ Log: pyexpat: add mappings for error messages. diff --git a/pypy/module/pyexpat/__init__.py b/pypy/module/pyexpat/__init__.py --- a/pypy/module/pyexpat/__init__.py +++ b/pypy/module/pyexpat/__init__.py @@ -9,10 +9,24 @@ def setup_after_space_initialization(self): from pypy.module.pyexpat import interp_pyexpat + space = self.space + # Three mappings for errors: the module contains errors + # message by symbol (errors.XML_ERROR_SYNTAX == 'syntax error'), + # codes is a dict mapping messages to numeric codes + # (errors.codes['syntax error'] == 2), and messages is a dict + # mapping numeric codes to messages (messages[2] == 'syntax error'). + w_codes = space.newdict() + w_messages = space.newdict() for name in interp_pyexpat.xml_error_list: - self.space.setattr(self, self.space.wrap(name), - interp_pyexpat.ErrorString(self.space, - getattr(interp_pyexpat, name))) + w_name = space.wrap(name) + num = getattr(interp_pyexpat, name) + w_num = space.wrap(num) + w_message = interp_pyexpat.ErrorString(space, num) + space.setattr(self, w_name, w_message) + space.setitem(w_codes, w_message, w_num) + space.setitem(w_messages, w_num, w_message) + space.setattr(self, space.wrap("codes"), w_codes) + space.setattr(self, space.wrap("messages"), w_messages) class ModelModule(MixedModule): "Definition of pyexpat.model module." 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 @@ -788,7 +788,7 @@ type_name = space.type(w_encoding).getname(space) raise OperationError( space.w_TypeError, - space.wrap('ParserCreate() argument 1 must be string or None,' + space.wrap('ParserCreate() argument 1 must be str or None,' ' not %s' % (type_name,))) if space.is_none(w_namespace_separator): @@ -808,7 +808,7 @@ type_name = space.type(w_namespace_separator).getname(space) raise OperationError( space.w_TypeError, - space.wrap('ParserCreate() argument 2 must be string or None,' + space.wrap('ParserCreate() argument 2 must be str or None,' ' not %s' % (type_name,))) # Explicitly passing None means no interning is desired. diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py --- a/pypy/module/pyexpat/test/test_parser.py +++ b/pypy/module/pyexpat/test/test_parser.py @@ -148,3 +148,17 @@ def test_model(self): import pyexpat assert isinstance(pyexpat.model.XML_CTYPE_EMPTY, int) + + def test_codes(self): + from pyexpat import errors + # verify mapping of errors.codes and errors.messages + message = errors.messages[errors.codes[errors.XML_ERROR_SYNTAX]] + assert errors.XML_ERROR_SYNTAX == message + + def test_expaterror(self): + import pyexpat + from pyexpat import errors + xml = '<' + parser = pyexpat.ParserCreate() + e = raises(pyexpat.ExpatError, parser.Parse, xml, True) + assert e.value.code == errors.codes[errors.XML_ERROR_UNCLOSED_TOKEN] From noreply at buildbot.pypy.org Sat Oct 20 23:30:17 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 23:30:17 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Remove pyexpat.Parser.returns_unicode (always True) Message-ID: <20121020213017.2157D1C1CE6@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58282:09541f104186 Date: 2012-10-20 22:40 +0200 http://bitbucket.org/pypy/pypy/changeset/09541f104186/ Log: Remove pyexpat.Parser.returns_unicode (always True) 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 @@ -410,7 +410,6 @@ self.w_intern = w_intern - self.returns_unicode = True self.ordered_attributes = False self.specified_attributes = False @@ -458,11 +457,8 @@ # Handlers management def w_convert(self, space, s): - if self.returns_unicode: - from pypy.interpreter.unicodehelper import PyUnicode_DecodeUTF8 - return space.wrap(PyUnicode_DecodeUTF8(space, s)) - else: - return space.wrapbytes(s) + from pypy.interpreter.unicodehelper import PyUnicode_DecodeUTF8 + return space.wrap(PyUnicode_DecodeUTF8(space, s)) def w_convert_charp(self, space, data): if data: @@ -755,7 +751,6 @@ namespace_prefixes = GetSetProperty(W_XMLParserType.get_namespace_prefixes, W_XMLParserType.set_namespace_prefixes, cls=W_XMLParserType), - returns_unicode = bool_property('returns_unicode', W_XMLParserType), ordered_attributes = bool_property('ordered_attributes', W_XMLParserType), specified_attributes = bool_property('specified_attributes', W_XMLParserType), intern = GetSetProperty(W_XMLParserType.get_intern, cls=W_XMLParserType), diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py --- a/pypy/module/pyexpat/test/test_parser.py +++ b/pypy/module/pyexpat/test/test_parser.py @@ -89,7 +89,6 @@ def gotText(text): assert text == "caf\xe9" p.CharacterDataHandler = gotText - assert p.returns_unicode p.Parse(xml) def test_explicit_encoding(self): From noreply at buildbot.pypy.org Sat Oct 20 23:30:18 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 23:30:18 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix tests to pass with -A Message-ID: <20121020213018.523201C1CE6@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58283:b8a23c0df759 Date: 2012-10-20 22:42 +0200 http://bitbucket.org/pypy/pypy/changeset/b8a23c0df759/ Log: Fix tests to pass with -A diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py --- a/pypy/module/pyexpat/test/test_parser.py +++ b/pypy/module/pyexpat/test/test_parser.py @@ -48,7 +48,7 @@ p.CharacterDataHandler = lambda s: data.append(s) encoding = encoding_arg is None and 'utf-8' or encoding_arg - res = p.Parse("\u00f6".encode(encoding), isfinal=True) + res = p.Parse("\u00f6".encode(encoding), True) assert res == 1 assert data == ["\u00f6"] @@ -79,7 +79,8 @@ p = pyexpat.ParserCreate() p.buffer_size = 150 assert p.buffer_size == 150 - raises(TypeError, setattr, p, 'buffer_size', sys.maxint + 1) + raises((ValueError, TypeError), + setattr, p, 'buffer_size', sys.maxsize + 1) def test_encoding_xml(self): # use one of the few encodings built-in in expat From noreply at buildbot.pypy.org Sat Oct 20 23:30:19 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 23:30:19 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix %r formatting when given a string with printable character: the result is not ascii... Message-ID: <20121020213019.8FDA41C1CE6@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58284:0a29fdad36f4 Date: 2012-10-20 23:10 +0200 http://bitbucket.org/pypy/pypy/changeset/0a29fdad36f4/ Log: Fix %r formatting when given a string with printable character: the result is not ascii... diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py --- a/pypy/objspace/std/formatting.py +++ b/pypy/objspace/std/formatting.py @@ -447,7 +447,7 @@ self.std_wp(s) def fmt_r(self, w_value): - self.std_wp(self.space.str_w(self.space.repr(w_value))) + self.std_wp(self.space.unicode_w(self.space.repr(w_value))) def fmt_c(self, w_value): self.prec = -1 # just because diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -839,6 +839,10 @@ return '\u1234' '%s' % X() + def test_formatting_unicode__repr__(self): + # Printable character + assert '%r' % chr(0xe9) == "'\xe9'" + def test_str_subclass(self): class Foo9(str): def __str__(self): From noreply at buildbot.pypy.org Sat Oct 20 23:30:20 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 23:30:20 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix for -A tests which define a "cls.w_xxx" Message-ID: <20121020213020.C57621C1CE6@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58285:4a4315d7af97 Date: 2012-10-20 23:13 +0200 http://bitbucket.org/pypy/pypy/changeset/4a4315d7af97/ Log: Fix for -A tests which define a "cls.w_xxx" diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -242,10 +242,12 @@ self = Test() """ defs = [] - for symbol, (code, args) in definitions.items(): - defs.append(str(code)) - args = ','.join(repr(arg) for arg in args) - defs.append("self.%s = anonymous(%s)\n" % (symbol, args)) + for symbol, value in definitions.items(): + if isinstance(value, tuple) and isinstance(value[0], py.code.Source): + code, args = value + defs.append(str(code)) + args = ','.join(repr(arg) for arg in args) + defs.append("self.%s = anonymous(%s)\n" % (symbol, args)) source = py.code.Source(target)[1:].deindent() pyfile = udir.join('src.py') source = helpers + '\n'.join(defs) + str(source) From noreply at buildbot.pypy.org Sat Oct 20 23:30:21 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 23:30:21 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix one test in test_unicode.py Message-ID: <20121020213021.E2A6D1C1CE6@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58286:5c956274053b Date: 2012-10-20 23:14 +0200 http://bitbucket.org/pypy/pypy/changeset/5c956274053b/ Log: Fix one test in test_unicode.py diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -210,8 +210,7 @@ u = space.unicode_w(w_object) eh = unicodehelper.encode_error_handler(space) return space.wrapbytes(unicode_encode_utf_8( - u, len(u), None, errorhandler=eh, - allow_surrogates=True)) + u, len(u), None, errorhandler=eh)) from pypy.module._codecs.interp_codecs import lookup_codec w_encoder = space.getitem(lookup_codec(space, encoding), space.wrap(0)) if errors is None: From noreply at buildbot.pypy.org Sat Oct 20 23:30:23 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sat, 20 Oct 2012 23:30:23 +0200 (CEST) Subject: [pypy-commit] pypy py3k: PyPy extension: inspect.getargs() works on built-in functions. Message-ID: <20121020213023.0DC6E1C1CE6@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58287:9fe4526f1973 Date: 2012-10-20 23:20 +0200 http://bitbucket.org/pypy/pypy/changeset/9fe4526f1973/ Log: PyPy extension: inspect.getargs() works on built-in functions. Port the diff from 2.7. diff --git a/lib-python/3.2/inspect.py b/lib-python/3.2/inspect.py --- a/lib-python/3.2/inspect.py +++ b/lib-python/3.2/inspect.py @@ -767,7 +767,13 @@ and 'varkw' are the names of the * and ** arguments or None.""" if not iscode(co): - raise TypeError('{!r} is not a code object'.format(co)) + if hasattr(len, 'func_code') and type(co) is type(len.func_code): + # PyPy extension: built-in function objects have a func_code too. + # There is no co_code on it, but co_argcount and co_varnames and + # co_flags are present. + pass + else: + raise TypeError('{!r} is not a code object'.format(co)) nargs = co.co_argcount names = co.co_varnames From noreply at buildbot.pypy.org Sun Oct 21 00:36:50 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 21 Oct 2012 00:36:50 +0200 (CEST) Subject: [pypy-commit] pypy python-numpy: merge numpypy-problems branch into branch Message-ID: <20121020223650.900271C0129@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: python-numpy Changeset: r58288:62538b72de87 Date: 2012-10-20 21:27 +0200 http://bitbucket.org/pypy/pypy/changeset/62538b72de87/ Log: merge numpypy-problems branch into branch diff too long, truncating to 2000 out of 91553 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,5 +1,6 @@ syntax: glob *.py[co] +*.sw[po] *~ .*.swp .idea diff --git a/lib-python/2.7/BaseHTTPServer.py b/lib-python/2.7/BaseHTTPServer.py --- a/lib-python/2.7/BaseHTTPServer.py +++ b/lib-python/2.7/BaseHTTPServer.py @@ -244,14 +244,11 @@ self.request_version = version = self.default_request_version self.close_connection = 1 requestline = self.raw_requestline - if requestline[-2:] == '\r\n': - requestline = requestline[:-2] - elif requestline[-1:] == '\n': - requestline = requestline[:-1] + requestline = requestline.rstrip('\r\n') self.requestline = requestline words = requestline.split() if len(words) == 3: - [command, path, version] = words + command, path, version = words if version[:5] != 'HTTP/': self.send_error(400, "Bad request version (%r)" % version) return False @@ -277,7 +274,7 @@ "Invalid HTTP Version (%s)" % base_version_number) return False elif len(words) == 2: - [command, path] = words + command, path = words self.close_connection = 1 if command != 'GET': self.send_error(400, diff --git a/lib-python/2.7/ConfigParser.py b/lib-python/2.7/ConfigParser.py --- a/lib-python/2.7/ConfigParser.py +++ b/lib-python/2.7/ConfigParser.py @@ -142,6 +142,7 @@ def __init__(self, section): Error.__init__(self, 'No section: %r' % (section,)) self.section = section + self.args = (section, ) class DuplicateSectionError(Error): """Raised when a section is multiply-created.""" @@ -149,6 +150,7 @@ def __init__(self, section): Error.__init__(self, "Section %r already exists" % section) self.section = section + self.args = (section, ) class NoOptionError(Error): """A requested option was not found.""" @@ -158,6 +160,7 @@ (option, section)) self.option = option self.section = section + self.args = (option, section) class InterpolationError(Error): """Base class for interpolation-related exceptions.""" @@ -166,6 +169,7 @@ Error.__init__(self, msg) self.option = option self.section = section + self.args = (option, section, msg) class InterpolationMissingOptionError(InterpolationError): """A string substitution required a setting which was not available.""" @@ -179,6 +183,7 @@ % (section, option, reference, rawval)) InterpolationError.__init__(self, option, section, msg) self.reference = reference + self.args = (option, section, rawval, reference) class InterpolationSyntaxError(InterpolationError): """Raised when the source text into which substitutions are made @@ -194,6 +199,7 @@ "\trawval : %s\n" % (section, option, rawval)) InterpolationError.__init__(self, option, section, msg) + self.args = (option, section, rawval) class ParsingError(Error): """Raised when a configuration file does not follow legal syntax.""" @@ -202,6 +208,7 @@ Error.__init__(self, 'File contains parsing errors: %s' % filename) self.filename = filename self.errors = [] + self.args = (filename, ) def append(self, lineno, line): self.errors.append((lineno, line)) @@ -218,6 +225,7 @@ self.filename = filename self.lineno = lineno self.line = line + self.args = (filename, lineno, line) class RawConfigParser: @@ -570,7 +578,7 @@ def keys(self): result = [] seen = set() - for mapping in self_maps: + for mapping in self._maps: for key in mapping: if key not in seen: result.append(key) diff --git a/lib-python/2.7/HTMLParser.py b/lib-python/2.7/HTMLParser.py --- a/lib-python/2.7/HTMLParser.py +++ b/lib-python/2.7/HTMLParser.py @@ -14,7 +14,6 @@ # Regular expressions used for parsing interesting_normal = re.compile('[&<]') -interesting_cdata = re.compile(r'<(/|\Z)') incomplete = re.compile('&[a-zA-Z#]') entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') @@ -24,25 +23,31 @@ piclose = re.compile('>') commentclose = re.compile(r'--\s*>') tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*') +# see http://www.w3.org/TR/html5/tokenization.html#tag-open-state +# and http://www.w3.org/TR/html5/tokenization.html#tag-name-state +tagfind_tolerant = re.compile('[a-zA-Z][^\t\n\r\f />\x00]*') + attrfind = re.compile( - r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' - r'(\'[^\']*\'|"[^"]*"|[^\s"\'=<>`]*))?') + r'[\s/]*((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' + r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*') locatestarttagend = re.compile(r""" <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name - (?:\s+ # whitespace before attribute name - (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name - (?:\s*=\s* # value indicator + (?:[\s/]* # optional whitespace before attribute name + (?:(?<=['"\s/])[^\s/>][^\s/=>]* # attribute name + (?:\s*=+\s* # value indicator (?:'[^']*' # LITA-enclosed value - |\"[^\"]*\" # LIT-enclosed value - |[^'\">\s]+ # bare value + |"[^"]*" # LIT-enclosed value + |(?!['"])[^>\s]* # bare value ) - )? - ) - )* + )?(?:\s|/(?!>))* + )* + )? \s* # trailing whitespace """, re.VERBOSE) endendtag = re.compile('>') +# the HTML 5 spec, section 8.1.2.2, doesn't allow spaces between +# ') @@ -96,6 +101,7 @@ self.rawdata = '' self.lasttag = '???' self.interesting = interesting_normal + self.cdata_elem = None markupbase.ParserBase.reset(self) def feed(self, data): @@ -120,11 +126,13 @@ """Return full source of start tag: '<...>'.""" return self.__starttag_text - def set_cdata_mode(self): - self.interesting = interesting_cdata + def set_cdata_mode(self, elem): + self.cdata_elem = elem.lower() + self.interesting = re.compile(r'' % self.cdata_elem, re.I) def clear_cdata_mode(self): self.interesting = interesting_normal + self.cdata_elem = None # Internal -- handle data as far as reasonable. May leave state # and data to be processed by a subsequent call. If 'end' is @@ -138,6 +146,8 @@ if match: j = match.start() else: + if self.cdata_elem: + break j = n if i < j: self.handle_data(rawdata[i:j]) i = self.updatepos(i, j) @@ -153,16 +163,23 @@ elif startswith("', i + 1) + if k < 0: + k = rawdata.find('<', i + 1) + if k < 0: + k = i + 1 + else: + k += 1 + self.handle_data(rawdata[i:k]) i = self.updatepos(i, k) elif startswith("&#", i): match = charref.match(rawdata, i) @@ -206,11 +223,46 @@ else: assert 0, "interesting.search() lied" # end while - if end and i < n: + if end and i < n and not self.cdata_elem: self.handle_data(rawdata[i:n]) i = self.updatepos(i, n) self.rawdata = rawdata[i:] + # Internal -- parse html declarations, return length or -1 if not terminated + # See w3.org/TR/html5/tokenization.html#markup-declaration-open-state + # See also parse_declaration in _markupbase + def parse_html_declaration(self, i): + rawdata = self.rawdata + if rawdata[i:i+2] != ' + gtpos = rawdata.find('>', i+9) + if gtpos == -1: + return -1 + self.handle_decl(rawdata[i+2:gtpos]) + return gtpos+1 + else: + return self.parse_bogus_comment(i) + + # Internal -- parse bogus comment, return length or -1 if not terminated + # see http://www.w3.org/TR/html5/tokenization.html#bogus-comment-state + def parse_bogus_comment(self, i, report=1): + rawdata = self.rawdata + if rawdata[i:i+2] not in ('', i+2) + if pos == -1: + return -1 + if report: + self.handle_comment(rawdata[i+2:pos]) + return pos + 1 + # Internal -- parse processing instr, return end or -1 if not terminated def parse_pi(self, i): rawdata = self.rawdata @@ -249,6 +301,7 @@ elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ attrvalue[:1] == '"' == attrvalue[-1:]: attrvalue = attrvalue[1:-1] + if attrvalue: attrvalue = self.unescape(attrvalue) attrs.append((attrname.lower(), attrvalue)) k = m.end() @@ -262,15 +315,15 @@ - self.__starttag_text.rfind("\n") else: offset = offset + len(self.__starttag_text) - self.error("junk characters in start tag: %r" - % (rawdata[k:endpos][:20],)) + self.handle_data(rawdata[i:endpos]) + return endpos if end.endswith('/>'): # XHTML-style empty tag: self.handle_startendtag(tag, attrs) else: self.handle_starttag(tag, attrs) if tag in self.CDATA_CONTENT_ELEMENTS: - self.set_cdata_mode() + self.set_cdata_mode(tag) return endpos # Internal -- check to see if we have a complete starttag; return end @@ -300,8 +353,10 @@ # end of input in or before attribute value, or we have the # '/' from a '/>' ending return -1 - self.updatepos(i, j) - self.error("malformed start tag") + if j > i: + return j + else: + return i + 1 raise AssertionError("we should not get here!") # Internal -- parse endtag, return end or -1 if incomplete @@ -311,14 +366,38 @@ match = endendtag.search(rawdata, i+1) # > if not match: return -1 - j = match.end() + gtpos = match.end() match = endtagfind.match(rawdata, i) # if not match: - self.error("bad end tag: %r" % (rawdata[i:j],)) - tag = match.group(1) - self.handle_endtag(tag.lower()) + if self.cdata_elem is not None: + self.handle_data(rawdata[i:gtpos]) + return gtpos + # find the name: w3.org/TR/html5/tokenization.html#tag-name-state + namematch = tagfind_tolerant.match(rawdata, i+2) + if not namematch: + # w3.org/TR/html5/tokenization.html#end-tag-open-state + if rawdata[i:i+3] == '': + return i+3 + else: + return self.parse_bogus_comment(i) + tagname = namematch.group().lower() + # consume and ignore other stuff between the name and the > + # Note: this is not 100% correct, since we might have things like + # , but looking for > after tha name should cover + # most of the cases and is much simpler + gtpos = rawdata.find('>', namematch.end()) + self.handle_endtag(tagname) + return gtpos+1 + + elem = match.group(1).lower() # script or style + if self.cdata_elem is not None: + if elem != self.cdata_elem: + self.handle_data(rawdata[i:gtpos]) + return gtpos + + self.handle_endtag(elem) self.clear_cdata_mode() - return j + return gtpos # Overridable -- finish processing of start+end tag: def handle_startendtag(self, tag, attrs): @@ -358,7 +437,7 @@ pass def unknown_decl(self, data): - self.error("unknown declaration: %r" % (data,)) + pass # Internal -- helper to remove special character quoting entitydefs = None diff --git a/lib-python/2.7/SocketServer.py b/lib-python/2.7/SocketServer.py --- a/lib-python/2.7/SocketServer.py +++ b/lib-python/2.7/SocketServer.py @@ -82,7 +82,7 @@ data is stored externally (e.g. in the file system), a synchronous class will essentially render the service "deaf" while one request is being handled -- which may be for a very long time if a client is slow -to reqd all the data it has requested. Here a threading or forking +to read all the data it has requested. Here a threading or forking server is appropriate. In some cases, it may be appropriate to process part of a request @@ -589,8 +589,7 @@ """Start a new thread to process the request.""" t = threading.Thread(target = self.process_request_thread, args = (request, client_address)) - if self.daemon_threads: - t.setDaemon (1) + t.daemon = self.daemon_threads t.start() diff --git a/lib-python/2.7/_pyio.py b/lib-python/2.7/_pyio.py --- a/lib-python/2.7/_pyio.py +++ b/lib-python/2.7/_pyio.py @@ -8,6 +8,7 @@ import abc import codecs import warnings +import errno # Import thread instead of threading to reduce startup cost try: from thread import allocate_lock as Lock @@ -720,8 +721,11 @@ def close(self): if self.raw is not None and not self.closed: - self.flush() - self.raw.close() + try: + # may raise BlockingIOError or BrokenPipeError etc + self.flush() + finally: + self.raw.close() def detach(self): if self.raw is None: @@ -1074,13 +1078,9 @@ # XXX we can implement some more tricks to try and avoid # partial writes if len(self._write_buf) > self.buffer_size: - # We're full, so let's pre-flush the buffer - try: - self._flush_unlocked() - except BlockingIOError as e: - # We can't accept anything else. - # XXX Why not just let the exception pass through? - raise BlockingIOError(e.errno, e.strerror, 0) + # We're full, so let's pre-flush the buffer. (This may + # raise BlockingIOError with characters_written == 0.) + self._flush_unlocked() before = len(self._write_buf) self._write_buf.extend(b) written = len(self._write_buf) - before @@ -1111,24 +1111,23 @@ def _flush_unlocked(self): if self.closed: raise ValueError("flush of closed file") - written = 0 - try: - while self._write_buf: - try: - n = self.raw.write(self._write_buf) - except IOError as e: - if e.errno != EINTR: - raise - continue - if n > len(self._write_buf) or n < 0: - raise IOError("write() returned incorrect number of bytes") - del self._write_buf[:n] - written += n - except BlockingIOError as e: - n = e.characters_written + while self._write_buf: + try: + n = self.raw.write(self._write_buf) + except BlockingIOError: + raise RuntimeError("self.raw should implement RawIOBase: it " + "should not raise BlockingIOError") + except IOError as e: + if e.errno != EINTR: + raise + continue + if n is None: + raise BlockingIOError( + errno.EAGAIN, + "write could not complete without blocking", 0) + if n > len(self._write_buf) or n < 0: + raise IOError("write() returned incorrect number of bytes") del self._write_buf[:n] - written += n - raise BlockingIOError(e.errno, e.strerror, written) def tell(self): return _BufferedIOMixin.tell(self) + len(self._write_buf) diff --git a/lib-python/2.7/aifc.py b/lib-python/2.7/aifc.py --- a/lib-python/2.7/aifc.py +++ b/lib-python/2.7/aifc.py @@ -162,6 +162,12 @@ except struct.error: raise EOFError +def _read_ushort(file): + try: + return struct.unpack('>H', file.read(2))[0] + except struct.error: + raise EOFError + def _read_string(file): length = ord(file.read(1)) if length == 0: @@ -194,13 +200,19 @@ def _write_short(f, x): f.write(struct.pack('>h', x)) +def _write_ushort(f, x): + f.write(struct.pack('>H', x)) + def _write_long(f, x): + f.write(struct.pack('>l', x)) + +def _write_ulong(f, x): f.write(struct.pack('>L', x)) def _write_string(f, s): if len(s) > 255: raise ValueError("string exceeds maximum pstring length") - f.write(chr(len(s))) + f.write(struct.pack('B', len(s))) f.write(s) if len(s) & 1 == 0: f.write(chr(0)) @@ -218,7 +230,7 @@ lomant = 0 else: fmant, expon = math.frexp(x) - if expon > 16384 or fmant >= 1: # Infinity or NaN + if expon > 16384 or fmant >= 1 or fmant != fmant: # Infinity or NaN expon = sign|0x7FFF himant = 0 lomant = 0 @@ -234,9 +246,9 @@ fmant = math.ldexp(fmant - fsmant, 32) fsmant = math.floor(fmant) lomant = long(fsmant) - _write_short(f, expon) - _write_long(f, himant) - _write_long(f, lomant) + _write_ushort(f, expon) + _write_ulong(f, himant) + _write_ulong(f, lomant) from chunk import Chunk @@ -840,15 +852,15 @@ if self._aifc: self._file.write('AIFC') self._file.write('FVER') - _write_long(self._file, 4) - _write_long(self._file, self._version) + _write_ulong(self._file, 4) + _write_ulong(self._file, self._version) else: self._file.write('AIFF') self._file.write('COMM') - _write_long(self._file, commlength) + _write_ulong(self._file, commlength) _write_short(self._file, self._nchannels) self._nframes_pos = self._file.tell() - _write_long(self._file, self._nframes) + _write_ulong(self._file, self._nframes) _write_short(self._file, self._sampwidth * 8) _write_float(self._file, self._framerate) if self._aifc: @@ -856,9 +868,9 @@ _write_string(self._file, self._compname) self._file.write('SSND') self._ssnd_length_pos = self._file.tell() - _write_long(self._file, self._datalength + 8) - _write_long(self._file, 0) - _write_long(self._file, 0) + _write_ulong(self._file, self._datalength + 8) + _write_ulong(self._file, 0) + _write_ulong(self._file, 0) def _write_form_length(self, datalength): if self._aifc: @@ -869,8 +881,8 @@ else: commlength = 18 verslength = 0 - _write_long(self._file, 4 + verslength + self._marklength + \ - 8 + commlength + 16 + datalength) + _write_ulong(self._file, 4 + verslength + self._marklength + \ + 8 + commlength + 16 + datalength) return commlength def _patchheader(self): @@ -888,9 +900,9 @@ self._file.seek(self._form_length_pos, 0) dummy = self._write_form_length(datalength) self._file.seek(self._nframes_pos, 0) - _write_long(self._file, self._nframeswritten) + _write_ulong(self._file, self._nframeswritten) self._file.seek(self._ssnd_length_pos, 0) - _write_long(self._file, datalength + 8) + _write_ulong(self._file, datalength + 8) self._file.seek(curpos, 0) self._nframes = self._nframeswritten self._datalength = datalength @@ -905,13 +917,13 @@ length = length + len(name) + 1 + 6 if len(name) & 1 == 0: length = length + 1 - _write_long(self._file, length) + _write_ulong(self._file, length) self._marklength = length + 8 _write_short(self._file, len(self._markers)) for marker in self._markers: id, pos, name = marker _write_short(self._file, id) - _write_long(self._file, pos) + _write_ulong(self._file, pos) _write_string(self._file, name) def open(f, mode=None): diff --git a/lib-python/2.7/asyncore.py b/lib-python/2.7/asyncore.py --- a/lib-python/2.7/asyncore.py +++ b/lib-python/2.7/asyncore.py @@ -132,7 +132,8 @@ is_w = obj.writable() if is_r: r.append(fd) - if is_w: + # accepting sockets should not be writable + if is_w and not obj.accepting: w.append(fd) if is_r or is_w: e.append(fd) @@ -179,7 +180,8 @@ flags = 0 if obj.readable(): flags |= select.POLLIN | select.POLLPRI - if obj.writable(): + # accepting sockets should not be writable + if obj.writable() and not obj.accepting: flags |= select.POLLOUT if flags: # Only check for exceptions if object was either readable diff --git a/lib-python/2.7/cgi.py b/lib-python/2.7/cgi.py --- a/lib-python/2.7/cgi.py +++ b/lib-python/2.7/cgi.py @@ -293,7 +293,7 @@ while s[:1] == ';': s = s[1:] end = s.find(';') - while end > 0 and s.count('"', 0, end) % 2: + while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: end = s.find(';', end + 1) if end < 0: end = len(s) diff --git a/lib-python/2.7/cmd.py b/lib-python/2.7/cmd.py --- a/lib-python/2.7/cmd.py +++ b/lib-python/2.7/cmd.py @@ -209,6 +209,8 @@ if cmd is None: return self.default(line) self.lastcmd = line + if line == 'EOF' : + self.lastcmd = '' if cmd == '': return self.default(line) else: diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -312,6 +312,7 @@ def _asdict(self): 'Return a new OrderedDict which maps field names to their values' return OrderedDict(zip(self._fields, self)) \n + __dict__ = property(_asdict) \n def _replace(_self, **kwds): 'Return a new %(typename)s object replacing specified fields with new values' result = _self._make(map(kwds.pop, %(field_names)r, _self)) diff --git a/lib-python/2.7/compileall.py b/lib-python/2.7/compileall.py --- a/lib-python/2.7/compileall.py +++ b/lib-python/2.7/compileall.py @@ -1,4 +1,4 @@ -"""Module/script to "compile" all .py files to .pyc (or .pyo) file. +"""Module/script to byte-compile all .py files to .pyc (or .pyo) files. When called as a script with arguments, this compiles the directories given as arguments recursively; the -l option prevents it from @@ -26,8 +26,8 @@ dir: the directory to byte-compile maxlevels: maximum recursion level (default 10) - ddir: if given, purported directory name (this is the - directory name that will show up in error messages) + ddir: the directory that will be prepended to the path to the + file as it is compiled into each byte-code file. force: if 1, force compilation, even if timestamps are up-to-date quiet: if 1, be quiet during compilation """ @@ -64,8 +64,8 @@ Arguments (only fullname is required): fullname: the file to byte-compile - ddir: if given, purported directory name (this is the - directory name that will show up in error messages) + ddir: if given, the directory name compiled in to the + byte-code file. force: if 1, force compilation, even if timestamps are up-to-date quiet: if 1, be quiet during compilation """ @@ -157,14 +157,27 @@ print msg print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \ "[-x regexp] [-i list] [directory|file ...]" - print "-l: don't recurse down" + print + print "arguments: zero or more file and directory names to compile; " \ + "if no arguments given, " + print " defaults to the equivalent of -l sys.path" + print + print "options:" + print "-l: don't recurse into subdirectories" print "-f: force rebuild even if timestamps are up-to-date" - print "-q: quiet operation" - print "-d destdir: purported directory name for error messages" - print " if no directory arguments, -l sys.path is assumed" - print "-x regexp: skip files matching the regular expression regexp" - print " the regexp is searched for in the full path of the file" - print "-i list: expand list with its content (file and directory names)" + print "-q: output only error messages" + print "-d destdir: directory to prepend to file paths for use in " \ + "compile-time tracebacks and in" + print " runtime tracebacks in cases where the source " \ + "file is unavailable" + print "-x regexp: skip files matching the regular expression regexp; " \ + "the regexp is searched for" + print " in the full path of each file considered for " \ + "compilation" + print "-i file: add all the files and directories listed in file to " \ + "the list considered for" + print ' compilation; if "-", names are read from stdin' + sys.exit(2) maxlevels = 10 ddir = None @@ -205,7 +218,7 @@ else: success = compile_path() except KeyboardInterrupt: - print "\n[interrupt]" + print "\n[interrupted]" success = 0 return success diff --git a/lib-python/2.7/cookielib.py b/lib-python/2.7/cookielib.py --- a/lib-python/2.7/cookielib.py +++ b/lib-python/2.7/cookielib.py @@ -1014,7 +1014,7 @@ (not erhn.startswith(".") and not ("."+erhn).endswith(domain))): _debug(" effective request-host %s (even with added " - "initial dot) does not end end with %s", + "initial dot) does not end with %s", erhn, domain) return False if (cookie.version > 0 or diff --git a/lib-python/2.7/ctypes/__init__.py b/lib-python/2.7/ctypes/__init__.py --- a/lib-python/2.7/ctypes/__init__.py +++ b/lib-python/2.7/ctypes/__init__.py @@ -263,6 +263,22 @@ from _ctypes import POINTER, pointer, _pointer_type_cache +def _reset_cache(): + _pointer_type_cache.clear() + _c_functype_cache.clear() + if _os.name in ("nt", "ce"): + _win_functype_cache.clear() + # _SimpleCData.c_wchar_p_from_param + POINTER(c_wchar).from_param = c_wchar_p.from_param + # _SimpleCData.c_char_p_from_param + POINTER(c_char).from_param = c_char_p.from_param + _pointer_type_cache[None] = c_void_p + # XXX for whatever reasons, creating the first instance of a callback + # function is needed for the unittests on Win64 to succeed. This MAY + # be a compiler bug, since the problem occurs only when _ctypes is + # compiled with the MS SDK compiler. Or an uninitialized variable? + CFUNCTYPE(c_int)(lambda: None) + try: from _ctypes import set_conversion_mode except ImportError: @@ -279,8 +295,6 @@ class c_wchar(_SimpleCData): _type_ = "u" - POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param - def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array @@ -299,8 +313,6 @@ return buf raise TypeError(init) -POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param - # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: @@ -463,8 +475,6 @@ descr = FormatError(code).strip() return WindowsError(code, descr) -_pointer_type_cache[None] = c_void_p - if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int @@ -550,8 +560,4 @@ elif sizeof(kind) == 8: c_uint64 = kind del(kind) -# XXX for whatever reasons, creating the first instance of a callback -# function is needed for the unittests on Win64 to succeed. This MAY -# be a compiler bug, since the problem occurs only when _ctypes is -# compiled with the MS SDK compiler. Or an uninitialized variable? -CFUNCTYPE(c_int)(lambda: None) +_reset_cache() diff --git a/lib-python/2.7/ctypes/_endian.py b/lib-python/2.7/ctypes/_endian.py --- a/lib-python/2.7/ctypes/_endian.py +++ b/lib-python/2.7/ctypes/_endian.py @@ -4,20 +4,24 @@ import sys from ctypes import * -_array_type = type(c_int * 3) +_array_type = type(Array) def _other_endian(typ): """Return the type with the 'other' byte order. Simple types like c_int and so on already have __ctype_be__ and __ctype_le__ attributes which contain the types, for more complicated types - only arrays are supported. + arrays and structures are supported. """ - try: + # check _OTHER_ENDIAN attribute (present if typ is primitive type) + if hasattr(typ, _OTHER_ENDIAN): return getattr(typ, _OTHER_ENDIAN) - except AttributeError: - if type(typ) == _array_type: - return _other_endian(typ._type_) * typ._length_ - raise TypeError("This type does not support other endian: %s" % typ) + # if typ is array + if isinstance(typ, _array_type): + return _other_endian(typ._type_) * typ._length_ + # if typ is structure + if issubclass(typ, Structure): + return typ + raise TypeError("This type does not support other endian: %s" % typ) class _swapped_meta(type(Structure)): def __setattr__(self, attrname, value): diff --git a/lib-python/2.7/ctypes/test/test_as_parameter.py b/lib-python/2.7/ctypes/test/test_as_parameter.py --- a/lib-python/2.7/ctypes/test/test_as_parameter.py +++ b/lib-python/2.7/ctypes/test/test_as_parameter.py @@ -74,6 +74,7 @@ def test_callbacks(self): f = dll._testfunc_callback_i_if f.restype = c_int + f.argtypes = None MyCallback = CFUNCTYPE(c_int, c_int) diff --git a/lib-python/2.7/ctypes/test/test_buffers.py b/lib-python/2.7/ctypes/test/test_buffers.py --- a/lib-python/2.7/ctypes/test/test_buffers.py +++ b/lib-python/2.7/ctypes/test/test_buffers.py @@ -20,6 +20,10 @@ self.assertEqual(b[::2], "ac") self.assertEqual(b[::5], "a") + def test_buffer_interface(self): + self.assertEqual(len(bytearray(create_string_buffer(0))), 0) + self.assertEqual(len(bytearray(create_string_buffer(1))), 1) + def test_string_conversion(self): b = create_string_buffer(u"abc") self.assertEqual(len(b), 4) # trailing nul char diff --git a/lib-python/2.7/ctypes/test/test_byteswap.py b/lib-python/2.7/ctypes/test/test_byteswap.py --- a/lib-python/2.7/ctypes/test/test_byteswap.py +++ b/lib-python/2.7/ctypes/test/test_byteswap.py @@ -1,4 +1,4 @@ -import sys, unittest, struct, math +import sys, unittest, struct, math, ctypes from binascii import hexlify from ctypes import * @@ -191,19 +191,34 @@ pass self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)]) + @xfail def test_struct_struct(self): - # Nested structures with different byte order not (yet) supported - if sys.byteorder == "little": - base = BigEndianStructure - else: - base = LittleEndianStructure + # nested structures with different byteorders - class T(Structure): - _fields_ = [("a", c_int), - ("b", c_int)] - class S(base): - pass - self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)]) + # create nested structures with given byteorders and set memory to data + + for nested, data in ( + (BigEndianStructure, b'\0\0\0\1\0\0\0\2'), + (LittleEndianStructure, b'\1\0\0\0\2\0\0\0'), + ): + for parent in ( + BigEndianStructure, + LittleEndianStructure, + Structure, + ): + class NestedStructure(nested): + _fields_ = [("x", c_uint32), + ("y", c_uint32)] + + class TestStructure(parent): + _fields_ = [("point", NestedStructure)] + + self.assertEqual(len(data), sizeof(TestStructure)) + ptr = POINTER(TestStructure) + s = cast(data, ptr)[0] + del ctypes._pointer_type_cache[TestStructure] + self.assertEqual(s.point.x, 1) + self.assertEqual(s.point.y, 2) @xfail def test_struct_fields_2(self): diff --git a/lib-python/2.7/ctypes/test/test_callbacks.py b/lib-python/2.7/ctypes/test/test_callbacks.py --- a/lib-python/2.7/ctypes/test/test_callbacks.py +++ b/lib-python/2.7/ctypes/test/test_callbacks.py @@ -142,6 +142,14 @@ if isinstance(x, X)] self.assertEqual(len(live), 0) + def test_issue12483(self): + import gc + class Nasty: + def __del__(self): + gc.collect() + CFUNCTYPE(None)(lambda x=Nasty(): None) + + try: WINFUNCTYPE except NameError: diff --git a/lib-python/2.7/ctypes/test/test_functions.py b/lib-python/2.7/ctypes/test/test_functions.py --- a/lib-python/2.7/ctypes/test/test_functions.py +++ b/lib-python/2.7/ctypes/test/test_functions.py @@ -253,6 +253,7 @@ def test_callbacks(self): f = dll._testfunc_callback_i_if f.restype = c_int + f.argtypes = None MyCallback = CFUNCTYPE(c_int, c_int) diff --git a/lib-python/2.7/ctypes/test/test_structures.py b/lib-python/2.7/ctypes/test/test_structures.py --- a/lib-python/2.7/ctypes/test/test_structures.py +++ b/lib-python/2.7/ctypes/test/test_structures.py @@ -239,6 +239,14 @@ pass self.assertRaises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)]) + def test_invalid_name(self): + # field name must be string + def declare_with_name(name): + class S(Structure): + _fields_ = [(name, c_int)] + + self.assertRaises(TypeError, declare_with_name, u"x\xe9") + def test_intarray_fields(self): class SomeInts(Structure): _fields_ = [("a", c_int * 4)] @@ -324,6 +332,18 @@ else: self.assertEqual(msg, "(Phone) exceptions.TypeError: too many initializers") + def test_huge_field_name(self): + # issue12881: segfault with large structure field names + def create_class(length): + class S(Structure): + _fields_ = [('x' * length, c_int)] + + for length in [10 ** i for i in range(0, 8)]: + try: + create_class(length) + except MemoryError: + # MemoryErrors are OK, we just don't want to segfault + pass def get_except(self, func, *args): try: diff --git a/lib-python/2.7/ctypes/util.py b/lib-python/2.7/ctypes/util.py --- a/lib-python/2.7/ctypes/util.py +++ b/lib-python/2.7/ctypes/util.py @@ -182,28 +182,6 @@ else: - def _findLib_ldconfig(name): - # XXX assuming GLIBC's ldconfig (with option -p) - expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) - f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null') - try: - data = f.read() - finally: - f.close() - res = re.search(expr, data) - if not res: - # Hm, this works only for libs needed by the python executable. - cmd = 'ldd %s 2>/dev/null' % sys.executable - f = os.popen(cmd) - try: - data = f.read() - finally: - f.close() - res = re.search(expr, data) - if not res: - return None - return res.group(0) - def _findSoname_ldconfig(name): import struct if struct.calcsize('l') == 4: @@ -220,8 +198,7 @@ abi_type = mach_map.get(machine, 'libc6') # XXX assuming GLIBC's ldconfig (with option -p) - expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \ - % (abi_type, re.escape(name)) + expr = r'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type) f = os.popen('/sbin/ldconfig -p 2>/dev/null') try: data = f.read() diff --git a/lib-python/2.7/decimal.py b/lib-python/2.7/decimal.py --- a/lib-python/2.7/decimal.py +++ b/lib-python/2.7/decimal.py @@ -21,7 +21,7 @@ This is a Py2.3 implementation of decimal floating point arithmetic based on the General Decimal Arithmetic Specification: - www2.hursley.ibm.com/decimal/decarith.html + http://speleotrove.com/decimal/decarith.html and IEEE standard 854-1987: @@ -1942,9 +1942,9 @@ nonzero. For efficiency, other._exp should not be too large, so that 10**abs(other._exp) is a feasible calculation.""" - # In the comments below, we write x for the value of self and - # y for the value of other. Write x = xc*10**xe and y = - # yc*10**ye. + # In the comments below, we write x for the value of self and y for the + # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc + # and yc positive integers not divisible by 10. # The main purpose of this method is to identify the *failure* # of x**y to be exactly representable with as little effort as @@ -1952,13 +1952,12 @@ # eliminate the possibility of x**y being exact. Only if all # these tests are passed do we go on to actually compute x**y. - # Here's the main idea. First normalize both x and y. We - # express y as a rational m/n, with m and n relatively prime - # and n>0. Then for x**y to be exactly representable (at - # *any* precision), xc must be the nth power of a positive - # integer and xe must be divisible by n. If m is negative - # then additionally xc must be a power of either 2 or 5, hence - # a power of 2**n or 5**n. + # Here's the main idea. Express y as a rational number m/n, with m and + # n relatively prime and n>0. Then for x**y to be exactly + # representable (at *any* precision), xc must be the nth power of a + # positive integer and xe must be divisible by n. If y is negative + # then additionally xc must be a power of either 2 or 5, hence a power + # of 2**n or 5**n. # # There's a limit to how small |y| can be: if y=m/n as above # then: @@ -2030,21 +2029,43 @@ return None # now xc is a power of 2; e is its exponent e = _nbits(xc)-1 - # find e*y and xe*y; both must be integers - if ye >= 0: - y_as_int = yc*10**ye - e = e*y_as_int - xe = xe*y_as_int - else: - ten_pow = 10**-ye - e, remainder = divmod(e*yc, ten_pow) - if remainder: - return None - xe, remainder = divmod(xe*yc, ten_pow) - if remainder: - return None - - if e*65 >= p*93: # 93/65 > log(10)/log(5) + + # We now have: + # + # x = 2**e * 10**xe, e > 0, and y < 0. + # + # The exact result is: + # + # x**y = 5**(-e*y) * 10**(e*y + xe*y) + # + # provided that both e*y and xe*y are integers. Note that if + # 5**(-e*y) >= 10**p, then the result can't be expressed + # exactly with p digits of precision. + # + # Using the above, we can guard against large values of ye. + # 93/65 is an upper bound for log(10)/log(5), so if + # + # ye >= len(str(93*p//65)) + # + # then + # + # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), + # + # so 5**(-e*y) >= 10**p, and the coefficient of the result + # can't be expressed in p digits. + + # emax >= largest e such that 5**e < 10**p. + emax = p*93//65 + if ye >= len(str(emax)): + return None + + # Find -e*y and -xe*y; both must be integers + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: return None xc = 5**e @@ -2058,19 +2079,20 @@ while xc % 5 == 0: xc //= 5 e -= 1 - if ye >= 0: - y_as_integer = yc*10**ye - e = e*y_as_integer - xe = xe*y_as_integer - else: - ten_pow = 10**-ye - e, remainder = divmod(e*yc, ten_pow) - if remainder: - return None - xe, remainder = divmod(xe*yc, ten_pow) - if remainder: - return None - if e*3 >= p*10: # 10/3 > log(10)/log(2) + + # Guard against large values of ye, using the same logic as in + # the 'xc is a power of 2' branch. 10/3 is an upper bound for + # log(10)/log(2). + emax = p*10//3 + if ye >= len(str(emax)): + return None + + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: return None xc = 2**e else: @@ -5463,6 +5485,27 @@ hex_n = "%x" % n return 4*len(hex_n) - correction[hex_n[0]] +def _decimal_lshift_exact(n, e): + """ Given integers n and e, return n * 10**e if it's an integer, else None. + + The computation is designed to avoid computing large powers of 10 + unnecessarily. + + >>> _decimal_lshift_exact(3, 4) + 30000 + >>> _decimal_lshift_exact(300, -999999999) # returns None + + """ + if n == 0: + return 0 + elif e >= 0: + return n * 10**e + else: + # val_n = largest power of 10 dividing n. + str_n = str(abs(n)) + val_n = len(str_n) - len(str_n.rstrip('0')) + return None if val_n < -e else n // 10**-e + def _sqrt_nearest(n, a): """Closest integer to the square root of the positive integer n. a is an initial approximation to the square root. Any positive integer diff --git a/lib-python/2.7/distutils/__init__.py b/lib-python/2.7/distutils/__init__.py --- a/lib-python/2.7/distutils/__init__.py +++ b/lib-python/2.7/distutils/__init__.py @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "2.7.2" +__version__ = "2.7.3" #--end constants-- diff --git a/lib-python/2.7/distutils/ccompiler.py b/lib-python/2.7/distutils/ccompiler.py --- a/lib-python/2.7/distutils/ccompiler.py +++ b/lib-python/2.7/distutils/ccompiler.py @@ -18,58 +18,6 @@ from distutils.util import split_quoted, execute from distutils import log -_sysconfig = __import__('sysconfig') - -def customize_compiler(compiler): - """Do any platform-specific customization of a CCompiler instance. - - Mainly needed on Unix, so we can plug in the information that - varies across Unices and is stored in Python's Makefile. - """ - if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ - _sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO', 'AR', - 'ARFLAGS') - - if 'CC' in os.environ: - cc = os.environ['CC'] - if 'CXX' in os.environ: - cxx = os.environ['CXX'] - if 'LDSHARED' in os.environ: - ldshared = os.environ['LDSHARED'] - if 'CPP' in os.environ: - cpp = os.environ['CPP'] - else: - cpp = cc + " -E" # not always - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: - cflags = opt + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] - cflags = cflags + ' ' + os.environ['CPPFLAGS'] - ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - if 'AR' in os.environ: - ar = os.environ['AR'] - if 'ARFLAGS' in os.environ: - archiver = ar + ' ' + os.environ['ARFLAGS'] - else: - archiver = ar + ' ' + ar_flags - - cc_cmd = cc + ' ' + cflags - compiler.set_executables( - preprocessor=cpp, - compiler=cc_cmd, - compiler_so=cc_cmd + ' ' + ccshared, - compiler_cxx=cxx, - linker_so=ldshared, - linker_exe=cc, - archiver=archiver) - - compiler.shared_lib_extension = so_ext - class CCompiler: """Abstract base class to define the interface that must be implemented by real compiler classes. Also has some utility methods used by diff --git a/lib-python/2.7/distutils/command/bdist_dumb.py b/lib-python/2.7/distutils/command/bdist_dumb.py --- a/lib-python/2.7/distutils/command/bdist_dumb.py +++ b/lib-python/2.7/distutils/command/bdist_dumb.py @@ -58,7 +58,7 @@ self.format = None self.keep_temp = 0 self.dist_dir = None - self.skip_build = 0 + self.skip_build = None self.relative = 0 self.owner = None self.group = None @@ -78,7 +78,8 @@ self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'), - ('plat_name', 'plat_name')) + ('plat_name', 'plat_name'), + ('skip_build', 'skip_build')) def run(self): if not self.skip_build: diff --git a/lib-python/2.7/distutils/command/bdist_msi.py b/lib-python/2.7/distutils/command/bdist_msi.py --- a/lib-python/2.7/distutils/command/bdist_msi.py +++ b/lib-python/2.7/distutils/command/bdist_msi.py @@ -131,18 +131,22 @@ self.no_target_optimize = 0 self.target_version = None self.dist_dir = None - self.skip_build = 0 + self.skip_build = None self.install_script = None self.pre_install_script = None self.versions = None def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'msi') + short_version = get_python_version() if (not self.target_version) and self.distribution.has_ext_modules(): self.target_version = short_version + if self.target_version: self.versions = [self.target_version] if not self.skip_build and self.distribution.has_ext_modules()\ diff --git a/lib-python/2.7/distutils/command/bdist_wininst.py b/lib-python/2.7/distutils/command/bdist_wininst.py --- a/lib-python/2.7/distutils/command/bdist_wininst.py +++ b/lib-python/2.7/distutils/command/bdist_wininst.py @@ -71,7 +71,7 @@ self.dist_dir = None self.bitmap = None self.title = None - self.skip_build = 0 + self.skip_build = None self.install_script = None self.pre_install_script = None self.user_access_control = None @@ -80,6 +80,8 @@ def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + if self.bdist_dir is None: if self.skip_build and self.plat_name: # If build is skipped and plat_name is overridden, bdist will @@ -89,8 +91,10 @@ # next the command will be initialized using that name bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'wininst') + if not self.target_version: self.target_version = "" + if not self.skip_build and self.distribution.has_ext_modules(): short_version = get_python_version() if self.target_version and self.target_version != short_version: diff --git a/lib-python/2.7/distutils/command/build_clib.py b/lib-python/2.7/distutils/command/build_clib.py --- a/lib-python/2.7/distutils/command/build_clib.py +++ b/lib-python/2.7/distutils/command/build_clib.py @@ -19,7 +19,7 @@ import os from distutils.core import Command from distutils.errors import DistutilsSetupError -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler from distutils import log def show_compilers(): diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py --- a/lib-python/2.7/distutils/command/build_ext.py +++ b/lib-python/2.7/distutils/command/build_ext.py @@ -160,8 +160,7 @@ if plat_py_include != py_include: self.include_dirs.append(plat_py_include) - if isinstance(self.libraries, str): - self.libraries = [self.libraries] + self.ensure_string_list('libraries') # Life is easier if we're not forever checking for None, so # simplify these options to empty lists if unset diff --git a/lib-python/2.7/distutils/command/check.py b/lib-python/2.7/distutils/command/check.py --- a/lib-python/2.7/distutils/command/check.py +++ b/lib-python/2.7/distutils/command/check.py @@ -5,6 +5,7 @@ __revision__ = "$Id$" from distutils.core import Command +from distutils.dist import PKG_INFO_ENCODING from distutils.errors import DistutilsSetupError try: @@ -108,6 +109,8 @@ def check_restructuredtext(self): """Checks if the long string fields are reST-compliant.""" data = self.distribution.get_long_description() + if not isinstance(data, unicode): + data = data.decode(PKG_INFO_ENCODING) for warning in self._check_rst_data(data): line = warning[-1].get('line') if line is None: diff --git a/lib-python/2.7/distutils/command/config.py b/lib-python/2.7/distutils/command/config.py --- a/lib-python/2.7/distutils/command/config.py +++ b/lib-python/2.7/distutils/command/config.py @@ -16,7 +16,7 @@ from distutils.core import Command from distutils.errors import DistutilsExecError -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler from distutils import log LANG_EXT = {'c': '.c', 'c++': '.cxx'} diff --git a/lib-python/2.7/distutils/command/register.py b/lib-python/2.7/distutils/command/register.py --- a/lib-python/2.7/distutils/command/register.py +++ b/lib-python/2.7/distutils/command/register.py @@ -10,7 +10,6 @@ import urllib2 import getpass import urlparse -import StringIO from warnings import warn from distutils.core import PyPIRCCommand @@ -260,21 +259,30 @@ boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = '\n--' + boundary end_boundary = sep_boundary + '--' - body = StringIO.StringIO() + chunks = [] for key, value in data.items(): # handle multiple entries for the same name if type(value) not in (type([]), type( () )): value = [value] for value in value: - body.write(sep_boundary) - body.write('\nContent-Disposition: form-data; name="%s"'%key) - body.write("\n\n") - body.write(value) + chunks.append(sep_boundary) + chunks.append('\nContent-Disposition: form-data; name="%s"'%key) + chunks.append("\n\n") + chunks.append(value) if value and value[-1] == '\r': - body.write('\n') # write an extra newline (lurve Macs) - body.write(end_boundary) - body.write("\n") - body = body.getvalue() + chunks.append('\n') # write an extra newline (lurve Macs) + chunks.append(end_boundary) + chunks.append("\n") + + # chunks may be bytes (str) or unicode objects that we need to encode + body = [] + for chunk in chunks: + if isinstance(chunk, unicode): + body.append(chunk.encode('utf-8')) + else: + body.append(chunk) + + body = ''.join(body) # build the Request headers = { diff --git a/lib-python/2.7/distutils/command/sdist.py b/lib-python/2.7/distutils/command/sdist.py --- a/lib-python/2.7/distutils/command/sdist.py +++ b/lib-python/2.7/distutils/command/sdist.py @@ -182,14 +182,20 @@ reading the manifest, or just using the default file set -- it all depends on the user's options. """ - # new behavior: + # new behavior when using a template: # the file list is recalculated everytime because # even if MANIFEST.in or setup.py are not changed # the user might have added some files in the tree that # need to be included. # - # This makes --force the default and only behavior. + # This makes --force the default and only behavior with templates. template_exists = os.path.isfile(self.template) + if not template_exists and self._manifest_is_not_generated(): + self.read_manifest() + self.filelist.sort() + self.filelist.remove_duplicates() + return + if not template_exists: self.warn(("manifest template '%s' does not exist " + "(using default file list)") % @@ -314,7 +320,10 @@ try: self.filelist.process_template_line(line) - except DistutilsTemplateError, msg: + # the call above can raise a DistutilsTemplateError for + # malformed lines, or a ValueError from the lower-level + # convert_path function + except (DistutilsTemplateError, ValueError) as msg: self.warn("%s, line %d: %s" % (template.filename, template.current_line, msg)) @@ -352,23 +361,28 @@ by 'add_defaults()' and 'read_template()') to the manifest file named by 'self.manifest'. """ - if os.path.isfile(self.manifest): - fp = open(self.manifest) - try: - first_line = fp.readline() - finally: - fp.close() - - if first_line != '# file GENERATED by distutils, do NOT edit\n': - log.info("not writing to manually maintained " - "manifest file '%s'" % self.manifest) - return + if self._manifest_is_not_generated(): + log.info("not writing to manually maintained " + "manifest file '%s'" % self.manifest) + return content = self.filelist.files[:] content.insert(0, '# file GENERATED by distutils, do NOT edit') self.execute(file_util.write_file, (self.manifest, content), "writing manifest file '%s'" % self.manifest) + def _manifest_is_not_generated(self): + # check for special comment used in 2.7.1 and higher + if not os.path.isfile(self.manifest): + return False + + fp = open(self.manifest, 'rU') + try: + first_line = fp.readline() + finally: + fp.close() + return first_line != '# file GENERATED by distutils, do NOT edit\n' + def read_manifest(self): """Read the manifest file (named by 'self.manifest') and use it to fill in 'self.filelist', the list of files to include in the source @@ -376,12 +390,11 @@ """ log.info("reading manifest file '%s'", self.manifest) manifest = open(self.manifest) - while 1: - line = manifest.readline() - if line == '': # end of file - break - if line[-1] == '\n': - line = line[0:-1] + for line in manifest: + # ignore comments and blank lines + line = line.strip() + if line.startswith('#') or not line: + continue self.filelist.append(line) manifest.close() diff --git a/lib-python/2.7/distutils/dep_util.py b/lib-python/2.7/distutils/dep_util.py --- a/lib-python/2.7/distutils/dep_util.py +++ b/lib-python/2.7/distutils/dep_util.py @@ -7,6 +7,7 @@ __revision__ = "$Id$" import os +from stat import ST_MTIME from distutils.errors import DistutilsFileError def newer(source, target): @@ -27,7 +28,7 @@ if not os.path.exists(target): return True - return os.stat(source).st_mtime > os.stat(target).st_mtime + return os.stat(source)[ST_MTIME] > os.stat(target)[ST_MTIME] def newer_pairwise(sources, targets): """Walk two filename lists in parallel, testing if each source is newer @@ -71,7 +72,7 @@ # is more recent than 'target', then 'target' is out-of-date and # we can immediately return true. If we fall through to the end # of the loop, then 'target' is up-to-date and we return false. - target_mtime = os.stat(target).st_mtime + target_mtime = os.stat(target)[ST_MTIME] for source in sources: if not os.path.exists(source): @@ -82,7 +83,7 @@ elif missing == 'newer': # missing source means target is return True # out-of-date - if os.stat(source).st_mtime > target_mtime: + if os.stat(source)[ST_MTIME] > target_mtime: return True return False diff --git a/lib-python/2.7/distutils/dist.py b/lib-python/2.7/distutils/dist.py --- a/lib-python/2.7/distutils/dist.py +++ b/lib-python/2.7/distutils/dist.py @@ -1111,7 +1111,8 @@ """Write the PKG-INFO format data to a file object. """ version = '1.0' - if self.provides or self.requires or self.obsoletes: + if (self.provides or self.requires or self.obsoletes or + self.classifiers or self.download_url): version = '1.1' self._write_field(file, 'Metadata-Version', version) diff --git a/lib-python/2.7/distutils/filelist.py b/lib-python/2.7/distutils/filelist.py --- a/lib-python/2.7/distutils/filelist.py +++ b/lib-python/2.7/distutils/filelist.py @@ -210,6 +210,7 @@ Return 1 if files are found. """ + # XXX docstring lying about what the special chars are? files_found = 0 pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) self.debug_print("include_pattern: applying regex r'%s'" % @@ -297,11 +298,14 @@ # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, # and by extension they shouldn't match such "special characters" under # any OS. So change all non-escaped dots in the RE to match any - # character except the special characters. - # XXX currently the "special characters" are just slash -- i.e. this is - # Unix-only. - pattern_re = re.sub(r'((?\s*" manifest_buf = re.sub(pattern, "", manifest_buf) + # Now see if any other assemblies are referenced - if not, we + # don't want a manifest embedded. + pattern = re.compile( + r"""|)""", re.DOTALL) + if re.search(pattern, manifest_buf) is None: + return None + manifest_f = open(manifest_file, 'w') try: manifest_f.write(manifest_buf) + return manifest_file finally: manifest_f.close() except IOError: diff --git a/lib-python/2.7/distutils/spawn.py b/lib-python/2.7/distutils/spawn.py --- a/lib-python/2.7/distutils/spawn.py +++ b/lib-python/2.7/distutils/spawn.py @@ -96,17 +96,43 @@ raise DistutilsExecError, \ "command '%s' failed with exit status %d" % (cmd[0], rc) +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return exec_fn = search_path and os.execvp or os.execv + exec_args = [cmd[0], cmd] + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(cmd[0], cmd) + exec_fn(*exec_args) except OSError, e: sys.stderr.write("unable to execute %s: %s\n" % (cmd[0], e.strerror)) diff --git a/lib-python/2.7/distutils/sysconfig.py b/lib-python/2.7/distutils/sysconfig.py --- a/lib-python/2.7/distutils/sysconfig.py +++ b/lib-python/2.7/distutils/sysconfig.py @@ -26,4 +26,5 @@ from distutils.sysconfig_cpython import _config_vars # needed by setuptools from distutils.sysconfig_cpython import _variable_rx # read_setup_file() +_USE_CLANG = None diff --git a/lib-python/2.7/distutils/sysconfig_cpython.py b/lib-python/2.7/distutils/sysconfig_cpython.py --- a/lib-python/2.7/distutils/sysconfig_cpython.py +++ b/lib-python/2.7/distutils/sysconfig_cpython.py @@ -149,12 +149,43 @@ varies across Unices and is stored in Python's Makefile. """ if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \ + (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO') + 'CCSHARED', 'LDSHARED', 'SO', 'AR', + 'ARFLAGS') + newcc = None if 'CC' in os.environ: - cc = os.environ['CC'] + newcc = os.environ['CC'] + elif sys.platform == 'darwin' and cc == 'gcc-4.2': + # Issue #13590: + # Since Apple removed gcc-4.2 in Xcode 4.2, we can no + # longer assume it is available for extension module builds. + # If Python was built with gcc-4.2, check first to see if + # it is available on this system; if not, try to use clang + # instead unless the caller explicitly set CC. + global _USE_CLANG + if _USE_CLANG is None: + from distutils import log + from subprocess import Popen, PIPE + p = Popen("! type gcc-4.2 && type clang && exit 2", + shell=True, stdout=PIPE, stderr=PIPE) + p.wait() + if p.returncode == 2: + _USE_CLANG = True + log.warn("gcc-4.2 not found, using clang instead") + else: + _USE_CLANG = False + if _USE_CLANG: + newcc = 'clang' + if newcc: + # On OS X, if CC is overridden, use that as the default + # command for LDSHARED as well + if (sys.platform == 'darwin' + and 'LDSHARED' not in os.environ + and ldshared.startswith(cc)): + ldshared = newcc + ldshared[len(cc):] + cc = newcc if 'CXX' in os.environ: cxx = os.environ['CXX'] if 'LDSHARED' in os.environ: @@ -172,6 +203,12 @@ cpp = cpp + ' ' + os.environ['CPPFLAGS'] cflags = cflags + ' ' + os.environ['CPPFLAGS'] ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] + if 'AR' in os.environ: + ar = os.environ['AR'] + if 'ARFLAGS' in os.environ: + archiver = ar + ' ' + os.environ['ARFLAGS'] + else: + archiver = ar + ' ' + ar_flags cc_cmd = cc + ' ' + cflags compiler.set_executables( @@ -180,7 +217,8 @@ compiler_so=cc_cmd + ' ' + ccshared, compiler_cxx=cxx, linker_so=ldshared, - linker_exe=cc) + linker_exe=cc, + archiver=archiver) compiler.shared_lib_extension = so_ext @@ -380,21 +418,6 @@ raise DistutilsPlatformError(my_msg) - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target - elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')): - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. diff --git a/lib-python/2.7/distutils/tests/Setup.sample b/lib-python/2.7/distutils/tests/Setup.sample old mode 100755 new mode 100644 diff --git a/lib-python/2.7/distutils/tests/support.py b/lib-python/2.7/distutils/tests/support.py --- a/lib-python/2.7/distutils/tests/support.py +++ b/lib-python/2.7/distutils/tests/support.py @@ -1,7 +1,10 @@ """Support code for distutils test cases.""" import os +import sys import shutil import tempfile +import unittest +import sysconfig from copy import deepcopy import warnings @@ -9,6 +12,7 @@ from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL from distutils.core import Distribution + def capture_warnings(func): def _capture_warnings(*args, **kw): with warnings.catch_warnings(): @@ -16,6 +20,7 @@ return func(*args, **kw) return _capture_warnings + class LoggingSilencer(object): def setUp(self): @@ -49,6 +54,7 @@ def clear_logs(self): self.logs = [] + class TempdirManager(object): """Mix-in class that handles temporary directories for test cases. @@ -57,9 +63,13 @@ def setUp(self): super(TempdirManager, self).setUp() + self.old_cwd = os.getcwd() self.tempdirs = [] def tearDown(self): + # Restore working dir, for Solaris and derivatives, where rmdir() + # on the current directory fails. + os.chdir(self.old_cwd) super(TempdirManager, self).tearDown() while self.tempdirs: d = self.tempdirs.pop() @@ -105,6 +115,7 @@ return pkg_dir, dist + class DummyCommand: """Class to store options for retrieval via set_undefined_options().""" @@ -115,6 +126,7 @@ def ensure_finalized(self): pass + class EnvironGuard(object): def setUp(self): @@ -131,3 +143,79 @@ del os.environ[key] super(EnvironGuard, self).tearDown() + + +def copy_xxmodule_c(directory): From noreply at buildbot.pypy.org Sun Oct 21 00:36:51 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 21 Oct 2012 00:36:51 +0200 (CEST) Subject: [pypy-commit] pypy python-numpy: merge default into branch Message-ID: <20121020223651.C42641C0129@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: python-numpy Changeset: r58289:87d26a2a5f73 Date: 2012-10-20 21:30 +0200 http://bitbucket.org/pypy/pypy/changeset/87d26a2a5f73/ Log: merge default into branch diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,8 +4,9 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi +from pypy.rlib import jit, clibffi, jit_libffi, rposix from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -147,9 +148,13 @@ argtype = self.fargs[i] if isinstance(argtype, W_CTypePointer): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) - if get_mustfree_flag(data): + flag = get_mustfree_flag(data) + if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') + elif flag == 2: + file = rffi.cast(rffi.CCHARPP, data)[0] + rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -164,6 +169,27 @@ assert isinstance(abi, int) return space.wrap(abi) +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +def prepare_file_call_argument(fileobj): + import os + space = fileobj.space + fileobj.direct_flush() + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fd2 = os.dup(fd) + f = rffi_fdopen(fd2, fileobj.mode) + if not f: + os.close(fd2) + raise OSError(rposix.get_errno(), "fdopen failed") + except OSError, e: + raise wrap_oserror(space, e) + return f + # ____________________________________________________________ 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 @@ -157,7 +157,7 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - raise self._convert_error("compatible pointer", w_ob) + raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): from pypy.module._cffi_backend import ctypearray @@ -177,7 +177,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = [] + _attrs_ = ['is_file'] + _immutable_fields_ = ['is_file'] def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -186,6 +187,7 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" + self.is_file = (ctitem.name == "struct _IO_FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -234,7 +236,7 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) - def _prepare_pointer_call_argument(self, w_init): + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): @@ -242,10 +244,19 @@ elif space.isinstance_w(w_init, space.w_basestring): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 + elif self.is_file: + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = space.interpclass_w(w_init) + if isinstance(ob, W_File): + result = ctypefunc.prepare_file_call_argument(ob) + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 2 + return 0 else: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 if self.ctitem.size <= 0: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 try: datasize = ovfcheck(length * self.ctitem.size) except OverflowError: @@ -258,25 +269,19 @@ except Exception: lltype.free(result, flavor='raw') raise - return result + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 1 def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag space = self.space ob = space.interpclass_w(w_ob) - if isinstance(ob, cdataobj.W_CData): - buffer = lltype.nullptr(rffi.CCHARP.TO) - else: - buffer = self._prepare_pointer_call_argument(w_ob) - # - if buffer: - rffi.cast(rffi.CCHARPP, cdata)[0] = buffer - set_mustfree_flag(cdata, True) - return True - else: - set_mustfree_flag(cdata, False) + result = (not isinstance(ob, cdataobj.W_CData) and + self._prepare_pointer_call_argument(w_ob, cdata)) + if result == 0: self.convert_from_object(cdata, w_ob) - return False + set_mustfree_flag(cdata, result) + return result def getcfield(self, attr): return self.ctitem.getcfield(attr) 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 @@ -2211,3 +2211,56 @@ buffer(p)[:] = bytearray(b"foo\x00") assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] + +def test_FILE(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fscanf = ll.load_function(BFunc2, "fscanf") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r', 256) + fw1 = posix.fdopen(fdw, 'w', 256) + # + fw1.write(b"X") + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.close() + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"Xhello" + fr1.close() + +def test_FILE_only_for_FILE_arg(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + B_NOT_FILE = new_struct_type("NOT_FILE") + B_NOT_FILEP = new_pointer_type(B_NOT_FILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not file") diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -98,12 +98,13 @@ try: return W_LongObject.fromfloat(space, w_floatobj.floatval) except OverflowError: - if isnan(w_floatobj.floatval): - raise OperationError( - space.w_ValueError, - space.wrap("cannot convert float NaN to integer")) - raise OperationError(space.w_OverflowError, - space.wrap("cannot convert float infinity to long")) + raise OperationError( + space.w_OverflowError, + space.wrap("cannot convert float infinity to integer")) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("cannot convert float NaN to integer")) + def trunc__Float(space, w_floatobj): whole = math.modf(w_floatobj.floatval)[1] try: @@ -308,7 +309,7 @@ # Convert to long and use its hash. try: w_lval = W_LongObject.fromfloat(space, v) - except OverflowError: + except (OverflowError, ValueError): # can't convert to long int -- arbitrary if v < 0: return -271828 diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -1,7 +1,7 @@ from pypy.rlib.rarithmetic import LONG_BIT, intmask, longlongmask, r_uint, r_ulonglong, r_longlonglong from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen, is_valid_int from pypy.rlib.rarithmetic import most_neg_value_of_same_type -from pypy.rlib.rfloat import isfinite +from pypy.rlib.rfloat import isinf, isnan from pypy.rlib.debug import make_sure_not_resized, check_regular_int from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.rlib import jit @@ -207,10 +207,11 @@ def fromfloat(dval): """ Create a new bigint object from a float """ # This function is not marked as pure because it can raise - if isfinite(dval): - return rbigint._fromfloat_finite(dval) - else: - raise OverflowError + if isinf(dval): + raise OverflowError("cannot convert float infinity to integer") + if isnan(dval): + raise ValueError("cannot convert float NaN to integer") + return rbigint._fromfloat_finite(dval) @staticmethod @jit.elidable diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -4,6 +4,7 @@ from random import random, randint, sample from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF from pypy.rlib.rbigint import _store_digit, _mask_digit +from pypy.rlib.rfloat import NAN from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask from pypy.rpython.test.test_llinterp import interpret @@ -266,6 +267,7 @@ x = 12345.6789e200 x *= x assert raises(OverflowError, rbigint.fromfloat, x) + assert raises(ValueError, rbigint.fromfloat, NAN) # f1 = rbigint.fromfloat(9007199254740991.0) assert f1.tolong() == 9007199254740991 diff --git a/pypy/translator/goal/query.py b/pypy/translator/goal/query.py --- a/pypy/translator/goal/query.py +++ b/pypy/translator/goal/query.py @@ -49,7 +49,7 @@ s_ev = annotator.binding(ev, None) if s_et: if s_et.knowntype == type: - if s_et.__class__ == annmodel.SomeObject: + if s_et.__class__ == annmodel.SomeType: if hasattr(s_et, 'is_type_of') and s_et.is_type_of == [ev]: continue else: From noreply at buildbot.pypy.org Sun Oct 21 00:36:52 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 21 Oct 2012 00:36:52 +0200 (CEST) Subject: [pypy-commit] pypy python-numpy: fix merge Message-ID: <20121020223652.F018D1C0129@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: python-numpy Changeset: r58290:a75d4ab09850 Date: 2012-10-20 22:42 +0200 http://bitbucket.org/pypy/pypy/changeset/a75d4ab09850/ Log: fix merge 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 @@ -784,7 +784,41 @@ real = GetSetProperty(W_NDimArray.descr_get_real), imag = GetSetProperty(W_NDimArray.descr_get_imag), - __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), + argsort = interp2app(W_NDimArray.descr_argsort), + astype = interp2app(W_NDimArray.descr_astype), + base = GetSetProperty(W_NDimArray.descr_base), + byteswap = interp2app(W_NDimArray.descr_byteswap), + choose = interp2app(W_NDimArray.descr_choose), + clip = interp2app(W_NDimArray.descr_clip), + conj = interp2app(W_NDimArray.descr_conj), + conjugate = interp2app(W_NDimArray.descr_conj), + ctypes = GetSetProperty(W_NDimArray.descr_ctypes), + cumprod = interp2app(W_NDimArray.descr_cumprod), + cumsum = interp2app(W_NDimArray.descr_cumsum), + data = GetSetProperty(W_NDimArray.descr_data), + diagonal = interp2app(W_NDimArray.descr_diagonal), + dump = interp2app(W_NDimArray.descr_dump), + dumps = interp2app(W_NDimArray.descr_dumps), + flags = GetSetProperty(W_NDimArray.descr_get_flags, + W_NDimArray.descr_set_flags), + getfield = interp2app(W_NDimArray.descr_getfield), + itemset = interp2app(W_NDimArray.descr_itemset), + newbyteorder = interp2app(W_NDimArray.descr_newbyteorder), + ptp = interp2app(W_NDimArray.descr_ptp), + put = interp2app(W_NDimArray.descr_put), + resize = interp2app(W_NDimArray.descr_resize), + round = interp2app(W_NDimArray.descr_round), + searchsorted = interp2app(W_NDimArray.descr_searchsorted), + setasflat = interp2app(W_NDimArray.descr_setasflat), + setfield = interp2app(W_NDimArray.descr_setfield), + setflags = interp2app(W_NDimArray.descr_setflags), + sort = interp2app(W_NDimArray.descr_sort), + squeeze = interp2app(W_NDimArray.descr_squeeze), + strides = GetSetProperty(W_NDimArray.descr_strides), + tofile = interp2app(W_NDimArray.descr_tofile), + trace = interp2app(W_NDimArray.descr_trace), + view = interp2app(W_NDimArray.descr_view), + __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) @unwrap_spec(ndmin=int, copy=bool, subok=bool) @@ -855,42 +889,6 @@ return space.wrap(arr) - argsort = interp2app(BaseArray.descr_argsort), - astype = interp2app(BaseArray.descr_astype), - base = GetSetProperty(BaseArray.descr_base), - byteswap = interp2app(BaseArray.descr_byteswap), - choose = interp2app(BaseArray.descr_choose), - clip = interp2app(BaseArray.descr_clip), - conj = interp2app(BaseArray.descr_conj), - conjugate = interp2app(BaseArray.descr_conj), - ctypes = GetSetProperty(BaseArray.descr_ctypes), - cumprod = interp2app(BaseArray.descr_cumprod), - cumsum = interp2app(BaseArray.descr_cumsum), - data = GetSetProperty(BaseArray.descr_data), - diagonal = interp2app(BaseArray.descr_diagonal), - dump = interp2app(BaseArray.descr_dump), - dumps = interp2app(BaseArray.descr_dumps), - flags = GetSetProperty(BaseArray.descr_get_flags, - BaseArray.descr_set_flags), - getfield = interp2app(BaseArray.descr_getfield), - imag = GetSetProperty(BaseArray.descr_imag), - itemset = interp2app(BaseArray.descr_itemset), - newbyteorder = interp2app(BaseArray.descr_newbyteorder), - ptp = interp2app(BaseArray.descr_ptp), - put = interp2app(BaseArray.descr_put), - real = GetSetProperty(BaseArray.descr_real), - resize = interp2app(BaseArray.descr_resize), - round = interp2app(BaseArray.descr_round), - searchsorted = interp2app(BaseArray.descr_searchsorted), - setasflat = interp2app(BaseArray.descr_setasflat), - setfield = interp2app(BaseArray.descr_setfield), - setflags = interp2app(BaseArray.descr_setflags), - sort = interp2app(BaseArray.descr_sort), - squeeze = interp2app(BaseArray.descr_squeeze), - strides = GetSetProperty(BaseArray.descr_strides), - tofile = interp2app(BaseArray.descr_tofile), - trace = interp2app(BaseArray.descr_trace), - view = interp2app(BaseArray.descr_view), W_FlatIterator.typedef = TypeDef( 'flatiter', __iter__ = interp2app(W_FlatIterator.descr_iter), From noreply at buildbot.pypy.org Sun Oct 21 00:36:54 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 21 Oct 2012 00:36:54 +0200 (CEST) Subject: [pypy-commit] pypy python-numpy: add unwrap_spec for ndarray attributes Message-ID: <20121020223654.14CD31C0129@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: python-numpy Changeset: r58291:7dd2d9959f3b Date: 2012-10-20 23:31 +0200 http://bitbucket.org/pypy/pypy/changeset/7dd2d9959f3b/ Log: add unwrap_spec for ndarray attributes 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 @@ -375,7 +375,8 @@ space.w_False])) return w_d - def descr_argsort(self, space, w_axis=-1, w_kind='quicksort', w_order=None): + @unwrap_spec(axis=int, kind=str) + def descr_argsort(self, space, axis=-1, kind='quicksort', w_order=None): raise OperationError(space.w_NotImplementedError, space.wrap( "argsort not implemented yet")) @@ -387,11 +388,13 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "base not implemented yet")) - def descr_byteswap(self, space, w_inplace=False): + @unwrap_spec(inplace=bool) + def descr_byteswap(self, space, inplace=False): raise OperationError(space.w_NotImplementedError, space.wrap( "byteswap not implemented yet")) - def descr_choose(self, space, w_choices, w_out=None, w_mode='raise'): + @unwrap_spec(mode=str) + def descr_choose(self, space, w_choices, w_out=None, mode='raise'): raise OperationError(space.w_NotImplementedError, space.wrap( "choose not implemented yet")) @@ -419,7 +422,8 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "data not implemented yet")) - def descr_diagonal(self, space, w_offset=0, w_axis1=0, w_axis2=1): + @unwrap_spec(offset=int, axis1=int, axis2=int) + def descr_diagonal(self, space, offset=0, axis1=0, axis2=1): raise OperationError(space.w_NotImplementedError, space.wrap( "diagonal not implemented yet")) @@ -461,7 +465,8 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "ptp (peak to peak) not implemented yet")) - def descr_put(self, space, w_indices, w_values, w_mode='raise'): + @unwrap_spec(mode=str) + def descr_put(self, space, w_indices, w_values, mode='raise'): raise OperationError(space.w_NotImplementedError, space.wrap( "put not implemented yet")) @@ -469,15 +474,18 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "real not implemented yet")) - def descr_resize(self, space, w_new_shape, w_refcheck=True): + @unwrap_spec(refcheck=bool) + def descr_resize(self, space, w_new_shape, refcheck=True): raise OperationError(space.w_NotImplementedError, space.wrap( "resize not implemented yet")) - def descr_round(self, space, w_decimals=0, w_out=None): + @unwrap_spec(decimals=int) + def descr_round(self, space, decimals=0, w_out=None): raise OperationError(space.w_NotImplementedError, space.wrap( "round not implemented yet")) - def descr_searchsorted(self, space, w_v, w_side='left'): + @unwrap_spec(side=str) + def descr_searchsorted(self, space, w_v, side='left'): raise OperationError(space.w_NotImplementedError, space.wrap( "searchsorted not implemented yet")) @@ -485,7 +493,8 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setasflat not implemented yet")) - def descr_setfield(self, space, w_val, w_dtype, w_offset=0): + @unwrap_spec(offset=int) + def descr_setfield(self, space, w_val, w_dtype, offset=0): raise OperationError(space.w_NotImplementedError, space.wrap( "setfield not implemented yet")) @@ -493,7 +502,8 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setflags not implemented yet")) - def descr_sort(self, space, w_axis=-1, w_kind='quicksort', w_order=None): + @unwrap_spec(axis=int, kind=str) + def descr_sort(self, space, axis=-1, kind='quicksort', w_order=None): raise OperationError(space.w_NotImplementedError, space.wrap( "sort not implemented yet")) @@ -505,11 +515,13 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "strides not implemented yet")) - def descr_tofile(self, space, w_fid, w_sep="", w_format="%s"): + @unwrap_spec(sep=str, format_=str) + def descr_tofile(self, space, w_fid, sep="", format_="%s"): raise OperationError(space.w_NotImplementedError, space.wrap( "tofile not implemented yet")) - def descr_trace(self, space, w_offset=0, w_axis1=0, w_axis2=1, + @unwrap_spec(offset=int, axis1=str, axis2=int) + def descr_trace(self, space, offset=0, axis1=0, axis2=1, w_dtype=None, w_out=None): raise OperationError(space.w_NotImplementedError, space.wrap( "trace not implemented yet")) From noreply at buildbot.pypy.org Sun Oct 21 00:58:46 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 21 Oct 2012 00:58:46 +0200 (CEST) Subject: [pypy-commit] pypy python-numpy: with this, numpy.tests() starts to run Message-ID: <20121020225846.B49371C0318@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: python-numpy Changeset: r58292:86d451eaee0a Date: 2012-10-21 00:58 +0200 http://bitbucket.org/pypy/pypy/changeset/86d451eaee0a/ Log: with this, numpy.tests() starts to run diff --git a/lib_pypy/numpy/core/numerictypes.py b/lib_pypy/numpy/core/_numerictypes.py rename from lib_pypy/numpy/core/numerictypes.py rename to lib_pypy/numpy/core/_numerictypes.py From noreply at buildbot.pypy.org Sun Oct 21 02:52:11 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 21 Oct 2012 02:52:11 +0200 (CEST) Subject: [pypy-commit] pypy default: require a min. of Java 6, skip the jvm tests otherwise Message-ID: <20121021005211.305F71C029E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r58293:16e5d86c8254 Date: 2012-10-20 17:49 -0700 http://bitbucket.org/pypy/pypy/changeset/16e5d86c8254/ Log: require a min. of Java 6, skip the jvm tests otherwise diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -100,7 +100,7 @@ To translate and run for the CLI you must have the SDK installed: Windows users need the `.NET Framework SDK`_, while Linux and Mac users can use Mono_. To translate and run for the JVM you must have a JDK -installed (at least version 5) and ``java``/``javac`` on your path. +installed (at least version 6) and ``java``/``javac`` on your path. A slightly larger example +++++++++++++++++++++++++ diff --git a/pypy/translator/jvm/genjvm.py b/pypy/translator/jvm/genjvm.py --- a/pypy/translator/jvm/genjvm.py +++ b/pypy/translator/jvm/genjvm.py @@ -2,11 +2,12 @@ Backend for the JVM. """ +import os +import re +import subprocess import sys -import os import py -import subprocess from pypy.tool.udir import udir from pypy.translator.translator import TranslationContext from pypy.translator.oosupport.genoo import GenOO @@ -25,6 +26,8 @@ JVMWeakRefConst from pypy.translator.jvm.prebuiltnodes import create_interlink_node +MIN_JAVA_VERSION = '1.6.0' + class JvmError(Exception): """ Indicates an error occurred in JVM backend """ @@ -222,12 +225,35 @@ jvm = GenJvm(tmpdir, t, EntryPoint(main_graph, True, True)) return jvm.generate_source() +_missing_support_programs = None + def detect_missing_support_programs(): - def check(exechelper): - if py.path.local.sysfind(exechelper) is None: - py.test.skip("%s is not on your path" % exechelper) - check(getoption('javac')) - check(getoption('java')) + global _missing_support_programs + if _missing_support_programs is not None: + if _missing_support_programs: + py.test.skip(_missing_support_programs) + return + + def missing(msg): + global _missing_support_programs + _missing_support_programs = msg + py.test.skip(msg) + + for cmd in 'javac', 'java': + if py.path.local.sysfind(getoption(cmd)) is None: + missing("%s is not on your path" % cmd) + if not _check_java_version(MIN_JAVA_VERSION): + missing('Minimum of Java %s required' % MIN_JAVA_VERSION) + _missing_support_programs = False + +def _check_java_version(version): + """Determine if java meets the specified version""" + cmd = [getoption('java'), '-version'] + with open(os.devnull, 'w') as devnull: + stderr = subprocess.Popen(cmd, stdout=devnull, + stderr=subprocess.PIPE).communicate()[1] + search = re.search('[\.0-9]+', stderr) + return search and search.group() >= version class GenJvm(GenOO): From noreply at buildbot.pypy.org Sun Oct 21 03:52:26 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 21 Oct 2012 03:52:26 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Test that all opcodes are implemented in FSFrame Message-ID: <20121021015226.43D711C02F5@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58294:50574051a53e Date: 2012-10-20 23:36 +0100 http://bitbucket.org/pypy/pypy/changeset/50574051a53e/ Log: Test that all opcodes are implemented in FSFrame diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -55,6 +55,12 @@ result[op.opname] += 1 return result +def test_all_opcodes_defined(): + opnames = set(host_bytecode_spec.method_names) + methods = set([name for name in dir(FlowSpaceFrame) if name.upper() == name]) + handled_elsewhere = set(['EXTENDED_ARG']) + missing = opnames - methods - handled_elsewhere + assert not missing class TestFlowObjSpace(Base): From noreply at buildbot.pypy.org Sun Oct 21 03:52:27 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 21 Oct 2012 03:52:27 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Add UNARY_OPS to FSFrame Message-ID: <20121021015227.725B71C02F5@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58295:31f0efb6b794 Date: 2012-10-21 02:21 +0100 http://bitbucket.org/pypy/pypy/changeset/31f0efb6b794/ Log: Add UNARY_OPS to FSFrame diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -211,6 +211,22 @@ # ____________________________________________________________ +_unary_ops=[('UNARY_POSITIVE', "pos"), + ('UNARY_NEGATIVE', "neg"), + ('UNARY_NOT', "not_"), + ('UNARY_CONVERT', "repr"), + ('UNARY_INVERT', "invert"),] + +def unaryoperation(OPCODE, op): + def UNARY_OP(self, *ignored): + operation = getattr(self.space, op) + w_1 = self.popvalue() + w_result = operation(w_1) + self.pushvalue(w_result) + UNARY_OP.unaryop = op + UNARY_OP.func_name = OPCODE + return UNARY_OP + compare_method = [ "cmp_lt", # "<" "cmp_le", # "<=" @@ -225,7 +241,7 @@ "cmp_exc_match", ] -class FlowSpaceFrame(pyframe.PyFrame): +class FlowSpaceFrame(object): opcode_method_names = host_bytecode_spec.method_names def __init__(self, space, graph, code): @@ -838,6 +854,9 @@ def DUP_TOPX(self, itemcount, next_instr): self.dupvalues(itemcount) + for OPCODE, op in _unary_ops: + locals()[OPCODE] = unaryoperation(OPCODE, op) + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. From noreply at buildbot.pypy.org Sun Oct 21 03:52:28 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 21 Oct 2012 03:52:28 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: Add BINARY_OPS to FSFrame Message-ID: <20121021015228.9C3041C02F5@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: translation-cleanup Changeset: r58296:dce1aedd5af6 Date: 2012-10-21 02:35 +0100 http://bitbucket.org/pypy/pypy/changeset/dce1aedd5af6/ Log: Add BINARY_OPS to FSFrame diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -211,7 +211,7 @@ # ____________________________________________________________ -_unary_ops=[('UNARY_POSITIVE', "pos"), +_unary_ops = [('UNARY_POSITIVE', "pos"), ('UNARY_NEGATIVE', "neg"), ('UNARY_NOT', "not_"), ('UNARY_CONVERT', "repr"), @@ -227,6 +227,46 @@ UNARY_OP.func_name = OPCODE return UNARY_OP +_binary_ops = [ + ('BINARY_MULTIPLY', "mul"), + ('BINARY_TRUE_DIVIDE', "truediv"), + ('BINARY_FLOOR_DIVIDE', "floordiv"), + ('BINARY_DIVIDE', "div"), + ('BINARY_MODULO', "mod"), + ('BINARY_ADD', "add"), + ('BINARY_SUBTRACT', "sub"), + ('BINARY_SUBSCR', "getitem"), + ('BINARY_LSHIFT', "lshift"), + ('BINARY_RSHIFT', "rshift"), + ('BINARY_AND', "and_"), + ('BINARY_XOR', "xor"), + ('BINARY_OR', "or_"), + ('INPLACE_MULTIPLY', "inplace_mul"), + ('INPLACE_TRUE_DIVIDE', "inplace_truediv"), + ('INPLACE_FLOOR_DIVIDE', "inplace_floordiv"), + ('INPLACE_DIVIDE', "inplace_div"), + ('INPLACE_MODULO', "inplace_mod"), + ('INPLACE_ADD', "inplace_add"), + ('INPLACE_SUBTRACT', "inplace_sub"), + ('INPLACE_LSHIFT', "inplace_lshift"), + ('INPLACE_RSHIFT', "inplace_rshift"), + ('INPLACE_AND', "inplace_and"), + ('INPLACE_XOR', "inplace_xor"), + ('INPLACE_OR', "inplace_or"), +] + +def binaryoperation(OPCODE, op): + """NOT_RPYTHON""" + def BINARY_OP(self, *ignored): + operation = getattr(self.space, op) + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = operation(w_1, w_2) + self.pushvalue(w_result) + BINARY_OP.binop = op + BINARY_OP.func_name = OPCODE + return BINARY_OP + compare_method = [ "cmp_lt", # "<" "cmp_le", # "<=" @@ -241,7 +281,7 @@ "cmp_exc_match", ] -class FlowSpaceFrame(object): +class FlowSpaceFrame(pyframe.PyFrame): opcode_method_names = host_bytecode_spec.method_names def __init__(self, space, graph, code): @@ -857,6 +897,9 @@ for OPCODE, op in _unary_ops: locals()[OPCODE] = unaryoperation(OPCODE, op) + for OPCODE, op in _binary_ops: + locals()[OPCODE] = binaryoperation(OPCODE, op) + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. From noreply at buildbot.pypy.org Sun Oct 21 05:13:06 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 21 Oct 2012 05:13:06 +0200 (CEST) Subject: [pypy-commit] pypy default: 2.5 compat Message-ID: <20121021031306.CE2121C1C84@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r58297:af4f8fdae89d Date: 2012-10-20 20:13 -0700 http://bitbucket.org/pypy/pypy/changeset/af4f8fdae89d/ Log: 2.5 compat diff --git a/pypy/translator/jvm/genjvm.py b/pypy/translator/jvm/genjvm.py --- a/pypy/translator/jvm/genjvm.py +++ b/pypy/translator/jvm/genjvm.py @@ -2,6 +2,7 @@ Backend for the JVM. """ +from __future__ import with_statement import os import re import subprocess From noreply at buildbot.pypy.org Sun Oct 21 09:28:14 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 09:28:14 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Finally found the fix for test_memmgr. Message-ID: <20121021072814.0EDC61C1D1D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58298:ff197755dc98 Date: 2012-10-21 09:27 +0200 http://bitbucket.org/pypy/pypy/changeset/ff197755dc98/ Log: Finally found the fix for test_memmgr. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -1,4 +1,4 @@ - +import weakref from pypy.jit.backend import model from pypy.jit.backend.llgraph import support from pypy.jit.metainterp.history import Const, getkind, AbstractDescr @@ -18,8 +18,36 @@ invalid = False def __init__(self, inputargs, operations): - self.inputargs = inputargs - self.operations = operations + # We need to clone the list of operations because the + # front-end will mutate them under our feet again. We also + # need to make sure things get freed. + def mapping(box, _cache={}): + if isinstance(box, Const) or box is None: + return box + try: + newbox = _cache[box] + except KeyError: + newbox = _cache[box] = box.clonebox() + return newbox + # + self.inputargs = map(mapping, inputargs) + self.operations = [] + for op in operations: + if op.getdescr() is not None: + newdescr = WeakrefDescr(op.getdescr()) + else: + newdescr = None + newop = op.copy_and_change(op.getopnum(), + map(mapping, op.getarglist()), + mapping(op.result), + newdescr) + if op.getfailargs() is not None: + newop.setfailargs(map(mapping, op.getfailargs())) + self.operations.append(newop) + +class WeakrefDescr(AbstractDescr): + def __init__(self, realdescr): + self.realdescrref = weakref.ref(realdescr) class GuardFailed(Exception): def __init__(self, failargs, descr): @@ -189,14 +217,9 @@ self._record_labels(lltrace) def _record_labels(self, lltrace): - # xxx pfff, we need to clone the list of operations because the - # front-end will mutate them under our feet again - # xXX pffffffff2 not enough to make sure things are freed - lltrace.operations = [op.copy_and_change(op.getopnum()) - for op in lltrace.operations] for i, op in enumerate(lltrace.operations): if op.getopnum() == rop.LABEL: - op.getdescr()._llgraph_target = (lltrace, i) + _getdescr(op)._llgraph_target = (lltrace, i) def invalidate_loop(self, looptoken): for trace in looptoken.compiled_loop_token._llgraph_alltraces: @@ -277,7 +300,7 @@ else: guard_op = frame.lltrace.operations[frame.current_index + 1] frame.latest_values = frame._getfailargs(guard_op, call_op.result) - descr = guard_op.getdescr() + descr = _getdescr(guard_op) frame.latest_descr = descr return descr @@ -637,8 +660,8 @@ self.current_op = op # for label self.current_index = i try: - resval = getattr(self, 'execute_' + op.getopname())(op.getdescr(), - *args) + resval = getattr(self, 'execute_' + op.getopname())( + _getdescr(op), *args) except Jump, j: self.lltrace, i = j.descr._llgraph_target label_op = self.lltrace.operations[i] @@ -879,6 +902,13 @@ def execute_jit_frame(self, _): return self +def _getdescr(op): + d = op.getdescr() + if d is not None: + d = d.realdescrref() + assert d is not None, "the descr disappeared: %r" % (op,) + return d + def _setup(): def _make_impl_from_blackhole_interp(opname): from pypy.jit.metainterp.blackhole import BlackholeInterpreter diff --git a/pypy/jit/metainterp/test/test_memmgr.py b/pypy/jit/metainterp/test/test_memmgr.py --- a/pypy/jit/metainterp/test/test_memmgr.py +++ b/pypy/jit/metainterp/test/test_memmgr.py @@ -117,8 +117,7 @@ # we should see only the loop and the entry bridge self.check_target_token_count(2) - def XXXskipped_test_target_loop_kept_alive_or_not(self): - # SKIPPED: the llgraph backend keeps too much things alive + def test_target_loop_kept_alive_or_not(self): myjitdriver = JitDriver(greens=['m'], reds=['n']) def g(m): n = 10 @@ -161,8 +160,7 @@ # we should see a loop for each call to g() self.check_enter_count(8 + 20*2) - def XXXskipped_test_throw_away_old_loops(self): - # SKIPPED: the llgraph backend keeps too much things alive + def test_throw_away_old_loops(self): myjitdriver = JitDriver(greens=['m'], reds=['n']) def g(m): n = 10 @@ -214,33 +212,12 @@ g(u, 0); g(u+2, 0) # \ make more loops for g(u+1) to g(u+4), g(u, 0); g(u+3, 0) # / but keeps g(u) alive g(u, 0); g(u+4, 0) # / - g(u, 0); g(u+5, 0) # / - g(u, 0); g(u+6, 0) # / - g(u, 0); g(u+7, 0) # / - g(u, 0); g(u+8, 0) # / - g(u, 0); g(u+9, 0) # / - g(u, 0); g(u+10, 0) # / - g(u, 0); g(u+11, 0) # / - g(u, 0); g(u+12, 0) # / g(u, 8) # call g(u) again, with its call_assembler to h(u) return 42 - res = self.meta_interp(f, [1], loop_longevity=3, inline=True) + res = self.meta_interp(f, [1], loop_longevity=4, inline=True) assert res == 42 - self.check_jitcell_token_count(6+8) - # - # manually free the inner loops of the llgraph backend - tokens = [t() for t in get_stats().jitcell_token_wrefs] - for token in tokens: - if token is not None: - for key in token.compiled_loop_token.__dict__.keys(): - if key.startswith('_llgraph_'): - setattr(token.compiled_loop_token, key, 'STUBBED') - del tokens, token - import gc; gc.collect(); gc.collect(); gc.collect(); gc.collect() - # from pypy.translator.tool.reftracker import track - # track(get_stats().jitcell_token_wrefs[8]()) - # + self.check_jitcell_token_count(6) tokens = [t() for t in get_stats().jitcell_token_wrefs] # Some loops have been freed assert None in tokens @@ -277,3 +254,4 @@ finally: if hasattr(test, 'teardown_class'): test.teardown_class() + From noreply at buildbot.pypy.org Sun Oct 21 12:34:28 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 12:34:28 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: in-progress, the current situation of fixes Message-ID: <20121021103428.3C1FA1C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58299:73d377e08a91 Date: 2012-10-21 12:33 +0200 http://bitbucket.org/pypy/pypy/changeset/73d377e08a91/ Log: in-progress, the current situation of fixes diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py --- a/pypy/jit/codewriter/jtransform.py +++ b/pypy/jit/codewriter/jtransform.py @@ -415,9 +415,10 @@ self.make_three_lists(op.args[1:1+num_green_args]) + self.make_three_lists(op.args[1+num_green_args:])) kind = getkind(op.result.concretetype)[0] - op0 = SpaceOperation('recursive_call_%s' % kind, args, op.result) - op1 = SpaceOperation('-live-', [], None) - return ops + [op0, op1] + op0 = SpaceOperation('-live-', [], None) + op1 = SpaceOperation('recursive_call_%s' % kind, args, op.result) + op2 = SpaceOperation('-live-', [], None) + return ops + [op0, op1, op2] handle_residual_indirect_call = handle_residual_call diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -753,6 +753,7 @@ jfdescr = jfdescrbox.getref_base() descr = cpu.jitframe_cast_jfdescr_to_descr(jfdescr) if not descr: + xxx raise SwitchToBlackhole(Counters.ABORT_ESCAPE) resume.rebuild_virtualizable_from_resumedata(self.metainterp, descr, vinfo, box, jfbox) @@ -891,8 +892,8 @@ opimpl_residual_call_irf_f = _opimpl_residual_call3 opimpl_residual_call_irf_v = _opimpl_residual_call3 - @arguments("int", "boxes3", "boxes3") - def _opimpl_recursive_call(self, jdindex, greenboxes, redboxes): + @arguments("int", "boxes3", "boxes3", "orgpc") + def _opimpl_recursive_call(self, jdindex, greenboxes, redboxes, orgpc): targetjitdriver_sd = self.metainterp.staticdata.jitdrivers_sd[jdindex] allboxes = greenboxes + redboxes warmrunnerstate = targetjitdriver_sd.warmstate @@ -900,6 +901,7 @@ if warmrunnerstate.inlining: if warmrunnerstate.can_inline_callable(greenboxes): portal_code = targetjitdriver_sd.mainjitcode + self.orgpc_before_recursive_call = orgpc return self.metainterp.perform_call(portal_code, allboxes, greenkey=greenboxes) assembler_call = True @@ -908,16 +910,17 @@ self.verify_green_args(targetjitdriver_sd, greenboxes) # return self.do_recursive_call(targetjitdriver_sd, allboxes, - assembler_call) + assembler_call, orgpc=orgpc) def do_recursive_call(self, targetjitdriver_sd, allboxes, - assembler_call=False): + assembler_call=False, orgpc=-1): portal_code = targetjitdriver_sd.mainjitcode k = targetjitdriver_sd.portal_runner_adr funcbox = ConstInt(heaptracker.adr2int(k)) return self.do_residual_call(funcbox, portal_code.calldescr, allboxes, assembler_call=assembler_call, - assembler_call_jd=targetjitdriver_sd) + assembler_call_jd=targetjitdriver_sd, + orgpc=orgpc) opimpl_recursive_call_i = _opimpl_recursive_call opimpl_recursive_call_r = _opimpl_recursive_call @@ -1098,7 +1101,8 @@ pass frame = self.metainterp.framestack[-1] frame.do_recursive_call(jitdriver_sd, greenboxes + redboxes, - assembler_call=True) + assembler_call=True, + orgpc=frame.orgpc_before_recursive_call) raise ChangeFrame def debug_merge_point(self, jitdriver_sd, jd_index, portal_call_depth, current_call_id, greenkey): @@ -1377,7 +1381,8 @@ def do_residual_call(self, funcbox, descr, argboxes, assembler_call=False, - assembler_call_jd=None): + assembler_call_jd=None, + orgpc=-1): # First build allboxes: it may need some reordering from the # list provided in argboxes, depending on the order in which # the arguments are expected by the function @@ -1412,7 +1417,7 @@ # effectinfo = descr.get_extra_info() if (assembler_call or - effectinfo.check_forces_virtual_or_virtualizable()): + effectinfo.check_forces_virtual_or_virtualizable()): # residual calls require attention to keep virtualizables in-sync self.metainterp.clear_exception() self.metainterp.vable_and_vrefs_before_residual_call() @@ -1420,7 +1425,8 @@ rop.CALL_MAY_FORCE, allboxes, descr=descr) self.metainterp.vrefs_after_residual_call() if assembler_call: - self.metainterp.direct_assembler_call(assembler_call_jd) + self.metainterp.direct_assembler_call(assembler_call_jd, + orgpc) if resbox is not None: self.make_result_of_lastop(resbox) self.metainterp.vable_after_residual_call() @@ -2528,7 +2534,7 @@ self.history.operations[-1] = newop return resbox - def direct_assembler_call(self, targetjitdriver_sd): + def direct_assembler_call(self, targetjitdriver_sd, orgpc): """ Generate a direct call to assembler for portal entry point, patching the CALL_MAY_FORCE that occurred just now. """ @@ -2540,10 +2546,12 @@ args = arglist[num_green_args+1:] assert len(args) == targetjitdriver_sd.num_red_args warmrunnerstate = targetjitdriver_sd.warmstate - if targetjitdriver_sd.virtualizable_info is not None: + if targetjitdriver_sd.virtualizable_info is not None and orgpc != -1: vbox = args[targetjitdriver_sd.index_of_virtualizable] frame = self.framestack[-1] - frame._force_virtualizable_if_necessary(vbox, frame.pc) + import pdb + pdb.set_trace() + frame._force_virtualizable_if_necessary(vbox, orgpc) token = warmrunnerstate.get_assembler_token(greenargs) op = op.copy_and_change(rop.CALL_ASSEMBLER, args=args, descr=token) self.history.operations.append(op) From noreply at buildbot.pypy.org Sun Oct 21 12:34:29 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 12:34:29 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: merge Message-ID: <20121021103429.6671A1C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58300:82043a33f366 Date: 2012-10-21 12:34 +0200 http://bitbucket.org/pypy/pypy/changeset/82043a33f366/ Log: merge diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -1,4 +1,4 @@ - +import weakref from pypy.jit.backend import model from pypy.jit.backend.llgraph import support from pypy.jit.metainterp.history import Const, getkind, AbstractDescr @@ -18,8 +18,36 @@ invalid = False def __init__(self, inputargs, operations): - self.inputargs = inputargs - self.operations = operations + # We need to clone the list of operations because the + # front-end will mutate them under our feet again. We also + # need to make sure things get freed. + def mapping(box, _cache={}): + if isinstance(box, Const) or box is None: + return box + try: + newbox = _cache[box] + except KeyError: + newbox = _cache[box] = box.clonebox() + return newbox + # + self.inputargs = map(mapping, inputargs) + self.operations = [] + for op in operations: + if op.getdescr() is not None: + newdescr = WeakrefDescr(op.getdescr()) + else: + newdescr = None + newop = op.copy_and_change(op.getopnum(), + map(mapping, op.getarglist()), + mapping(op.result), + newdescr) + if op.getfailargs() is not None: + newop.setfailargs(map(mapping, op.getfailargs())) + self.operations.append(newop) + +class WeakrefDescr(AbstractDescr): + def __init__(self, realdescr): + self.realdescrref = weakref.ref(realdescr) class GuardFailed(Exception): def __init__(self, failargs, descr): @@ -189,14 +217,9 @@ self._record_labels(lltrace) def _record_labels(self, lltrace): - # xxx pfff, we need to clone the list of operations because the - # front-end will mutate them under our feet again - # xXX pffffffff2 not enough to make sure things are freed - lltrace.operations = [op.copy_and_change(op.getopnum()) - for op in lltrace.operations] for i, op in enumerate(lltrace.operations): if op.getopnum() == rop.LABEL: - op.getdescr()._llgraph_target = (lltrace, i) + _getdescr(op)._llgraph_target = (lltrace, i) def invalidate_loop(self, looptoken): for trace in looptoken.compiled_loop_token._llgraph_alltraces: @@ -277,7 +300,7 @@ else: guard_op = frame.lltrace.operations[frame.current_index + 1] frame.latest_values = frame._getfailargs(guard_op, call_op.result) - descr = guard_op.getdescr() + descr = _getdescr(guard_op) frame.latest_descr = descr return descr @@ -637,8 +660,8 @@ self.current_op = op # for label self.current_index = i try: - resval = getattr(self, 'execute_' + op.getopname())(op.getdescr(), - *args) + resval = getattr(self, 'execute_' + op.getopname())( + _getdescr(op), *args) except Jump, j: self.lltrace, i = j.descr._llgraph_target label_op = self.lltrace.operations[i] @@ -879,6 +902,13 @@ def execute_jit_frame(self, _): return self +def _getdescr(op): + d = op.getdescr() + if d is not None: + d = d.realdescrref() + assert d is not None, "the descr disappeared: %r" % (op,) + return d + def _setup(): def _make_impl_from_blackhole_interp(opname): from pypy.jit.metainterp.blackhole import BlackholeInterpreter diff --git a/pypy/jit/metainterp/test/test_memmgr.py b/pypy/jit/metainterp/test/test_memmgr.py --- a/pypy/jit/metainterp/test/test_memmgr.py +++ b/pypy/jit/metainterp/test/test_memmgr.py @@ -117,8 +117,7 @@ # we should see only the loop and the entry bridge self.check_target_token_count(2) - def XXXskipped_test_target_loop_kept_alive_or_not(self): - # SKIPPED: the llgraph backend keeps too much things alive + def test_target_loop_kept_alive_or_not(self): myjitdriver = JitDriver(greens=['m'], reds=['n']) def g(m): n = 10 @@ -161,8 +160,7 @@ # we should see a loop for each call to g() self.check_enter_count(8 + 20*2) - def XXXskipped_test_throw_away_old_loops(self): - # SKIPPED: the llgraph backend keeps too much things alive + def test_throw_away_old_loops(self): myjitdriver = JitDriver(greens=['m'], reds=['n']) def g(m): n = 10 @@ -214,33 +212,12 @@ g(u, 0); g(u+2, 0) # \ make more loops for g(u+1) to g(u+4), g(u, 0); g(u+3, 0) # / but keeps g(u) alive g(u, 0); g(u+4, 0) # / - g(u, 0); g(u+5, 0) # / - g(u, 0); g(u+6, 0) # / - g(u, 0); g(u+7, 0) # / - g(u, 0); g(u+8, 0) # / - g(u, 0); g(u+9, 0) # / - g(u, 0); g(u+10, 0) # / - g(u, 0); g(u+11, 0) # / - g(u, 0); g(u+12, 0) # / g(u, 8) # call g(u) again, with its call_assembler to h(u) return 42 - res = self.meta_interp(f, [1], loop_longevity=3, inline=True) + res = self.meta_interp(f, [1], loop_longevity=4, inline=True) assert res == 42 - self.check_jitcell_token_count(6+8) - # - # manually free the inner loops of the llgraph backend - tokens = [t() for t in get_stats().jitcell_token_wrefs] - for token in tokens: - if token is not None: - for key in token.compiled_loop_token.__dict__.keys(): - if key.startswith('_llgraph_'): - setattr(token.compiled_loop_token, key, 'STUBBED') - del tokens, token - import gc; gc.collect(); gc.collect(); gc.collect(); gc.collect() - # from pypy.translator.tool.reftracker import track - # track(get_stats().jitcell_token_wrefs[8]()) - # + self.check_jitcell_token_count(6) tokens = [t() for t in get_stats().jitcell_token_wrefs] # Some loops have been freed assert None in tokens @@ -277,3 +254,4 @@ finally: if hasattr(test, 'teardown_class'): test.teardown_class() + From noreply at buildbot.pypy.org Sun Oct 21 12:39:04 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 12:39:04 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: __repr__ for MIFrame Message-ID: <20121021103904.9E8FD1C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58301:ee6afd63975c Date: 2012-10-21 12:38 +0200 http://bitbucket.org/pypy/pypy/changeset/ee6afd63975c/ Log: __repr__ for MIFrame diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -41,6 +41,11 @@ self.registers_r = [None] * 256 self.registers_f = [None] * 256 + def __repr__(self): + if hasattr(self, 'jitcode'): + return '' % self.jitcode.name + return '>' + def setup(self, jitcode, greenkey=None): assert isinstance(jitcode, JitCode) self.jitcode = jitcode @@ -1094,6 +1099,8 @@ # with make_result_of_lastop(), so the lastop must be right: # it must be the call to 'self', and not the jit_merge_point # itself, which has no result at all. + import pdb + pdb.set_trace() assert len(self.metainterp.framestack) >= 2 try: self.metainterp.finishframe(None) @@ -2549,8 +2556,6 @@ if targetjitdriver_sd.virtualizable_info is not None and orgpc != -1: vbox = args[targetjitdriver_sd.index_of_virtualizable] frame = self.framestack[-1] - import pdb - pdb.set_trace() frame._force_virtualizable_if_necessary(vbox, orgpc) token = warmrunnerstate.get_assembler_token(greenargs) op = op.copy_and_change(rop.CALL_ASSEMBLER, args=args, descr=token) From noreply at buildbot.pypy.org Sun Oct 21 12:43:40 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 12:43:40 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: (arigo, fijal) fix the test Message-ID: <20121021104340.24E851C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58302:7c1965be6d4a Date: 2012-10-21 12:43 +0200 http://bitbucket.org/pypy/pypy/changeset/7c1965be6d4a/ Log: (arigo, fijal) fix the test diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -906,7 +906,6 @@ if warmrunnerstate.inlining: if warmrunnerstate.can_inline_callable(greenboxes): portal_code = targetjitdriver_sd.mainjitcode - self.orgpc_before_recursive_call = orgpc return self.metainterp.perform_call(portal_code, allboxes, greenkey=greenboxes) assembler_call = True @@ -1099,8 +1098,8 @@ # with make_result_of_lastop(), so the lastop must be right: # it must be the call to 'self', and not the jit_merge_point # itself, which has no result at all. - import pdb - pdb.set_trace() + vbox = redboxes[jitdriver_sd.index_of_virtualizable] + self._force_virtualizable_if_necessary(vbox, orgpc) assert len(self.metainterp.framestack) >= 2 try: self.metainterp.finishframe(None) @@ -1109,7 +1108,7 @@ frame = self.metainterp.framestack[-1] frame.do_recursive_call(jitdriver_sd, greenboxes + redboxes, assembler_call=True, - orgpc=frame.orgpc_before_recursive_call) + orgpc=-1) # don't force the virtualizable raise ChangeFrame def debug_merge_point(self, jitdriver_sd, jd_index, portal_call_depth, current_call_id, greenkey): From noreply at buildbot.pypy.org Sun Oct 21 12:45:58 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 12:45:58 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: make it officially a fatal error Message-ID: <20121021104558.5A7D31C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58303:33ec2e772f03 Date: 2012-10-21 12:45 +0200 http://bitbucket.org/pypy/pypy/changeset/33ec2e772f03/ Log: make it officially a fatal error diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -758,8 +758,7 @@ jfdescr = jfdescrbox.getref_base() descr = cpu.jitframe_cast_jfdescr_to_descr(jfdescr) if not descr: - xxx - raise SwitchToBlackhole(Counters.ABORT_ESCAPE) + raise Exception("descr should not be none while inside a recursive call") resume.rebuild_virtualizable_from_resumedata(self.metainterp, descr, vinfo, box, jfbox) self._opimpl_setfield_gc_any(box, vinfo.jit_frame_descr, From noreply at buildbot.pypy.org Sun Oct 21 12:47:45 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 12:47:45 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: test for failure in the blackhole Message-ID: <20121021104745.D21151C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58304:8c68dcff413d Date: 2012-10-21 12:47 +0200 http://bitbucket.org/pypy/pypy/changeset/8c68dcff413d/ Log: test for failure in the blackhole diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -1019,6 +1019,38 @@ res = self.meta_interp(main, [], inline=True) assert res == main() + def test_call_assembler_force_in_the_blackhole(self): + class Frame(object): + _virtualizable2_ = ['thing'] + + def __init__(self, thing): + self.thing = thing + + driver = JitDriver(greens = ['codeno'], + reds = ['i', 'frame', 'frames'], + virtualizables = ['frame']) + + def portal(codeno, frame, frames): + i = 0 + while i < 10: + driver.jit_merge_point(i=i, frame=frame, codeno=codeno, + frames=frames) + frame.thing = frame.thing + 1 + if codeno == 0: + no = (i % 2) + newframe = frames[no] + frame.thing += portal(no + 1, newframe, None) + frame.thing += newframe.thing + i += 1 + return frame.thing + + def main(): + frames = [Frame(1), Frame(2)] + return portal(0, Frame(0), frames) + + res = self.meta_interp(main, [], inline=True) + assert res == main() + def test_assembler_call_red_args(self): driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], get_printable_location = lambda codeno : str(codeno)) From noreply at buildbot.pypy.org Sun Oct 21 13:11:51 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 13:11:51 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Oups Message-ID: <20121021111151.9A3C01C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58305:ff19c249b0f4 Date: 2012-10-21 12:54 +0200 http://bitbucket.org/pypy/pypy/changeset/ff19c249b0f4/ Log: Oups diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -45,8 +45,8 @@ def clone(self): return FORCE_SPILL(self.OPNUM, self.getarglist()[:]) - def copy_and_change(self, opnum): # no arguments accepted - return self.clone() + def copy_and_change(self, opnum, args, result, descr): + return FORCE_SPILL(opnum, args, result, descr) def default_fail_descr(model, fail_args=None): From noreply at buildbot.pypy.org Sun Oct 21 13:11:52 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 13:11:52 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Fix test Message-ID: <20121021111152.DF9BA1C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58306:25a1e657b489 Date: 2012-10-21 13:00 +0200 http://bitbucket.org/pypy/pypy/changeset/25a1e657b489/ Log: Fix test diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2004,7 +2004,7 @@ assert self.cpu.get_finish_value_ref(frame) == xptr frame = self.cpu.execute_token(looptoken, 0) assert self.cpu.get_latest_value_int(frame, 0) == 1 - excvalue = self.cpu.get_finish_value_ref(frame) + excvalue = self.cpu.grab_exc_value(frame) assert not excvalue ytp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) @@ -2023,7 +2023,7 @@ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_latest_value_int(frame, 0) == 1 - excvalue = self.cpu.get_finish_value_ref(frame) + excvalue = self.cpu.grab_exc_value(frame) assert excvalue == yptr exc_tp = xtp @@ -2040,7 +2040,7 @@ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_latest_value_int(frame, 0) == 1 - excvalue = self.cpu.get_finish_value_ref(frame) + excvalue = self.cpu.grab_exc_value(frame) assert excvalue == xptr frame = self.cpu.execute_token(looptoken, 0) assert self.cpu.get_finish_value_int(frame) == -100 From noreply at buildbot.pypy.org Sun Oct 21 13:11:54 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 13:11:54 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Fix the logic for force() and call_may_force() Message-ID: <20121021111154.10B081C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58307:d497d888e892 Date: 2012-10-21 13:02 +0200 http://bitbucket.org/pypy/pypy/changeset/d497d888e892/ Log: Fix the logic for force() and call_may_force() diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -294,15 +294,6 @@ def force(self, frame): assert not frame._forced frame._forced = True - call_op = frame.current_op - if call_op.getopnum() == rop.FINISH: - guard_op = call_op - else: - guard_op = frame.lltrace.operations[frame.current_index + 1] - frame.latest_values = frame._getfailargs(guard_op, call_op.result) - descr = _getdescr(guard_op) - frame.latest_descr = descr - return descr def set_savedata_ref(self, frame, data): frame.saved_data = data @@ -858,7 +849,16 @@ res = _example_res[getkind(TP.RESULT)[0]] return res - execute_call_may_force = execute_call + def execute_call_may_force(self, calldescr, func, *args): + call_op = self.lltrace.operations[self.current_index] + guard_op = self.lltrace.operations[self.current_index + 1] + assert guard_op.getopnum() == rop.GUARD_NOT_FORCED + self.latest_values = self._getfailargs(guard_op, skip=call_op.result) + self.latest_descr = _getdescr(guard_op) + res = self.execute_call(calldescr, func, *args) + del self.latest_descr + del self.latest_values + return res def execute_call_release_gil(self, descr, func, *args): call_args = support.cast_call_args_in_order(descr.ARGS, args) diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2200,8 +2200,10 @@ def maybe_force(token, flag): assert lltype.typeOf(token) == cpu.JITFRAMEPTR if flag: - descr = self.cpu.force(token) + descr = self.cpu.get_latest_descr(token) values.append(descr) + x = self.cpu.force(token) + assert x is None values.append(self.cpu.get_latest_value_int(token, 0)) values.append(self.cpu.get_latest_value_int(token, 1)) values.append(token) @@ -2329,16 +2331,17 @@ assert values == [1, 10, frame] def test_force_from_finish(self): + finishdescr = BasicFailDescr(1) loop = parse(''' [i1, i2] p0 = jit_frame() finish(p0, descr=faildescr1) [i1, i2] - ''', namespace={'faildescr1': BasicFailDescr(1)}) + ''', namespace={'faildescr1': finishdescr}) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) - descr = self.cpu.force(frame) - assert self.cpu.get_latest_descr(frame) is descr + self.cpu.force(frame) + assert self.cpu.get_latest_descr(frame) is finishdescr assert self.cpu.get_latest_value_int(frame, 0) == 20 assert self.cpu.get_latest_value_int(frame, 1) == 0 From noreply at buildbot.pypy.org Sun Oct 21 13:11:55 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 13:11:55 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Fix fix fix the tests Message-ID: <20121021111155.3B1391C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58308:0b96e01dc86c Date: 2012-10-21 13:10 +0200 http://bitbucket.org/pypy/pypy/changeset/0b96e01dc86c/ Log: Fix fix fix the tests diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2550,10 +2550,11 @@ i0 = BoxInt() faildescr = BasicFailDescr(1) labeldescr = TargetToken() + finishdescr = BasicFailDescr(3) ops = [ ResOperation(rop.GUARD_NOT_INVALIDATED, [], None, descr=faildescr), ResOperation(rop.LABEL, [i0], None, descr=labeldescr), - ResOperation(rop.FINISH, [i0], None, descr=BasicFailDescr(3)), + ResOperation(rop.FINISH, [i0], None, descr=finishdescr), ] ops[0].setfailargs([]) looptoken = JitCellToken() @@ -2771,6 +2772,7 @@ i18 = int_add(i17, i9) finish(i18) []''' loop = parse(ops) + loop.operations[-1].getdescr().fast_path_done = True looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() fail_number = self.cpu.get_fail_descr_number( @@ -2798,7 +2800,8 @@ self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) args = [i+1 for i in range(10)] frame = self.cpu.execute_token(othertoken, *args) - assert self.cpu.get_finish_value_int(frame) == 97 + res = self.cpu.get_finish_value_int(frame) + assert res == 97 assert called == [] # test the slow path, going via assembler_helper() @@ -2839,6 +2842,7 @@ f2 = float_add(f0, f1) finish(f2) []''' loop = parse(ops) + loop.operations[-1].getdescr().fast_path_done = True fail_number = self.cpu.get_fail_descr_number( loop.operations[1].getdescr()) looptoken = JitCellToken() @@ -2930,6 +2934,7 @@ f2 = float_add(f0, f1) finish(f2) []''' loop = parse(ops) + loop.operations[-1].getdescr().fast_path_done = True looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) @@ -2968,18 +2973,19 @@ del called[:] # compile a replacement - ops = ''' + ops2 = ''' [f0, f1] i0 = float_eq(f0, -2.0) guard_false(i0) [] f2 = float_sub(f0, f1) finish(f2) []''' - loop = parse(ops) + loop2 = parse(ops2) + loop2.operations[-1].getdescr().fast_path_done = True looptoken2 = JitCellToken() looptoken2.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken2) + self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) fail_number = self.cpu.get_fail_descr_number( - loop.operations[1].getdescr()) + loop2.operations[1].getdescr()) # install it self.cpu.redirect_call_assembler(looptoken, looptoken2) @@ -3403,12 +3409,12 @@ res = self.cpu.get_latest_value_int(frame, 0) assert res == 10 - inputargs = [i0] - operations = [ + inputargs2 = [i0] + operations2 = [ ResOperation(rop.INT_SUB, [i0, ConstInt(20)], i2), ResOperation(rop.JUMP, [i2], None, descr=targettoken2), ] - self.cpu.compile_bridge(faildescr, inputargs, operations, looptoken) + self.cpu.compile_bridge(faildescr, inputargs2, operations2, looptoken) frame = self.cpu.execute_token(looptoken, 2) assert self.cpu.get_latest_descr(frame).identifier == 3 @@ -3520,8 +3526,8 @@ i10 = BoxInt(); i11 = BoxInt(); i12 = BoxInt(); i13 = BoxInt(); i14 = BoxInt() i15 = BoxInt(); i16 = BoxInt(); i17 = BoxInt(); i18 = BoxInt(); i19 = BoxInt() i20 = BoxInt() - inputargs = [i0] - operations = [ + inputargs2 = [i0] + operations2 = [ ResOperation(rop.LABEL, [i0], None, descr=targettoken1), ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), ResOperation(rop.INT_ADD, [i1, ConstInt(1)], i2), @@ -3550,15 +3556,16 @@ ResOperation(rop.GUARD_TRUE, [i20], None, descr=BasicFailDescr(42)), ResOperation(rop.JUMP, [i19], None, descr=targettoken1), ] - operations[-2].setfailargs([]) - self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken1) + operations2[-2].setfailargs([]) + self.cpu.compile_bridge(faildescr1, inputargs2, operations2, + looptoken1) looptoken2 = JitCellToken() - inputargs = [BoxInt()] - operations = [ + inputargs3 = [BoxInt()] + operations3 = [ ResOperation(rop.JUMP, [ConstInt(0)], None, descr=targettoken1), ] - self.cpu.compile_loop(inputargs, operations, looptoken2) + self.cpu.compile_loop(inputargs3, operations3, looptoken2) frame = self.cpu.execute_token(looptoken2, -9) assert self.cpu.get_latest_descr(frame).identifier == 42 From noreply at buildbot.pypy.org Sun Oct 21 13:11:56 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 13:11:56 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: merge heads Message-ID: <20121021111156.596DD1C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58309:a2118e60e259 Date: 2012-10-21 13:11 +0200 http://bitbucket.org/pypy/pypy/changeset/a2118e60e259/ Log: merge heads diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -41,6 +41,11 @@ self.registers_r = [None] * 256 self.registers_f = [None] * 256 + def __repr__(self): + if hasattr(self, 'jitcode'): + return '' % self.jitcode.name + return '>' + def setup(self, jitcode, greenkey=None): assert isinstance(jitcode, JitCode) self.jitcode = jitcode @@ -753,8 +758,7 @@ jfdescr = jfdescrbox.getref_base() descr = cpu.jitframe_cast_jfdescr_to_descr(jfdescr) if not descr: - xxx - raise SwitchToBlackhole(Counters.ABORT_ESCAPE) + raise Exception("descr should not be none while inside a recursive call") resume.rebuild_virtualizable_from_resumedata(self.metainterp, descr, vinfo, box, jfbox) self._opimpl_setfield_gc_any(box, vinfo.jit_frame_descr, @@ -901,7 +905,6 @@ if warmrunnerstate.inlining: if warmrunnerstate.can_inline_callable(greenboxes): portal_code = targetjitdriver_sd.mainjitcode - self.orgpc_before_recursive_call = orgpc return self.metainterp.perform_call(portal_code, allboxes, greenkey=greenboxes) assembler_call = True @@ -1094,6 +1097,8 @@ # with make_result_of_lastop(), so the lastop must be right: # it must be the call to 'self', and not the jit_merge_point # itself, which has no result at all. + vbox = redboxes[jitdriver_sd.index_of_virtualizable] + self._force_virtualizable_if_necessary(vbox, orgpc) assert len(self.metainterp.framestack) >= 2 try: self.metainterp.finishframe(None) @@ -1102,7 +1107,7 @@ frame = self.metainterp.framestack[-1] frame.do_recursive_call(jitdriver_sd, greenboxes + redboxes, assembler_call=True, - orgpc=frame.orgpc_before_recursive_call) + orgpc=-1) # don't force the virtualizable raise ChangeFrame def debug_merge_point(self, jitdriver_sd, jd_index, portal_call_depth, current_call_id, greenkey): @@ -2549,8 +2554,6 @@ if targetjitdriver_sd.virtualizable_info is not None and orgpc != -1: vbox = args[targetjitdriver_sd.index_of_virtualizable] frame = self.framestack[-1] - import pdb - pdb.set_trace() frame._force_virtualizable_if_necessary(vbox, orgpc) token = warmrunnerstate.get_assembler_token(greenargs) op = op.copy_and_change(rop.CALL_ASSEMBLER, args=args, descr=token) diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -1019,6 +1019,38 @@ res = self.meta_interp(main, [], inline=True) assert res == main() + def test_call_assembler_force_in_the_blackhole(self): + class Frame(object): + _virtualizable2_ = ['thing'] + + def __init__(self, thing): + self.thing = thing + + driver = JitDriver(greens = ['codeno'], + reds = ['i', 'frame', 'frames'], + virtualizables = ['frame']) + + def portal(codeno, frame, frames): + i = 0 + while i < 10: + driver.jit_merge_point(i=i, frame=frame, codeno=codeno, + frames=frames) + frame.thing = frame.thing + 1 + if codeno == 0: + no = (i % 2) + newframe = frames[no] + frame.thing += portal(no + 1, newframe, None) + frame.thing += newframe.thing + i += 1 + return frame.thing + + def main(): + frames = [Frame(1), Frame(2)] + return portal(0, Frame(0), frames) + + res = self.meta_interp(main, [], inline=True) + assert res == main() + def test_assembler_call_red_args(self): driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], get_printable_location = lambda codeno : str(codeno)) From noreply at buildbot.pypy.org Sun Oct 21 13:25:34 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 13:25:34 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: s/FlowSpaceFrame(pyframe.PyFrame)/FlowSpaceFrame(object)/ Message-ID: <20121021112534.87D281C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: translation-cleanup Changeset: r58310:ed42a04d80cc Date: 2012-10-21 13:25 +0200 http://bitbucket.org/pypy/pypy/changeset/ed42a04d80cc/ Log: s/FlowSpaceFrame(pyframe.PyFrame)/FlowSpaceFrame(object)/ diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -31,21 +31,21 @@ # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', - 'truediv', 'floordiv', 'divmod', 'pow', + 'truediv', 'floordiv', 'divmod', 'and_', 'or_', 'xor', 'lshift', 'rshift', 'getitem', 'setitem', 'delitem', 'getitem_idx', 'getitem_key', 'getitem_idx_key', 'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv', 'inplace_floordiv', 'inplace_div', - 'inplace_mod', 'inplace_pow', + 'inplace_mod', 'inplace_lshift', 'inplace_rshift', 'inplace_and', 'inplace_or', 'inplace_xor', 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'is_', 'cmp', 'coerce', ] +[opname+'_ovf' for opname in - """add sub mul floordiv div mod pow lshift + """add sub mul floordiv div mod lshift """.split() ]) @@ -65,7 +65,6 @@ def inplace_floordiv((obj1, obj2)): return pair(obj1, obj2).floordiv() def inplace_div((obj1, obj2)): return pair(obj1, obj2).div() def inplace_mod((obj1, obj2)): return pair(obj1, obj2).mod() - def inplace_pow((obj1, obj2)): return pair(obj1, obj2).pow(s_None) def inplace_lshift((obj1, obj2)): return pair(obj1, obj2).lshift() def inplace_rshift((obj1, obj2)): return pair(obj1, obj2).rshift() def inplace_and((obj1, obj2)): return pair(obj1, obj2).and_() @@ -301,19 +300,6 @@ return SomeInteger(nonneg=int1.nonneg, knowntype=int1.knowntype) rshift.can_only_throw = [] - def pow((int1, int2), obj3): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - pow.can_only_throw = [ZeroDivisionError] - pow_ovf = _clone(pow, [ZeroDivisionError, OverflowError]) - - def inplace_pow((int1, int2)): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - inplace_pow.can_only_throw = [ZeroDivisionError] - def _compare_helper((int1, int2), opname, operation): r = SomeBool() if int1.is_immutable_constant() and int2.is_immutable_constant(): @@ -500,9 +486,6 @@ div.can_only_throw = [] truediv = div - def pow((flt1, flt2), obj3): - raise NotImplementedError("float power not supported, use math.pow") - # repeat these in order to copy the 'can_only_throw' attribute inplace_div = div inplace_truediv = truediv diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -13,7 +13,7 @@ from pypy.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong from pypy.rlib.rarithmetic import r_singlefloat from pypy.rlib import objectmodel -from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.objspace.flow.objspace import FlowObjSpace, FlowingError from pypy.translator.test import snippet @@ -1431,15 +1431,6 @@ assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_pow(self): - def f(n): - n **= 2 - return 2 ** n - a = self.RPythonAnnotator() - s = a.build_types(f, [int]) - # result should be an integer - assert s.knowntype == int - def test_inplace_div(self): def f(n): n /= 2 @@ -3156,10 +3147,9 @@ x **= y return x ** y a = self.RPythonAnnotator() - s = a.build_types(f, [int, int]) - assert isinstance(s, annmodel.SomeInteger) - a = self.RPythonAnnotator() - py.test.raises(NotImplementedError, a.build_types, f, [float, float]) + py.test.raises(FlowingError, a.build_types, f, [int, int]) + a = self.RPythonAnnotator() + py.test.raises(FlowingError, a.build_types, f, [float, float]) def test_intcmp_bug(self): def g(x, y): diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -104,7 +104,7 @@ def _combine_starargs_wrapped(self, w_stararg): # unpack the * arguments space = self.space - args_w = space.fixedview(w_stararg) + args_w = space.unpackiterable(w_stararg) self.arguments_w = self.arguments_w + args_w def _combine_starstarargs_wrapped(self, w_starstararg): @@ -117,7 +117,7 @@ self.keywords_w = values_w else: if set(keywords) & set(self.keywords): - raise TypeError("got multiple values for keyword argument '%s'", key) + raise TypeError("got multiple values for keyword arguments '%s'", set(keywords) & set(self.keywords)) self.keywords = self.keywords + keywords self.keywords_w = self.keywords_w + values_w return diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -267,6 +267,27 @@ BINARY_OP.func_name = OPCODE return BINARY_OP +_unsupported_ops = [ + ('BINARY_POWER', "a ** b"), + ('BUILD_CLASS', 'creating new classes'), + ('EXEC_STMT', 'exec statement'), + ('STOP_CODE', '???'), + ('STORE_NAME', 'modifying globals'), + ('INPLACE_POWER', 'a **= b'), + ('LOAD_LOCALS', 'locals()'), + ('IMPORT_STAR', 'import *'), + ('MISSING_OPCODE', '???'), + ('DELETE_GLOBAL', 'modifying globals'), + ('DELETE_NAME', 'modifying globals'), + ('DELETE_ATTR', 'deleting attributes'), +] + +def unsupportedoperation(OPCODE, msg): + def UNSUPPORTED(self, *ignored): + raise FlowingError(self, "%s is not RPython" % (msg,)) + UNSUPPORTED.func_name = OPCODE + return UNSUPPORTED + compare_method = [ "cmp_lt", # "<" "cmp_le", # "<=" @@ -281,7 +302,7 @@ "cmp_exc_match", ] -class FlowSpaceFrame(pyframe.PyFrame): +class FlowSpaceFrame(object): opcode_method_names = host_bytecode_spec.method_names def __init__(self, space, graph, code): @@ -337,6 +358,11 @@ "peek past the bottom of the stack") return self.locals_stack_w[index] + def pushrevvalues(self, n, values_w): # n should be len(values_w) + assert len(values_w) == n + for i in range(n - 1, -1, -1): + self.pushvalue(values_w[i]) + def settopvalue(self, w_object, index_from_top=0): index = self.valuestackdepth + ~index_from_top assert index >= self.pycode.co_nlocals, ( @@ -838,6 +864,7 @@ def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) + LOAD_NAME = LOAD_GLOBAL def LOAD_ATTR(self, nameindex, next_instr): "obj.attributename" @@ -900,6 +927,9 @@ for OPCODE, op in _binary_ops: locals()[OPCODE] = binaryoperation(OPCODE, op) + for OPCODE, op in _unsupported_ops: + locals()[OPCODE] = unsupportedoperation(OPCODE, op) + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. @@ -955,6 +985,140 @@ fn = self.space.newfunction(w_codeobj, self.w_globals, defaults) self.pushvalue(fn) + def STORE_ATTR(self, nameindex, next_instr): + "obj.attributename = newvalue" + w_attributename = self.getname_w(nameindex) + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setattr(w_obj, w_attributename, w_newvalue) + + def UNPACK_SEQUENCE(self, itemcount, next_instr): + w_iterable = self.popvalue() + items = self.space.unpackiterable(w_iterable, itemcount) + self.pushrevvalues(itemcount, items) + + def slice(self, w_start, w_end): + w_obj = self.popvalue() + w_result = self.space.getslice(w_obj, w_start, w_end) + self.pushvalue(w_result) + + def SLICE_0(self, oparg, next_instr): + self.slice(self.space.w_None, self.space.w_None) + + def SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.slice(w_start, self.space.w_None) + + def SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.slice(self.space.w_None, w_end) + + def SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.slice(w_start, w_end) + + def storeslice(self, w_start, w_end): + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setslice(w_obj, w_start, w_end, w_newvalue) + + def STORE_SLICE_0(self, oparg, next_instr): + self.storeslice(self.space.w_None, self.space.w_None) + + def STORE_SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.storeslice(w_start, self.space.w_None) + + def STORE_SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.storeslice(self.space.w_None, w_end) + + def STORE_SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.storeslice(w_start, w_end) + + def deleteslice(self, w_start, w_end): + w_obj = self.popvalue() + self.space.delslice(w_obj, w_start, w_end) + + def DELETE_SLICE_0(self, oparg, next_instr): + self.deleteslice(self.space.w_None, self.space.w_None) + + def DELETE_SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.deleteslice(w_start, self.space.w_None) + + def DELETE_SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.deleteslice(self.space.w_None, w_end) + + def DELETE_SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.deleteslice(w_start, w_end) + + def LIST_APPEND(self, oparg, next_instr): + w = self.popvalue() + v = self.peekvalue(oparg - 1) + self.space.call_method(v, 'append', w) + + def DELETE_FAST(self, varindex, next_instr): + if self.locals_stack_w[varindex] is None: + varname = self.getlocalvarname(varindex) + message = "local variable '%s' referenced before assignment" + raise UnboundLocalError(message, varname) + self.locals_stack_w[varindex] = None + + def STORE_MAP(self, oparg, next_instr): + w_key = self.popvalue() + w_value = self.popvalue() + w_dict = self.peekvalue() + self.space.setitem(w_dict, w_key, w_value) + + def STORE_SUBSCR(self, oparg, next_instr): + "obj[subscr] = newvalue" + w_subscr = self.popvalue() + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setitem(w_obj, w_subscr, w_newvalue) + + def BUILD_SLICE(self, numargs, next_instr): + if numargs == 3: + w_step = self.popvalue() + elif numargs == 2: + w_step = self.space.w_None + else: + raise BytecodeCorruption + w_end = self.popvalue() + w_start = self.popvalue() + w_slice = self.space.newslice(w_start, w_end, w_step) + self.pushvalue(w_slice) + + def DELETE_SUBSCR(self, oparg, next_instr): + "del obj[subscr]" + w_subscr = self.popvalue() + w_obj = self.popvalue() + self.space.delitem(w_obj, w_subscr) + + def BUILD_TUPLE(self, itemcount, next_instr): + items = self.popvalues(itemcount) + w_tuple = self.space.newtuple(items) + self.pushvalue(w_tuple) + + def BUILD_LIST(self, itemcount, next_instr): + items = self.popvalues(itemcount) + w_list = self.space.newlist(items) + self.pushvalue(w_list) + + def BUILD_MAP(self, itemcount, next_instr): + w_dict = self.space.newdict() + self.pushvalue(w_dict) + + def NOP(self, *args): + pass + # XXX Unimplemented 2.7 opcodes ---------------- # Set literals, set comprehensions diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -226,7 +226,7 @@ w_real_class = self.wrap(rstackovf._StackOverflow) return self._exception_match(w_exc_type, w_real_class) # checking a tuple of classes - for w_klass in self.fixedview(w_check_class): + for w_klass in self.unpackiterable(w_check_class): if self.exception_match(w_exc_type, w_klass): return True return False @@ -285,10 +285,6 @@ tweak_generator_graph(graph) return graph - def fixedview(self, w_tuple, expected_length=None): - return self.unpackiterable(w_tuple, expected_length) - listview = fixedview_unroll = fixedview - def unpackiterable(self, w_iterable, expected_length=None): if not isinstance(w_iterable, Variable): l = list(self.unwrap(w_iterable)) diff --git a/pypy/rpython/rfloat.py b/pypy/rpython/rfloat.py --- a/pypy/rpython/rfloat.py +++ b/pypy/rpython/rfloat.py @@ -53,8 +53,6 @@ # 'floordiv' on floats not supported in RPython - # pow on floats not supported in RPython - #comparisons: eq is_ ne lt le gt ge def rtype_eq(_, hop): diff --git a/pypy/rpython/rint.py b/pypy/rpython/rint.py --- a/pypy/rpython/rint.py +++ b/pypy/rpython/rint.py @@ -126,33 +126,6 @@ return _rtype_template(hop, 'rshift') rtype_inplace_rshift = rtype_rshift - def rtype_pow(_, hop): - raise MissingRTypeOperation("'**' not supported in RPython") - - rtype_pow_ovf = rtype_pow - rtype_inplace_pow = rtype_pow - -## def rtype_pow(_, hop, suffix=''): -## if hop.has_implicit_exception(ZeroDivisionError): -## suffix += '_zer' -## s_int3 = hop.args_s[2] -## rresult = hop.rtyper.makerepr(hop.s_result) -## if s_int3.is_constant() and s_int3.const is None: -## vlist = hop.inputargs(rresult, rresult, Void)[:2] -## else: -## vlist = hop.inputargs(rresult, rresult, rresult) -## hop.exception_is_here() -## return hop.genop(rresult.opprefix + 'pow' + suffix, vlist, resulttype=rresult) - -## def rtype_pow_ovf(_, hop): -## if hop.s_result.unsigned: -## raise TyperError("forbidden uint_pow_ovf") -## hop.has_implicit_exception(OverflowError) # record that we know about it -## return self.rtype_pow(_, hop, suffix='_ovf') - -## def rtype_inplace_pow(_, hop): -## return _rtype_template(hop, 'pow', [ZeroDivisionError]) - #comparisons: eq is_ ne lt le gt ge def rtype_eq(_, hop): diff --git a/pypy/translator/c/src/float.h b/pypy/translator/c/src/float.h --- a/pypy/translator/c/src/float.h +++ b/pypy/translator/c/src/float.h @@ -27,7 +27,6 @@ #define OP_FLOAT_SUB(x,y,r) r = x - y #define OP_FLOAT_MUL(x,y,r) r = x * y #define OP_FLOAT_TRUEDIV(x,y,r) r = x / y -#define OP_FLOAT_POW(x,y,r) r = pow(x, y) /*** conversions ***/ From noreply at buildbot.pypy.org Sun Oct 21 13:39:20 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 13:39:20 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: kill last mentions of pypy.interpreter from flow objspace, great job ronan! Message-ID: <20121021113920.C04671C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: translation-cleanup Changeset: r58311:a43ff0456b69 Date: 2012-10-21 13:39 +0200 http://bitbucket.org/pypy/pypy/changeset/a43ff0456b69/ Log: kill last mentions of pypy.interpreter from flow objspace, great job ronan! diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,12 +1,14 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import BytecodeCorruption from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) -from pypy.interpreter.astcompiler.consts import (CO_GENERATOR, CO_VARARGS, - CO_VARKEYWORDS) from pypy.objspace.flow.argument import Signature +from pypy.objspace.flow.flowcontext import BytecodeCorruption + +CO_GENERATOR = 0x0020 +CO_VARARGS = 0x0004 +CO_VARKEYWORDS = 0x0008 def cpython_code_signature(code): "([list-of-arg-names], vararg-name-or-None, kwarg-name-or-None)." diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -7,9 +7,7 @@ from pypy.tool.error import source_lines from pypy.tool.stdlib_opcode import host_bytecode_spec -from pypy.interpreter import pyframe from pypy.objspace.flow.argument import ArgumentsForTranslation -from pypy.interpreter.pyopcode import BytecodeCorruption from pypy.objspace.flow.model import (Constant, Variable, Block, Link, UnwrapException, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, @@ -51,6 +49,9 @@ class ImplicitOperationError(FSException): pass +class BytecodeCorruption(Exception): + pass + class SpamBlock(Block): # make slots optional, for debugging if hasattr(Block, '__slots__'): diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -7,7 +7,6 @@ import types from inspect import CO_NEWLOCALS -from pypy.interpreter.baseobjspace import ObjSpace from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.objspace.flow.model import (Constant, Variable, WrapException, UnwrapException, checkgraph, SpaceOperation) @@ -569,5 +568,5 @@ setattr(FlowObjSpace, name, generic_operator) -for (name, symbol, arity, specialnames) in ObjSpace.MethodTable: +for (name, symbol, arity, specialnames) in operation.MethodTable: make_op(name, arity) diff --git a/pypy/objspace/flow/operation.py b/pypy/objspace/flow/operation.py --- a/pypy/objspace/flow/operation.py +++ b/pypy/objspace/flow/operation.py @@ -6,10 +6,91 @@ import __builtin__ import __future__ import operator -from pypy.interpreter.baseobjspace import ObjSpace from pypy.tool.sourcetools import compile2 from pypy.rlib.rarithmetic import ovfcheck +# this is a copy that should be shared with standard objspace + +MethodTable = [ +# method name # symbol # number of arguments # special method name(s) + ('is_', 'is', 2, []), + ('id', 'id', 1, []), + ('type', 'type', 1, []), + ('isinstance', 'isinstance', 2, ['__instancecheck__']), + ('issubtype', 'issubtype', 2, ['__subclasscheck__']), # not for old-style classes + ('repr', 'repr', 1, ['__repr__']), + ('str', 'str', 1, ['__str__']), + ('format', 'format', 2, ['__format__']), + ('len', 'len', 1, ['__len__']), + ('hash', 'hash', 1, ['__hash__']), + ('getattr', 'getattr', 2, ['__getattribute__']), + ('setattr', 'setattr', 3, ['__setattr__']), + ('delattr', 'delattr', 2, ['__delattr__']), + ('getitem', 'getitem', 2, ['__getitem__']), + ('setitem', 'setitem', 3, ['__setitem__']), + ('delitem', 'delitem', 2, ['__delitem__']), + ('getslice', 'getslice', 3, ['__getslice__']), + ('setslice', 'setslice', 4, ['__setslice__']), + ('delslice', 'delslice', 3, ['__delslice__']), + ('trunc', 'trunc', 1, ['__trunc__']), + ('pos', 'pos', 1, ['__pos__']), + ('neg', 'neg', 1, ['__neg__']), + ('nonzero', 'truth', 1, ['__nonzero__']), + ('abs' , 'abs', 1, ['__abs__']), + ('hex', 'hex', 1, ['__hex__']), + ('oct', 'oct', 1, ['__oct__']), + ('ord', 'ord', 1, []), + ('invert', '~', 1, ['__invert__']), + ('add', '+', 2, ['__add__', '__radd__']), + ('sub', '-', 2, ['__sub__', '__rsub__']), + ('mul', '*', 2, ['__mul__', '__rmul__']), + ('truediv', '/', 2, ['__truediv__', '__rtruediv__']), + ('floordiv', '//', 2, ['__floordiv__', '__rfloordiv__']), + ('div', 'div', 2, ['__div__', '__rdiv__']), + ('mod', '%', 2, ['__mod__', '__rmod__']), + ('divmod', 'divmod', 2, ['__divmod__', '__rdivmod__']), + ('pow', '**', 3, ['__pow__', '__rpow__']), + ('lshift', '<<', 2, ['__lshift__', '__rlshift__']), + ('rshift', '>>', 2, ['__rshift__', '__rrshift__']), + ('and_', '&', 2, ['__and__', '__rand__']), + ('or_', '|', 2, ['__or__', '__ror__']), + ('xor', '^', 2, ['__xor__', '__rxor__']), + ('int', 'int', 1, ['__int__']), + ('index', 'index', 1, ['__index__']), + ('float', 'float', 1, ['__float__']), + ('long', 'long', 1, ['__long__']), + ('inplace_add', '+=', 2, ['__iadd__']), + ('inplace_sub', '-=', 2, ['__isub__']), + ('inplace_mul', '*=', 2, ['__imul__']), + ('inplace_truediv', '/=', 2, ['__itruediv__']), + ('inplace_floordiv','//=', 2, ['__ifloordiv__']), + ('inplace_div', 'div=', 2, ['__idiv__']), + ('inplace_mod', '%=', 2, ['__imod__']), + ('inplace_pow', '**=', 2, ['__ipow__']), + ('inplace_lshift', '<<=', 2, ['__ilshift__']), + ('inplace_rshift', '>>=', 2, ['__irshift__']), + ('inplace_and', '&=', 2, ['__iand__']), + ('inplace_or', '|=', 2, ['__ior__']), + ('inplace_xor', '^=', 2, ['__ixor__']), + ('lt', '<', 2, ['__lt__', '__gt__']), + ('le', '<=', 2, ['__le__', '__ge__']), + ('eq', '==', 2, ['__eq__', '__eq__']), + ('ne', '!=', 2, ['__ne__', '__ne__']), + ('gt', '>', 2, ['__gt__', '__lt__']), + ('ge', '>=', 2, ['__ge__', '__le__']), + ('cmp', 'cmp', 2, ['__cmp__']), # rich cmps preferred + ('coerce', 'coerce', 2, ['__coerce__', '__coerce__']), + ('contains', 'contains', 2, ['__contains__']), + ('iter', 'iter', 1, ['__iter__']), + ('next', 'next', 1, ['next']), +# ('call', 'call', 3, ['__call__']), + ('get', 'get', 3, ['__get__']), + ('set', 'set', 3, ['__set__']), + ('delete', 'delete', 2, ['__delete__']), + ('userdel', 'del', 1, ['__del__']), + ('buffer', 'buffer', 1, ['__buffer__']), # see buffer.py + ] + FunctionByName = {} # dict {"operation_name": } OperationName = {} # dict {: "operation_name"} @@ -223,7 +304,7 @@ def setup(): # insert all operators - for line in ObjSpace.MethodTable: + for line in MethodTable: name = line[0] if hasattr(operator, name): Table.append((name, getattr(operator, name))) @@ -234,7 +315,7 @@ if func not in OperationName: OperationName[func] = name # check that the result is complete - for line in ObjSpace.MethodTable: + for line in MethodTable: name = line[0] Arity[name] = line[2] assert name in FunctionByName diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -749,7 +749,7 @@ def test_mergeable(self): def myfunc(x): if x: - from pypy.interpreter.error import OperationError + from pypy.objspace.flow.flowcontext import BytecodeCorruption s = 12 else: s = x.abc From noreply at buildbot.pypy.org Sun Oct 21 13:40:59 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 13:40:59 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: one more Message-ID: <20121021114059.BDDA31C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: translation-cleanup Changeset: r58312:fcb1bc74e5ca Date: 2012-10-21 13:40 +0200 http://bitbucket.org/pypy/pypy/changeset/fcb1bc74e5ca/ Log: one more diff --git a/pypy/annotation/specialize.py b/pypy/annotation/specialize.py --- a/pypy/annotation/specialize.py +++ b/pypy/annotation/specialize.py @@ -6,7 +6,7 @@ from pypy.objspace.flow.model import Block, Link, Variable, SpaceOperation from pypy.objspace.flow.model import Constant, checkgraph from pypy.annotation import model as annmodel -from pypy.interpreter.argument import Signature +from pypy.objspace.flow.argument import Signature def flatten_star_args(funcdesc, args_s): argnames, vararg, kwarg = funcdesc.signature From noreply at buildbot.pypy.org Sun Oct 21 15:16:19 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 15:16:19 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: fixes for blackhole Message-ID: <20121021131619.91C0D1C0171@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: continulet-jit-3 Changeset: r58313:8157ebf4f6e7 Date: 2012-10-21 15:15 +0200 http://bitbucket.org/pypy/pypy/changeset/8157ebf4f6e7/ Log: fixes for blackhole diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -295,6 +295,11 @@ assert not frame._forced frame._forced = True + def force_vable_if_necessary(self, vable): + if vable.jitframe: + self.force(vable.jitframe) + vable.jitframe = lltype.nulltpr(llmemory.GCREF.TO) + def set_savedata_ref(self, frame, data): frame.saved_data = data diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -39,6 +39,9 @@ # ____________________________________________________________ +def bh_force_vable(vinfo, vable): + vable = lltype.cast_opaque_ptr(vinfo.VTYPEPTR, vable) + vinfo.force_virtualizable_if_necessary(vable) class BlackholeInterpBuilder(object): verbose = True @@ -147,6 +150,8 @@ value = self elif argtype == 'cpu': value = self.cpu + elif argtype == 'vinfo': + value = self.vinfo elif argtype == 'pc': value = position elif argtype == 'd' or argtype == 'j': @@ -1165,34 +1170,47 @@ def bhimpl_arraylen_gc(cpu, array, arraydescr): return cpu.bh_arraylen_gc(array, arraydescr) - @arguments("cpu", "r", "d", "d", "i", returns="i") - def bhimpl_getarrayitem_vable_i(cpu, vable, fielddescr, arraydescr, index): + @arguments("cpu", "vinfo", "r", "d", "d", "i", returns="i") + def bhimpl_getarrayitem_vable_i(cpu, vinfo, vable, fielddescr, arraydescr, + index): + bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fielddescr) return cpu.bh_getarrayitem_gc_i(array, index, arraydescr) - @arguments("cpu", "r", "d", "d", "i", returns="r") - def bhimpl_getarrayitem_vable_r(cpu, vable, fielddescr, arraydescr, index): + @arguments("cpu", "vinfo", "r", "d", "d", "i", returns="r") + def bhimpl_getarrayitem_vable_r(cpu, vinfo, vable, fielddescr, arraydescr, + index): + bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fielddescr) return cpu.bh_getarrayitem_gc_r(array, index, arraydescr) @arguments("cpu", "r", "d", "d", "i", returns="f") - def bhimpl_getarrayitem_vable_f(cpu, vable, fielddescr, arraydescr, index): + def bhimpl_getarrayitem_vable_f(cpu, vinfo, vable, fielddescr, arraydescr, + index): + bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fielddescr) return cpu.bh_getarrayitem_gc_f(array, index, arraydescr) - @arguments("cpu", "r", "d", "d", "i", "i") - def bhimpl_setarrayitem_vable_i(cpu, vable, fdescr, adescr, index, newval): + @arguments("cpu", "vinfo", "r", "d", "d", "i", "i") + def bhimpl_setarrayitem_vable_i(cpu, vinfo, vable, fdescr, adescr, index, + newval): + bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fdescr) cpu.bh_setarrayitem_gc_i(array, index, newval, adescr) - @arguments("cpu", "r", "d", "d", "i", "r") - def bhimpl_setarrayitem_vable_r(cpu, vable, fdescr, adescr, index, newval): + @arguments("cpu", "vinfo", "r", "d", "d", "i", "r") + def bhimpl_setarrayitem_vable_r(cpu, vinfo, vable, fdescr, adescr, index, + newval): + bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fdescr) cpu.bh_setarrayitem_gc_r(array, index, newval, adescr) - @arguments("cpu", "r", "d", "d", "i", "f") - def bhimpl_setarrayitem_vable_f(cpu, vable, fdescr, adescr, index, newval): + @arguments("cpu", "vinfo", "r", "d", "d", "i", "f") + def bhimpl_setarrayitem_vable_f(cpu, vinfo, vable, fdescr, adescr, index, + newval): + bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fdescr) cpu.bh_setarrayitem_gc_f(array, index, newval, adescr) - @arguments("cpu", "r", "d", "d", returns="i") - def bhimpl_arraylen_vable(cpu, vable, fdescr, adescr): + @arguments("cpu", "vinfo", "r", "d", "d", returns="i") + def bhimpl_arraylen_vable(cpu, vinfo, vable, fdescr, adescr): + bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fdescr) return cpu.bh_arraylen_gc(array, adescr) @@ -1230,9 +1248,18 @@ bhimpl_getfield_gc_r_pure = bhimpl_getfield_gc_r bhimpl_getfield_gc_f_pure = bhimpl_getfield_gc_f - bhimpl_getfield_vable_i = bhimpl_getfield_gc_i - bhimpl_getfield_vable_r = bhimpl_getfield_gc_r - bhimpl_getfield_vable_f = bhimpl_getfield_gc_f + @arguments("cpu", "vinfo", "r", "d", returns="i") + def bhimpl_getfield_vable_i(cpu, vinfo, vable, fielddescr): + bh_force_vable(vinfo, vable) + return cpu.bh_getfield_gc_i(vable, fielddescr) + @arguments("cpu", "vinfo", "r", "d", returns="r") + def bhimpl_getfield_vable_r(cpu, vinfo, vable, fielddescr): + bh_force_vable(vinfo, vable) + return cpu.bh_getfield_gc_r(vable, fielddescr) + @arguments("cpu", "vinfo", "r", "d", returns="f") + def bhimpl_getfield_vable_f(cpu, vinfo, vable, fielddescr): + bh_force_vable(vinfo, vable) + return cpu.bh_getfield_gc_f(vable, fielddescr) bhimpl_getfield_gc_i_greenfield = bhimpl_getfield_gc_i bhimpl_getfield_gc_r_greenfield = bhimpl_getfield_gc_r @@ -1262,9 +1289,18 @@ def bhimpl_setfield_gc_f(cpu, struct, fielddescr, newvalue): cpu.bh_setfield_gc_f(struct, newvalue, fielddescr) - bhimpl_setfield_vable_i = bhimpl_setfield_gc_i - bhimpl_setfield_vable_r = bhimpl_setfield_gc_r - bhimpl_setfield_vable_f = bhimpl_setfield_gc_f + @arguments("cpu", "vinfo", "r", "d", "i") + def bhimpl_setfield_vable_i(cpu, vinfo, struct, fielddescr, newvalue): + bh_force_vable(vinfo, struct) + cpu.bh_setfield_gc_i(struct, newvalue, fielddescr) + @arguments("cpu", "vinfo", "r", "d", "r") + def bhimpl_setfield_vable_r(cpu, vinfo, struct, fielddescr, newvalue): + bh_force_vable(vinfo, struct) + cpu.bh_setfield_gc_r(struct, newvalue, fielddescr) + @arguments("cpu", "vinfo", "r", "d", "f") + def bhimpl_setfield_vable_f(cpu, vinfo, struct, fielddescr, newvalue): + bh_force_vable(vinfo, struct) + cpu.bh_setfield_gc_f(struct, newvalue, fielddescr) @arguments("cpu", "i", "d", "i") def bhimpl_setfield_raw_i(cpu, struct, fielddescr, newvalue): diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -628,7 +628,8 @@ # an inconsistent state rstack._stack_criticalcode_start() try: - faildescr = cpu.force(jitframetoken) + cpu.force(jitframetoken) + faildescr = cpu.get_latest_descr(jitframetoken) assert isinstance(faildescr, ResumeGuardForcedDescr) faildescr.handle_async_forcing(jitframetoken) finally: diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py --- a/pypy/jit/metainterp/resume.py +++ b/pypy/jit/metainterp/resume.py @@ -1082,6 +1082,7 @@ frameinfo = storage.rd_frame_info_list while True: curbh = blackholeinterpbuilder.acquire_interp() + curbh.vinfo = jitdriver_sd.virtualizable_info curbh.nextblackholeinterp = nextbh nextbh = curbh frameinfo = frameinfo.prev diff --git a/pypy/jit/metainterp/virtualizable.py b/pypy/jit/metainterp/virtualizable.py --- a/pypy/jit/metainterp/virtualizable.py +++ b/pypy/jit/metainterp/virtualizable.py @@ -280,6 +280,7 @@ def force_virtualizable_if_necessary(virtualizable): if virtualizable.jit_frame != jitframe.TOKEN_NONE: self.force_now(virtualizable) + self.force_virtualizable_if_necessary = force_virtualizable_if_necessary force_virtualizable_if_necessary._always_inline_ = True # all_graphs = self.warmrunnerdesc.translator.graphs From noreply at buildbot.pypy.org Sun Oct 21 15:32:23 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 15:32:23 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: This is only adding confusion. Message-ID: <20121021133223.42D4A1C0171@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58314:28e88d052273 Date: 2012-10-21 15:18 +0200 http://bitbucket.org/pypy/pypy/changeset/28e88d052273/ Log: This is only adding confusion. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -616,7 +616,6 @@ class LLFrame(object): _TYPE = llmemory.GCREF - latest_descr = None # some obscure hacks to support comparison with llmemory.GCREF def __ne__(self, other): From noreply at buildbot.pypy.org Sun Oct 21 15:32:24 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 15:32:24 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Test and fix. Message-ID: <20121021133224.A568C1C0171@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58315:7e70e3dbc09b Date: 2012-10-21 15:32 +0200 http://bitbucket.org/pypy/pypy/changeset/7e70e3dbc09b/ Log: Test and fix. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -875,6 +875,13 @@ frame = self.cpu._execute_token(descr, *args) if frame._execution_finished_normally: # fast path return frame.finish_value + # + call_op = self.lltrace.operations[self.current_index] + guard_op = self.lltrace.operations[self.current_index + 1] + assert guard_op.getopnum() == rop.GUARD_NOT_FORCED + self.latest_values = self._getfailargs(guard_op, skip=call_op.result) + self.latest_descr = _getdescr(guard_op) + # jd = descr.outermost_jitdriver_sd assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish try: @@ -885,6 +892,9 @@ if self.current_op.result is not None: return _example_res[self.current_op.result.type] return None + # + del self.latest_descr + del self.latest_values return support.cast_result(lltype.typeOf(result), result) def execute_same_as(self, _, x): diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2750,7 +2750,6 @@ FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], lltype.Signed)) class FakeJitDriverSD: - index_of_virtualizable = -1 _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper) assembler_helper_adr = llmemory.cast_ptr_to_adr( _assembler_helper_ptr) @@ -2823,7 +2822,6 @@ FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], lltype.Float)) class FakeJitDriverSD: - index_of_virtualizable = -1 _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper) assembler_helper_adr = llmemory.cast_ptr_to_adr( _assembler_helper_ptr) @@ -2878,6 +2876,50 @@ assert longlong.getrealfloat(x) == 13.5 assert called == [fail_number] + def test_assembler_call_get_latest_descr(self): + called = [] + def assembler_helper(jitframe): + jitframe1 = self.cpu.get_finish_value_ref(jitframe) + called.append(self.cpu.get_latest_descr(jitframe1)) + return lltype.nullptr(llmemory.GCREF.TO) + + FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], + llmemory.GCREF)) + class FakeJitDriverSD: + _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper) + assembler_helper_adr = llmemory.cast_ptr_to_adr( + _assembler_helper_ptr) + + ops = ''' + [p0] + finish(p0) []''' + loop = parse(ops) + # not a fast_path finish! + looptoken = JitCellToken() + looptoken.outermost_jitdriver_sd = FakeJitDriverSD() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + ARGS = [llmemory.GCREF] + RES = llmemory.GCREF + FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( + lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES, + EffectInfo.MOST_GENERAL) + + foodescr = BasicFailDescr(66) + ops = ''' + [] + p0 = jit_frame() + p1 = call_assembler(p0, descr=looptoken) + guard_not_forced(descr=foodescr) [] + finish() [] + ''' + loop2 = parse(ops, namespace=locals()) + othertoken = JitCellToken() + self.cpu.compile_loop(loop2.inputargs, loop2.operations, othertoken) + + frame = self.cpu.execute_token(othertoken) + assert not self.cpu.get_finish_value_ref(frame) + assert called == [foodescr] + def test_raw_malloced_getarrayitem(self): ARRAY = rffi.CArray(lltype.Signed) descr = self.cpu.arraydescrof(ARRAY) @@ -2915,7 +2957,6 @@ FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], lltype.Float)) class FakeJitDriverSD: - index_of_virtualizable = -1 _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper) assembler_helper_adr = llmemory.cast_ptr_to_adr( _assembler_helper_ptr) From noreply at buildbot.pypy.org Sun Oct 21 15:38:49 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 15:38:49 +0200 (CEST) Subject: [pypy-commit] pypy continulet-jit-3: Test and fix 2. Message-ID: <20121021133849.AA0D61C021A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: continulet-jit-3 Changeset: r58316:9e8ff9145588 Date: 2012-10-21 15:38 +0200 http://bitbucket.org/pypy/pypy/changeset/9e8ff9145588/ Log: Test and fix 2. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -872,26 +872,26 @@ return support.cast_result(descr.RESULT, result) def execute_call_assembler(self, descr, *args): - frame = self.cpu._execute_token(descr, *args) - if frame._execution_finished_normally: # fast path - return frame.finish_value - # call_op = self.lltrace.operations[self.current_index] guard_op = self.lltrace.operations[self.current_index + 1] assert guard_op.getopnum() == rop.GUARD_NOT_FORCED self.latest_values = self._getfailargs(guard_op, skip=call_op.result) self.latest_descr = _getdescr(guard_op) # - jd = descr.outermost_jitdriver_sd - assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish - try: - result = assembler_helper_ptr(frame) - except LLException, lle: - assert self.last_exception is None, "exception left behind" - self.last_exception = lle - if self.current_op.result is not None: - return _example_res[self.current_op.result.type] - return None + frame = self.cpu._execute_token(descr, *args) + if frame._execution_finished_normally: # fast path + result = frame.finish_value + else: + jd = descr.outermost_jitdriver_sd + assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish + try: + result = assembler_helper_ptr(frame) + except LLException, lle: + assert self.last_exception is None, "exception left behind" + self.last_exception = lle + if self.current_op.result is not None: + return _example_res[self.current_op.result.type] + return None # del self.latest_descr del self.latest_values diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2885,6 +2885,15 @@ FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], llmemory.GCREF)) + + def func2(jitframe1): + called.append(self.cpu.get_latest_descr(jitframe1)) + FPTR2 = lltype.Ptr(lltype.FuncType([llmemory.GCREF], lltype.Void)) + fptr2 = llhelper(FPTR2, func2) + calldescr2 = self.cpu.calldescrof(FPTR2.TO, FPTR2.TO.ARGS, + FPTR2.TO.RESULT, + EffectInfo.MOST_GENERAL) + class FakeJitDriverSD: _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper) assembler_helper_adr = llmemory.cast_ptr_to_adr( @@ -2892,8 +2901,9 @@ ops = ''' [p0] + call(ConstClass(fptr2), p0, descr=calldescr2) finish(p0) []''' - loop = parse(ops) + loop = parse(ops, namespace=locals()) # not a fast_path finish! looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() @@ -2918,7 +2928,7 @@ frame = self.cpu.execute_token(othertoken) assert not self.cpu.get_finish_value_ref(frame) - assert called == [foodescr] + assert called == [foodescr] * 2 def test_raw_malloced_getarrayitem(self): ARRAY = rffi.CArray(lltype.Signed) From noreply at buildbot.pypy.org Sun Oct 21 15:47:50 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 15:47:50 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: fix, not sure how to write a test for it Message-ID: <20121021134750.79DE01C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: translation-cleanup Changeset: r58317:4436184487f3 Date: 2012-10-21 15:47 +0200 http://bitbucket.org/pypy/pypy/changeset/4436184487f3/ Log: fix, not sure how to write a test for it diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -920,7 +920,13 @@ self.pushvalue(w_1) def DUP_TOPX(self, itemcount, next_instr): - self.dupvalues(itemcount) + delta = itemcount - 1 + while True: + itemcount -= 1 + if itemcount < 0: + break + w_value = self.peekvalue(delta) + self.pushvalue(w_value) for OPCODE, op in _unary_ops: locals()[OPCODE] = unaryoperation(OPCODE, op) From noreply at buildbot.pypy.org Sun Oct 21 17:16:56 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 17:16:56 +0200 (CEST) Subject: [pypy-commit] pypy default: (ronan mostly) merging translation-cleanup branch, where we split Message-ID: <20121021151656.7FCB81C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58318:3fdbd7395926 Date: 2012-10-21 17:16 +0200 http://bitbucket.org/pypy/pypy/changeset/3fdbd7395926/ Log: (ronan mostly) merging translation-cleanup branch, where we split interpreter and the RPython compilation toolchain diff too long, truncating to 2000 out of 2672 lines diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -31,21 +31,21 @@ # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', - 'truediv', 'floordiv', 'divmod', 'pow', + 'truediv', 'floordiv', 'divmod', 'and_', 'or_', 'xor', 'lshift', 'rshift', 'getitem', 'setitem', 'delitem', 'getitem_idx', 'getitem_key', 'getitem_idx_key', 'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv', 'inplace_floordiv', 'inplace_div', - 'inplace_mod', 'inplace_pow', + 'inplace_mod', 'inplace_lshift', 'inplace_rshift', 'inplace_and', 'inplace_or', 'inplace_xor', 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'is_', 'cmp', 'coerce', ] +[opname+'_ovf' for opname in - """add sub mul floordiv div mod pow lshift + """add sub mul floordiv div mod lshift """.split() ]) @@ -65,7 +65,6 @@ def inplace_floordiv((obj1, obj2)): return pair(obj1, obj2).floordiv() def inplace_div((obj1, obj2)): return pair(obj1, obj2).div() def inplace_mod((obj1, obj2)): return pair(obj1, obj2).mod() - def inplace_pow((obj1, obj2)): return pair(obj1, obj2).pow(s_None) def inplace_lshift((obj1, obj2)): return pair(obj1, obj2).lshift() def inplace_rshift((obj1, obj2)): return pair(obj1, obj2).rshift() def inplace_and((obj1, obj2)): return pair(obj1, obj2).and_() @@ -301,19 +300,6 @@ return SomeInteger(nonneg=int1.nonneg, knowntype=int1.knowntype) rshift.can_only_throw = [] - def pow((int1, int2), obj3): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - pow.can_only_throw = [ZeroDivisionError] - pow_ovf = _clone(pow, [ZeroDivisionError, OverflowError]) - - def inplace_pow((int1, int2)): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - inplace_pow.can_only_throw = [ZeroDivisionError] - def _compare_helper((int1, int2), opname, operation): r = SomeBool() if int1.is_immutable_constant() and int2.is_immutable_constant(): @@ -500,9 +486,6 @@ div.can_only_throw = [] truediv = div - def pow((flt1, flt2), obj3): - raise NotImplementedError("float power not supported, use math.pow") - # repeat these in order to copy the 'can_only_throw' attribute inplace_div = div inplace_truediv = truediv diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -16,7 +16,7 @@ from pypy.annotation.dictdef import DictDef from pypy.annotation import description from pypy.annotation.signature import annotationoftype -from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.rlib.objectmodel import r_dict, Symbolic from pypy.tool.algo.unionfind import UnionFind from pypy.rpython.lltypesystem import lltype, llmemory @@ -101,7 +101,7 @@ def consider_list_delitem(self, idx): return self.indexrepr(idx) - + def consider_str_join(self, s): if s.is_constant(): return repr(s.const) @@ -224,7 +224,7 @@ check_no_flags(s_value_or_def.listdef.listitem) elif isinstance(s_value_or_def, SomeDict): check_no_flags(s_value_or_def.dictdef.dictkey) - check_no_flags(s_value_or_def.dictdef.dictvalue) + check_no_flags(s_value_or_def.dictdef.dictvalue) elif isinstance(s_value_or_def, SomeTuple): for s_item in s_value_or_def.items: check_no_flags(s_item) @@ -238,9 +238,9 @@ elif isinstance(s_value_or_def, ListItem): if s_value_or_def in seen: return - seen.add(s_value_or_def) + seen.add(s_value_or_def) check_no_flags(s_value_or_def.s_value) - + for clsdef in self.classdefs: check_no_flags(clsdef) @@ -366,14 +366,14 @@ listdef = ListDef(self, s_ImpossibleValue) for e in x: listdef.generalize(self.immutablevalue(e, False)) - result = SomeList(listdef) + result = SomeList(listdef) elif tp is dict or tp is r_dict: if need_const: key = Constant(x) try: return self.immutable_cache[key] except KeyError: - result = SomeDict(DictDef(self, + result = SomeDict(DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict)) @@ -396,7 +396,7 @@ result.const_box = key return result else: - dictdef = DictDef(self, + dictdef = DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict) @@ -545,7 +545,7 @@ return True else: return False - + def getfrozen(self, pyobj): return description.FrozenDesc(self, pyobj) @@ -566,7 +566,7 @@ key = (x.__class__, x) if key in self.seen_mutable: return - clsdef = self.getuniqueclassdef(x.__class__) + clsdef = self.getuniqueclassdef(x.__class__) self.seen_mutable[key] = True self.event('mutable', x) source = InstanceSource(self, x) @@ -586,7 +586,7 @@ except KeyError: access_sets = map[attrname] = UnionFind(description.ClassAttrFamily) return access_sets - + def pbc_getattr(self, pbc, s_attr): assert s_attr.is_constant() attr = s_attr.const @@ -598,7 +598,7 @@ first = descs[0] if len(descs) == 1: return first.s_read_attribute(attr) - + change = first.mergeattrfamilies(descs[1:], attr) attrfamily = first.getattrfamily(attr) @@ -700,7 +700,7 @@ def ondegenerated(self, what, s_value, where=None, called_from_graph=None): self.annotator.ondegenerated(what, s_value, where=where, called_from_graph=called_from_graph) - + def whereami(self): return self.annotator.whereami(self.position_key) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -1,8 +1,7 @@ import types, py from pypy.objspace.flow.model import Constant, FunctionGraph -from pypy.interpreter.pycode import cpython_code_signature -from pypy.interpreter.argument import rawshape -from pypy.interpreter.argument import ArgErr +from pypy.objspace.flow.bytecode import cpython_code_signature +from pypy.objspace.flow.argument import rawshape, ArgErr from pypy.tool.sourcetools import valid_identifier from pypy.tool.pairtype import extendabletype @@ -181,7 +180,7 @@ name = pyobj.func_name if signature is None: if hasattr(pyobj, '_generator_next_method_of_'): - from pypy.interpreter.argument import Signature + from pypy.objspace.flow.argument import Signature signature = Signature(['entry']) # haaaaaack defaults = () else: @@ -260,7 +259,7 @@ try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: - raise TypeError("signature mismatch: %s() %s" % + raise TypeError("signature mismatch: %s() %s" % (self.name, e.getmsg())) return inputcells diff --git a/pypy/annotation/specialize.py b/pypy/annotation/specialize.py --- a/pypy/annotation/specialize.py +++ b/pypy/annotation/specialize.py @@ -6,7 +6,7 @@ from pypy.objspace.flow.model import Block, Link, Variable, SpaceOperation from pypy.objspace.flow.model import Constant, checkgraph from pypy.annotation import model as annmodel -from pypy.interpreter.argument import Signature +from pypy.objspace.flow.argument import Signature def flatten_star_args(funcdesc, args_s): argnames, vararg, kwarg = funcdesc.signature diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -13,7 +13,7 @@ from pypy.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong from pypy.rlib.rarithmetic import r_singlefloat from pypy.rlib import objectmodel -from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.objspace.flow.objspace import FlowObjSpace, FlowingError from pypy.translator.test import snippet @@ -1431,15 +1431,6 @@ assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_pow(self): - def f(n): - n **= 2 - return 2 ** n - a = self.RPythonAnnotator() - s = a.build_types(f, [int]) - # result should be an integer - assert s.knowntype == int - def test_inplace_div(self): def f(n): n /= 2 @@ -3156,10 +3147,9 @@ x **= y return x ** y a = self.RPythonAnnotator() - s = a.build_types(f, [int, int]) - assert isinstance(s, annmodel.SomeInteger) - a = self.RPythonAnnotator() - py.test.raises(NotImplementedError, a.build_types, f, [float, float]) + py.test.raises(FlowingError, a.build_types, f, [int, int]) + a = self.RPythonAnnotator() + py.test.raises(FlowingError, a.build_types, f, [float, float]) def test_intcmp_bug(self): def g(x, y): diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -504,149 +504,6 @@ w_key = keyword_names_w[i - limit] space.setitem(w_kwds, w_key, keywords_w[i]) -class ArgumentsForTranslation(Arguments): - def __init__(self, space, args_w, keywords=None, keywords_w=None, - w_stararg=None, w_starstararg=None): - self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False - Arguments.__init__(self, space, args_w, keywords, keywords_w) - - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - - def prepend(self, w_firstarg): # used often - "Return a new Arguments with a new argument inserted first." - return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - def copy(self): - return ArgumentsForTranslation(self.space, self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - - - def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None, - blindargs=0): - self.combine_if_necessary() - # _match_signature is destructive - return Arguments._match_signature( - self, w_firstarg, scope_w, signature, - defaults_w, blindargs) - - def unpack(self): - self.combine_if_necessary() - return Arguments.unpack(self) - - def match_signature(self, signature, defaults_w): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - return self._parse(None, signature, defaults_w) - - def unmatch_signature(self, signature, data_w): - """kind of inverse of match_signature""" - args_w, kwds_w = self.unpack() - need_cnt = len(args_w) - need_kwds = kwds_w.keys() - space = self.space - argnames, varargname, kwargname = signature - cnt = len(argnames) - data_args_w = data_w[:cnt] - if varargname: - data_w_stararg = data_w[cnt] - cnt += 1 - else: - data_w_stararg = space.newtuple([]) - - unfiltered_kwds_w = {} - if kwargname: - data_w_starargarg = data_w[cnt] - for w_key in space.unpackiterable(data_w_starargarg): - key = space.str_w(w_key) - w_value = space.getitem(data_w_starargarg, w_key) - unfiltered_kwds_w[key] = w_value - cnt += 1 - assert len(data_w) == cnt - - ndata_args_w = len(data_args_w) - if ndata_args_w >= need_cnt: - 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) - else: - stararg_w = space.unpackiterable(data_w_stararg) - datalen = len(data_args_w) - args_w = [None] * (datalen + len(stararg_w)) - for i in range(0, datalen): - args_w[i] = data_args_w[i] - for i in range(0, len(stararg_w)): - args_w[i + datalen] = stararg_w[i] - assert len(args_w) == need_cnt - - keywords = [] - keywords_w = [] - for key in need_kwds: - keywords.append(key) - keywords_w.append(unfiltered_kwds_w[key]) - - return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) - - @staticmethod - def frompacked(space, w_args=None, w_kwds=None): - raise NotImplementedError("go away") - - @staticmethod - def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w): - args_w = data_w[:shape_cnt] - p = end_keys = shape_cnt + len(shape_keys) - if shape_star: - w_star = data_w[p] - p += 1 - else: - w_star = None - if shape_stst: - w_starstar = data_w[p] - p += 1 - else: - w_starstar = None - return ArgumentsForTranslation(space, args_w, list(shape_keys), - data_w[shape_cnt:end_keys], w_star, - w_starstar) - - def flatten(self): - """ Argument <-> list of w_objects together with "shape" information """ - shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape() - data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)] - for key in shape_keys] - if shape_star: - data_w.append(self.w_stararg) - if shape_stst: - data_w.append(self.w_starstararg) - return (shape_cnt, shape_keys, shape_star, shape_stst), data_w - - def _rawshape(self, nextra=0): - assert not self.combine_has_happened - shape_cnt = len(self.arguments_w)+nextra # Number of positional args - if self.keywords: - shape_keys = self.keywords[:] # List of keywords (strings) - shape_keys.sort() - else: - shape_keys = [] - shape_star = self.w_stararg is not None # Flag: presence of *arg - shape_stst = self.w_starstararg is not None # Flag: presence of **kwds - return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted - -def rawshape(args, nextra=0): - return args._rawshape(nextra) - - # # ArgErr family of exceptions raised in case of argument mismatch. # We try to give error messages following CPython's, which are very informative. 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 @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- import py -from pypy.interpreter.argument import (Arguments, ArgumentsForTranslation, - ArgErr, ArgErrUnknownKwds, ArgErrMultipleValues, ArgErrCount, rawshape, - Signature) +from pypy.interpreter.argument import (Arguments, ArgErr, ArgErrUnknownKwds, + ArgErrMultipleValues, ArgErrCount, Signature) from pypy.interpreter.error import OperationError @@ -687,206 +686,3 @@ def f(x): pass e = raises(TypeError, "f(**{u'ü' : 19})") assert "?" in str(e.value) - -def make_arguments_for_translation(space, args_w, keywords_w={}, - w_stararg=None, w_starstararg=None): - return ArgumentsForTranslation(space, args_w, keywords_w.keys(), - keywords_w.values(), w_stararg, - w_starstararg) - -class TestArgumentsForTranslation(object): - - def test_prepend(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ["0"]) - args1 = args.prepend("thingy") - assert args1 is not args - assert args1.arguments_w == ["thingy", "0"] - assert args1.keywords is args.keywords - assert args1.keywords_w is args.keywords_w - - def test_unmatch_signature(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - sig = Signature(['a', 'b', 'c'], 'r', None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - def test_rawshape(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert rawshape(args) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1]) - assert rawshape(args, 2) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert rawshape(args) == (5, (), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert rawshape(args) == (1, ('b', 'c'), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert rawshape(args) == (1, ('c', ), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert rawshape(args) == (1, ('c', 'd'), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert rawshape(args) == (5, ('d', 'e'), False, False) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert rawshape(args) == (0, (), True, True) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert rawshape(args) == (2, ('g', ), True, True) - - def test_copy_and_shape(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ['a'], ['x'], [1], - ['w1'], {'y': 'w2'}) - args1 = args.copy() - args.combine_if_necessary() - assert rawshape(args1) == (1, ('x',), True, True) - - - def test_flatten(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert args.flatten() == ((3, (), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1]) - assert args.flatten() == ((1, (), False, False), [1]) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert args.flatten() == ((5, (), False, False), [1,2,3,4,5]) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert args.flatten() == ((1, ('c', ), False, False), [1, 5]) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7]) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert args.flatten() == ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert args.flatten() == ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - - def test_stararg_flowspace_variable(self): - space = DummySpace() - var = object() - shape = ((2, ('g', ), True, False), [1, 2, 9, var]) - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=var) - assert args.flatten() == shape - - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - - def test_fromshape(self): - space = DummySpace() - shape = ((3, (), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, (), False, False), [1]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, (), False, False), [1,2,3,4,5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('b', 'c'), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', ), False, False), [1, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', 'd'), False, False), [1, 5, 7]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/flow/argument.py @@ -0,0 +1,498 @@ +""" +Arguments objects. +""" + +class Signature(object): + _immutable_ = True + _immutable_fields_ = ["argnames[*]"] + __slots__ = ("argnames", "varargname", "kwargname") + + def __init__(self, argnames, varargname=None, kwargname=None): + self.argnames = argnames + self.varargname = varargname + self.kwargname = kwargname + + def find_argname(self, name): + try: + return self.argnames.index(name) + except ValueError: + return -1 + + def num_argnames(self): + return len(self.argnames) + + def has_vararg(self): + return self.varargname is not None + + def has_kwarg(self): + return self.kwargname is not None + + def scope_length(self): + scopelen = len(self.argnames) + scopelen += self.has_vararg() + scopelen += self.has_kwarg() + return scopelen + + def getallvarnames(self): + argnames = self.argnames + if self.varargname is not None: + argnames = argnames + [self.varargname] + if self.kwargname is not None: + argnames = argnames + [self.kwargname] + return argnames + + def __repr__(self): + return "Signature(%r, %r, %r)" % ( + self.argnames, self.varargname, self.kwargname) + + def __eq__(self, other): + if not isinstance(other, Signature): + return NotImplemented + return (self.argnames == other.argnames and + self.varargname == other.varargname and + self.kwargname == other.kwargname) + + def __ne__(self, other): + if not isinstance(other, Signature): + return NotImplemented + return not self == other + + + # make it look tuply for its use in the annotator + + def __len__(self): + return 3 + + def __getitem__(self, i): + if i == 0: + return self.argnames + if i == 1: + return self.varargname + if i == 2: + return self.kwargname + raise IndexError + +class ArgumentsForTranslation(object): + def __init__(self, space, args_w, keywords=None, keywords_w=None, + w_stararg=None, w_starstararg=None): + self.w_stararg = w_stararg + self.w_starstararg = w_starstararg + self.combine_has_happened = False + self.space = space + assert isinstance(args_w, list) + self.arguments_w = args_w + self.keywords = keywords + self.keywords_w = keywords_w + self.keyword_names_w = None + + def __repr__(self): + """ NOT_RPYTHON """ + name = self.__class__.__name__ + if not self.keywords: + return '%s(%s)' % (name, self.arguments_w,) + else: + return '%s(%s, %s, %s)' % (name, self.arguments_w, + self.keywords, self.keywords_w) + + def _combine_wrapped(self, w_stararg, w_starstararg): + "unpack the *arg and **kwd into arguments_w and keywords_w" + if w_stararg is not None: + self._combine_starargs_wrapped(w_stararg) + if w_starstararg is not None: + self._combine_starstarargs_wrapped(w_starstararg) + + def _combine_starargs_wrapped(self, w_stararg): + # unpack the * arguments + space = self.space + args_w = space.unpackiterable(w_stararg) + self.arguments_w = self.arguments_w + args_w + + def _combine_starstarargs_wrapped(self, w_starstararg): + # unpack the ** arguments + space = self.space + keywords, values_w = space.view_as_kwargs(w_starstararg) + if keywords is not None: # this path also taken for empty dicts + if self.keywords is None: + self.keywords = keywords + self.keywords_w = values_w + else: + if set(keywords) & set(self.keywords): + raise TypeError("got multiple values for keyword arguments '%s'", set(keywords) & set(self.keywords)) + self.keywords = self.keywords + keywords + self.keywords_w = self.keywords_w + values_w + return + if space.isinstance_w(w_starstararg, space.w_dict): + keys_w = space.unpackiterable(w_starstararg) + else: + w_keys = space.call_method(w_starstararg, "keys") + keys_w = space.unpackiterable(w_keys) + keywords_w = [None] * len(keys_w) + keywords = [None] * len(keys_w) + for i, w_key in enumerate(keys_w): + key = space.str_w(w_key) + if key in self.keywords: + raise TypeError("got multiple values for keyword argument '%s'" % key) + keywords[i] = key + keywords_w[i] = space.getitem(w_starstararg, w_key) + self.keyword_names_w = keys_w + if self.keywords is None: + self.keywords = keywords + self.keywords_w = keywords_w + else: + self.keywords = self.keywords + keywords + self.keywords_w = self.keywords_w + keywords_w + + + def fixedunpack(self, argcount): + """The simplest argument parsing: get the 'argcount' arguments, + or raise a real ValueError if the length is wrong.""" + if self.keywords: + raise ValueError, "no keyword arguments expected" + if len(self.arguments_w) > argcount: + raise ValueError, "too many arguments (%d expected)" % argcount + elif len(self.arguments_w) < argcount: + raise ValueError, "not enough arguments (%d expected)" % argcount + return self.arguments_w + + def combine_if_necessary(self): + if self.combine_has_happened: + return + self._combine_wrapped(self.w_stararg, self.w_starstararg) + self.combine_has_happened = True + + def prepend(self, w_firstarg): # used often + "Return a new Arguments with a new argument inserted first." + return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, + self.keywords, self.keywords_w, self.w_stararg, + self.w_starstararg) + + def copy(self): + return ArgumentsForTranslation(self.space, self.arguments_w, + self.keywords, self.keywords_w, self.w_stararg, + self.w_starstararg) + + def _match_signature(self, scope_w, signature, defaults_w=None): + """Parse args and kwargs according to the signature of a code object, + or raise an ArgErr in case of failure. + """ + # args_w = list of the normal actual parameters, wrapped + # scope_w = resulting list of wrapped values + # + self.combine_if_necessary() + co_argcount = signature.num_argnames() # expected formal arguments, without */** + + args_w = self.arguments_w + num_args = len(args_w) + keywords = self.keywords or [] + num_kwds = len(keywords) + + # put as many positional input arguments into place as available + take = min(num_args, co_argcount) + scope_w[:take] = args_w[:take] + input_argcount = take + + # collect extra positional arguments into the *vararg + if signature.has_vararg(): + if num_args > co_argcount: + starargs_w = args_w[co_argcount:] + else: + starargs_w = [] + scope_w[co_argcount] = self.space.newtuple(starargs_w) + elif num_args > co_argcount: + raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) + + # if a **kwargs argument is needed, create the dict + w_kwds = None + if signature.has_kwarg(): + w_kwds = self.space.newdict(kwargs=True) + scope_w[co_argcount + signature.has_vararg()] = w_kwds + + # handle keyword arguments + num_remainingkwds = 0 + keywords_w = self.keywords_w + kwds_mapping = None + if num_kwds: + # kwds_mapping maps target indexes in the scope (minus input_argcount) + # to positions in the keywords_w list + kwds_mapping = [-1] * (co_argcount - input_argcount) + # match the keywords given at the call site to the argument names + # the called function takes + # this function must not take a scope_w, to make the scope not + # escape + num_remainingkwds = len(keywords) + for i, name in enumerate(keywords): + # If name was not encoded as a string, it could be None. In that + # case, it's definitely not going to be in the signature. + if name is None: + continue + j = signature.find_argname(name) + # if j == -1 nothing happens + if j < input_argcount: + # check that no keyword argument conflicts with these. + if j >= 0: + raise ArgErrMultipleValues(name) + else: + kwds_mapping[j - input_argcount] = i # map to the right index + num_remainingkwds -= 1 + + if num_remainingkwds: + if w_kwds is not None: + # collect extra keyword arguments into the **kwarg + limit = len(keywords) + if self.keyword_names_w is not None: + limit -= len(self.keyword_names_w) + for i in range(len(keywords)): + if i in kwds_mapping: + continue + if i < limit: + w_key = self.space.wrap(keywords[i]) + else: + w_key = self.keyword_names_w[i - limit] + self.space.setitem(w_kwds, w_key, keywords_w[i]) + else: + if co_argcount == 0: + raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) + raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords, + kwds_mapping, self.keyword_names_w) + + # check for missing arguments and fill them from the kwds, + # or with defaults, if available + missing = 0 + if input_argcount < co_argcount: + def_first = co_argcount - (0 if defaults_w is None else len(defaults_w)) + j = 0 + kwds_index = -1 + for i in range(input_argcount, co_argcount): + if kwds_mapping is not None: + kwds_index = kwds_mapping[j] + j += 1 + if kwds_index >= 0: + scope_w[i] = keywords_w[kwds_index] + continue + defnum = i - def_first + if defnum >= 0: + scope_w[i] = defaults_w[defnum] + else: + missing += 1 + if missing: + raise ArgErrCount(num_args, num_kwds, signature, defaults_w, missing) + + def unpack(self): + "Return a ([w1,w2...], {'kw':w3...}) pair." + self.combine_if_necessary() + kwds_w = {} + if self.keywords: + for i in range(len(self.keywords)): + kwds_w[self.keywords[i]] = self.keywords_w[i] + return self.arguments_w, kwds_w + + + def match_signature(self, signature, defaults_w): + """Parse args and kwargs according to the signature of a code object, + or raise an ArgErr in case of failure. + """ + scopelen = signature.scope_length() + scope_w = [None] * scopelen + self._match_signature(scope_w, signature, defaults_w) + return scope_w + + def unmatch_signature(self, signature, data_w): + """kind of inverse of match_signature""" + args_w, kwds_w = self.unpack() + need_cnt = len(args_w) + need_kwds = kwds_w.keys() + space = self.space + argnames, varargname, kwargname = signature + cnt = len(argnames) + data_args_w = data_w[:cnt] + if varargname: + data_w_stararg = data_w[cnt] + cnt += 1 + else: + data_w_stararg = space.newtuple([]) + + unfiltered_kwds_w = {} + if kwargname: + data_w_starargarg = data_w[cnt] + for w_key in space.unpackiterable(data_w_starargarg): + key = space.str_w(w_key) + w_value = space.getitem(data_w_starargarg, w_key) + unfiltered_kwds_w[key] = w_value + cnt += 1 + assert len(data_w) == cnt + + ndata_args_w = len(data_args_w) + if ndata_args_w >= need_cnt: + 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) + else: + stararg_w = space.unpackiterable(data_w_stararg) + datalen = len(data_args_w) + args_w = [None] * (datalen + len(stararg_w)) + for i in range(0, datalen): + args_w[i] = data_args_w[i] + for i in range(0, len(stararg_w)): + args_w[i + datalen] = stararg_w[i] + assert len(args_w) == need_cnt + + keywords = [] + keywords_w = [] + for key in need_kwds: + keywords.append(key) + keywords_w.append(unfiltered_kwds_w[key]) + + return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) + + @staticmethod + def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w): + args_w = data_w[:shape_cnt] + p = end_keys = shape_cnt + len(shape_keys) + if shape_star: + w_star = data_w[p] + p += 1 + else: + w_star = None + if shape_stst: + w_starstar = data_w[p] + p += 1 + else: + w_starstar = None + return ArgumentsForTranslation(space, args_w, list(shape_keys), + data_w[shape_cnt:end_keys], w_star, + w_starstar) + + def flatten(self): + """ Argument <-> list of w_objects together with "shape" information """ + shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape() + data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)] + for key in shape_keys] + if shape_star: + data_w.append(self.w_stararg) + if shape_stst: + data_w.append(self.w_starstararg) + return (shape_cnt, shape_keys, shape_star, shape_stst), data_w + + def _rawshape(self, nextra=0): + assert not self.combine_has_happened + shape_cnt = len(self.arguments_w)+nextra # Number of positional args + if self.keywords: + shape_keys = self.keywords[:] # List of keywords (strings) + shape_keys.sort() + else: + shape_keys = [] + shape_star = self.w_stararg is not None # Flag: presence of *arg + shape_stst = self.w_starstararg is not None # Flag: presence of **kwds + return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted + +def rawshape(args, nextra=0): + return args._rawshape(nextra) + + +# +# ArgErr family of exceptions raised in case of argument mismatch. +# We try to give error messages following CPython's, which are very informative. +# + +class ArgErr(Exception): + + def getmsg(self): + raise NotImplementedError + +class ArgErrCount(ArgErr): + + def __init__(self, got_nargs, nkwds, signature, + defaults_w, missing_args): + self.signature = signature + + self.num_defaults = 0 if defaults_w is None else len(defaults_w) + self.missing_args = missing_args + self.num_args = got_nargs + self.num_kwds = nkwds + + def getmsg(self): + n = self.signature.num_argnames() + if n == 0: + msg = "takes no arguments (%d given)" % ( + self.num_args + self.num_kwds) + else: + defcount = self.num_defaults + has_kwarg = self.signature.has_kwarg() + num_args = self.num_args + num_kwds = self.num_kwds + if defcount == 0 and not self.signature.has_vararg(): + msg1 = "exactly" + if not has_kwarg: + num_args += num_kwds + num_kwds = 0 + elif not self.missing_args: + msg1 = "at most" + else: + msg1 = "at least" + has_kwarg = False + n -= defcount + if n == 1: + plural = "" + else: + plural = "s" + if has_kwarg or num_kwds > 0: + msg2 = " non-keyword" + else: + msg2 = "" + msg = "takes %s %d%s argument%s (%d given)" % ( + msg1, + n, + msg2, + plural, + num_args) + return msg + +class ArgErrMultipleValues(ArgErr): + + def __init__(self, argname): + self.argname = argname + + def getmsg(self): + msg = "got multiple values for keyword argument '%s'" % ( + self.argname) + return msg + +class ArgErrUnknownKwds(ArgErr): + + def __init__(self, space, num_remainingkwds, keywords, kwds_mapping, + keyword_names_w): + name = '' + self.num_kwds = num_remainingkwds + if num_remainingkwds == 1: + for i in range(len(keywords)): + if i not in kwds_mapping: + name = keywords[i] + if name is None: + # We'll assume it's unicode. Encode it. + # Careful, I *think* it should not be possible to + # get an IndexError here but you never know. + try: + if keyword_names_w is None: + raise IndexError + # note: negative-based indexing from the end + w_name = keyword_names_w[i - len(keywords)] + except IndexError: + name = '?' + else: + w_enc = space.wrap(space.sys.defaultencoding) + w_err = space.wrap("replace") + w_name = space.call_method(w_name, "encode", w_enc, + w_err) + name = space.str_w(w_name) + break + self.kwd_name = name + + def getmsg(self): + if self.num_kwds == 1: + msg = "got an unexpected keyword argument '%s'" % ( + self.kwd_name) + else: + msg = "got %d unexpected keyword arguments" % ( + self.num_kwds) + return msg diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,11 +1,30 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import (BytecodeCorruption, - cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) -from pypy.interpreter.astcompiler.consts import CO_GENERATOR +from pypy.objspace.flow.argument import Signature +from pypy.objspace.flow.flowcontext import BytecodeCorruption + +CO_GENERATOR = 0x0020 +CO_VARARGS = 0x0004 +CO_VARKEYWORDS = 0x0008 + +def cpython_code_signature(code): + "([list-of-arg-names], vararg-name-or-None, kwarg-name-or-None)." + argcount = code.co_argcount + argnames = list(code.co_varnames[:argcount]) + if code.co_flags & CO_VARARGS: + varargname = code.co_varnames[argcount] + argcount += 1 + else: + varargname = None + if code.co_flags & CO_VARKEYWORDS: + kwargname = code.co_varnames[argcount] + argcount += 1 + else: + kwargname = None + return Signature(argnames, varargname, kwargname) class HostCode(object): """ diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -6,9 +6,8 @@ import collections from pypy.tool.error import source_lines -from pypy.interpreter import pyframe -from pypy.interpreter.argument import ArgumentsForTranslation -from pypy.interpreter.pyopcode import Return, BytecodeCorruption +from pypy.tool.stdlib_opcode import host_bytecode_spec +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.objspace.flow.model import (Constant, Variable, Block, Link, UnwrapException, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, @@ -31,6 +30,10 @@ class StopFlowing(Exception): pass +class Return(Exception): + def __init__(self, value): + self.value = value + class FSException(Exception): def __init__(self, w_type, w_value): assert w_type is not None @@ -46,6 +49,9 @@ class ImplicitOperationError(FSException): pass +class BytecodeCorruption(Exception): + pass + class SpamBlock(Block): # make slots optional, for debugging if hasattr(Block, '__slots__'): @@ -206,6 +212,83 @@ # ____________________________________________________________ +_unary_ops = [('UNARY_POSITIVE', "pos"), + ('UNARY_NEGATIVE', "neg"), + ('UNARY_NOT', "not_"), + ('UNARY_CONVERT', "repr"), + ('UNARY_INVERT', "invert"),] + +def unaryoperation(OPCODE, op): + def UNARY_OP(self, *ignored): + operation = getattr(self.space, op) + w_1 = self.popvalue() + w_result = operation(w_1) + self.pushvalue(w_result) + UNARY_OP.unaryop = op + UNARY_OP.func_name = OPCODE + return UNARY_OP + +_binary_ops = [ + ('BINARY_MULTIPLY', "mul"), + ('BINARY_TRUE_DIVIDE', "truediv"), + ('BINARY_FLOOR_DIVIDE', "floordiv"), + ('BINARY_DIVIDE', "div"), + ('BINARY_MODULO', "mod"), + ('BINARY_ADD', "add"), + ('BINARY_SUBTRACT', "sub"), + ('BINARY_SUBSCR', "getitem"), + ('BINARY_LSHIFT', "lshift"), + ('BINARY_RSHIFT', "rshift"), + ('BINARY_AND', "and_"), + ('BINARY_XOR', "xor"), + ('BINARY_OR', "or_"), + ('INPLACE_MULTIPLY', "inplace_mul"), + ('INPLACE_TRUE_DIVIDE', "inplace_truediv"), + ('INPLACE_FLOOR_DIVIDE', "inplace_floordiv"), + ('INPLACE_DIVIDE', "inplace_div"), + ('INPLACE_MODULO', "inplace_mod"), + ('INPLACE_ADD', "inplace_add"), + ('INPLACE_SUBTRACT', "inplace_sub"), + ('INPLACE_LSHIFT', "inplace_lshift"), + ('INPLACE_RSHIFT', "inplace_rshift"), + ('INPLACE_AND', "inplace_and"), + ('INPLACE_XOR', "inplace_xor"), + ('INPLACE_OR', "inplace_or"), +] + +def binaryoperation(OPCODE, op): + """NOT_RPYTHON""" + def BINARY_OP(self, *ignored): + operation = getattr(self.space, op) + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = operation(w_1, w_2) + self.pushvalue(w_result) + BINARY_OP.binop = op + BINARY_OP.func_name = OPCODE + return BINARY_OP + +_unsupported_ops = [ + ('BINARY_POWER', "a ** b"), + ('BUILD_CLASS', 'creating new classes'), + ('EXEC_STMT', 'exec statement'), + ('STOP_CODE', '???'), + ('STORE_NAME', 'modifying globals'), + ('INPLACE_POWER', 'a **= b'), + ('LOAD_LOCALS', 'locals()'), + ('IMPORT_STAR', 'import *'), + ('MISSING_OPCODE', '???'), + ('DELETE_GLOBAL', 'modifying globals'), + ('DELETE_NAME', 'modifying globals'), + ('DELETE_ATTR', 'deleting attributes'), +] + +def unsupportedoperation(OPCODE, msg): + def UNSUPPORTED(self, *ignored): + raise FlowingError(self, "%s is not RPython" % (msg,)) + UNSUPPORTED.func_name = OPCODE + return UNSUPPORTED + compare_method = [ "cmp_lt", # "<" "cmp_le", # "<=" @@ -220,7 +303,8 @@ "cmp_exc_match", ] -class FlowSpaceFrame(pyframe.CPythonFrame): +class FlowSpaceFrame(object): + opcode_method_names = host_bytecode_spec.method_names def __init__(self, space, graph, code): self.graph = graph @@ -228,7 +312,7 @@ self.pycode = code self.space = space self.w_globals = Constant(func.func_globals) - self.lastblock = None + self.blockstack = [] self.init_closure(func.func_closure) self.f_lineno = code.co_firstlineno @@ -255,6 +339,63 @@ self.valuestackdepth = code.co_nlocals self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals) + def pushvalue(self, w_object): + depth = self.valuestackdepth + self.locals_stack_w[depth] = w_object + self.valuestackdepth = depth + 1 + + def popvalue(self): + depth = self.valuestackdepth - 1 + assert depth >= self.pycode.co_nlocals, "pop from empty value stack" + w_object = self.locals_stack_w[depth] + self.locals_stack_w[depth] = None + self.valuestackdepth = depth + return w_object + + def peekvalue(self, index_from_top=0): + # NOTE: top of the stack is peekvalue(0). + index = self.valuestackdepth + ~index_from_top + assert index >= self.pycode.co_nlocals, ( + "peek past the bottom of the stack") + return self.locals_stack_w[index] + + def pushrevvalues(self, n, values_w): # n should be len(values_w) + assert len(values_w) == n + for i in range(n - 1, -1, -1): + self.pushvalue(values_w[i]) + + def settopvalue(self, w_object, index_from_top=0): + index = self.valuestackdepth + ~index_from_top + assert index >= self.pycode.co_nlocals, ( + "settop past the bottom of the stack") + self.locals_stack_w[index] = w_object + + def popvalues(self, n): + values_w = [self.popvalue() for i in range(n)] + values_w.reverse() + return values_w + + def peekvalues(self, n): + values_w = [None] * n + base = self.valuestackdepth - n + while True: + n -= 1 + if n < 0: + break + values_w[n] = self.locals_stack_w[base+n] + return values_w + + def dropvalues(self, n): + finaldepth = self.valuestackdepth - n + for n in range(finaldepth, self.valuestackdepth): + self.locals_stack_w[n] = None + self.valuestackdepth = finaldepth + + def dropvaluesuntil(self, finaldepth): + for n in range(finaldepth, self.valuestackdepth): + self.locals_stack_w[n] = None + self.valuestackdepth = finaldepth + def save_locals_stack(self): return self.locals_stack_w[:self.valuestackdepth] @@ -262,6 +403,20 @@ 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): # getfastscope() can return real None, for undefined locals data = self.save_locals_stack() @@ -272,7 +427,7 @@ data.append(self.last_exception.w_type) data.append(self.last_exception.w_value) recursively_flatten(self.space, data) - return FrameState(data, self.get_blocklist(), self.last_instr) + return FrameState(data, self.blockstack[:], self.last_instr) def setstate(self, state): """ Reset the frame to the given state. """ @@ -285,7 +440,7 @@ else: self.last_exception = FSException(data[-2], data[-1]) self.last_instr = state.next_instr - self.set_blocklist(state.blocklist) + self.blockstack = state.blocklist[:] def recording(self, block): """ Setup recording of the block and return the recorder. """ @@ -336,7 +491,6 @@ block = self.pendingblocks.popleft() try: self.recorder = self.recording(block) - self.frame_finished_execution = False while True: self.last_instr = self.handle_bytecode(self.last_instr) self.recorder.final_state = self.getstate() @@ -362,9 +516,8 @@ except StopFlowing: pass - except Return: - w_result = self.popvalue() - assert w_result is not None + except Return as exc: + w_result = exc.value link = Link([w_result], graph.returnblock) self.recorder.crnt_block.closeblock(link) @@ -540,8 +693,7 @@ w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: - self.pushvalue(w_returnvalue) # XXX ping pong - raise Return + raise Return(w_returnvalue) else: unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) @@ -561,31 +713,25 @@ if w_top == self.space.w_None: # finally: block with no unroller active return - try: - unroller = self.space.unwrap(w_top) - except UnwrapException: - pass + elif isinstance(w_top, SuspendedUnroller): + # case of a finally: block + return self.unroll_finally(w_top) else: - if isinstance(unroller, SuspendedUnroller): - # case of a finally: block - return self.unroll_finally(unroller) - # case of an except: block. We popped the exception type - self.popvalue() # Now we pop the exception value - unroller = self.space.unwrap(self.popvalue()) - return self.unroll_finally(unroller) + # case of an except: block. We popped the exception type + self.popvalue() # Now we pop the exception value + unroller = self.popvalue() + return self.unroll_finally(unroller) def unroll_finally(self, unroller): # go on unrolling the stack block = self.unrollstack(unroller.kind) if block is None: - w_result = unroller.nomoreblocks() - self.pushvalue(w_result) - raise Return + unroller.nomoreblocks() else: return block.handle(self, unroller) def POP_BLOCK(self, oparg, next_instr): - block = self.pop_block() + block = self.blockstack.pop() block.cleanupstack(self) # the block knows how to clean up the value stack def JUMP_ABSOLUTE(self, jumpto, next_instr): @@ -611,6 +757,41 @@ def PRINT_NEWLINE(self, oparg, next_instr): self.space.appcall(rpython_print_newline) + def JUMP_FORWARD(self, jumpby, next_instr): + next_instr += jumpby + return next_instr + + def POP_JUMP_IF_FALSE(self, target, next_instr): + w_value = self.popvalue() + if not self.space.is_true(w_value): + return target + return next_instr + + def POP_JUMP_IF_TRUE(self, target, next_instr): + w_value = self.popvalue() + if self.space.is_true(w_value): + return target + return next_instr + + def JUMP_IF_FALSE_OR_POP(self, target, next_instr): + w_value = self.peekvalue() + if not self.space.is_true(w_value): + return target + self.popvalue() + return next_instr + + def JUMP_IF_TRUE_OR_POP(self, target, next_instr): + w_value = self.peekvalue() + if self.space.is_true(w_value): + return target + self.popvalue() + return next_instr + + def GET_ITER(self, oparg, next_instr): + w_iterable = self.popvalue() + w_iterator = self.space.iter(w_iterable) + self.pushvalue(w_iterator) + def FOR_ITER(self, jumpby, next_instr): w_iterator = self.peekvalue() try: @@ -626,16 +807,16 @@ return next_instr def SETUP_LOOP(self, offsettoend, next_instr): - block = LoopBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = LoopBlock(self, next_instr + offsettoend) + self.blockstack.append(block) def SETUP_EXCEPT(self, offsettoend, next_instr): - block = ExceptBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = ExceptBlock(self, next_instr + offsettoend) + self.blockstack.append(block) def SETUP_FINALLY(self, offsettoend, next_instr): - block = FinallyBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = FinallyBlock(self, next_instr + offsettoend) + self.blockstack.append(block) def SETUP_WITH(self, offsettoend, next_instr): # A simpler version than the 'real' 2.7 one: @@ -645,8 +826,8 @@ w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__")) self.settopvalue(w_exit) w_result = self.space.call_method(w_manager, "__enter__") - block = WithBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = WithBlock(self, next_instr + offsettoend) + self.blockstack.append(block) self.pushvalue(w_result) def WITH_CLEANUP(self, oparg, next_instr): @@ -654,14 +835,13 @@ # and cannot suppress the exception. # This opcode changed a lot between CPython versions if sys.version_info >= (2, 6): - w_unroller = self.popvalue() + unroller = self.popvalue() w_exitfunc = self.popvalue() - self.pushvalue(w_unroller) + self.pushvalue(unroller) else: w_exitfunc = self.popvalue() - w_unroller = self.peekvalue(0) + unroller = self.peekvalue(0) - unroller = self.space.unwrap(w_unroller) w_None = self.space.w_None if isinstance(unroller, SApplicationException): operr = unroller.operr @@ -678,9 +858,14 @@ raise FlowingError(self, "Local variable referenced before assignment") self.pushvalue(w_value) + def LOAD_CONST(self, constindex, next_instr): + w_const = self.getconstant_w(constindex) + self.pushvalue(w_const) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) + LOAD_NAME = LOAD_GLOBAL def LOAD_ATTR(self, nameindex, next_instr): "obj.attributename" @@ -693,6 +878,65 @@ def LOAD_DEREF(self, varindex, next_instr): self.pushvalue(self.closure[varindex]) + def STORE_FAST(self, varindex, next_instr): + w_newvalue = self.popvalue() + assert w_newvalue is not None + self.locals_stack_w[varindex] = w_newvalue + + def STORE_GLOBAL(self, nameindex, next_instr): + varname = self.getname_u(nameindex) + raise FlowingError(self, + "Attempting to modify global variable %r." % (varname)) + + def POP_TOP(self, oparg, next_instr): + self.popvalue() + + def ROT_TWO(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_2) + + def ROT_THREE(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + w_3 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_3) + self.pushvalue(w_2) + + def ROT_FOUR(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + w_3 = self.popvalue() + w_4 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_4) + self.pushvalue(w_3) + self.pushvalue(w_2) + + def DUP_TOP(self, oparg, next_instr): + w_1 = self.peekvalue() + self.pushvalue(w_1) + + def DUP_TOPX(self, itemcount, next_instr): + delta = itemcount - 1 + while True: + itemcount -= 1 + if itemcount < 0: + break + w_value = self.peekvalue(delta) + self.pushvalue(w_value) + + for OPCODE, op in _unary_ops: + locals()[OPCODE] = unaryoperation(OPCODE, op) + + for OPCODE, op in _binary_ops: + locals()[OPCODE] = binaryoperation(OPCODE, op) + + for OPCODE, op in _unsupported_ops: + locals()[OPCODE] = unsupportedoperation(OPCODE, op) + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. @@ -700,12 +944,188 @@ self.pushvalue(self.space.newlist([])) self.pushvalue(last_val) + def call_function(self, oparg, w_star=None, w_starstar=None): + n_arguments = oparg & 0xff + n_keywords = (oparg>>8) & 0xff + if n_keywords: + keywords = [None] * n_keywords + keywords_w = [None] * n_keywords + while True: + n_keywords -= 1 + if n_keywords < 0: + break + w_value = self.popvalue() + w_key = self.popvalue() + key = self.space.str_w(w_key) + keywords[n_keywords] = key + keywords_w[n_keywords] = w_value + else: + keywords = None + keywords_w = None + arguments = self.popvalues(n_arguments) + args = self.argument_factory(arguments, keywords, keywords_w, w_star, + w_starstar) + w_function = self.popvalue() + w_result = self.space.call_args(w_function, args) + self.pushvalue(w_result) + + def CALL_FUNCTION(self, oparg, next_instr): + self.call_function(oparg) + CALL_METHOD = CALL_FUNCTION + + def CALL_FUNCTION_VAR(self, oparg, next_instr): + w_varargs = self.popvalue() + self.call_function(oparg, w_varargs) + + def CALL_FUNCTION_KW(self, oparg, next_instr): + w_varkw = self.popvalue() + self.call_function(oparg, None, w_varkw) + + def CALL_FUNCTION_VAR_KW(self, oparg, next_instr): + w_varkw = self.popvalue() + w_varargs = self.popvalue() + self.call_function(oparg, w_varargs, w_varkw) + def MAKE_FUNCTION(self, numdefaults, next_instr): w_codeobj = self.popvalue() defaults = self.popvalues(numdefaults) fn = self.space.newfunction(w_codeobj, self.w_globals, defaults) self.pushvalue(fn) + def STORE_ATTR(self, nameindex, next_instr): + "obj.attributename = newvalue" + w_attributename = self.getname_w(nameindex) + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setattr(w_obj, w_attributename, w_newvalue) + + def UNPACK_SEQUENCE(self, itemcount, next_instr): + w_iterable = self.popvalue() + items = self.space.unpackiterable(w_iterable, itemcount) + self.pushrevvalues(itemcount, items) + + def slice(self, w_start, w_end): + w_obj = self.popvalue() + w_result = self.space.getslice(w_obj, w_start, w_end) + self.pushvalue(w_result) + + def SLICE_0(self, oparg, next_instr): + self.slice(self.space.w_None, self.space.w_None) + + def SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.slice(w_start, self.space.w_None) + + def SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.slice(self.space.w_None, w_end) + + def SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.slice(w_start, w_end) + + def storeslice(self, w_start, w_end): + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setslice(w_obj, w_start, w_end, w_newvalue) + + def STORE_SLICE_0(self, oparg, next_instr): + self.storeslice(self.space.w_None, self.space.w_None) + + def STORE_SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.storeslice(w_start, self.space.w_None) + + def STORE_SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.storeslice(self.space.w_None, w_end) + + def STORE_SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.storeslice(w_start, w_end) + + def deleteslice(self, w_start, w_end): + w_obj = self.popvalue() + self.space.delslice(w_obj, w_start, w_end) + + def DELETE_SLICE_0(self, oparg, next_instr): + self.deleteslice(self.space.w_None, self.space.w_None) + + def DELETE_SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.deleteslice(w_start, self.space.w_None) + + def DELETE_SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.deleteslice(self.space.w_None, w_end) + + def DELETE_SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.deleteslice(w_start, w_end) + + def LIST_APPEND(self, oparg, next_instr): + w = self.popvalue() + v = self.peekvalue(oparg - 1) + self.space.call_method(v, 'append', w) + + def DELETE_FAST(self, varindex, next_instr): + if self.locals_stack_w[varindex] is None: + varname = self.getlocalvarname(varindex) + message = "local variable '%s' referenced before assignment" + raise UnboundLocalError(message, varname) + self.locals_stack_w[varindex] = None + + def STORE_MAP(self, oparg, next_instr): + w_key = self.popvalue() + w_value = self.popvalue() + w_dict = self.peekvalue() + self.space.setitem(w_dict, w_key, w_value) + + def STORE_SUBSCR(self, oparg, next_instr): + "obj[subscr] = newvalue" + w_subscr = self.popvalue() + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setitem(w_obj, w_subscr, w_newvalue) + + def BUILD_SLICE(self, numargs, next_instr): + if numargs == 3: + w_step = self.popvalue() + elif numargs == 2: + w_step = self.space.w_None + else: + raise BytecodeCorruption + w_end = self.popvalue() + w_start = self.popvalue() + w_slice = self.space.newslice(w_start, w_end, w_step) + self.pushvalue(w_slice) + + def DELETE_SUBSCR(self, oparg, next_instr): + "del obj[subscr]" + w_subscr = self.popvalue() + w_obj = self.popvalue() + self.space.delitem(w_obj, w_subscr) + + def BUILD_TUPLE(self, itemcount, next_instr): + items = self.popvalues(itemcount) + w_tuple = self.space.newtuple(items) + self.pushvalue(w_tuple) + + def BUILD_LIST(self, itemcount, next_instr): + items = self.popvalues(itemcount) + w_list = self.space.newlist(items) + self.pushvalue(w_list) + + def BUILD_MAP(self, itemcount, next_instr): + w_dict = self.space.newdict() + self.pushvalue(w_dict) + + def NOP(self, *args): + pass + # XXX Unimplemented 2.7 opcodes ---------------- # Set literals, set comprehensions @@ -765,7 +1185,7 @@ self.w_returnvalue = w_returnvalue def nomoreblocks(self): - return self.w_returnvalue + raise Return(self.w_returnvalue) def state_unpack_variables(self, space): return [self.w_returnvalue] @@ -823,10 +1243,9 @@ """Abstract base class for frame blocks from the blockstack, used by the SETUP_XXX and POP_BLOCK opcodes.""" - def __init__(self, frame, handlerposition, previous): + def __init__(self, frame, handlerposition): self.handlerposition = handlerposition self.valuestackdepth = frame.valuestackdepth - self.previous = previous # this makes a linked list of blocks def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -856,7 +1275,7 @@ # 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 - frame.append_block(self) + frame.blockstack.append(self) return unroller.jump_to else: # jump to the end of the loop @@ -878,7 +1297,7 @@ # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. - frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(unroller) frame.pushvalue(operationerr.get_w_value(frame.space)) frame.pushvalue(operationerr.w_type) frame.last_exception = operationerr @@ -894,7 +1313,7 @@ # any abnormal reason for unrolling a finally: triggers the end of # the block unrolling and the entering the finally: handler. self.cleanupstack(frame) - frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(unroller) return self.handlerposition # jump to the handler diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -6,9 +6,6 @@ self.mergeable = mergeable self.blocklist = blocklist self.next_instr = next_instr - for w1 in self.mergeable: - assert isinstance(w1, (Variable, Constant)) or w1 is None, ( - '%r found in frame state' % w1) def copy(self): "Make a copy of this state in which all Variables are fresh." @@ -109,12 +106,10 @@ from pypy.objspace.flow.flowcontext import SuspendedUnroller i = 0 while i < len(lst): - item = lst[i] - if not (isinstance(item, Constant) and - isinstance(item.value, SuspendedUnroller)): + unroller = lst[i] + if not isinstance(unroller, SuspendedUnroller): i += 1 else: - unroller = item.value vars = unroller.state_unpack_variables(space) key = unroller.__class__, len(vars) try: @@ -132,4 +127,4 @@ arguments = lst[i+1: i+1+argcount] del lst[i+1: i+1+argcount] unroller = unrollerclass.state_pack_variables(space, *arguments) - lst[i] = space.wrap(unroller) + lst[i] = unroller diff --git a/pypy/objspace/flow/generator.py b/pypy/objspace/flow/generator.py --- a/pypy/objspace/flow/generator.py +++ b/pypy/objspace/flow/generator.py @@ -6,7 +6,7 @@ from pypy.translator.unsimplify import split_block from pypy.translator.simplify import eliminate_empty_blocks, simplify_graph from pypy.tool.sourcetools import func_with_new_name -from pypy.interpreter.argument import Signature +from pypy.objspace.flow.argument import Signature class AbstractPosition(object): diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -7,8 +7,7 @@ import types from inspect import CO_NEWLOCALS -from pypy.interpreter.baseobjspace import ObjSpace -from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.objspace.flow.model import (Constant, Variable, WrapException, UnwrapException, checkgraph, SpaceOperation) from pypy.objspace.flow.bytecode import HostCode @@ -226,7 +225,7 @@ w_real_class = self.wrap(rstackovf._StackOverflow) return self._exception_match(w_exc_type, w_real_class) # checking a tuple of classes - for w_klass in self.fixedview(w_check_class): + for w_klass in self.unpackiterable(w_check_class): if self.exception_match(w_exc_type, w_klass): return True return False @@ -285,10 +284,6 @@ tweak_generator_graph(graph) return graph - def fixedview(self, w_tuple, expected_length=None): - return self.unpackiterable(w_tuple, expected_length) - listview = fixedview_unroll = fixedview - def unpackiterable(self, w_iterable, expected_length=None): if not isinstance(w_iterable, Variable): l = list(self.unwrap(w_iterable)) @@ -427,10 +422,6 @@ raise FSException(self.w_ImportError, self.wrap("cannot import name '%s'" % w_name.value)) - def call_valuestack(self, w_func, nargs, frame): - args = frame.make_arguments(nargs) - return self.call_args(w_func, args) - def call_method(self, w_obj, methname, *arg_w): w_meth = self.getattr(w_obj, self.wrap(methname)) return self.call_function(w_meth, *arg_w) @@ -577,5 +568,5 @@ setattr(FlowObjSpace, name, generic_operator) -for (name, symbol, arity, specialnames) in ObjSpace.MethodTable: +for (name, symbol, arity, specialnames) in operation.MethodTable: From noreply at buildbot.pypy.org Sun Oct 21 17:16:57 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 17:16:57 +0200 (CEST) Subject: [pypy-commit] pypy translation-cleanup: close merged branch Message-ID: <20121021151657.C41DC1C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: translation-cleanup Changeset: r58319:1d4c6f783600 Date: 2012-10-21 17:16 +0200 http://bitbucket.org/pypy/pypy/changeset/1d4c6f783600/ Log: close merged branch From noreply at buildbot.pypy.org Sun Oct 21 17:40:17 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 17:40:17 +0200 (CEST) Subject: [pypy-commit] pypy default: Remove the line printing "Warning: pypy does not implement hash Message-ID: <20121021154017.67C5A1C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58320:09713cd66425 Date: 2012-10-21 17:40 +0200 http://bitbucket.org/pypy/pypy/changeset/09713cd66425/ Log: Remove the line printing "Warning: pypy does not implement hash randomization". See http://bugs.python.org/issue14621 . diff --git a/pypy/translator/goal/app_main.py b/pypy/translator/goal/app_main.py --- a/pypy/translator/goal/app_main.py +++ b/pypy/translator/goal/app_main.py @@ -12,6 +12,7 @@ -m mod library module to be run as a script (terminates option list) -W arg warning control (arg is action:message:category:module:lineno) -E ignore environment variables (such as PYTHONPATH) + -R ignored (see http://bugs.python.org/issue14621) --version print the PyPy version --info print translation information about this PyPy executable """ @@ -445,9 +446,11 @@ (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): options["inspect"] = 1 - if (options["hash_randomization"] or os.getenv('PYTHONHASHSEED')): - print >> sys.stderr, ( - "Warning: pypy does not implement hash randomization") +## We don't print the warning, because it offers no additional security +## in CPython either (http://bugs.python.org/issue14621) +## if (options["hash_randomization"] or os.getenv('PYTHONHASHSEED')): +## print >> sys.stderr, ( +## "Warning: pypy does not implement hash randomization") if PYTHON26 and we_are_translated(): flags = [options[flag] for flag in sys_flags] From noreply at buildbot.pypy.org Sun Oct 21 17:48:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 17:48:34 +0200 (CEST) Subject: [pypy-commit] pypy default: Doc update: -R Message-ID: <20121021154834.5F0DB1C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58321:170dab0d8e14 Date: 2012-10-21 17:44 +0200 http://bitbucket.org/pypy/pypy/changeset/170dab0d8e14/ Log: Doc update: -R diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -285,9 +285,9 @@ Miscellaneous ------------- -* Hash randomization is not supported in PyPy. Passing ``-R`` to the - command line, or setting the ``PYTHONHASHSEED`` environment variable - will display a warning message. +* Hash randomization (``-R``) is ignored in PyPy. As documented in + http://bugs.python.org/issue14621 , some of us believe it has no + purpose in CPython either. * ``sys.setrecursionlimit()`` is ignored (and not needed) on PyPy. On CPython it would set the maximum number of nested From noreply at buildbot.pypy.org Sun Oct 21 17:48:35 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 17:48:35 +0200 (CEST) Subject: [pypy-commit] pypy default: Doc update: sys.setrecursionlimit Message-ID: <20121021154835.97E211C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58322:2d2a163a6fbd Date: 2012-10-21 17:48 +0200 http://bitbucket.org/pypy/pypy/changeset/2d2a163a6fbd/ Log: Doc update: sys.setrecursionlimit diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -289,13 +289,10 @@ http://bugs.python.org/issue14621 , some of us believe it has no purpose in CPython either. -* ``sys.setrecursionlimit()`` is ignored (and not needed) on - PyPy. On CPython it would set the maximum number of nested - calls that can occur before a RuntimeError is raised; on PyPy - overflowing the stack also causes RuntimeErrors, but the limit - is checked at a lower level. (The limit is currently hard-coded - at 768 KB, corresponding to roughly 1480 Python calls on - Linux.) +* ``sys.setrecursionlimit(n)`` sets the limit only approximately, + by setting the usable stack space to ``n * 768`` bytes. On Linux, + depending on the compiler settings, the default of 768KB is enough + for about 1400 calls. * assignment to ``__class__`` is limited to the cases where it works on CPython 2.5. On CPython 2.6 and 2.7 it works in a bit From noreply at buildbot.pypy.org Sun Oct 21 18:44:41 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 18:44:41 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: a bit of random progress Message-ID: <20121021164441.F29421C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58323:325c9a54410e Date: 2012-10-21 18:22 +0200 http://bitbucket.org/pypy/pypy/changeset/325c9a54410e/ Log: a bit of random progress diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -5,7 +5,7 @@ JitCellToken, TargetToken) from pypy.jit.metainterp.resoperation import rop, create_resop_dispatch,\ create_resop, ConstInt, ConstPtr, ConstFloat, create_resop_2,\ - create_resop_1, BoxInt, Box, BoxPtr, BoxFloat + create_resop_1, create_resop_0, INT, REF, FLOAT from pypy.jit.metainterp.typesystem import deref from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass @@ -20,16 +20,22 @@ def boxfloat(x): - return BoxFloat(longlong.getfloatstorage(x)) + return create_resop_0(rop.INPUT_f, longlong.getfloatstorage(x)) + +def boxint(x=0): + return create_resop_0(rop.INPUT_i, x) + +def boxptr(x=lltype.nullptr(llmemory.GCREF.TO)): + return create_resop_0(rop.INPUT_r, x) def constfloat(x): return ConstFloat(longlong.getfloatstorage(x)) def boxlonglong(ll): if longlong.is_64_bit: - return BoxInt(ll) + return boxint(ll) else: - return BoxFloat(ll) + return boxfloat(ll) class Runner(object): @@ -46,11 +52,11 @@ self.cpu.compile_loop(inputargs, operations, looptoken) args = [] for box in inputargs: - if isinstance(box, BoxInt): + if box.type == INT: args.append(box.getint()) - elif isinstance(box, BoxPtr): + elif box.type == REF: args.append(box.getref_base()) - elif isinstance(box, BoxFloat): + elif box.type == FLOAT: args.append(box.getfloatstorage()) else: raise NotImplementedError(box) @@ -95,9 +101,6 @@ if descr is not None: op0.setdescr(descr) inputargs = [] - for box in valueboxes: - if isinstance(box, Box) and box not in inputargs: - inputargs.append(box) return inputargs, [op0, op1] class BaseBackendTest(Runner): @@ -494,14 +497,14 @@ calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) res = self.execute_operation(rop.CALL_i, - [funcbox, BoxInt(num), BoxInt(num)], + [funcbox, boxint(num), boxint(num)], 'int', descr=calldescr) assert res == 2 * num # then, try it with the dynamic calldescr dyn_calldescr = cpu._calldescr_dynamic_for_tests( [ffi_type, ffi_type], ffi_type) res = self.execute_operation(rop.CALL_i, - [funcbox, BoxInt(num), BoxInt(num)], + [funcbox, boxint(num), boxint(num)], 'int', descr=dyn_calldescr) assert res == 2 * num @@ -518,7 +521,7 @@ EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) args = ([boxfloat(.1) for i in range(7)] + - [BoxInt(1), BoxInt(2), boxfloat(.2), boxfloat(.3), + [boxint(1), boxint(2), boxfloat(.2), boxfloat(.3), boxfloat(.4)]) res = self.execute_operation(rop.CALL_f, [funcbox] + args, @@ -542,7 +545,7 @@ func_ptr = llhelper(FPTR, func) args = range(16) funcbox = self.get_funcbox(self.cpu, func_ptr) - res = self.execute_operation(rop.CALL_i, [funcbox] + map(BoxInt, args), 'int', descr=calldescr) + res = self.execute_operation(rop.CALL_i, [funcbox] + map(boxint, args), 'int', descr=calldescr) assert res == func(*args) def test_call_box_func(self): @@ -563,7 +566,7 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) res = self.execute_operation(rop.CALL_i, - [funcbox, BoxInt(arg1), BoxInt(arg2)], + [funcbox, boxint(arg1), boxint(arg2)], 'int', descr=calldescr) assert res == f(arg1, arg2) @@ -588,7 +591,7 @@ funcbox = self.get_funcbox(cpu, func_ptr) args = [280-24*i for i in range(nb_args)] res = self.execute_operation(rop.CALL_i, - [funcbox] + map(BoxInt, args), + [funcbox] + map(boxint, args), 'int', descr=calldescr) assert res == func_ints(*args) @@ -613,7 +616,7 @@ fielddescr = self.cpu.fielddescrof(self.S, 'value') assert not fielddescr.is_pointer_field() # - res = self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(39082)], + res = self.execute_operation(rop.SETFIELD_GC, [t_box, boxint(39082)], 'void', descr=fielddescr) assert res is None res = self.execute_operation(rop.GETFIELD_GC_i, [t_box], @@ -623,11 +626,11 @@ fielddescr1 = self.cpu.fielddescrof(self.S, 'chr1') fielddescr2 = self.cpu.fielddescrof(self.S, 'chr2') shortdescr = self.cpu.fielddescrof(self.S, 'short') - self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(250)], + self.execute_operation(rop.SETFIELD_GC, [t_box, boxint(250)], 'void', descr=fielddescr2) - self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(133)], + self.execute_operation(rop.SETFIELD_GC, [t_box, boxint(133)], 'void', descr=fielddescr1) - self.execute_operation(rop.SETFIELD_GC, [t_box, BoxInt(1331)], + self.execute_operation(rop.SETFIELD_GC, [t_box, boxint(1331)], 'void', descr=shortdescr) res = self.execute_operation(rop.GETFIELD_GC_i, [t_box], 'int', descr=fielddescr2) @@ -675,9 +678,9 @@ def test_passing_guards(self): t_box, T_box = self.alloc_instance(self.T) nullbox = self.null_instance() - all = [(rop.GUARD_TRUE, [BoxInt(1)]), - (rop.GUARD_FALSE, [BoxInt(0)]), - (rop.GUARD_VALUE, [BoxInt(42), ConstInt(42)]), + all = [(rop.GUARD_TRUE, [boxint(1)]), + (rop.GUARD_FALSE, [boxint(0)]), + (rop.GUARD_VALUE, [boxint(42), ConstInt(42)]), ] if not self.avoid_instances: all.extend([ @@ -702,9 +705,9 @@ def test_failing_guards(self): t_box, T_box = self.alloc_instance(self.T) nullbox = self.null_instance() - all = [(rop.GUARD_TRUE, [BoxInt(0)]), - (rop.GUARD_FALSE, [BoxInt(1)]), - (rop.GUARD_VALUE, [BoxInt(42), ConstInt(41)]), + all = [(rop.GUARD_TRUE, [boxint(0)]), + (rop.GUARD_FALSE, [boxint(1)]), + (rop.GUARD_VALUE, [boxint(42), ConstInt(41)]), ] if not self.avoid_instances: all.extend([ @@ -731,7 +734,7 @@ def test_ooops(self): def clone(box): - return BoxPtr(box.value) + return boxptr(box.value) u1_box, U_box = self.alloc_instance(self.U) u2_box, U_box = self.alloc_instance(self.U) @@ -770,11 +773,11 @@ r = self.execute_operation(rop.ARRAYLEN_GC, [a_box], 'int', descr=arraydescr) assert r == 342 - r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(310), - BoxInt(744)], + r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(310), + boxint(744)], 'void', descr=arraydescr) assert r is None - r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, BoxInt(310)], + r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, boxint(310)], 'int', descr=arraydescr) assert r == 744 @@ -785,11 +788,11 @@ r = self.execute_operation(rop.ARRAYLEN_GC, [a_box], 'int', descr=arraydescr) assert r == 342 - r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(310), - BoxInt(7441)], + r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(310), + boxint(7441)], 'void', descr=arraydescr) assert r is None - r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, BoxInt(310)], + r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, boxint(310)], 'int', descr=arraydescr) assert r == 7441 # @@ -799,18 +802,18 @@ r = self.execute_operation(rop.ARRAYLEN_GC, [a_box], 'int', descr=arraydescr) assert r == 11 - r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(4), - BoxInt(150)], + r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(4), + boxint(150)], 'void', descr=arraydescr) assert r is None - r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(3), - BoxInt(160)], + r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(3), + boxint(160)], 'void', descr=arraydescr) assert r is None - r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, BoxInt(4)], + r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, boxint(4)], 'int', descr=arraydescr) assert r == 150 - r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, BoxInt(3)], + r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, boxint(3)], 'int', descr=arraydescr) assert r == 160 @@ -823,11 +826,11 @@ r = self.execute_operation(rop.ARRAYLEN_GC, [b_box], 'int', descr=arraydescr) assert r == 3 - r = self.execute_operation(rop.SETARRAYITEM_GC, [b_box, BoxInt(1), + r = self.execute_operation(rop.SETARRAYITEM_GC, [b_box, boxint(1), a_box], 'void', descr=arraydescr) assert r is None - r = self.execute_operation(rop.GETARRAYITEM_GC_r, [b_box, BoxInt(1)], + r = self.execute_operation(rop.GETARRAYITEM_GC_r, [b_box, boxint(1)], 'ref', descr=arraydescr) assert r == a_box.value # @@ -838,11 +841,11 @@ r = self.execute_operation(rop.ARRAYLEN_GC, [a_box], 'int', descr=arraydescr) assert r == 342 - r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(310), - BoxInt(7441)], + r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(310), + boxint(7441)], 'void', descr=arraydescr) assert r is None - r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, BoxInt(310)], + r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, boxint(310)], 'int', descr=arraydescr) assert r == 7441 # @@ -853,41 +856,41 @@ r = self.execute_operation(rop.ARRAYLEN_GC, [a_box], 'int', descr=arraydescr) assert r == 311 - r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(304), - BoxInt(1)], + r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(304), + boxint(1)], 'void', descr=arraydescr) assert r is None - r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(303), - BoxInt(0)], + r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(303), + boxint(0)], 'void', descr=arraydescr) assert r is None - r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(302), - BoxInt(1)], + r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(302), + boxint(1)], 'void', descr=arraydescr) assert r is None - r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, BoxInt(304)], + r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, boxint(304)], 'int', descr=arraydescr) assert r == 1 - r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, BoxInt(303)], + r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, boxint(303)], 'int', descr=arraydescr) assert r == 0 - r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, BoxInt(302)], + r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, boxint(302)], 'int', descr=arraydescr) assert r == 1 if self.cpu.supports_floats: a_box, A = self.alloc_array_of(lltype.Float, 31) arraydescr = self.cpu.arraydescrof(A) - self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(1), + self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(1), boxfloat(3.5)], 'void', descr=arraydescr) - self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(2), + self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(2), constfloat(4.5)], 'void', descr=arraydescr) - r = self.execute_operation(rop.GETARRAYITEM_GC_f, [a_box, BoxInt(1)], + r = self.execute_operation(rop.GETARRAYITEM_GC_f, [a_box, boxint(1)], 'float', descr=arraydescr) assert r == 3.5 - r = self.execute_operation(rop.GETARRAYITEM_GC_f, [a_box, BoxInt(2)], + r = self.execute_operation(rop.GETARRAYITEM_GC_f, [a_box, boxint(2)], 'float', descr=arraydescr) assert r == 4.5 @@ -898,11 +901,11 @@ r = self.execute_operation(rop.ARRAYLEN_GC, [a_box], 'int', descr=arraydescr) assert r == 342 - r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(310), - BoxInt(7441)], + r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, boxint(310), + boxint(7441)], 'void', descr=arraydescr) assert r is None - r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, BoxInt(310)], + r = self.execute_operation(rop.GETARRAYITEM_GC_i, [a_box, boxint(310)], 'int', descr=arraydescr) assert r == 7441 @@ -923,13 +926,13 @@ s_box, S = self.alloc_instance(TP) kdescr = self.cpu.interiorfielddescrof(A, 'k') pdescr = self.cpu.interiorfielddescrof(A, 'p') - self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, BoxInt(3), + self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, boxint(3), boxfloat(1.5)], 'void', descr=kdescr) f = self.cpu.bh_getinteriorfield_gc_f(a_box.getref_base(), 3, kdescr) assert longlong.getrealfloat(f) == 1.5 self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, kdescr, longlong.getfloatstorage(2.5)) - r = self.execute_operation(rop.GETINTERIORFIELD_GC_f, [a_box, BoxInt(3)], + r = self.execute_operation(rop.GETINTERIORFIELD_GC_f, [a_box, boxint(3)], 'float', descr=kdescr) assert r == 2.5 # @@ -943,8 +946,8 @@ ('vui', rffi.UINT)] for name, TYPE in NUMBER_FIELDS[::-1]: vdescr = self.cpu.interiorfielddescrof(A, name) - self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, BoxInt(3), - BoxInt(-15)], + self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, boxint(3), + boxint(-15)], 'void', descr=vdescr) for name, TYPE in NUMBER_FIELDS: vdescr = self.cpu.interiorfielddescrof(A, name) @@ -958,11 +961,11 @@ for name, TYPE in NUMBER_FIELDS: vdescr = self.cpu.interiorfielddescrof(A, name) r = self.execute_operation(rop.GETINTERIORFIELD_GC_i, - [a_box, BoxInt(3)], + [a_box, boxint(3)], 'int', descr=vdescr) assert r == rffi.cast(lltype.Signed, rffi.cast(TYPE, -25)) # - self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, BoxInt(4), + self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, boxint(4), s_box], 'void', descr=pdescr) r = self.cpu.bh_getinteriorfield_gc_r(a_box.getref_base(), 4, pdescr) @@ -970,7 +973,7 @@ self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, pdescr, s_box.getref_base()) r = self.execute_operation(rop.GETINTERIORFIELD_GC_r, - [a_box, BoxInt(3)], + [a_box, boxint(3)], 'ref', descr=pdescr) assert r == s_box.getref_base() @@ -978,22 +981,22 @@ s_box = self.alloc_string("hello\xfe") r = self.execute_operation(rop.STRLEN, [s_box], 'int') assert r == 6 - r = self.execute_operation(rop.STRGETITEM, [s_box, BoxInt(5)], 'int') + r = self.execute_operation(rop.STRGETITEM, [s_box, boxint(5)], 'int') assert r == 254 - r = self.execute_operation(rop.STRSETITEM, [s_box, BoxInt(4), - BoxInt(153)], 'void') + r = self.execute_operation(rop.STRSETITEM, [s_box, boxint(4), + boxint(153)], 'void') assert r is None - r = self.execute_operation(rop.STRGETITEM, [s_box, BoxInt(5)], 'int') + r = self.execute_operation(rop.STRGETITEM, [s_box, boxint(5)], 'int') assert r == 254 - r = self.execute_operation(rop.STRGETITEM, [s_box, BoxInt(4)], 'int') + r = self.execute_operation(rop.STRGETITEM, [s_box, boxint(4)], 'int') assert r == 153 def test_copystrcontent(self): s_box = self.alloc_string("abcdef") for s_box in [s_box, s_box.constbox()]: - for srcstart_box in [BoxInt(2), ConstInt(2)]: - for dststart_box in [BoxInt(3), ConstInt(3)]: - for length_box in [BoxInt(4), ConstInt(4)]: + for srcstart_box in [boxint(2), ConstInt(2)]: + for dststart_box in [boxint(3), ConstInt(3)]: + for length_box in [boxint(4), ConstInt(4)]: for r_box_is_const in [False, True]: r_box = self.alloc_string("!???????!") if r_box_is_const: @@ -1008,9 +1011,9 @@ def test_copyunicodecontent(self): s_box = self.alloc_unicode(u"abcdef") for s_box in [s_box, s_box.constbox()]: - for srcstart_box in [BoxInt(2), ConstInt(2)]: - for dststart_box in [BoxInt(3), ConstInt(3)]: - for length_box in [BoxInt(4), ConstInt(4)]: + for srcstart_box in [boxint(2), ConstInt(2)]: + for dststart_box in [boxint(3), ConstInt(3)]: + for length_box in [boxint(4), ConstInt(4)]: for r_box_is_const in [False, True]: r_box = self.alloc_unicode(u"!???????!") if r_box_is_const: @@ -1032,23 +1035,23 @@ u_box = self.alloc_unicode(u"hello\u1234") r = self.execute_operation(rop.UNICODELEN, [u_box], 'int') assert r == 6 - r = self.execute_operation(rop.UNICODEGETITEM, [u_box, BoxInt(5)], + r = self.execute_operation(rop.UNICODEGETITEM, [u_box, boxint(5)], 'int') assert r == 0x1234 - r = self.execute_operation(rop.UNICODESETITEM, [u_box, BoxInt(4), - BoxInt(31313)], 'void') + r = self.execute_operation(rop.UNICODESETITEM, [u_box, boxint(4), + boxint(31313)], 'void') assert r is None - r = self.execute_operation(rop.UNICODEGETITEM, [u_box, BoxInt(5)], + r = self.execute_operation(rop.UNICODEGETITEM, [u_box, boxint(5)], 'int') assert r == 0x1234 - r = self.execute_operation(rop.UNICODEGETITEM, [u_box, BoxInt(4)], + r = self.execute_operation(rop.UNICODEGETITEM, [u_box, boxint(4)], 'int') assert r == 31313 def test_same_as(self): r = self.execute_operation(rop.SAME_AS_i, [ConstInt(5)], 'int') assert r == 5 - r = self.execute_operation(rop.SAME_AS_i, [BoxInt(5)], 'int') + r = self.execute_operation(rop.SAME_AS_i, [boxint(5)], 'int') assert r == 5 u_box = self.alloc_unicode(u"hello\u1234") r = self.execute_operation(rop.SAME_AS_r, [u_box.constbox()], 'ref') @@ -1081,7 +1084,7 @@ for k in range(nb_args): kind = r.randrange(0, numkinds) if kind == 0: - inputargs.append(BoxInt()) + inputargs.append(boxint()) values.append(r.randrange(-100000, 100000)) else: inputargs.append(BoxFloat()) @@ -1096,7 +1099,7 @@ ks = range(nb_args) random.shuffle(ks) for k in ks: - if isinstance(inputargs[k], BoxInt): + if isinstance(inputargs[k], boxint): x = r.randrange(-100000, 100000) operations.append( create_resop_2(rop.INT_ADD, 0, inputargs[k], @@ -1185,9 +1188,9 @@ values = [] S = lltype.GcStruct('S') for box in inpargs: - if isinstance(box, BoxInt): + if isinstance(box, boxint): values.append(r.randrange(-10000, 10000)) - elif isinstance(box, BoxPtr): + elif isinstance(box, boxptr): p = lltype.malloc(S) values.append(lltype.cast_opaque_ptr(llmemory.GCREF, p)) elif isinstance(box, BoxFloat): @@ -1210,9 +1213,9 @@ assert dstvalues[index_counter] == 11 dstvalues[index_counter] = 0 for i, (box, val) in enumerate(zip(inpargs, dstvalues)): - if isinstance(box, BoxInt): + if isinstance(box, boxint): got = self.cpu.get_latest_value_int(i) - elif isinstance(box, BoxPtr): + elif isinstance(box, boxptr): got = self.cpu.get_latest_value_ref(i) elif isinstance(box, BoxFloat): got = self.cpu.get_latest_value_float(i) @@ -1275,17 +1278,17 @@ for combinaison in ["bb", "bc", "cb"]: # if combinaison[0] == 'b': - ibox1 = BoxInt() + ibox1 = boxint() else: ibox1 = ConstInt(-42) if combinaison[1] == 'b': - ibox2 = BoxInt() + ibox2 = boxint() else: ibox2 = ConstInt(-42) faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) inputargs = [ib for ib in [ibox1, ibox2] - if isinstance(ib, BoxInt)] + if isinstance(ib, boxint)] op0 = create_resop_2(opname, 0, ibox1, ibox2) op1 = create_resop_1(opguard, None, op0) op1.setdescr(faildescr1) @@ -1409,7 +1412,7 @@ # args = [] for box in inputargs: - if isinstance(box, BoxInt): + if isinstance(box, boxint): args.append(box.getint()) elif isinstance(box, BoxFloat): args.append(box.getfloatstorage()) @@ -1586,24 +1589,24 @@ t.parent.parent.typeptr = vtable_for_T elif T == self.U: t.parent.parent.parent.typeptr = vtable_for_T - t_box = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, t)) + t_box = boxptr(lltype.cast_opaque_ptr(llmemory.GCREF, t)) T_box = ConstInt(heaptracker.adr2int(vtable_for_T_addr)) return t_box, T_box def null_instance(self): - return BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) + return boxptr(lltype.nullptr(llmemory.GCREF.TO)) def alloc_array_of(self, ITEM, length): A = lltype.GcArray(ITEM) a = lltype.malloc(A, length) - a_box = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, a)) + a_box = boxptr(lltype.cast_opaque_ptr(llmemory.GCREF, a)) return a_box, A def alloc_string(self, string): s = rstr.mallocstr(len(string)) for i in range(len(string)): s.chars[i] = string[i] - s_box = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s)) + s_box = boxptr(lltype.cast_opaque_ptr(llmemory.GCREF, s)) return s_box def look_string(self, string_box): @@ -1614,7 +1617,7 @@ u = rstr.mallocunicode(len(unicode)) for i in range(len(unicode)): u.chars[i] = unicode[i] - u_box = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, u)) + u_box = boxptr(lltype.cast_opaque_ptr(llmemory.GCREF, u)) return u_box def look_unicode(self, unicode_box): @@ -1624,13 +1627,13 @@ def test_cast_int_to_ptr(self): res = self.execute_operation(rop.CAST_INT_TO_PTR, - [BoxInt(-17)], 'ref') + [boxint(-17)], 'ref') assert lltype.cast_ptr_to_int(res) == -17 def test_cast_ptr_to_int(self): x = lltype.cast_int_to_ptr(llmemory.GCREF, -19) res = self.execute_operation(rop.CAST_PTR_TO_INT, - [BoxPtr(x)], 'int') + [boxptr(x)], 'int') assert res == -19 def test_convert_float_bytes(self): @@ -1647,9 +1650,9 @@ def test_ooops_non_gc(self): x = lltype.malloc(lltype.Struct('x'), flavor='raw') v = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) - r = self.execute_operation(rop.PTR_EQ, [BoxInt(v), BoxInt(v)], 'int') + r = self.execute_operation(rop.PTR_EQ, [boxint(v), boxint(v)], 'int') assert r == 1 - r = self.execute_operation(rop.PTR_NE, [BoxInt(v), BoxInt(v)], 'int') + r = self.execute_operation(rop.PTR_NE, [boxint(v), boxint(v)], 'int') assert r == 0 lltype.free(x, flavor='raw') @@ -1662,9 +1665,9 @@ assert r1 != r2 xdescr = cpu.fielddescrof(S, 'x') ydescr = cpu.fielddescrof(S, 'y') - self.execute_operation(rop.SETFIELD_GC, [BoxPtr(r1), BoxInt(150)], + self.execute_operation(rop.SETFIELD_GC, [boxptr(r1), boxint(150)], 'void', descr=ydescr) - self.execute_operation(rop.SETFIELD_GC, [BoxPtr(r1), BoxInt(190)], + self.execute_operation(rop.SETFIELD_GC, [boxptr(r1), boxint(190)], 'void', descr=xdescr) s = lltype.cast_opaque_ptr(lltype.Ptr(S), r1) assert s.x == chr(190) @@ -1682,11 +1685,11 @@ descr1 = cpu.fielddescrof(self.S, 'chr1') descr2 = cpu.fielddescrof(self.S, 'chr2') descrshort = cpu.fielddescrof(self.S, 'short') - self.execute_operation(rop.SETFIELD_GC, [BoxPtr(r1), BoxInt(150)], + self.execute_operation(rop.SETFIELD_GC, [boxptr(r1), boxint(150)], 'void', descr=descr2) - self.execute_operation(rop.SETFIELD_GC, [BoxPtr(r1), BoxInt(190)], + self.execute_operation(rop.SETFIELD_GC, [boxptr(r1), boxint(190)], 'void', descr=descr1) - self.execute_operation(rop.SETFIELD_GC, [BoxPtr(r1), BoxInt(1313)], + self.execute_operation(rop.SETFIELD_GC, [boxptr(r1), boxint(1313)], 'void', descr=descrshort) s = lltype.cast_opaque_ptr(lltype.Ptr(self.T), r1) assert s.parent.chr1 == chr(190) @@ -1696,7 +1699,7 @@ self.cpu.bh_setfield_gc_i(r1, descrshort, 1333) r = self.cpu.bh_getfield_gc_i(r1, descrshort) assert r == 1333 - r = self.execute_operation(rop.GETFIELD_GC_i, [BoxPtr(r1)], 'int', + r = self.execute_operation(rop.GETFIELD_GC_i, [boxptr(r1)], 'int', descr=descrshort) assert r == 1333 t = lltype.cast_opaque_ptr(lltype.Ptr(self.T), t_box.value) @@ -1705,9 +1708,9 @@ def test_new_array(self): A = lltype.GcArray(lltype.Signed) arraydescr = self.cpu.arraydescrof(A) - r1 = self.execute_operation(rop.NEW_ARRAY, [BoxInt(342)], + r1 = self.execute_operation(rop.NEW_ARRAY, [boxint(342)], 'ref', descr=arraydescr) - r2 = self.execute_operation(rop.NEW_ARRAY, [BoxInt(342)], + r2 = self.execute_operation(rop.NEW_ARRAY, [boxint(342)], 'ref', descr=arraydescr) assert r1 != r2 a = lltype.cast_opaque_ptr(lltype.Ptr(A), r1) @@ -1715,15 +1718,15 @@ assert len(a) == 342 def test_new_string(self): - r1 = self.execute_operation(rop.NEWSTR, [BoxInt(342)], 'ref') - r2 = self.execute_operation(rop.NEWSTR, [BoxInt(342)], 'ref') + r1 = self.execute_operation(rop.NEWSTR, [boxint(342)], 'ref') + r2 = self.execute_operation(rop.NEWSTR, [boxint(342)], 'ref') assert r1 != r2 a = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), r1) assert len(a.chars) == 342 def test_new_unicode(self): - r1 = self.execute_operation(rop.NEWUNICODE, [BoxInt(342)], 'ref') - r2 = self.execute_operation(rop.NEWUNICODE, [BoxInt(342)], 'ref') + r1 = self.execute_operation(rop.NEWUNICODE, [boxint(342)], 'ref') + r2 = self.execute_operation(rop.NEWUNICODE, [boxint(342)], 'ref') assert r1 != r2 a = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), r1) assert len(a.chars) == 342 @@ -1842,7 +1845,7 @@ tgcref = lltype.cast_opaque_ptr(llmemory.GCREF, t) del record[:] self.execute_operation(rop.COND_CALL_GC_WB, - [BoxPtr(sgcref), ConstPtr(tgcref)], + [boxptr(sgcref), ConstPtr(tgcref)], 'void', descr=WriteBarrierDescr()) if cond: assert record == [s] @@ -1877,7 +1880,7 @@ sgcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) del record[:] self.execute_operation(rop.COND_CALL_GC_WB_ARRAY, - [BoxPtr(sgcref), ConstInt(123), BoxPtr(sgcref)], + [boxptr(sgcref), ConstInt(123), boxptr(sgcref)], 'void', descr=WriteBarrierDescr()) if cond: assert record == [s] @@ -1916,7 +1919,7 @@ def get_write_barrier_from_array_fn(self, cpu): return funcbox.getint() # - for BoxIndexCls in [BoxInt, ConstInt]*3: + for BoxIndexCls in [boxint, ConstInt]*3: for cond in [-1, 0, 1, 2]: # cond=-1:GCFLAG_TRACK_YOUNG_PTRS, GCFLAG_CARDS_SET are not set # cond=0: GCFLAG_CARDS_SET is never set @@ -1942,7 +1945,7 @@ del record[:] box_index = BoxIndexCls((9<<7) + 17) self.execute_operation(rop.COND_CALL_GC_WB_ARRAY, - [BoxPtr(sgcref), box_index, BoxPtr(sgcref)], + [boxptr(sgcref), box_index, boxptr(sgcref)], 'void', descr=WriteBarrierDescr()) if cond in [0, 1]: assert record == [s.data] @@ -2186,14 +2189,14 @@ [types.ulong, types.pointer], types.ulong, abiname='FFI_STDCALL') - i1 = BoxInt() - i2 = BoxInt() + i1 = boxint() + i2 = boxint() faildescr = BasicFailDescr(1) # if the stdcall convention is ignored, then ESP is wrong after the # call: 8 bytes too much. If we repeat the call often enough, crash. ops = [] for i in range(50): - i3 = BoxInt() + i3 = boxint() ops += [ ResOperation(rop.CALL_RELEASE_GIL, [funcbox, i1, i2], i3, descr=calldescr), @@ -2390,14 +2393,14 @@ #descrfld_ry = cpu.fielddescrof(RS, 'y') #rs.y = a #x = cpu.do_getfield_raw( - # BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs))), + # boxint(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs))), # descrfld_ry) - #assert isinstance(x, BoxPtr) + #assert isinstance(x, boxptr) #assert x.getref(lltype.Ptr(A)) == a # #rs.y = lltype.nullptr(A) #cpu.do_setfield_raw( - # BoxInt(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs))), x, + # boxint(cpu.cast_adr_to_int(llmemory.cast_ptr_to_adr(rs))), x, # descrfld_ry) #assert rs.y == a # @@ -2446,12 +2449,12 @@ def test_guards_nongc(self): x = lltype.malloc(lltype.Struct('x'), flavor='raw') v = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) - vbox = BoxInt(v) + vbox = boxint(v) ops = [ (rop.GUARD_NONNULL, vbox, False), (rop.GUARD_ISNULL, vbox, True), - (rop.GUARD_NONNULL, BoxInt(0), True), - (rop.GUARD_ISNULL, BoxInt(0), False), + (rop.GUARD_NONNULL, boxint(0), True), + (rop.GUARD_ISNULL, boxint(0), False), ] for opname, arg, res in ops: self.execute_operation(opname, [arg], 'void') @@ -2590,8 +2593,8 @@ a = lltype.malloc(ARRAY, 10, flavor='raw') a[7] = -4242 addr = llmemory.cast_ptr_to_adr(a) - abox = BoxInt(heaptracker.adr2int(addr)) - r1 = self.execute_operation(rop.GETARRAYITEM_RAW_i, [abox, BoxInt(7)], + abox = boxint(heaptracker.adr2int(addr)) + r1 = self.execute_operation(rop.GETARRAYITEM_RAW_i, [abox, boxint(7)], 'int', descr=descr) assert r1 == -4242 lltype.free(a, flavor='raw') @@ -2601,9 +2604,9 @@ descr = self.cpu.arraydescrof(ARRAY) a = lltype.malloc(ARRAY, 10, flavor='raw') addr = llmemory.cast_ptr_to_adr(a) - abox = BoxInt(heaptracker.adr2int(addr)) - self.execute_operation(rop.SETARRAYITEM_RAW, [abox, BoxInt(5), - BoxInt(12345)], + abox = boxint(heaptracker.adr2int(addr)) + self.execute_operation(rop.SETARRAYITEM_RAW, [abox, boxint(5), + boxint(12345)], 'void', descr=descr) assert a[5] == 12345 lltype.free(a, flavor='raw') @@ -2723,7 +2726,7 @@ expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value)) s.x = rffi.cast(RESTYPE, value) s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) - res = self.execute_operation(rop.GETFIELD_GC_i, [BoxPtr(s_gcref)], + res = self.execute_operation(rop.GETFIELD_GC_i, [boxptr(s_gcref)], 'int', descr=descrfld_x) assert res == expected, ( "%r: got %r, expected %r" % (RESTYPE, res.value, expected)) @@ -2765,7 +2768,7 @@ a[3] = rffi.cast(RESTYPE, value) a_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, a) res = self.execute_operation(rop.GETARRAYITEM_GC_i, - [BoxPtr(a_gcref), BoxInt(3)], + [boxptr(a_gcref), boxint(3)], 'int', descr=descrarray) assert res == expected, ( "%r: got %r, expected %r" % (RESTYPE, res.value, expected)) @@ -2808,7 +2811,7 @@ a[3] = rffi.cast(RESTYPE, value) a_rawint = heaptracker.adr2int(llmemory.cast_ptr_to_adr(a)) res = self.execute_operation(rop.GETARRAYITEM_RAW_i, - [BoxInt(a_rawint), BoxInt(3)], + [boxint(a_rawint), boxint(3)], 'int', descr=descrarray) assert res == expected, ( "%r: got %r, expected %r" % (RESTYPE, res.value, expected)) @@ -2878,7 +2881,7 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(self.cpu, f) - res = self.execute_operation(rop.CALL_i, [funcbox, BoxInt(value)], + res = self.execute_operation(rop.CALL_i, [funcbox, boxint(value)], 'int', descr=calldescr) assert res == expected, ( "%r: got %r, expected %r" % (RESTYPE, res.value, expected)) @@ -3002,7 +3005,7 @@ funcbox = self.get_funcbox(self.cpu, f) ivalue = longlong.singlefloat2int(value) iexpected = longlong.singlefloat2int(expected) - res = self.execute_operation(rop.CALL_i, [funcbox, BoxInt(ivalue)], + res = self.execute_operation(rop.CALL_i, [funcbox, boxint(ivalue)], 'int', descr=calldescr) assert res == iexpected @@ -3026,8 +3029,8 @@ excdescr) self.cpu.setup_once() # xxx redo it, because we added # propagate_exception_v - i0 = BoxInt() - p0 = BoxPtr() + i0 = boxint() + p0 = boxptr() operations = [ ResOperation(rop.NEWUNICODE, [i0], p0), ResOperation(rop.FINISH, [p0], None, descr=BasicFailDescr(1)) From noreply at buildbot.pypy.org Sun Oct 21 18:44:51 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 18:44:51 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: Merge continuelet-jit-3 branch. It has no conflicts except one giant one Message-ID: <20121021164451.E9CA81C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58324:299033399e68 Date: 2012-10-21 18:44 +0200 http://bitbucket.org/pypy/pypy/changeset/299033399e68/ Log: Merge continuelet-jit-3 branch. It has no conflicts except one giant one in runner_test.py. Will take a while to recover diff too long, truncating to 2000 out of 103772 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,5 +1,6 @@ syntax: glob *.py[co] +*.sw[po] *~ .*.swp .idea diff --git a/lib-python/2.7/BaseHTTPServer.py b/lib-python/2.7/BaseHTTPServer.py --- a/lib-python/2.7/BaseHTTPServer.py +++ b/lib-python/2.7/BaseHTTPServer.py @@ -244,14 +244,11 @@ self.request_version = version = self.default_request_version self.close_connection = 1 requestline = self.raw_requestline - if requestline[-2:] == '\r\n': - requestline = requestline[:-2] - elif requestline[-1:] == '\n': - requestline = requestline[:-1] + requestline = requestline.rstrip('\r\n') self.requestline = requestline words = requestline.split() if len(words) == 3: - [command, path, version] = words + command, path, version = words if version[:5] != 'HTTP/': self.send_error(400, "Bad request version (%r)" % version) return False @@ -277,7 +274,7 @@ "Invalid HTTP Version (%s)" % base_version_number) return False elif len(words) == 2: - [command, path] = words + command, path = words self.close_connection = 1 if command != 'GET': self.send_error(400, diff --git a/lib-python/2.7/ConfigParser.py b/lib-python/2.7/ConfigParser.py --- a/lib-python/2.7/ConfigParser.py +++ b/lib-python/2.7/ConfigParser.py @@ -142,6 +142,7 @@ def __init__(self, section): Error.__init__(self, 'No section: %r' % (section,)) self.section = section + self.args = (section, ) class DuplicateSectionError(Error): """Raised when a section is multiply-created.""" @@ -149,6 +150,7 @@ def __init__(self, section): Error.__init__(self, "Section %r already exists" % section) self.section = section + self.args = (section, ) class NoOptionError(Error): """A requested option was not found.""" @@ -158,6 +160,7 @@ (option, section)) self.option = option self.section = section + self.args = (option, section) class InterpolationError(Error): """Base class for interpolation-related exceptions.""" @@ -166,6 +169,7 @@ Error.__init__(self, msg) self.option = option self.section = section + self.args = (option, section, msg) class InterpolationMissingOptionError(InterpolationError): """A string substitution required a setting which was not available.""" @@ -179,6 +183,7 @@ % (section, option, reference, rawval)) InterpolationError.__init__(self, option, section, msg) self.reference = reference + self.args = (option, section, rawval, reference) class InterpolationSyntaxError(InterpolationError): """Raised when the source text into which substitutions are made @@ -194,6 +199,7 @@ "\trawval : %s\n" % (section, option, rawval)) InterpolationError.__init__(self, option, section, msg) + self.args = (option, section, rawval) class ParsingError(Error): """Raised when a configuration file does not follow legal syntax.""" @@ -202,6 +208,7 @@ Error.__init__(self, 'File contains parsing errors: %s' % filename) self.filename = filename self.errors = [] + self.args = (filename, ) def append(self, lineno, line): self.errors.append((lineno, line)) @@ -218,6 +225,7 @@ self.filename = filename self.lineno = lineno self.line = line + self.args = (filename, lineno, line) class RawConfigParser: @@ -570,7 +578,7 @@ def keys(self): result = [] seen = set() - for mapping in self_maps: + for mapping in self._maps: for key in mapping: if key not in seen: result.append(key) diff --git a/lib-python/2.7/HTMLParser.py b/lib-python/2.7/HTMLParser.py --- a/lib-python/2.7/HTMLParser.py +++ b/lib-python/2.7/HTMLParser.py @@ -14,7 +14,6 @@ # Regular expressions used for parsing interesting_normal = re.compile('[&<]') -interesting_cdata = re.compile(r'<(/|\Z)') incomplete = re.compile('&[a-zA-Z#]') entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') @@ -24,25 +23,31 @@ piclose = re.compile('>') commentclose = re.compile(r'--\s*>') tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*') +# see http://www.w3.org/TR/html5/tokenization.html#tag-open-state +# and http://www.w3.org/TR/html5/tokenization.html#tag-name-state +tagfind_tolerant = re.compile('[a-zA-Z][^\t\n\r\f />\x00]*') + attrfind = re.compile( - r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' - r'(\'[^\']*\'|"[^"]*"|[^\s"\'=<>`]*))?') + r'[\s/]*((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' + r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*') locatestarttagend = re.compile(r""" <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name - (?:\s+ # whitespace before attribute name - (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name - (?:\s*=\s* # value indicator + (?:[\s/]* # optional whitespace before attribute name + (?:(?<=['"\s/])[^\s/>][^\s/=>]* # attribute name + (?:\s*=+\s* # value indicator (?:'[^']*' # LITA-enclosed value - |\"[^\"]*\" # LIT-enclosed value - |[^'\">\s]+ # bare value + |"[^"]*" # LIT-enclosed value + |(?!['"])[^>\s]* # bare value ) - )? - ) - )* + )?(?:\s|/(?!>))* + )* + )? \s* # trailing whitespace """, re.VERBOSE) endendtag = re.compile('>') +# the HTML 5 spec, section 8.1.2.2, doesn't allow spaces between +# ') @@ -96,6 +101,7 @@ self.rawdata = '' self.lasttag = '???' self.interesting = interesting_normal + self.cdata_elem = None markupbase.ParserBase.reset(self) def feed(self, data): @@ -120,11 +126,13 @@ """Return full source of start tag: '<...>'.""" return self.__starttag_text - def set_cdata_mode(self): - self.interesting = interesting_cdata + def set_cdata_mode(self, elem): + self.cdata_elem = elem.lower() + self.interesting = re.compile(r'' % self.cdata_elem, re.I) def clear_cdata_mode(self): self.interesting = interesting_normal + self.cdata_elem = None # Internal -- handle data as far as reasonable. May leave state # and data to be processed by a subsequent call. If 'end' is @@ -138,6 +146,8 @@ if match: j = match.start() else: + if self.cdata_elem: + break j = n if i < j: self.handle_data(rawdata[i:j]) i = self.updatepos(i, j) @@ -153,16 +163,23 @@ elif startswith("', i + 1) + if k < 0: + k = rawdata.find('<', i + 1) + if k < 0: + k = i + 1 + else: + k += 1 + self.handle_data(rawdata[i:k]) i = self.updatepos(i, k) elif startswith("&#", i): match = charref.match(rawdata, i) @@ -206,11 +223,46 @@ else: assert 0, "interesting.search() lied" # end while - if end and i < n: + if end and i < n and not self.cdata_elem: self.handle_data(rawdata[i:n]) i = self.updatepos(i, n) self.rawdata = rawdata[i:] + # Internal -- parse html declarations, return length or -1 if not terminated + # See w3.org/TR/html5/tokenization.html#markup-declaration-open-state + # See also parse_declaration in _markupbase + def parse_html_declaration(self, i): + rawdata = self.rawdata + if rawdata[i:i+2] != ' + gtpos = rawdata.find('>', i+9) + if gtpos == -1: + return -1 + self.handle_decl(rawdata[i+2:gtpos]) + return gtpos+1 + else: + return self.parse_bogus_comment(i) + + # Internal -- parse bogus comment, return length or -1 if not terminated + # see http://www.w3.org/TR/html5/tokenization.html#bogus-comment-state + def parse_bogus_comment(self, i, report=1): + rawdata = self.rawdata + if rawdata[i:i+2] not in ('', i+2) + if pos == -1: + return -1 + if report: + self.handle_comment(rawdata[i+2:pos]) + return pos + 1 + # Internal -- parse processing instr, return end or -1 if not terminated def parse_pi(self, i): rawdata = self.rawdata @@ -249,6 +301,7 @@ elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ attrvalue[:1] == '"' == attrvalue[-1:]: attrvalue = attrvalue[1:-1] + if attrvalue: attrvalue = self.unescape(attrvalue) attrs.append((attrname.lower(), attrvalue)) k = m.end() @@ -262,15 +315,15 @@ - self.__starttag_text.rfind("\n") else: offset = offset + len(self.__starttag_text) - self.error("junk characters in start tag: %r" - % (rawdata[k:endpos][:20],)) + self.handle_data(rawdata[i:endpos]) + return endpos if end.endswith('/>'): # XHTML-style empty tag: self.handle_startendtag(tag, attrs) else: self.handle_starttag(tag, attrs) if tag in self.CDATA_CONTENT_ELEMENTS: - self.set_cdata_mode() + self.set_cdata_mode(tag) return endpos # Internal -- check to see if we have a complete starttag; return end @@ -300,8 +353,10 @@ # end of input in or before attribute value, or we have the # '/' from a '/>' ending return -1 - self.updatepos(i, j) - self.error("malformed start tag") + if j > i: + return j + else: + return i + 1 raise AssertionError("we should not get here!") # Internal -- parse endtag, return end or -1 if incomplete @@ -311,14 +366,38 @@ match = endendtag.search(rawdata, i+1) # > if not match: return -1 - j = match.end() + gtpos = match.end() match = endtagfind.match(rawdata, i) # if not match: - self.error("bad end tag: %r" % (rawdata[i:j],)) - tag = match.group(1) - self.handle_endtag(tag.lower()) + if self.cdata_elem is not None: + self.handle_data(rawdata[i:gtpos]) + return gtpos + # find the name: w3.org/TR/html5/tokenization.html#tag-name-state + namematch = tagfind_tolerant.match(rawdata, i+2) + if not namematch: + # w3.org/TR/html5/tokenization.html#end-tag-open-state + if rawdata[i:i+3] == '': + return i+3 + else: + return self.parse_bogus_comment(i) + tagname = namematch.group().lower() + # consume and ignore other stuff between the name and the > + # Note: this is not 100% correct, since we might have things like + # , but looking for > after tha name should cover + # most of the cases and is much simpler + gtpos = rawdata.find('>', namematch.end()) + self.handle_endtag(tagname) + return gtpos+1 + + elem = match.group(1).lower() # script or style + if self.cdata_elem is not None: + if elem != self.cdata_elem: + self.handle_data(rawdata[i:gtpos]) + return gtpos + + self.handle_endtag(elem) self.clear_cdata_mode() - return j + return gtpos # Overridable -- finish processing of start+end tag: def handle_startendtag(self, tag, attrs): @@ -358,7 +437,7 @@ pass def unknown_decl(self, data): - self.error("unknown declaration: %r" % (data,)) + pass # Internal -- helper to remove special character quoting entitydefs = None diff --git a/lib-python/2.7/SocketServer.py b/lib-python/2.7/SocketServer.py --- a/lib-python/2.7/SocketServer.py +++ b/lib-python/2.7/SocketServer.py @@ -82,7 +82,7 @@ data is stored externally (e.g. in the file system), a synchronous class will essentially render the service "deaf" while one request is being handled -- which may be for a very long time if a client is slow -to reqd all the data it has requested. Here a threading or forking +to read all the data it has requested. Here a threading or forking server is appropriate. In some cases, it may be appropriate to process part of a request @@ -589,8 +589,7 @@ """Start a new thread to process the request.""" t = threading.Thread(target = self.process_request_thread, args = (request, client_address)) - if self.daemon_threads: - t.setDaemon (1) + t.daemon = self.daemon_threads t.start() diff --git a/lib-python/2.7/_pyio.py b/lib-python/2.7/_pyio.py --- a/lib-python/2.7/_pyio.py +++ b/lib-python/2.7/_pyio.py @@ -8,6 +8,7 @@ import abc import codecs import warnings +import errno # Import thread instead of threading to reduce startup cost try: from thread import allocate_lock as Lock @@ -720,8 +721,11 @@ def close(self): if self.raw is not None and not self.closed: - self.flush() - self.raw.close() + try: + # may raise BlockingIOError or BrokenPipeError etc + self.flush() + finally: + self.raw.close() def detach(self): if self.raw is None: @@ -1074,13 +1078,9 @@ # XXX we can implement some more tricks to try and avoid # partial writes if len(self._write_buf) > self.buffer_size: - # We're full, so let's pre-flush the buffer - try: - self._flush_unlocked() - except BlockingIOError as e: - # We can't accept anything else. - # XXX Why not just let the exception pass through? - raise BlockingIOError(e.errno, e.strerror, 0) + # We're full, so let's pre-flush the buffer. (This may + # raise BlockingIOError with characters_written == 0.) + self._flush_unlocked() before = len(self._write_buf) self._write_buf.extend(b) written = len(self._write_buf) - before @@ -1111,24 +1111,23 @@ def _flush_unlocked(self): if self.closed: raise ValueError("flush of closed file") - written = 0 - try: - while self._write_buf: - try: - n = self.raw.write(self._write_buf) - except IOError as e: - if e.errno != EINTR: - raise - continue - if n > len(self._write_buf) or n < 0: - raise IOError("write() returned incorrect number of bytes") - del self._write_buf[:n] - written += n - except BlockingIOError as e: - n = e.characters_written + while self._write_buf: + try: + n = self.raw.write(self._write_buf) + except BlockingIOError: + raise RuntimeError("self.raw should implement RawIOBase: it " + "should not raise BlockingIOError") + except IOError as e: + if e.errno != EINTR: + raise + continue + if n is None: + raise BlockingIOError( + errno.EAGAIN, + "write could not complete without blocking", 0) + if n > len(self._write_buf) or n < 0: + raise IOError("write() returned incorrect number of bytes") del self._write_buf[:n] - written += n - raise BlockingIOError(e.errno, e.strerror, written) def tell(self): return _BufferedIOMixin.tell(self) + len(self._write_buf) diff --git a/lib-python/2.7/aifc.py b/lib-python/2.7/aifc.py --- a/lib-python/2.7/aifc.py +++ b/lib-python/2.7/aifc.py @@ -162,6 +162,12 @@ except struct.error: raise EOFError +def _read_ushort(file): + try: + return struct.unpack('>H', file.read(2))[0] + except struct.error: + raise EOFError + def _read_string(file): length = ord(file.read(1)) if length == 0: @@ -194,13 +200,19 @@ def _write_short(f, x): f.write(struct.pack('>h', x)) +def _write_ushort(f, x): + f.write(struct.pack('>H', x)) + def _write_long(f, x): + f.write(struct.pack('>l', x)) + +def _write_ulong(f, x): f.write(struct.pack('>L', x)) def _write_string(f, s): if len(s) > 255: raise ValueError("string exceeds maximum pstring length") - f.write(chr(len(s))) + f.write(struct.pack('B', len(s))) f.write(s) if len(s) & 1 == 0: f.write(chr(0)) @@ -218,7 +230,7 @@ lomant = 0 else: fmant, expon = math.frexp(x) - if expon > 16384 or fmant >= 1: # Infinity or NaN + if expon > 16384 or fmant >= 1 or fmant != fmant: # Infinity or NaN expon = sign|0x7FFF himant = 0 lomant = 0 @@ -234,9 +246,9 @@ fmant = math.ldexp(fmant - fsmant, 32) fsmant = math.floor(fmant) lomant = long(fsmant) - _write_short(f, expon) - _write_long(f, himant) - _write_long(f, lomant) + _write_ushort(f, expon) + _write_ulong(f, himant) + _write_ulong(f, lomant) from chunk import Chunk @@ -840,15 +852,15 @@ if self._aifc: self._file.write('AIFC') self._file.write('FVER') - _write_long(self._file, 4) - _write_long(self._file, self._version) + _write_ulong(self._file, 4) + _write_ulong(self._file, self._version) else: self._file.write('AIFF') self._file.write('COMM') - _write_long(self._file, commlength) + _write_ulong(self._file, commlength) _write_short(self._file, self._nchannels) self._nframes_pos = self._file.tell() - _write_long(self._file, self._nframes) + _write_ulong(self._file, self._nframes) _write_short(self._file, self._sampwidth * 8) _write_float(self._file, self._framerate) if self._aifc: @@ -856,9 +868,9 @@ _write_string(self._file, self._compname) self._file.write('SSND') self._ssnd_length_pos = self._file.tell() - _write_long(self._file, self._datalength + 8) - _write_long(self._file, 0) - _write_long(self._file, 0) + _write_ulong(self._file, self._datalength + 8) + _write_ulong(self._file, 0) + _write_ulong(self._file, 0) def _write_form_length(self, datalength): if self._aifc: @@ -869,8 +881,8 @@ else: commlength = 18 verslength = 0 - _write_long(self._file, 4 + verslength + self._marklength + \ - 8 + commlength + 16 + datalength) + _write_ulong(self._file, 4 + verslength + self._marklength + \ + 8 + commlength + 16 + datalength) return commlength def _patchheader(self): @@ -888,9 +900,9 @@ self._file.seek(self._form_length_pos, 0) dummy = self._write_form_length(datalength) self._file.seek(self._nframes_pos, 0) - _write_long(self._file, self._nframeswritten) + _write_ulong(self._file, self._nframeswritten) self._file.seek(self._ssnd_length_pos, 0) - _write_long(self._file, datalength + 8) + _write_ulong(self._file, datalength + 8) self._file.seek(curpos, 0) self._nframes = self._nframeswritten self._datalength = datalength @@ -905,13 +917,13 @@ length = length + len(name) + 1 + 6 if len(name) & 1 == 0: length = length + 1 - _write_long(self._file, length) + _write_ulong(self._file, length) self._marklength = length + 8 _write_short(self._file, len(self._markers)) for marker in self._markers: id, pos, name = marker _write_short(self._file, id) - _write_long(self._file, pos) + _write_ulong(self._file, pos) _write_string(self._file, name) def open(f, mode=None): diff --git a/lib-python/2.7/asyncore.py b/lib-python/2.7/asyncore.py --- a/lib-python/2.7/asyncore.py +++ b/lib-python/2.7/asyncore.py @@ -132,7 +132,8 @@ is_w = obj.writable() if is_r: r.append(fd) - if is_w: + # accepting sockets should not be writable + if is_w and not obj.accepting: w.append(fd) if is_r or is_w: e.append(fd) @@ -179,7 +180,8 @@ flags = 0 if obj.readable(): flags |= select.POLLIN | select.POLLPRI - if obj.writable(): + # accepting sockets should not be writable + if obj.writable() and not obj.accepting: flags |= select.POLLOUT if flags: # Only check for exceptions if object was either readable diff --git a/lib-python/2.7/cgi.py b/lib-python/2.7/cgi.py --- a/lib-python/2.7/cgi.py +++ b/lib-python/2.7/cgi.py @@ -293,7 +293,7 @@ while s[:1] == ';': s = s[1:] end = s.find(';') - while end > 0 and s.count('"', 0, end) % 2: + while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: end = s.find(';', end + 1) if end < 0: end = len(s) diff --git a/lib-python/2.7/cmd.py b/lib-python/2.7/cmd.py --- a/lib-python/2.7/cmd.py +++ b/lib-python/2.7/cmd.py @@ -209,6 +209,8 @@ if cmd is None: return self.default(line) self.lastcmd = line + if line == 'EOF' : + self.lastcmd = '' if cmd == '': return self.default(line) else: diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -312,6 +312,7 @@ def _asdict(self): 'Return a new OrderedDict which maps field names to their values' return OrderedDict(zip(self._fields, self)) \n + __dict__ = property(_asdict) \n def _replace(_self, **kwds): 'Return a new %(typename)s object replacing specified fields with new values' result = _self._make(map(kwds.pop, %(field_names)r, _self)) diff --git a/lib-python/2.7/compileall.py b/lib-python/2.7/compileall.py --- a/lib-python/2.7/compileall.py +++ b/lib-python/2.7/compileall.py @@ -1,4 +1,4 @@ -"""Module/script to "compile" all .py files to .pyc (or .pyo) file. +"""Module/script to byte-compile all .py files to .pyc (or .pyo) files. When called as a script with arguments, this compiles the directories given as arguments recursively; the -l option prevents it from @@ -26,8 +26,8 @@ dir: the directory to byte-compile maxlevels: maximum recursion level (default 10) - ddir: if given, purported directory name (this is the - directory name that will show up in error messages) + ddir: the directory that will be prepended to the path to the + file as it is compiled into each byte-code file. force: if 1, force compilation, even if timestamps are up-to-date quiet: if 1, be quiet during compilation """ @@ -64,8 +64,8 @@ Arguments (only fullname is required): fullname: the file to byte-compile - ddir: if given, purported directory name (this is the - directory name that will show up in error messages) + ddir: if given, the directory name compiled in to the + byte-code file. force: if 1, force compilation, even if timestamps are up-to-date quiet: if 1, be quiet during compilation """ @@ -157,14 +157,27 @@ print msg print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \ "[-x regexp] [-i list] [directory|file ...]" - print "-l: don't recurse down" + print + print "arguments: zero or more file and directory names to compile; " \ + "if no arguments given, " + print " defaults to the equivalent of -l sys.path" + print + print "options:" + print "-l: don't recurse into subdirectories" print "-f: force rebuild even if timestamps are up-to-date" - print "-q: quiet operation" - print "-d destdir: purported directory name for error messages" - print " if no directory arguments, -l sys.path is assumed" - print "-x regexp: skip files matching the regular expression regexp" - print " the regexp is searched for in the full path of the file" - print "-i list: expand list with its content (file and directory names)" + print "-q: output only error messages" + print "-d destdir: directory to prepend to file paths for use in " \ + "compile-time tracebacks and in" + print " runtime tracebacks in cases where the source " \ + "file is unavailable" + print "-x regexp: skip files matching the regular expression regexp; " \ + "the regexp is searched for" + print " in the full path of each file considered for " \ + "compilation" + print "-i file: add all the files and directories listed in file to " \ + "the list considered for" + print ' compilation; if "-", names are read from stdin' + sys.exit(2) maxlevels = 10 ddir = None @@ -205,7 +218,7 @@ else: success = compile_path() except KeyboardInterrupt: - print "\n[interrupt]" + print "\n[interrupted]" success = 0 return success diff --git a/lib-python/2.7/cookielib.py b/lib-python/2.7/cookielib.py --- a/lib-python/2.7/cookielib.py +++ b/lib-python/2.7/cookielib.py @@ -1014,7 +1014,7 @@ (not erhn.startswith(".") and not ("."+erhn).endswith(domain))): _debug(" effective request-host %s (even with added " - "initial dot) does not end end with %s", + "initial dot) does not end with %s", erhn, domain) return False if (cookie.version > 0 or diff --git a/lib-python/2.7/ctypes/__init__.py b/lib-python/2.7/ctypes/__init__.py --- a/lib-python/2.7/ctypes/__init__.py +++ b/lib-python/2.7/ctypes/__init__.py @@ -263,6 +263,22 @@ from _ctypes import POINTER, pointer, _pointer_type_cache +def _reset_cache(): + _pointer_type_cache.clear() + _c_functype_cache.clear() + if _os.name in ("nt", "ce"): + _win_functype_cache.clear() + # _SimpleCData.c_wchar_p_from_param + POINTER(c_wchar).from_param = c_wchar_p.from_param + # _SimpleCData.c_char_p_from_param + POINTER(c_char).from_param = c_char_p.from_param + _pointer_type_cache[None] = c_void_p + # XXX for whatever reasons, creating the first instance of a callback + # function is needed for the unittests on Win64 to succeed. This MAY + # be a compiler bug, since the problem occurs only when _ctypes is + # compiled with the MS SDK compiler. Or an uninitialized variable? + CFUNCTYPE(c_int)(lambda: None) + try: from _ctypes import set_conversion_mode except ImportError: @@ -279,8 +295,6 @@ class c_wchar(_SimpleCData): _type_ = "u" - POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param - def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array @@ -299,8 +313,6 @@ return buf raise TypeError(init) -POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param - # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: @@ -463,8 +475,6 @@ descr = FormatError(code).strip() return WindowsError(code, descr) -_pointer_type_cache[None] = c_void_p - if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int @@ -550,8 +560,4 @@ elif sizeof(kind) == 8: c_uint64 = kind del(kind) -# XXX for whatever reasons, creating the first instance of a callback -# function is needed for the unittests on Win64 to succeed. This MAY -# be a compiler bug, since the problem occurs only when _ctypes is -# compiled with the MS SDK compiler. Or an uninitialized variable? -CFUNCTYPE(c_int)(lambda: None) +_reset_cache() diff --git a/lib-python/2.7/ctypes/_endian.py b/lib-python/2.7/ctypes/_endian.py --- a/lib-python/2.7/ctypes/_endian.py +++ b/lib-python/2.7/ctypes/_endian.py @@ -4,20 +4,24 @@ import sys from ctypes import * -_array_type = type(c_int * 3) +_array_type = type(Array) def _other_endian(typ): """Return the type with the 'other' byte order. Simple types like c_int and so on already have __ctype_be__ and __ctype_le__ attributes which contain the types, for more complicated types - only arrays are supported. + arrays and structures are supported. """ - try: + # check _OTHER_ENDIAN attribute (present if typ is primitive type) + if hasattr(typ, _OTHER_ENDIAN): return getattr(typ, _OTHER_ENDIAN) - except AttributeError: - if type(typ) == _array_type: - return _other_endian(typ._type_) * typ._length_ - raise TypeError("This type does not support other endian: %s" % typ) + # if typ is array + if isinstance(typ, _array_type): + return _other_endian(typ._type_) * typ._length_ + # if typ is structure + if issubclass(typ, Structure): + return typ + raise TypeError("This type does not support other endian: %s" % typ) class _swapped_meta(type(Structure)): def __setattr__(self, attrname, value): diff --git a/lib-python/2.7/ctypes/test/test_as_parameter.py b/lib-python/2.7/ctypes/test/test_as_parameter.py --- a/lib-python/2.7/ctypes/test/test_as_parameter.py +++ b/lib-python/2.7/ctypes/test/test_as_parameter.py @@ -74,6 +74,7 @@ def test_callbacks(self): f = dll._testfunc_callback_i_if f.restype = c_int + f.argtypes = None MyCallback = CFUNCTYPE(c_int, c_int) diff --git a/lib-python/2.7/ctypes/test/test_buffers.py b/lib-python/2.7/ctypes/test/test_buffers.py --- a/lib-python/2.7/ctypes/test/test_buffers.py +++ b/lib-python/2.7/ctypes/test/test_buffers.py @@ -20,6 +20,10 @@ self.assertEqual(b[::2], "ac") self.assertEqual(b[::5], "a") + def test_buffer_interface(self): + self.assertEqual(len(bytearray(create_string_buffer(0))), 0) + self.assertEqual(len(bytearray(create_string_buffer(1))), 1) + def test_string_conversion(self): b = create_string_buffer(u"abc") self.assertEqual(len(b), 4) # trailing nul char diff --git a/lib-python/2.7/ctypes/test/test_byteswap.py b/lib-python/2.7/ctypes/test/test_byteswap.py --- a/lib-python/2.7/ctypes/test/test_byteswap.py +++ b/lib-python/2.7/ctypes/test/test_byteswap.py @@ -1,4 +1,4 @@ -import sys, unittest, struct, math +import sys, unittest, struct, math, ctypes from binascii import hexlify from ctypes import * @@ -191,19 +191,34 @@ pass self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)]) + @xfail def test_struct_struct(self): - # Nested structures with different byte order not (yet) supported - if sys.byteorder == "little": - base = BigEndianStructure - else: - base = LittleEndianStructure + # nested structures with different byteorders - class T(Structure): - _fields_ = [("a", c_int), - ("b", c_int)] - class S(base): - pass - self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)]) + # create nested structures with given byteorders and set memory to data + + for nested, data in ( + (BigEndianStructure, b'\0\0\0\1\0\0\0\2'), + (LittleEndianStructure, b'\1\0\0\0\2\0\0\0'), + ): + for parent in ( + BigEndianStructure, + LittleEndianStructure, + Structure, + ): + class NestedStructure(nested): + _fields_ = [("x", c_uint32), + ("y", c_uint32)] + + class TestStructure(parent): + _fields_ = [("point", NestedStructure)] + + self.assertEqual(len(data), sizeof(TestStructure)) + ptr = POINTER(TestStructure) + s = cast(data, ptr)[0] + del ctypes._pointer_type_cache[TestStructure] + self.assertEqual(s.point.x, 1) + self.assertEqual(s.point.y, 2) @xfail def test_struct_fields_2(self): diff --git a/lib-python/2.7/ctypes/test/test_callbacks.py b/lib-python/2.7/ctypes/test/test_callbacks.py --- a/lib-python/2.7/ctypes/test/test_callbacks.py +++ b/lib-python/2.7/ctypes/test/test_callbacks.py @@ -142,6 +142,14 @@ if isinstance(x, X)] self.assertEqual(len(live), 0) + def test_issue12483(self): + import gc + class Nasty: + def __del__(self): + gc.collect() + CFUNCTYPE(None)(lambda x=Nasty(): None) + + try: WINFUNCTYPE except NameError: diff --git a/lib-python/2.7/ctypes/test/test_functions.py b/lib-python/2.7/ctypes/test/test_functions.py --- a/lib-python/2.7/ctypes/test/test_functions.py +++ b/lib-python/2.7/ctypes/test/test_functions.py @@ -253,6 +253,7 @@ def test_callbacks(self): f = dll._testfunc_callback_i_if f.restype = c_int + f.argtypes = None MyCallback = CFUNCTYPE(c_int, c_int) diff --git a/lib-python/2.7/ctypes/test/test_structures.py b/lib-python/2.7/ctypes/test/test_structures.py --- a/lib-python/2.7/ctypes/test/test_structures.py +++ b/lib-python/2.7/ctypes/test/test_structures.py @@ -239,6 +239,14 @@ pass self.assertRaises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)]) + def test_invalid_name(self): + # field name must be string + def declare_with_name(name): + class S(Structure): + _fields_ = [(name, c_int)] + + self.assertRaises(TypeError, declare_with_name, u"x\xe9") + def test_intarray_fields(self): class SomeInts(Structure): _fields_ = [("a", c_int * 4)] @@ -324,6 +332,18 @@ else: self.assertEqual(msg, "(Phone) exceptions.TypeError: too many initializers") + def test_huge_field_name(self): + # issue12881: segfault with large structure field names + def create_class(length): + class S(Structure): + _fields_ = [('x' * length, c_int)] + + for length in [10 ** i for i in range(0, 8)]: + try: + create_class(length) + except MemoryError: + # MemoryErrors are OK, we just don't want to segfault + pass def get_except(self, func, *args): try: diff --git a/lib-python/2.7/ctypes/util.py b/lib-python/2.7/ctypes/util.py --- a/lib-python/2.7/ctypes/util.py +++ b/lib-python/2.7/ctypes/util.py @@ -182,28 +182,6 @@ else: - def _findLib_ldconfig(name): - # XXX assuming GLIBC's ldconfig (with option -p) - expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) - f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null') - try: - data = f.read() - finally: - f.close() - res = re.search(expr, data) - if not res: - # Hm, this works only for libs needed by the python executable. - cmd = 'ldd %s 2>/dev/null' % sys.executable - f = os.popen(cmd) - try: - data = f.read() - finally: - f.close() - res = re.search(expr, data) - if not res: - return None - return res.group(0) - def _findSoname_ldconfig(name): import struct if struct.calcsize('l') == 4: @@ -220,8 +198,7 @@ abi_type = mach_map.get(machine, 'libc6') # XXX assuming GLIBC's ldconfig (with option -p) - expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \ - % (abi_type, re.escape(name)) + expr = r'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type) f = os.popen('/sbin/ldconfig -p 2>/dev/null') try: data = f.read() diff --git a/lib-python/2.7/decimal.py b/lib-python/2.7/decimal.py --- a/lib-python/2.7/decimal.py +++ b/lib-python/2.7/decimal.py @@ -21,7 +21,7 @@ This is a Py2.3 implementation of decimal floating point arithmetic based on the General Decimal Arithmetic Specification: - www2.hursley.ibm.com/decimal/decarith.html + http://speleotrove.com/decimal/decarith.html and IEEE standard 854-1987: @@ -1942,9 +1942,9 @@ nonzero. For efficiency, other._exp should not be too large, so that 10**abs(other._exp) is a feasible calculation.""" - # In the comments below, we write x for the value of self and - # y for the value of other. Write x = xc*10**xe and y = - # yc*10**ye. + # In the comments below, we write x for the value of self and y for the + # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc + # and yc positive integers not divisible by 10. # The main purpose of this method is to identify the *failure* # of x**y to be exactly representable with as little effort as @@ -1952,13 +1952,12 @@ # eliminate the possibility of x**y being exact. Only if all # these tests are passed do we go on to actually compute x**y. - # Here's the main idea. First normalize both x and y. We - # express y as a rational m/n, with m and n relatively prime - # and n>0. Then for x**y to be exactly representable (at - # *any* precision), xc must be the nth power of a positive - # integer and xe must be divisible by n. If m is negative - # then additionally xc must be a power of either 2 or 5, hence - # a power of 2**n or 5**n. + # Here's the main idea. Express y as a rational number m/n, with m and + # n relatively prime and n>0. Then for x**y to be exactly + # representable (at *any* precision), xc must be the nth power of a + # positive integer and xe must be divisible by n. If y is negative + # then additionally xc must be a power of either 2 or 5, hence a power + # of 2**n or 5**n. # # There's a limit to how small |y| can be: if y=m/n as above # then: @@ -2030,21 +2029,43 @@ return None # now xc is a power of 2; e is its exponent e = _nbits(xc)-1 - # find e*y and xe*y; both must be integers - if ye >= 0: - y_as_int = yc*10**ye - e = e*y_as_int - xe = xe*y_as_int - else: - ten_pow = 10**-ye - e, remainder = divmod(e*yc, ten_pow) - if remainder: - return None - xe, remainder = divmod(xe*yc, ten_pow) - if remainder: - return None - - if e*65 >= p*93: # 93/65 > log(10)/log(5) + + # We now have: + # + # x = 2**e * 10**xe, e > 0, and y < 0. + # + # The exact result is: + # + # x**y = 5**(-e*y) * 10**(e*y + xe*y) + # + # provided that both e*y and xe*y are integers. Note that if + # 5**(-e*y) >= 10**p, then the result can't be expressed + # exactly with p digits of precision. + # + # Using the above, we can guard against large values of ye. + # 93/65 is an upper bound for log(10)/log(5), so if + # + # ye >= len(str(93*p//65)) + # + # then + # + # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), + # + # so 5**(-e*y) >= 10**p, and the coefficient of the result + # can't be expressed in p digits. + + # emax >= largest e such that 5**e < 10**p. + emax = p*93//65 + if ye >= len(str(emax)): + return None + + # Find -e*y and -xe*y; both must be integers + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: return None xc = 5**e @@ -2058,19 +2079,20 @@ while xc % 5 == 0: xc //= 5 e -= 1 - if ye >= 0: - y_as_integer = yc*10**ye - e = e*y_as_integer - xe = xe*y_as_integer - else: - ten_pow = 10**-ye - e, remainder = divmod(e*yc, ten_pow) - if remainder: - return None - xe, remainder = divmod(xe*yc, ten_pow) - if remainder: - return None - if e*3 >= p*10: # 10/3 > log(10)/log(2) + + # Guard against large values of ye, using the same logic as in + # the 'xc is a power of 2' branch. 10/3 is an upper bound for + # log(10)/log(2). + emax = p*10//3 + if ye >= len(str(emax)): + return None + + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: return None xc = 2**e else: @@ -5463,6 +5485,27 @@ hex_n = "%x" % n return 4*len(hex_n) - correction[hex_n[0]] +def _decimal_lshift_exact(n, e): + """ Given integers n and e, return n * 10**e if it's an integer, else None. + + The computation is designed to avoid computing large powers of 10 + unnecessarily. + + >>> _decimal_lshift_exact(3, 4) + 30000 + >>> _decimal_lshift_exact(300, -999999999) # returns None + + """ + if n == 0: + return 0 + elif e >= 0: + return n * 10**e + else: + # val_n = largest power of 10 dividing n. + str_n = str(abs(n)) + val_n = len(str_n) - len(str_n.rstrip('0')) + return None if val_n < -e else n // 10**-e + def _sqrt_nearest(n, a): """Closest integer to the square root of the positive integer n. a is an initial approximation to the square root. Any positive integer diff --git a/lib-python/2.7/distutils/__init__.py b/lib-python/2.7/distutils/__init__.py --- a/lib-python/2.7/distutils/__init__.py +++ b/lib-python/2.7/distutils/__init__.py @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "2.7.2" +__version__ = "2.7.3" #--end constants-- diff --git a/lib-python/2.7/distutils/ccompiler.py b/lib-python/2.7/distutils/ccompiler.py --- a/lib-python/2.7/distutils/ccompiler.py +++ b/lib-python/2.7/distutils/ccompiler.py @@ -18,58 +18,6 @@ from distutils.util import split_quoted, execute from distutils import log -_sysconfig = __import__('sysconfig') - -def customize_compiler(compiler): - """Do any platform-specific customization of a CCompiler instance. - - Mainly needed on Unix, so we can plug in the information that - varies across Unices and is stored in Python's Makefile. - """ - if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ - _sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO', 'AR', - 'ARFLAGS') - - if 'CC' in os.environ: - cc = os.environ['CC'] - if 'CXX' in os.environ: - cxx = os.environ['CXX'] - if 'LDSHARED' in os.environ: - ldshared = os.environ['LDSHARED'] - if 'CPP' in os.environ: - cpp = os.environ['CPP'] - else: - cpp = cc + " -E" # not always - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: - cflags = opt + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] - cflags = cflags + ' ' + os.environ['CPPFLAGS'] - ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - if 'AR' in os.environ: - ar = os.environ['AR'] - if 'ARFLAGS' in os.environ: - archiver = ar + ' ' + os.environ['ARFLAGS'] - else: - archiver = ar + ' ' + ar_flags - - cc_cmd = cc + ' ' + cflags - compiler.set_executables( - preprocessor=cpp, - compiler=cc_cmd, - compiler_so=cc_cmd + ' ' + ccshared, - compiler_cxx=cxx, - linker_so=ldshared, - linker_exe=cc, - archiver=archiver) - - compiler.shared_lib_extension = so_ext - class CCompiler: """Abstract base class to define the interface that must be implemented by real compiler classes. Also has some utility methods used by diff --git a/lib-python/2.7/distutils/command/bdist_dumb.py b/lib-python/2.7/distutils/command/bdist_dumb.py --- a/lib-python/2.7/distutils/command/bdist_dumb.py +++ b/lib-python/2.7/distutils/command/bdist_dumb.py @@ -58,7 +58,7 @@ self.format = None self.keep_temp = 0 self.dist_dir = None - self.skip_build = 0 + self.skip_build = None self.relative = 0 self.owner = None self.group = None @@ -78,7 +78,8 @@ self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'), - ('plat_name', 'plat_name')) + ('plat_name', 'plat_name'), + ('skip_build', 'skip_build')) def run(self): if not self.skip_build: diff --git a/lib-python/2.7/distutils/command/bdist_msi.py b/lib-python/2.7/distutils/command/bdist_msi.py --- a/lib-python/2.7/distutils/command/bdist_msi.py +++ b/lib-python/2.7/distutils/command/bdist_msi.py @@ -131,18 +131,22 @@ self.no_target_optimize = 0 self.target_version = None self.dist_dir = None - self.skip_build = 0 + self.skip_build = None self.install_script = None self.pre_install_script = None self.versions = None def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'msi') + short_version = get_python_version() if (not self.target_version) and self.distribution.has_ext_modules(): self.target_version = short_version + if self.target_version: self.versions = [self.target_version] if not self.skip_build and self.distribution.has_ext_modules()\ diff --git a/lib-python/2.7/distutils/command/bdist_wininst.py b/lib-python/2.7/distutils/command/bdist_wininst.py --- a/lib-python/2.7/distutils/command/bdist_wininst.py +++ b/lib-python/2.7/distutils/command/bdist_wininst.py @@ -71,7 +71,7 @@ self.dist_dir = None self.bitmap = None self.title = None - self.skip_build = 0 + self.skip_build = None self.install_script = None self.pre_install_script = None self.user_access_control = None @@ -80,6 +80,8 @@ def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + if self.bdist_dir is None: if self.skip_build and self.plat_name: # If build is skipped and plat_name is overridden, bdist will @@ -89,8 +91,10 @@ # next the command will be initialized using that name bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'wininst') + if not self.target_version: self.target_version = "" + if not self.skip_build and self.distribution.has_ext_modules(): short_version = get_python_version() if self.target_version and self.target_version != short_version: diff --git a/lib-python/2.7/distutils/command/build_clib.py b/lib-python/2.7/distutils/command/build_clib.py --- a/lib-python/2.7/distutils/command/build_clib.py +++ b/lib-python/2.7/distutils/command/build_clib.py @@ -19,7 +19,7 @@ import os from distutils.core import Command from distutils.errors import DistutilsSetupError -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler from distutils import log def show_compilers(): diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py --- a/lib-python/2.7/distutils/command/build_ext.py +++ b/lib-python/2.7/distutils/command/build_ext.py @@ -160,8 +160,7 @@ if plat_py_include != py_include: self.include_dirs.append(plat_py_include) - if isinstance(self.libraries, str): - self.libraries = [self.libraries] + self.ensure_string_list('libraries') # Life is easier if we're not forever checking for None, so # simplify these options to empty lists if unset diff --git a/lib-python/2.7/distutils/command/check.py b/lib-python/2.7/distutils/command/check.py --- a/lib-python/2.7/distutils/command/check.py +++ b/lib-python/2.7/distutils/command/check.py @@ -5,6 +5,7 @@ __revision__ = "$Id$" from distutils.core import Command +from distutils.dist import PKG_INFO_ENCODING from distutils.errors import DistutilsSetupError try: @@ -108,6 +109,8 @@ def check_restructuredtext(self): """Checks if the long string fields are reST-compliant.""" data = self.distribution.get_long_description() + if not isinstance(data, unicode): + data = data.decode(PKG_INFO_ENCODING) for warning in self._check_rst_data(data): line = warning[-1].get('line') if line is None: diff --git a/lib-python/2.7/distutils/command/config.py b/lib-python/2.7/distutils/command/config.py --- a/lib-python/2.7/distutils/command/config.py +++ b/lib-python/2.7/distutils/command/config.py @@ -16,7 +16,7 @@ from distutils.core import Command from distutils.errors import DistutilsExecError -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler from distutils import log LANG_EXT = {'c': '.c', 'c++': '.cxx'} diff --git a/lib-python/2.7/distutils/command/register.py b/lib-python/2.7/distutils/command/register.py --- a/lib-python/2.7/distutils/command/register.py +++ b/lib-python/2.7/distutils/command/register.py @@ -10,7 +10,6 @@ import urllib2 import getpass import urlparse -import StringIO from warnings import warn from distutils.core import PyPIRCCommand @@ -260,21 +259,30 @@ boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = '\n--' + boundary end_boundary = sep_boundary + '--' - body = StringIO.StringIO() + chunks = [] for key, value in data.items(): # handle multiple entries for the same name if type(value) not in (type([]), type( () )): value = [value] for value in value: - body.write(sep_boundary) - body.write('\nContent-Disposition: form-data; name="%s"'%key) - body.write("\n\n") - body.write(value) + chunks.append(sep_boundary) + chunks.append('\nContent-Disposition: form-data; name="%s"'%key) + chunks.append("\n\n") + chunks.append(value) if value and value[-1] == '\r': - body.write('\n') # write an extra newline (lurve Macs) - body.write(end_boundary) - body.write("\n") - body = body.getvalue() + chunks.append('\n') # write an extra newline (lurve Macs) + chunks.append(end_boundary) + chunks.append("\n") + + # chunks may be bytes (str) or unicode objects that we need to encode + body = [] + for chunk in chunks: + if isinstance(chunk, unicode): + body.append(chunk.encode('utf-8')) + else: + body.append(chunk) + + body = ''.join(body) # build the Request headers = { diff --git a/lib-python/2.7/distutils/command/sdist.py b/lib-python/2.7/distutils/command/sdist.py --- a/lib-python/2.7/distutils/command/sdist.py +++ b/lib-python/2.7/distutils/command/sdist.py @@ -182,14 +182,20 @@ reading the manifest, or just using the default file set -- it all depends on the user's options. """ - # new behavior: + # new behavior when using a template: # the file list is recalculated everytime because # even if MANIFEST.in or setup.py are not changed # the user might have added some files in the tree that # need to be included. # - # This makes --force the default and only behavior. + # This makes --force the default and only behavior with templates. template_exists = os.path.isfile(self.template) + if not template_exists and self._manifest_is_not_generated(): + self.read_manifest() + self.filelist.sort() + self.filelist.remove_duplicates() + return + if not template_exists: self.warn(("manifest template '%s' does not exist " + "(using default file list)") % @@ -314,7 +320,10 @@ try: self.filelist.process_template_line(line) - except DistutilsTemplateError, msg: + # the call above can raise a DistutilsTemplateError for + # malformed lines, or a ValueError from the lower-level + # convert_path function + except (DistutilsTemplateError, ValueError) as msg: self.warn("%s, line %d: %s" % (template.filename, template.current_line, msg)) @@ -352,23 +361,28 @@ by 'add_defaults()' and 'read_template()') to the manifest file named by 'self.manifest'. """ - if os.path.isfile(self.manifest): - fp = open(self.manifest) - try: - first_line = fp.readline() - finally: - fp.close() - - if first_line != '# file GENERATED by distutils, do NOT edit\n': - log.info("not writing to manually maintained " - "manifest file '%s'" % self.manifest) - return + if self._manifest_is_not_generated(): + log.info("not writing to manually maintained " + "manifest file '%s'" % self.manifest) + return content = self.filelist.files[:] content.insert(0, '# file GENERATED by distutils, do NOT edit') self.execute(file_util.write_file, (self.manifest, content), "writing manifest file '%s'" % self.manifest) + def _manifest_is_not_generated(self): + # check for special comment used in 2.7.1 and higher + if not os.path.isfile(self.manifest): + return False + + fp = open(self.manifest, 'rU') + try: + first_line = fp.readline() + finally: + fp.close() + return first_line != '# file GENERATED by distutils, do NOT edit\n' + def read_manifest(self): """Read the manifest file (named by 'self.manifest') and use it to fill in 'self.filelist', the list of files to include in the source @@ -376,12 +390,11 @@ """ log.info("reading manifest file '%s'", self.manifest) manifest = open(self.manifest) - while 1: - line = manifest.readline() - if line == '': # end of file - break - if line[-1] == '\n': - line = line[0:-1] + for line in manifest: + # ignore comments and blank lines + line = line.strip() + if line.startswith('#') or not line: + continue self.filelist.append(line) manifest.close() diff --git a/lib-python/2.7/distutils/dep_util.py b/lib-python/2.7/distutils/dep_util.py --- a/lib-python/2.7/distutils/dep_util.py +++ b/lib-python/2.7/distutils/dep_util.py @@ -7,6 +7,7 @@ __revision__ = "$Id$" import os +from stat import ST_MTIME from distutils.errors import DistutilsFileError def newer(source, target): @@ -27,7 +28,7 @@ if not os.path.exists(target): return True - return os.stat(source).st_mtime > os.stat(target).st_mtime + return os.stat(source)[ST_MTIME] > os.stat(target)[ST_MTIME] def newer_pairwise(sources, targets): """Walk two filename lists in parallel, testing if each source is newer @@ -71,7 +72,7 @@ # is more recent than 'target', then 'target' is out-of-date and # we can immediately return true. If we fall through to the end # of the loop, then 'target' is up-to-date and we return false. - target_mtime = os.stat(target).st_mtime + target_mtime = os.stat(target)[ST_MTIME] for source in sources: if not os.path.exists(source): @@ -82,7 +83,7 @@ elif missing == 'newer': # missing source means target is return True # out-of-date - if os.stat(source).st_mtime > target_mtime: + if os.stat(source)[ST_MTIME] > target_mtime: return True return False diff --git a/lib-python/2.7/distutils/dist.py b/lib-python/2.7/distutils/dist.py --- a/lib-python/2.7/distutils/dist.py +++ b/lib-python/2.7/distutils/dist.py @@ -1111,7 +1111,8 @@ """Write the PKG-INFO format data to a file object. """ version = '1.0' - if self.provides or self.requires or self.obsoletes: + if (self.provides or self.requires or self.obsoletes or + self.classifiers or self.download_url): version = '1.1' self._write_field(file, 'Metadata-Version', version) diff --git a/lib-python/2.7/distutils/filelist.py b/lib-python/2.7/distutils/filelist.py --- a/lib-python/2.7/distutils/filelist.py +++ b/lib-python/2.7/distutils/filelist.py @@ -210,6 +210,7 @@ Return 1 if files are found. """ + # XXX docstring lying about what the special chars are? files_found = 0 pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) self.debug_print("include_pattern: applying regex r'%s'" % @@ -297,11 +298,14 @@ # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, # and by extension they shouldn't match such "special characters" under # any OS. So change all non-escaped dots in the RE to match any - # character except the special characters. - # XXX currently the "special characters" are just slash -- i.e. this is - # Unix-only. - pattern_re = re.sub(r'((?\s*" manifest_buf = re.sub(pattern, "", manifest_buf) + # Now see if any other assemblies are referenced - if not, we + # don't want a manifest embedded. + pattern = re.compile( + r"""|)""", re.DOTALL) + if re.search(pattern, manifest_buf) is None: + return None + manifest_f = open(manifest_file, 'w') try: manifest_f.write(manifest_buf) + return manifest_file finally: manifest_f.close() except IOError: diff --git a/lib-python/2.7/distutils/spawn.py b/lib-python/2.7/distutils/spawn.py --- a/lib-python/2.7/distutils/spawn.py +++ b/lib-python/2.7/distutils/spawn.py @@ -96,17 +96,43 @@ raise DistutilsExecError, \ "command '%s' failed with exit status %d" % (cmd[0], rc) +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return exec_fn = search_path and os.execvp or os.execv + exec_args = [cmd[0], cmd] + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(cmd[0], cmd) + exec_fn(*exec_args) except OSError, e: sys.stderr.write("unable to execute %s: %s\n" % (cmd[0], e.strerror)) diff --git a/lib-python/2.7/distutils/sysconfig.py b/lib-python/2.7/distutils/sysconfig.py --- a/lib-python/2.7/distutils/sysconfig.py +++ b/lib-python/2.7/distutils/sysconfig.py @@ -26,4 +26,5 @@ from distutils.sysconfig_cpython import _config_vars # needed by setuptools from distutils.sysconfig_cpython import _variable_rx # read_setup_file() +_USE_CLANG = None diff --git a/lib-python/2.7/distutils/sysconfig_cpython.py b/lib-python/2.7/distutils/sysconfig_cpython.py --- a/lib-python/2.7/distutils/sysconfig_cpython.py +++ b/lib-python/2.7/distutils/sysconfig_cpython.py @@ -149,12 +149,43 @@ varies across Unices and is stored in Python's Makefile. """ if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \ + (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO') + 'CCSHARED', 'LDSHARED', 'SO', 'AR', + 'ARFLAGS') + newcc = None if 'CC' in os.environ: - cc = os.environ['CC'] + newcc = os.environ['CC'] + elif sys.platform == 'darwin' and cc == 'gcc-4.2': + # Issue #13590: + # Since Apple removed gcc-4.2 in Xcode 4.2, we can no + # longer assume it is available for extension module builds. + # If Python was built with gcc-4.2, check first to see if + # it is available on this system; if not, try to use clang + # instead unless the caller explicitly set CC. + global _USE_CLANG + if _USE_CLANG is None: + from distutils import log + from subprocess import Popen, PIPE + p = Popen("! type gcc-4.2 && type clang && exit 2", + shell=True, stdout=PIPE, stderr=PIPE) + p.wait() + if p.returncode == 2: + _USE_CLANG = True + log.warn("gcc-4.2 not found, using clang instead") + else: + _USE_CLANG = False + if _USE_CLANG: + newcc = 'clang' + if newcc: + # On OS X, if CC is overridden, use that as the default + # command for LDSHARED as well + if (sys.platform == 'darwin' + and 'LDSHARED' not in os.environ + and ldshared.startswith(cc)): + ldshared = newcc + ldshared[len(cc):] + cc = newcc if 'CXX' in os.environ: cxx = os.environ['CXX'] if 'LDSHARED' in os.environ: @@ -172,6 +203,12 @@ cpp = cpp + ' ' + os.environ['CPPFLAGS'] cflags = cflags + ' ' + os.environ['CPPFLAGS'] ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] + if 'AR' in os.environ: + ar = os.environ['AR'] + if 'ARFLAGS' in os.environ: + archiver = ar + ' ' + os.environ['ARFLAGS'] + else: + archiver = ar + ' ' + ar_flags cc_cmd = cc + ' ' + cflags compiler.set_executables( @@ -180,7 +217,8 @@ compiler_so=cc_cmd + ' ' + ccshared, compiler_cxx=cxx, linker_so=ldshared, - linker_exe=cc) + linker_exe=cc, + archiver=archiver) compiler.shared_lib_extension = so_ext @@ -380,21 +418,6 @@ raise DistutilsPlatformError(my_msg) - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target - elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')): - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. diff --git a/lib-python/2.7/distutils/tests/Setup.sample b/lib-python/2.7/distutils/tests/Setup.sample old mode 100755 new mode 100644 diff --git a/lib-python/2.7/distutils/tests/support.py b/lib-python/2.7/distutils/tests/support.py --- a/lib-python/2.7/distutils/tests/support.py +++ b/lib-python/2.7/distutils/tests/support.py @@ -1,7 +1,10 @@ """Support code for distutils test cases.""" import os +import sys import shutil import tempfile +import unittest +import sysconfig from copy import deepcopy import warnings @@ -9,6 +12,7 @@ from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL from distutils.core import Distribution + def capture_warnings(func): def _capture_warnings(*args, **kw): with warnings.catch_warnings(): @@ -16,6 +20,7 @@ return func(*args, **kw) return _capture_warnings + class LoggingSilencer(object): def setUp(self): @@ -49,6 +54,7 @@ def clear_logs(self): self.logs = [] + class TempdirManager(object): """Mix-in class that handles temporary directories for test cases. @@ -57,9 +63,13 @@ def setUp(self): super(TempdirManager, self).setUp() + self.old_cwd = os.getcwd() self.tempdirs = [] def tearDown(self): + # Restore working dir, for Solaris and derivatives, where rmdir() + # on the current directory fails. + os.chdir(self.old_cwd) super(TempdirManager, self).tearDown() while self.tempdirs: d = self.tempdirs.pop() @@ -105,6 +115,7 @@ return pkg_dir, dist + class DummyCommand: """Class to store options for retrieval via set_undefined_options().""" @@ -115,6 +126,7 @@ def ensure_finalized(self): pass + class EnvironGuard(object): def setUp(self): @@ -131,3 +143,79 @@ del os.environ[key] super(EnvironGuard, self).tearDown() + + +def copy_xxmodule_c(directory): From noreply at buildbot.pypy.org Sun Oct 21 18:51:31 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 18:51:31 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: Upgrade runner_test.py, which is still not resolved Message-ID: <20121021165131.84EE61C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: result-in-resops Changeset: r58325:e48674cd3c40 Date: 2012-10-21 18:51 +0200 http://bitbucket.org/pypy/pypy/changeset/e48674cd3c40/ Log: Upgrade runner_test.py, which is still not resolved diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -129,7 +129,7 @@ return loop.inputargs, loop.operations, JitCellToken() def test_compile_linear_loop(self): -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr = BasicFailDescr(1) inputargs, ops, token = self.parse(""" [i0] @@ -139,6 +139,18 @@ self.cpu.compile_loop(inputargs, ops, token) fail = self.cpu.execute_token(token, 2) res = self.cpu.get_latest_value_int(0) +||||||| /tmp/runner_test.py~base._aMykN + i0 = BoxInt() + i1 = BoxInt() + operations = [ + ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), + ResOperation(rop.FINISH, [i1], None, descr=BasicFailDescr(1)) + ] + inputargs = [i0] + looptoken = JitCellToken() + self.cpu.compile_loop(inputargs, operations, looptoken) + fail = self.cpu.execute_token(looptoken, 2) + res = self.cpu.get_latest_value_int(0) ======= i0 = BoxInt() i1 = BoxInt() @@ -151,7 +163,7 @@ self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 2) res = self.cpu.get_finish_value_int(frame) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI assert res == 3 assert self.cpu.get_latest_descr(frame).identifier == 1 @@ -201,15 +213,19 @@ """, namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py fail = self.cpu.execute_token(looptoken, 44) assert fail.identifier == 3 res = self.cpu.get_latest_value_int(2) +||||||| /tmp/runner_test.py~base._aMykN + fail = self.cpu.execute_token(looptoken, 44) + assert fail.identifier == 2 + res = self.cpu.get_latest_value_int(2) ======= frame = self.cpu.execute_token(looptoken, 44) assert self.cpu.get_latest_descr(frame).identifier == 2 res = self.cpu.get_latest_value_int(frame, 2) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI assert res == 10 def test_backends_dont_keep_loops_alive(self): @@ -261,15 +277,19 @@ self.cpu.compile_bridge(faildescr4, inputargs, bridge_ops, looptoken) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py fail = self.cpu.execute_token(looptoken, 2) assert fail.identifier == 5 res = self.cpu.get_latest_value_int(0) +||||||| /tmp/runner_test.py~base._aMykN + fail = self.cpu.execute_token(looptoken, 2) + assert fail.identifier == 2 + res = self.cpu.get_latest_value_int(0) ======= frame = self.cpu.execute_token(looptoken, 2) assert self.cpu.get_latest_descr(frame).identifier == 2 res = self.cpu.get_latest_value_int(frame, 0) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI assert res == 20 assert self.cpu.total_compiled_loops == 1 @@ -324,21 +344,27 @@ namespace=locals()) self.cpu.compile_bridge(faildescr1, inputargs, bridge, looptoken) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py fail = self.cpu.execute_token(looptoken, 1) assert fail.identifier == 2 +||||||| /tmp/runner_test.py~base._aMykN + fail = self.cpu.execute_token(looptoken, 1) + assert fail.identifier == 3 ======= frame = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_latest_descr(frame).identifier == 3 ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI for i in range(1000): -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py res = self.cpu.get_latest_value_int(i) assert res == 1 + i +||||||| /tmp/runner_test.py~base._aMykN + res = self.cpu.get_latest_value_int(i) + assert res == 2 + i ======= res = self.cpu.get_latest_value_int(frame, i) assert res == 2 + i ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI def test_get_latest_value_count(self): faildescr1 = BasicFailDescr(1) @@ -368,7 +394,7 @@ return AbstractFailDescr.__setattr__(self, name, value) py.test.fail("finish descrs should not be touched") faildescr = UntouchableFailDescr() # to check that is not touched -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py namespace = {'faildescr': faildescr} inputargs, operations, looptoken = self.parse(""" [i0] @@ -378,6 +404,15 @@ fail = self.cpu.execute_token(looptoken, 99) assert fail is faildescr res = self.cpu.get_latest_value_int(0) +||||||| /tmp/runner_test.py~base._aMykN + looptoken = JitCellToken() + operations = [ + ResOperation(rop.FINISH, [i0], None, descr=faildescr) + ] + self.cpu.compile_loop([i0], operations, looptoken) + fail = self.cpu.execute_token(looptoken, 99) + assert fail is faildescr + res = self.cpu.get_latest_value_int(0) ======= looptoken = JitCellToken() operations = [ @@ -387,10 +422,10 @@ frame = self.cpu.execute_token(looptoken, 99) assert self.cpu.get_latest_descr(frame) is faildescr res = self.cpu.get_finish_value_int(frame) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI assert res == 99 -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, looptoken = self.parse(""" [] finish(42, descr=faildescr) @@ -399,6 +434,15 @@ fail = self.cpu.execute_token(looptoken) assert fail is faildescr res = self.cpu.get_latest_value_int(0) +||||||| /tmp/runner_test.py~base._aMykN + looptoken = JitCellToken() + operations = [ + ResOperation(rop.FINISH, [ConstInt(42)], None, descr=faildescr) + ] + self.cpu.compile_loop([], operations, looptoken) + fail = self.cpu.execute_token(looptoken) + assert fail is faildescr + res = self.cpu.get_latest_value_int(0) ======= looptoken = JitCellToken() operations = [ @@ -408,7 +452,7 @@ frame = self.cpu.execute_token(looptoken) assert self.cpu.get_latest_descr(frame) is faildescr res = self.cpu.get_finish_value_int(frame) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI assert res == 42 _, operations, looptoken = self.parse(""" @@ -443,7 +487,7 @@ def test_execute_operations_in_env(self): cpu = self.cpu -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, looptoken = self.parse(""" [ix, iy] label(iy, ix, descr=targettoken) @@ -457,6 +501,28 @@ self.cpu.execute_token(looptoken, 0, 10) assert self.cpu.get_latest_value_int(0) == 0 assert self.cpu.get_latest_value_int(1) == 55 +||||||| /tmp/runner_test.py~base._aMykN + x = BoxInt(123) + y = BoxInt(456) + z = BoxInt(579) + t = BoxInt(455) + u = BoxInt(0) # False + looptoken = JitCellToken() + targettoken = TargetToken() + operations = [ + ResOperation(rop.LABEL, [y, x], None, descr=targettoken), + ResOperation(rop.INT_ADD, [x, y], z), + ResOperation(rop.INT_SUB, [y, ConstInt(1)], t), + ResOperation(rop.INT_EQ, [t, ConstInt(0)], u), + ResOperation(rop.GUARD_FALSE, [u], None, + descr=BasicFailDescr()), + ResOperation(rop.JUMP, [t, z], None, descr=targettoken), + ] + operations[-2].setfailargs([t, z]) + cpu.compile_loop([x, y], operations, looptoken) + res = self.cpu.execute_token(looptoken, 0, 10) + assert self.cpu.get_latest_value_int(0) == 0 + assert self.cpu.get_latest_value_int(1) == 55 ======= x = BoxInt(123) y = BoxInt(456) @@ -479,7 +545,7 @@ frame = self.cpu.execute_token(looptoken, 0, 10) assert self.cpu.get_latest_value_int(frame, 0) == 0 assert self.cpu.get_latest_value_int(frame, 1) == 55 ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI def test_int_operations(self): from pypy.jit.metainterp.test.test_executor import get_int_tests @@ -516,6 +582,7 @@ """ % op, namespace={'faildescr1': BasicFailDescr(1), 'faildescr2': BasicFailDescr(2)}) else: +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, looptoken = self.parse(""" [i1, i2] ires = %s(i1, i2) @@ -523,20 +590,16 @@ finish(descr=faildescr2) """ % op, namespace={'faildescr1': BasicFailDescr(1), 'faildescr2': BasicFailDescr(2)}) - # -<<<<<<< local - self.cpu.compile_loop(inputargs, operations, looptoken) -======= - if not reversed: +||||||| /tmp/runner_test.py~base._aMykN + v_exc = self.cpu.ts.BoxRef() ops = [ ResOperation(opnum, [v1, v2], v_res), - ResOperation(rop.GUARD_NO_OVERFLOW, [], None, + ResOperation(rop.GUARD_OVERFLOW, [], None, descr=BasicFailDescr(1)), - ResOperation(rop.FINISH, [v_res], None, - descr=BasicFailDescr(2)), + ResOperation(rop.FINISH, [], None, descr=BasicFailDescr(2)), ] - ops[1].setfailargs([]) - else: + ops[1].setfailargs([v_res]) +======= v_exc = BoxPtr() ops = [ ResOperation(opnum, [v1, v2], v_res), @@ -545,10 +608,9 @@ ResOperation(rop.FINISH, [], None, descr=BasicFailDescr(2)), ] ops[1].setfailargs([v_res]) +>>>>>>> /tmp/runner_test.py~other.b8EcdI # - looptoken = JitCellToken() - self.cpu.compile_loop([v1, v2], ops, looptoken) ->>>>>>> other + self.cpu.compile_loop(inputargs, operations, looptoken) for x, y, z in testcases: frame = self.cpu.execute_token(looptoken, x, y) if (z == boom) ^ reversed: @@ -648,11 +710,13 @@ EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) args = ([boxfloat(.1) for i in range(7)] + -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py [boxint(1), boxint(2), boxfloat(.2), boxfloat(.3), +||||||| /tmp/runner_test.py~base._aMykN + [BoxInt(1), BoxInt(2), boxfloat(.2), boxfloat(.3), ======= [BoxInt(1), boxfloat(.2), BoxInt(2), boxfloat(.3), ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI boxfloat(.4)]) res = self.execute_operation(rop.CALL_f, [funcbox] + args, @@ -1072,13 +1136,16 @@ 'void', descr=kdescr) f = self.cpu.bh_getinteriorfield_gc_f(a_box.getref_base(), 3, kdescr) assert longlong.getrealfloat(f) == 1.5 -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, kdescr, longlong.getfloatstorage(2.5)) r = self.execute_operation(rop.GETINTERIORFIELD_GC_f, [a_box, boxint(3)], +||||||| /tmp/runner_test.py~base._aMykN + self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, kdescr, longlong.getfloatstorage(2.5)) + r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], ======= self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, longlong.getfloatstorage(2.5), kdescr) r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI 'float', descr=kdescr) assert r == 2.5 # @@ -1116,19 +1183,25 @@ 'void', descr=pdescr) r = self.cpu.bh_getinteriorfield_gc_r(a_box.getref_base(), 4, pdescr) assert r == s_box.getref_base() -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, pdescr, s_box.getref_base()) r = self.execute_operation(rop.GETINTERIORFIELD_GC_r, [a_box, boxint(3)], +||||||| /tmp/runner_test.py~base._aMykN + self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, pdescr, + s_box.getref_base()) + r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], ======= self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, s_box.getref_base(), pdescr) r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI 'ref', descr=pdescr) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py assert r == s_box.getref_base() +||||||| /tmp/runner_test.py~base._aMykN + assert r.getref_base() == s_box.getref_base() ======= assert r.getref_base() == s_box.getref_base() # @@ -1138,7 +1211,7 @@ 'void', descr=vsdescr) r = self.cpu.bh_getinteriorfield_gc_i(a_box.getref_base(), 4, vsdescr) assert r == 4 ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI def test_string_basic(self): s_box = self.alloc_string("hello\xfe") @@ -1282,11 +1355,13 @@ retvalues.insert(kk, y) # operations.append( -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py create_resop(rop.FINISH, None, retboxes, descr=faildescr) +||||||| /tmp/runner_test.py~base._aMykN + ResOperation(rop.FINISH, retboxes, None, descr=faildescr) ======= ResOperation(rop.FINISH, [], None, descr=faildescr) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI ) operations[-1].setfailargs(retboxes) print inputargs @@ -1298,13 +1373,16 @@ assert self.cpu.get_latest_descr(frame).identifier == 42 # for k in range(len(retvalues)): -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py if retboxes[k].type == 'i': got = self.cpu.get_latest_value_int(k) +||||||| /tmp/runner_test.py~base._aMykN + if isinstance(retboxes[k], BoxInt): + got = self.cpu.get_latest_value_int(k) ======= if isinstance(retboxes[k], BoxInt): got = self.cpu.get_latest_value_int(frame, k) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI else: got = self.cpu.get_latest_value_float(frame, k) assert got == retvalues[k] @@ -1372,13 +1450,16 @@ assert 0 values[index_counter] = 11 # -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py fail = self.cpu.execute_token(looptoken, *values) assert fail.identifier == 1 +||||||| /tmp/runner_test.py~base._aMykN + fail = self.cpu.execute_token(looptoken, *values) + assert fail.identifier == 15 ======= frame = self.cpu.execute_token(looptoken, *values) assert self.cpu.get_latest_descr(frame).identifier == 15 ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI # dstvalues = values[:] for _ in range(11): @@ -1390,19 +1471,25 @@ # assert dstvalues[index_counter] == 11 dstvalues[index_counter] = 0 -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py for i, (box, val) in enumerate(zip(inpargs, dstvalues)): if isinstance(box, boxint): got = self.cpu.get_latest_value_int(i) elif isinstance(box, boxptr): got = self.cpu.get_latest_value_ref(i) +||||||| /tmp/runner_test.py~base._aMykN + for i, (box, val) in enumerate(zip(inputargs, dstvalues)): + if isinstance(box, BoxInt): + got = self.cpu.get_latest_value_int(i) + elif isinstance(box, BoxPtr): + got = self.cpu.get_latest_value_ref(i) ======= for i, (box, val) in enumerate(zip(inputargs, dstvalues)): if isinstance(box, BoxInt): got = self.cpu.get_latest_value_int(frame, i) elif isinstance(box, BoxPtr): got = self.cpu.get_latest_value_ref(frame, i) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI elif isinstance(box, BoxFloat): got = self.cpu.get_latest_value_float(frame, i) else: @@ -1416,7 +1503,7 @@ fboxes = "f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11" faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py targettoken = TargetToken() inputargs, operations, looptoken = self.parse(""" [%(fboxes)s] @@ -1428,6 +1515,16 @@ 'faildescr2': faildescr2, 'targettoken': targettoken}) self.cpu.compile_loop(inputargs, operations, looptoken) +||||||| /tmp/runner_test.py~base._aMykN + operations = [ + ResOperation(rop.LABEL, fboxes, None, descr=targettoken), + ResOperation(rop.FLOAT_LE, [fboxes[0], constfloat(9.2)], i2), + ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1), + ResOperation(rop.FINISH, fboxes, None, descr=faildescr2), + ] + operations[-2].setfailargs(fboxes) + looptoken = JitCellToken() + self.cpu.compile_loop(fboxes, operations, looptoken) ======= operations = [ ResOperation(rop.LABEL, fboxes, None, descr=targettoken), @@ -1439,7 +1536,7 @@ operations[-1].setfailargs(fboxes) looptoken = JitCellToken() self.cpu.compile_loop(fboxes, operations, looptoken) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI inputargs, operations, _ = self.parse(""" [%s] @@ -1457,13 +1554,16 @@ assert self.cpu.get_latest_descr(frame).identifier == 2 res = self.cpu.get_latest_value_float(frame, 0) assert longlong.getrealfloat(res) == 8.5 -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py for i in range(1, len(fboxes.split(","))): got = longlong.getrealfloat(self.cpu.get_latest_value_float(i)) +||||||| /tmp/runner_test.py~base._aMykN + for i in range(1, len(fboxes)): + got = longlong.getrealfloat(self.cpu.get_latest_value_float(i)) ======= for i in range(1, len(fboxes)): got = longlong.getrealfloat(self.cpu.get_latest_value_float(frame, i)) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI assert got == 13.5 + 6.73 * i def test_compile_bridge_spilled_float(self): @@ -1975,14 +2075,15 @@ assert res == -19 def test_convert_float_bytes(self): -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py box = boxfloat(2.5) +||||||| /tmp/runner_test.py~base._aMykN ======= if not self.cpu.supports_floats: py.test.skip("requires floats") if not self.cpu.supports_longlong: py.test.skip("longlong test") ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI t = 'int' if longlong.is_64_bit else 'float' res = self.execute_operation(rop.CONVERT_FLOAT_BYTES_TO_LONGLONG, [box], t) @@ -2041,13 +2142,16 @@ assert s.parent.chr2 == chr(150) r = self.cpu.bh_getfield_gc_i(r1, descrshort) assert r == 1313 -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py self.cpu.bh_setfield_gc_i(r1, descrshort, 1333) r = self.cpu.bh_getfield_gc_i(r1, descrshort) +||||||| /tmp/runner_test.py~base._aMykN + self.cpu.bh_setfield_gc_i(r1.value, descrshort, 1333) + r = self.cpu.bh_getfield_gc_i(r1.value, descrshort) ======= self.cpu.bh_setfield_gc_i(r1.value, 1333, descrshort) r = self.cpu.bh_getfield_gc_i(r1.value, descrshort) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI assert r == 1333 r = self.execute_operation(rop.GETFIELD_GC_i, [boxptr(r1)], 'int', descr=descrshort) @@ -2090,17 +2194,22 @@ ops = ''' [i0] -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py i1 = same_as_i(1) call_n(ConstClass(fptr), i0, descr=calldescr) p0 = guard_exception(ConstClass(xtp), descr=faildescr2) [i1] finish(0, p0, descr=faildescr1) +||||||| /tmp/runner_test.py~base._aMykN + i1 = same_as(1) + call(ConstClass(fptr), i0, descr=calldescr) + p0 = guard_exception(ConstClass(xtp)) [i1] + finish(0, p0) ======= i1 = same_as(1) call(ConstClass(fptr), i0, descr=calldescr) p0 = guard_exception(ConstClass(xtp)) [i1] finish(p0) [] ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI ''' FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) fptr = llhelper(FPTR, func) @@ -2152,17 +2261,22 @@ exc_ptr = xptr ops = ''' [i0] -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py i1 = same_as_i(1) call_n(ConstClass(fptr), i0, descr=calldescr) guard_no_exception(descr=faildescr1) [i1] finish(0, descr=faildescr2) +||||||| /tmp/runner_test.py~base._aMykN + i1 = same_as(1) + call(ConstClass(fptr), i0, descr=calldescr) + guard_no_exception() [i1] + finish(0) ======= i1 = same_as(1) call(ConstClass(fptr), i0, descr=calldescr) guard_no_exception() [i1] finish(-100) [] ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI ''' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() @@ -2343,14 +2457,18 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) cpu = self.cpu -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py +||||||| /tmp/runner_test.py~base._aMykN + i0 = BoxInt() + i1 = BoxInt() + tok = BoxInt() ======= i0 = BoxInt() i1 = BoxInt() tok = BoxPtr() ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI faildescr = BasicFailDescr(1) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr0 = BasicFailDescr(0) inputargs, operations, looptoken = self.parse(""" [i0, i1] @@ -2363,6 +2481,20 @@ fail = self.cpu.execute_token(looptoken, 20, 0) assert fail.identifier == 0 assert self.cpu.get_latest_value_int(0) == 20 +||||||| /tmp/runner_test.py~base._aMykN + ops = [ + ResOperation(rop.FORCE_TOKEN, [], tok), + ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], None, + descr=calldescr), + ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), + ResOperation(rop.FINISH, [i0], None, descr=BasicFailDescr(0)) + ] + ops[2].setfailargs([i1, i0]) + looptoken = JitCellToken() + self.cpu.compile_loop([i0, i1], ops, looptoken) + fail = self.cpu.execute_token(looptoken, 20, 0) + assert fail.identifier == 0 + assert self.cpu.get_latest_value_int(0) == 20 ======= ops = [ ResOperation(rop.JIT_FRAME, [], tok), @@ -2377,7 +2509,7 @@ frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 assert self.cpu.get_finish_value_int(frame) == 20 ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI assert values == [] frame = self.cpu.execute_token(looptoken, 10, 1) @@ -2402,16 +2534,21 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) cpu = self.cpu -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr0 = BasicFailDescr(0) +||||||| /tmp/runner_test.py~base._aMykN + i0 = BoxInt() + i1 = BoxInt() + i2 = BoxInt() + tok = BoxInt() ======= i0 = BoxInt() i1 = BoxInt() i2 = BoxInt() tok = BoxPtr() ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI faildescr = BasicFailDescr(1) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, ops, looptoken = self.parse(""" [i0, i1] itok = force_token() @@ -2423,6 +2560,20 @@ fail = self.cpu.execute_token(looptoken, 20, 0) assert fail.identifier == 0 assert self.cpu.get_latest_value_int(0) == 42 +||||||| /tmp/runner_test.py~base._aMykN + ops = [ + ResOperation(rop.FORCE_TOKEN, [], tok), + ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], i2, + descr=calldescr), + ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), + ResOperation(rop.FINISH, [i2], None, descr=BasicFailDescr(0)) + ] + ops[2].setfailargs([i1, i2, i0]) + looptoken = JitCellToken() + self.cpu.compile_loop([i0, i1], ops, looptoken) + fail = self.cpu.execute_token(looptoken, 20, 0) + assert fail.identifier == 0 + assert self.cpu.get_latest_value_int(0) == 42 ======= ops = [ ResOperation(rop.JIT_FRAME, [], tok), @@ -2437,7 +2588,7 @@ frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 assert self.cpu.get_finish_value_int(frame) == 42 ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI assert values == [] frame = self.cpu.execute_token(looptoken, 10, 1) @@ -2464,15 +2615,20 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) cpu = self.cpu -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py +||||||| /tmp/runner_test.py~base._aMykN + i0 = BoxInt() + i1 = BoxInt() + f2 = BoxFloat() + tok = BoxInt() ======= i0 = BoxInt() i1 = BoxInt() f2 = BoxFloat() tok = BoxPtr() ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI faildescr = BasicFailDescr(1) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr0 = BasicFailDescr(0) inputargs, ops, looptoken = self.parse(""" [i0, i1] @@ -2485,6 +2641,20 @@ fail = self.cpu.execute_token(looptoken, 20, 0) assert fail.identifier == 0 x = self.cpu.get_latest_value_float(0) +||||||| /tmp/runner_test.py~base._aMykN + ops = [ + ResOperation(rop.FORCE_TOKEN, [], tok), + ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], f2, + descr=calldescr), + ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), + ResOperation(rop.FINISH, [f2], None, descr=BasicFailDescr(0)) + ] + ops[2].setfailargs([i1, f2, i0]) + looptoken = JitCellToken() + self.cpu.compile_loop([i0, i1], ops, looptoken) + fail = self.cpu.execute_token(looptoken, 20, 0) + assert fail.identifier == 0 + x = self.cpu.get_latest_value_float(0) ======= ops = [ ResOperation(rop.JIT_FRAME, [], tok), @@ -2499,7 +2669,7 @@ frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 x = self.cpu.get_finish_value_float(frame) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI assert longlong.getrealfloat(x) == 42.5 assert values == [] @@ -2537,13 +2707,17 @@ cpu = self.cpu func_adr = c_tolower.funcsym calldescr = cpu._calldescr_dynamic_for_tests([types.uchar], types.sint) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py +||||||| /tmp/runner_test.py~base._aMykN + i1 = BoxInt() + i2 = BoxInt() + tok = BoxInt() ======= i1 = BoxInt() i2 = BoxInt() ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI faildescr = BasicFailDescr(1) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr0 = BasicFailDescr(0) inputargs, operations, looptoken = self.parse(""" [i1] @@ -2555,6 +2729,19 @@ fail = self.cpu.execute_token(looptoken, ord('G')) assert fail.identifier == 0 assert self.cpu.get_latest_value_int(0) == ord('g') +||||||| /tmp/runner_test.py~base._aMykN + ops = [ + ResOperation(rop.CALL_RELEASE_GIL, [funcbox, i1], i2, + descr=calldescr), + ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), + ResOperation(rop.FINISH, [i2], None, descr=BasicFailDescr(0)) + ] + ops[1].setfailargs([i1, i2]) + looptoken = JitCellToken() + self.cpu.compile_loop([i1], ops, looptoken) + fail = self.cpu.execute_token(looptoken, ord('G')) + assert fail.identifier == 0 + assert self.cpu.get_latest_value_int(0) == ord('g') ======= ops = [ ResOperation(rop.CALL_RELEASE_GIL, [funcbox, i1], i2, @@ -2568,7 +2755,7 @@ frame = self.cpu.execute_token(looptoken, ord('G')) assert self.cpu.get_latest_descr(frame).identifier == 0 assert self.cpu.get_finish_value_int(frame) == ord('g') ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI def test_call_to_c_function_with_callback(self): from pypy.rlib.libffi import CDLL, types, ArgChain, clibffi @@ -2607,13 +2794,19 @@ calldescr = cpu._calldescr_dynamic_for_tests( [types.pointer, types_size_t, types_size_t, types.pointer], types.void) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py +||||||| /tmp/runner_test.py~base._aMykN + i0 = BoxInt() + i1 = BoxInt() + i2 = BoxInt() + i3 = BoxInt() + tok = BoxInt() ======= i0 = BoxInt() i1 = BoxInt() i2 = BoxInt() i3 = BoxInt() ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI faildescr = BasicFailDescr(1) faildescr0 = BasicFailDescr(0) inputargs, ops, looptoken = self.parse(""" @@ -2744,7 +2937,7 @@ # the guard, jumping to the label will hit the invalidation code too faildescr = BasicFailDescr(1) labeldescr = TargetToken() -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr3 = BasicFailDescr(3) inputargs, ops, looptoken = self.parse(""" [i0] @@ -2753,6 +2946,15 @@ finish(i0, descr=faildescr3) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) +||||||| /tmp/runner_test.py~base._aMykN + ops = [ + ResOperation(rop.GUARD_NOT_INVALIDATED, [], None, descr=faildescr), + ResOperation(rop.LABEL, [i0], None, descr=labeldescr), + ResOperation(rop.FINISH, [i0], None, descr=BasicFailDescr(3)), + ] + ops[0].setfailargs([]) + looptoken = JitCellToken() + self.cpu.compile_loop([i0], ops, looptoken) ======= finishdescr = BasicFailDescr(3) ops = [ @@ -2763,7 +2965,7 @@ ops[0].setfailargs([]) looptoken = JitCellToken() self.cpu.compile_loop([i0], ops, looptoken) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI # mark as failing self.cpu.invalidate_loop(looptoken) # attach a bridge @@ -2973,14 +3175,17 @@ i16 = int_add(i15, i7) i17 = int_add(i16, i8) i18 = int_add(i17, i9) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py finish(i18, descr=faildescr1)''' loop = parse(ops, namespace={'faildescr1': BasicFailDescr(1)}) +||||||| /tmp/runner_test.py~base._aMykN + finish(i18)''' + loop = parse(ops) ======= finish(i18) []''' loop = parse(ops) loop.operations[-1].getdescr().fast_path_done = True ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() fail_number = self.cpu.get_fail_descr_number( @@ -2997,15 +3202,19 @@ ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] i10 = int_add(i0, 42) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py i11 = call_assembler_i(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, descr=looptoken) guard_not_forced(descr=faildescr1)[] finish(i11, descr=faildescr2) +||||||| /tmp/runner_test.py~base._aMykN + i11 = call_assembler(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, descr=looptoken) + guard_not_forced()[] + finish(i11) ======= i11 = call_assembler(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, descr=looptoken) guard_not_forced()[] finish(i11) [] ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI ''' faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) @@ -3055,17 +3264,21 @@ i0 = float_eq(f0, -1.0) guard_false(i0) [] f2 = float_add(f0, f1) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py finish(f2, descr=faildescr)''' loop = parse(ops, namespace={'faildescr': BasicFailDescr(1)}) done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr()) +||||||| /tmp/runner_test.py~base._aMykN + finish(f2)''' + loop = parse(ops) + done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr()) ======= finish(f2) []''' loop = parse(ops) loop.operations[-1].getdescr().fast_path_done = True fail_number = self.cpu.get_fail_descr_number( loop.operations[1].getdescr()) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) @@ -3076,15 +3289,19 @@ assert longlong.getrealfloat(x) == 1.2 + 2.3 ops = ''' [f4, f5] -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py f3 = call_assembler_f(f4, f5, descr=looptoken) guard_not_forced(descr=faildescr1)[] finish(f3, descr=faildescr2) +||||||| /tmp/runner_test.py~base._aMykN + f3 = call_assembler(f4, f5, descr=looptoken) + guard_not_forced()[] + finish(f3) ======= f3 = call_assembler(f4, f5, descr=looptoken) guard_not_forced()[] finish(f3) [] ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI ''' faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) @@ -3214,14 +3431,17 @@ i0 = float_eq(f0, -1.0) guard_false(i0) [] f2 = float_add(f0, f1) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py finish(f2, descr=faildescr1)''' loop = parse(ops, namespace={'faildescr1': BasicFailDescr(1)}) +||||||| /tmp/runner_test.py~base._aMykN + finish(f2)''' + loop = parse(ops) ======= finish(f2) []''' loop = parse(ops) loop.operations[-1].getdescr().fast_path_done = True ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) @@ -3236,15 +3456,19 @@ ops = ''' [f4, f5] -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py f3 = call_assembler_f(f4, f5, descr=looptoken) guard_not_forced(descr=faildescr1)[] finish(f3, descr=faildescr2) +||||||| /tmp/runner_test.py~base._aMykN + f3 = call_assembler(f4, f5, descr=looptoken) + guard_not_forced()[] + finish(f3) ======= f3 = call_assembler(f4, f5, descr=looptoken) guard_not_forced()[] finish(f3) [] ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI ''' faildescr2 = BasicFailDescr(2) faildescr1 = BasicFailDescr(1) @@ -3273,14 +3497,17 @@ i0 = float_eq(f0, -2.0) guard_false(i0) [] f2 = float_sub(f0, f1) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py finish(f2, descr=faildescr)''' loop = parse(ops, namespace={'faildescr': BasicFailDescr(1)}) +||||||| /tmp/runner_test.py~base._aMykN + finish(f2)''' + loop = parse(ops) ======= finish(f2) []''' loop2 = parse(ops2) loop2.operations[-1].getdescr().fast_path_done = True ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI looptoken2 = JitCellToken() looptoken2.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) @@ -3703,13 +3930,20 @@ res = self.cpu.get_latest_value_int(frame, 0) assert res == 10 -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, _ = self.parse(""" [i0] i2 = int_sub(i0, 20) jump(i2, descr=targettoken2) """, locals()) self.cpu.compile_bridge(faildescr, inputargs, operations, looptoken) +||||||| /tmp/runner_test.py~base._aMykN + inputargs = [i0] + operations = [ + ResOperation(rop.INT_SUB, [i0, ConstInt(20)], i2), + ResOperation(rop.JUMP, [i2], None, descr=targettoken2), + ] + self.cpu.compile_bridge(faildescr, inputargs, operations, looptoken) ======= inputargs2 = [i0] operations2 = [ @@ -3717,7 +3951,7 @@ ResOperation(rop.JUMP, [i2], None, descr=targettoken2), ] self.cpu.compile_bridge(faildescr, inputargs2, operations2, looptoken) ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI frame = self.cpu.execute_token(looptoken, 2) assert self.cpu.get_latest_descr(frame).identifier == 3 @@ -3728,11 +3962,13 @@ ops = """ [i0] i1 = int_force_ge_zero(i0) # but forced to be in a register -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py finish(i1, descr=faildescr1) +||||||| /tmp/runner_test.py~base._aMykN + finish(i1, descr=1) ======= finish(i1, descr=1) [] ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI """ faildescr1 = BasicFailDescr(1) loop = parse(ops, self.cpu, namespace=locals()) @@ -3825,7 +4061,7 @@ cpu = self.cpu calldescr = cpu.calldescrof(deref(FPTR), (lltype.Signed,)*9, lltype.Void, EffectInfo.MOST_GENERAL) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, looptoken = self.parse(""" [i0] label(i0, descr=targettoken1) @@ -3855,6 +4091,46 @@ jump(i19, descr=targettoken1) """, locals()) self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken1) +||||||| /tmp/runner_test.py~base._aMykN + funcbox = self.get_funcbox(cpu, func_ptr) + + i0 = BoxInt(); i1 = BoxInt(); i2 = BoxInt(); i3 = BoxInt(); i4 = BoxInt() + i5 = BoxInt(); i6 = BoxInt(); i7 = BoxInt(); i8 = BoxInt(); i9 = BoxInt() + i10 = BoxInt(); i11 = BoxInt(); i12 = BoxInt(); i13 = BoxInt(); i14 = BoxInt() + i15 = BoxInt(); i16 = BoxInt(); i17 = BoxInt(); i18 = BoxInt(); i19 = BoxInt() + i20 = BoxInt() + inputargs = [i0] + operations = [ + ResOperation(rop.LABEL, [i0], None, descr=targettoken1), + ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), + ResOperation(rop.INT_ADD, [i1, ConstInt(1)], i2), + ResOperation(rop.INT_ADD, [i2, ConstInt(1)], i3), + ResOperation(rop.INT_ADD, [i3, ConstInt(1)], i4), + ResOperation(rop.INT_ADD, [i4, ConstInt(1)], i5), + ResOperation(rop.INT_ADD, [i5, ConstInt(1)], i6), + ResOperation(rop.INT_ADD, [i6, ConstInt(1)], i7), + ResOperation(rop.INT_ADD, [i7, ConstInt(1)], i8), + ResOperation(rop.INT_ADD, [i8, ConstInt(1)], i9), + ResOperation(rop.INT_ADD, [i9, ConstInt(1)], i10), + ResOperation(rop.INT_ADD, [i10, ConstInt(1)], i11), + ResOperation(rop.INT_ADD, [i11, ConstInt(1)], i12), + ResOperation(rop.INT_ADD, [i12, ConstInt(1)], i13), + ResOperation(rop.INT_ADD, [i13, ConstInt(1)], i14), + ResOperation(rop.INT_ADD, [i14, ConstInt(1)], i15), + ResOperation(rop.INT_ADD, [i15, ConstInt(1)], i16), + ResOperation(rop.INT_ADD, [i16, ConstInt(1)], i17), + ResOperation(rop.INT_ADD, [i17, ConstInt(1)], i18), + ResOperation(rop.INT_ADD, [i18, ConstInt(1)], i19), + ResOperation(rop.CALL, [funcbox, i2, i4, i6, i8, i10, i12, i14, i16, i18], + None, descr=calldescr), + ResOperation(rop.CALL, [funcbox, i2, i4, i6, i8, i10, i12, i14, i16, i18], + None, descr=calldescr), + ResOperation(rop.INT_LT, [i19, ConstInt(100)], i20), + ResOperation(rop.GUARD_TRUE, [i20], None, descr=BasicFailDescr(42)), + ResOperation(rop.JUMP, [i19], None, descr=targettoken1), + ] + operations[-2].setfailargs([]) + self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken1) ======= funcbox = self.get_funcbox(cpu, func_ptr) @@ -3896,14 +4172,21 @@ operations2[-2].setfailargs([]) self.cpu.compile_bridge(faildescr1, inputargs2, operations2, looptoken1) ->>>>>>> other - -<<<<<<< local +>>>>>>> /tmp/runner_test.py~other.b8EcdI + +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, looptoken2 = self.parse(""" [i0] jump(0, descr=targettoken1) """, locals()) self.cpu.compile_loop(inputargs, operations, looptoken2) +||||||| /tmp/runner_test.py~base._aMykN + looptoken2 = JitCellToken() + inputargs = [BoxInt()] + operations = [ + ResOperation(rop.JUMP, [ConstInt(0)], None, descr=targettoken1), + ] + self.cpu.compile_loop(inputargs, operations, looptoken2) ======= looptoken2 = JitCellToken() inputargs3 = [BoxInt()] @@ -3911,15 +4194,18 @@ ResOperation(rop.JUMP, [ConstInt(0)], None, descr=targettoken1), ] self.cpu.compile_loop(inputargs3, operations3, looptoken2) ->>>>>>> other - -<<<<<<< local + + frame = self.cpu.execute_token(looptoken2, -9) + assert self.cpu.get_latest_descr(frame).identifier == 42 +>>>>>>> /tmp/runner_test.py~other.b8EcdI + +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py fail = self.cpu.execute_token(looptoken2, -9) assert fail.identifier == 1 +||||||| /tmp/runner_test.py~base._aMykN + fail = self.cpu.execute_token(looptoken2, -9) + assert fail.identifier == 42 ======= - frame = self.cpu.execute_token(looptoken2, -9) - assert self.cpu.get_latest_descr(frame).identifier == 42 - def test_wrong_guard_nonnull_class(self): t_box, T_box = self.alloc_instance(self.T) null_box = self.null_instance() @@ -3938,7 +4224,7 @@ self.cpu.compile_bridge(faildescr, [], operations, looptoken) frame = self.cpu.execute_token(looptoken, null_box.getref_base()) assert self.cpu.get_latest_descr(frame).identifier == 99 ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI def test_raw_load_int(self): from pypy.rlib import rawstorage @@ -3948,13 +4234,16 @@ rffi.ULONG, rffi.LONG]: ops = """ [i0, i1] -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py i2 = raw_load_i(i0, i1, descr=arraydescr) finish(i2, descr=faildescr1) +||||||| /tmp/runner_test.py~base._aMykN + i2 = raw_load(i0, i1, descr=arraydescr) + finish(i2) ======= i2 = raw_load(i0, i1, descr=arraydescr) finish(i2) [] ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -3979,13 +4268,16 @@ for T in [rffi.DOUBLE]: ops = """ [i0, i1] -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py f2 = raw_load_f(i0, i1, descr=arraydescr) finish(f2, descr=faildescr1) +||||||| /tmp/runner_test.py~base._aMykN + f2 = raw_load(i0, i1, descr=arraydescr) + finish(f2) ======= f2 = raw_load(i0, i1, descr=arraydescr) finish(f2) [] ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -4013,11 +4305,13 @@ ops = """ [i0, i1, i2] raw_store(i0, i1, i2, descr=arraydescr) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py finish(descr=faildescr1) +||||||| /tmp/runner_test.py~base._aMykN + finish() ======= finish() [] ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -4042,11 +4336,13 @@ ops = """ [i0, i1, f2] raw_store(i0, i1, f2, descr=arraydescr) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py finish(descr=faildescr1) +||||||| /tmp/runner_test.py~base._aMykN + finish() ======= finish() [] ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -4063,7 +4359,50 @@ result = rawstorage.raw_storage_getitem(T, p, 16) assert result == rffi.cast(T, value) rawstorage.free_raw_storage(p) -<<<<<<< local +<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py +||||||| /tmp/runner_test.py~base._aMykN + +class OOtypeBackendTest(BaseBackendTest): + + type_system = 'ootype' + Ptr = staticmethod(lambda x: x) + FuncType = ootype.StaticMethod + malloc = staticmethod(ootype.new) + nullptr = staticmethod(ootype.null) + + def setup_class(cls): + py.test.skip("ootype tests skipped") + + @classmethod + def get_funcbox(cls, cpu, func_ptr): + return BoxObj(ootype.cast_to_object(func_ptr)) + + S = ootype.Instance('S', ootype.ROOT, {'value': ootype.Signed, + 'chr1': ootype.Char, + 'chr2': ootype.Char}) + S._add_fields({'next': S}) + T = ootype.Instance('T', S) + U = ootype.Instance('U', T) + + def alloc_instance(self, T): + t = ootype.new(T) + cls = ootype.classof(t) + t_box = BoxObj(ootype.cast_to_object(t)) + T_box = ConstObj(ootype.cast_to_object(cls)) + return t_box, T_box + + def null_instance(self): + return BoxObj(ootype.NULL) + + def alloc_array_of(self, ITEM, length): + py.test.skip("implement me") + + def alloc_string(self, string): + py.test.skip("implement me") + + def alloc_unicode(self, unicode): + py.test.skip("implement me") + ======= def test_forcing_op_with_fail_arg_in_reg(self): @@ -4143,4 +4482,4 @@ def alloc_unicode(self, unicode): py.test.skip("implement me") ->>>>>>> other +>>>>>>> /tmp/runner_test.py~other.b8EcdI From noreply at buildbot.pypy.org Sun Oct 21 19:09:33 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 21 Oct 2012 19:09:33 +0200 (CEST) Subject: [pypy-commit] pypy.org extradoc: update my profile pic Message-ID: <20121021170933.3873A1C0012@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r365:7543ac70ba00 Date: 2012-10-21 19:09 +0200 http://bitbucket.org/pypy/pypy.org/changeset/7543ac70ba00/ Log: update my profile pic diff --git a/image/people/fijal.jpg b/image/people/fijal.jpg index 150ca884fb0ab1ae82bed3c8cfa8e7fdc0bc3c3a..b12d616026c2403e4e4bfa3f0d03b7d24f926801 GIT binary patch [cut] From noreply at buildbot.pypy.org Sun Oct 21 19:11:59 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 19:11:59 +0200 (CEST) Subject: [pypy-commit] pypy default: Add a test for DUP_TOPX Message-ID: <20121021171159.7157E1C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58326:4aec0e991a07 Date: 2012-10-21 19:11 +0200 http://bitbucket.org/pypy/pypy/changeset/4aec0e991a07/ Log: Add a test for DUP_TOPX diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1126,6 +1126,14 @@ with py.test.raises(FlowingError): self.codetest(f) + def test_aug_assign(self): + # test for DUP_TOPX + lst = [2, 3, 4] + def f(x, y): + lst[x] += y + graph = self.codetest(f) + assert self.all_operations(graph) == {'xxx': 1} + DATA = {'x': 5, 'y': 6} From noreply at buildbot.pypy.org Sun Oct 21 19:22:32 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 19:22:32 +0200 (CEST) Subject: [pypy-commit] pypy default: pfff sorry Message-ID: <20121021172232.976751C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58327:bfe7293f68c5 Date: 2012-10-21 19:22 +0200 http://bitbucket.org/pypy/pypy/changeset/bfe7293f68c5/ Log: pfff sorry diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1132,7 +1132,9 @@ def f(x, y): lst[x] += y graph = self.codetest(f) - assert self.all_operations(graph) == {'xxx': 1} + assert self.all_operations(graph) == {'getitem': 1, + 'inplace_add': 1, + 'setitem': 1} DATA = {'x': 5, 'y': 6} From noreply at buildbot.pypy.org Sun Oct 21 19:30:13 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 21 Oct 2012 19:30:13 +0200 (CEST) Subject: [pypy-commit] pypy default: Python 2.6 compat Message-ID: <20121021173013.A5E371C0012@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58328:cc4bf90cc36f Date: 2012-10-21 19:29 +0200 http://bitbucket.org/pypy/pypy/changeset/cc4bf90cc36f/ Log: Python 2.6 compat diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -761,6 +761,20 @@ next_instr += jumpby return next_instr + def JUMP_IF_FALSE(self, stepby, next_instr): + # Python <= 2.6 only + 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): + # Python <= 2.6 only + w_cond = self.peekvalue() + if self.space.is_true(w_cond): + next_instr += stepby + return next_instr + def POP_JUMP_IF_FALSE(self, target, next_instr): w_value = self.popvalue() if not self.space.is_true(w_value): @@ -1068,7 +1082,10 @@ def LIST_APPEND(self, oparg, next_instr): w = self.popvalue() - v = self.peekvalue(oparg - 1) + if sys.version_info < (2, 7): + v = self.popvalue() + else: + v = self.peekvalue(oparg - 1) self.space.call_method(v, 'append', w) def DELETE_FAST(self, varindex, next_instr): diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py --- a/pypy/objspace/flow/test/test_objspace.py +++ b/pypy/objspace/flow/test/test_objspace.py @@ -1136,6 +1136,14 @@ 'inplace_add': 1, 'setitem': 1} + def test_list_append(self): + def f(iterable): + return [5 for x in iterable] + graph = self.codetest(f) + assert self.all_operations(graph) == {'getattr': 1, + 'iter': 1, 'newlist': 1, + 'next': 1, 'simple_call': 1} + DATA = {'x': 5, 'y': 6} From noreply at buildbot.pypy.org Sun Oct 21 19:48:15 2012 From: noreply at buildbot.pypy.org (stefanor) Date: Sun, 21 Oct 2012 19:48:15 +0200 (CEST) Subject: [pypy-commit] cffi default: subprocess.check_call is prettier Message-ID: <20121021174815.898CF1C0012@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r1003:201c71e13ab7 Date: 2012-10-21 19:32 +0200 http://bitbucket.org/cffi/cffi/changeset/201c71e13ab7/ Log: subprocess.check_call is prettier diff --git a/testing/test_zintegration.py b/testing/test_zintegration.py --- a/testing/test_zintegration.py +++ b/testing/test_zintegration.py @@ -4,7 +4,7 @@ def create_venv(name): tmpdir = udir.join(name) - subprocess.call(['virtualenv', '-p', sys.executable, str(tmpdir)]) + subprocess.check_call(['virtualenv', '-p', sys.executable, str(tmpdir)]) return tmpdir SNIPPET_DIR = py.path.local(__file__).join('..', 'snippets') @@ -19,14 +19,10 @@ python_f.write(py.code.Source(python_snippet)) try: os.chdir(str(SNIPPET_DIR.join(dirname))) - venv = venv_dir.join('bin/activate') - p = subprocess.Popen(['bash', '-c', '. %(venv)s && ' - 'python setup.py clean && ' - 'python setup.py install && ' - 'python %(python_f)s' % locals()]) - p.communicate() - if p.returncode != 0: - raise Exception("crashed") + vp = str(venv_dir.join('bin/python')) + subprocess.check_call((vp, 'setup.py', 'clean')) + subprocess.check_call((vp, 'setup.py', 'install')) + subprocess.check_call((vp, str(python_f))) finally: os.chdir(olddir) From noreply at buildbot.pypy.org Sun Oct 21 19:48:16 2012 From: noreply at buildbot.pypy.org (stefanor) Date: Sun, 21 Oct 2012 19:48:16 +0200 (CEST) Subject: [pypy-commit] cffi default: Symlink the packages our tests require into the test virtualenv Message-ID: <20121021174816.89E311C0012@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r1004:1ca307c260b7 Date: 2012-10-21 19:32 +0200 http://bitbucket.org/cffi/cffi/changeset/1ca307c260b7/ Log: Symlink the packages our tests require into the test virtualenv diff --git a/testing/test_zintegration.py b/testing/test_zintegration.py --- a/testing/test_zintegration.py +++ b/testing/test_zintegration.py @@ -1,10 +1,22 @@ import py, os, sys, shutil +import imp import subprocess from testing.udir import udir def create_venv(name): tmpdir = udir.join(name) subprocess.check_call(['virtualenv', '-p', sys.executable, str(tmpdir)]) + + site_packages = None + for dirpath, dirnames, filenames in os.walk(str(tmpdir)): + if os.path.basename(dirpath) == 'site-packages': + site_packages = dirpath + break + if site_packages: + for module in ('pycparser', 'ply'): + os.symlink(imp.find_module(module)[1], + os.path.join(site_packages, module)) + return tmpdir SNIPPET_DIR = py.path.local(__file__).join('..', 'snippets') From noreply at buildbot.pypy.org Sun Oct 21 20:30:29 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Sun, 21 Oct 2012 20:30:29 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: restructure talk, add some speed numbers Message-ID: <20121021183029.D65231C0012@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4888:4a9c26090909 Date: 2012-10-21 08:44 -0700 http://bitbucket.org/pypy/extradoc/changeset/4a9c26090909/ Log: restructure talk, add some speed numbers diff --git a/talk/dls2012/presentation/talk.tex b/talk/dls2012/presentation/talk.tex --- a/talk/dls2012/presentation/talk.tex +++ b/talk/dls2012/presentation/talk.tex @@ -116,15 +116,20 @@ \begin{frame} \frametitle{Optimizing traces} \begin{itemize} - \item Traces trivial to optimize, because there's no control flow + \item A trace is an extended basic block + \item traces are easy to optime due to lack of control flow merges \item most optimizations are one forward pass \item optimizers are often like symbolic executors \item can do optimizations that are untractable with full control flow - \item XXX example \end{itemize} \end{frame} \begin{frame} + \frametitle{Example} +\end{frame} + + +\begin{frame} \frametitle{Problems with this approach} \begin{itemize} \item most traces actually are loops @@ -146,6 +151,7 @@ \item apply the unchanged forward-pass optimizations \item do some post-processing \item pre-processing is done in such a way that the normal optimizations become loop-aware + \pause \item intuition: give the optimizations a second iteration of context to work with \end{itemize} \end{block} diff --git a/talk/vmil2012/presentation/figures/all_numbers.png b/talk/vmil2012/presentation/figures/all_numbers.png new file mode 100644 index 0000000000000000000000000000000000000000..9076ac193fc9ba1954e24e2ae372ec7e1e1f44e6 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/talk.tex b/talk/vmil2012/presentation/talk.tex --- a/talk/vmil2012/presentation/talk.tex +++ b/talk/vmil2012/presentation/talk.tex @@ -35,7 +35,7 @@ % does not look nice, try deleting the line with the fontenc. -\title{The Efficient Handling of Guards in the Design of RPython's Tracing JIT} +\title[Guards in RPython's Tracing JIT]{The Efficient Handling of Guards in the Design of RPython's Tracing JIT} \author[David Schneider, Carl Friedrich Bolz]{David Schneider \and \emph{Carl Friedrich Bolz}} % - Give the names in the same order as the appear in the paper. @@ -85,6 +85,21 @@ %\section{Introduction} \begin{frame} + \frametitle{RPython and PyPy} + \begin{itemize} + \item Context: RPython + \item a language for writing interpreters for dynamic languages + \item a generic tracing JIT, applicable to many languages + \item used to implement PyPy, an efficient Python interpreter + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{How fast is PyPy?} + \includegraphics[scale=0.3]{figures/all_numbers.png} +\end{frame} + +\begin{frame} \frametitle{Tracing JITs Compile by Observing an Interpreter} \begin{itemize} \item VM contains both an interpreter and the tracing JIT compiler @@ -109,6 +124,7 @@ \item Operations that check whether conditions are still true \item When a guard fails, execution of the trace stops and continues in the interpreter \pause + \item similar to deoptimization points, but more common, and patchable \item \emph{This talk:} technology and design decisions of guards \pause \begin{block}{Guard Characteristics} @@ -121,179 +137,6 @@ \end{itemize} \end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop03} -\end{frame} - -\begin{frame} - \frametitle{Inlining} - Tracing automatically does (potentially deep) inlining -\end{frame} - - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop04} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop05} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop06} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop07} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop08} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop09} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop10} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop11} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop12} -\end{frame} - -% this talk wants to go over a lot of details that are usually glossed over as -% "easy" when tracing JITs are introduced. - -\begin{frame} - \frametitle{Bridges} - \begin{itemize} - \item When a trace fails often, it becomes worth to attach a new trace to it - \item This is called a bridge - \item The bridge is attached by patching the guard machine code - \item when this guard fails in the future, the new trace is executed instead - \end{itemize} -\end{frame} - -\begin{frame} - \frametitle{RPython and PyPy} - \begin{itemize} - \item Context: RPython - \item a generic tracing JIT, applicable to many languages - \item main use: PyPy, an efficient Python interpreter - \end{itemize} -\end{frame} - -%\section{High-Level} - -\begin{frame} - \frametitle{Symbolic Frame Capturing} - \begin{itemize} - \item Guard can fail deep inside inlined function - \item when going back to the interpreter, call stack needs to be re-created - \item done with the help of symbolic frame stacks - \item these show how trace variables fill the to-be-built stack frames - \end{itemize} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop07} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/framechain1} -\end{frame} - - -\begin{frame} - \frametitle{Symbolic Frame Compression} - \begin{itemize} - \item There are \emph{a lot of} guards - \item Naively storing symbolic frames would be costly in terms of memory - \item need to store them compactly - \item observation: from one guard to the next, the non-top stack frames don't change - \item share these between subsequent guards - \pause - \item also need a byte-saving binary representation, but that's just boring work - \end{itemize} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop07} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/framechain1} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/loop08} -\end{frame} - -\begin{frame} - \includegraphics[scale=0.4]{figures/framechain2} -\end{frame} - -\begin{frame} - \frametitle{Interaction with Optimization} - \begin{itemize} - \item Some optimizations make it necessary to store extra information in symbolic frames - \pause - \item examples: - \begin{itemize} - \item allocation removal (need to allocate objects before resuming) - \item delayed heap stores (need to do stores before resuming interpreter) - \end{itemize} - \item can be compressed using similar techniques - \end{itemize} -\end{frame} - -\begin{frame} - \frametitle{Emitting Guards} - Guards are compiled as - \begin{itemize} - \item quick Check if the condition holds - \item and a mapping of machine locations to JIT-variables % indirection using the fail-boxes - \end{itemize} - \pause - In case of failure - \begin{itemize} - \item execution jumps to shared compensation code, decodes and stores mapping - \item returns to interpreter that rebuilds state - \end{itemize} -\end{frame} - -\begin{frame} - \frametitle{Compiling a Trace} - \begin{figure} - \centering - \includegraphics[width=1\textwidth]{figures/loop.pdf} - \end{figure} -\end{frame} - - -\begin{frame} - \frametitle{Compiling a Bridge} - \begin{figure} - \centering - \includegraphics[width=1\textwidth]{figures/bridge_compiled.pdf} - \end{figure} -\end{frame} -\begin{frame} - \frametitle{Patching Guards for Bridges} - \begin{figure} - \centering - \includegraphics[width=1\textwidth]{figures/bridge_patched.pdf} - \end{figure} -\end{frame} - - \begin{frame} \includegraphics[scale=0.6]{figures/op_percentage_after} \end{frame} @@ -341,6 +184,174 @@ \end{frame} \begin{frame} + \includegraphics[scale=0.4]{figures/loop03} +\end{frame} + +\begin{frame} + \frametitle{Inlining} + Tracing automatically does (potentially deep) inlining +\end{frame} + + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop04} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop05} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop06} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop07} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop08} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop09} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop10} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop11} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop12} +\end{frame} + +% this talk wants to go over a lot of details that are usually glossed over as +% "easy" when tracing JITs are introduced. + +%\section{High-Level} + +\begin{frame} + \frametitle{Symbolic Frame Capturing} + \begin{itemize} + \item Guard can fail deep inside inlined function + \item when going back to the interpreter, call stack needs to be re-created + \item done with the help of symbolic frame stacks + \item these show how trace variables fill the to-be-built interpreter stack frames + \end{itemize} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop07} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/framechain1} +\end{frame} + + +\begin{frame} + \frametitle{Symbolic Frame Compression} + \begin{itemize} + \item There are \emph{a lot of} guards + \item Naively storing symbolic frames would be costly in terms of memory + \item need to store them compactly + \item observation: from one guard to the next, the non-top stack frames don't change + \item share these between subsequent guards + \end{itemize} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop07} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/framechain1} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/loop08} +\end{frame} + +\begin{frame} + \includegraphics[scale=0.4]{figures/framechain2} +\end{frame} + +\begin{frame} + \frametitle{Compact Representation} + also need a byte-saving binary representation, but that's just boring work +\end{frame} + + +\begin{frame} + \frametitle{Interaction with Optimization} + \begin{itemize} + \item Some optimizations make it necessary to store extra information in symbolic frames + \pause + \item examples: + \begin{itemize} + \item allocation removal (need to allocate objects before resuming) + \item delayed heap stores (need to do stores before resuming interpreter) + \end{itemize} + \item can be compressed using similar techniques + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Emitting Guards} + Guards are compiled as + \begin{itemize} + \item quick check if the condition holds + \item and a mapping of machine locations to JIT-variables % indirection using the fail-boxes + \end{itemize} + \pause + In case of failure + \begin{itemize} + \item execution jumps to shared compensation code, decodes and stores mapping + \item returns to interpreter that rebuilds state + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Compiling a Trace} + \begin{figure} + \centering + \includegraphics[width=1\textwidth]{figures/loop.pdf} + \end{figure} +\end{frame} + +\begin{frame} + \frametitle{Bridges} + \begin{itemize} + \item When a trace fails often, it becomes worth to attach a new trace to it + \item This is called a bridge + \item The bridge is attached by patching the guard machine code + \item when this guard fails in the future, the new trace is executed instead + \end{itemize} +\end{frame} + + +\begin{frame} + \frametitle{Compiling a Bridge} + \begin{figure} + \centering + \includegraphics[width=1\textwidth]{figures/bridge_compiled.pdf} + \end{figure} +\end{frame} +\begin{frame} + \frametitle{Patching Guards for Bridges} + \begin{figure} + \centering + \includegraphics[width=1\textwidth]{figures/bridge_patched.pdf} + \end{figure} +\end{frame} + + + +\begin{frame} \frametitle{JIT memory overhead} \includegraphics[width=\textwidth]{figures/jit_memory} \end{frame} @@ -354,12 +365,23 @@ \begin{itemize} \item Things that sound simple still often need careful engineering \pause + \item guards are fundamental part of tracing JITs, need to be implemented well \item not even any direct performance gains \item keep memory usage sane \item allows good bridges \end{itemize} \end{frame} +\begin{frame} + \frametitle{Thank you! Questions?} + \begin{itemize} + \item Things that sound simple still often need careful engineering + \item guards are fundamental part of tracing JITs, need to be implemented well + \item not even any direct performance gains + \item keep memory usage sane + \item allows good bridges + \end{itemize} +\end{frame} %\section{Evaluation} %as in paper From noreply at buildbot.pypy.org Sun Oct 21 20:31:53 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Sun, 21 Oct 2012 20:31:53 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: talk as given Message-ID: <20121021183153.3D2EE1C0012@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4889:4e4617f40c20 Date: 2012-10-21 11:31 -0700 http://bitbucket.org/pypy/extradoc/changeset/4e4617f40c20/ Log: talk as given diff --git a/talk/vmil2012/presentation/bolz-vmil-guards-talk.pdf b/talk/vmil2012/presentation/bolz-vmil-guards-talk.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0dc1e6fc97efe3b5904d8e11578eb19e3cc6494a GIT binary patch [cut] From noreply at buildbot.pypy.org Sun Oct 21 22:52:53 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 21 Oct 2012 22:52:53 +0200 (CEST) Subject: [pypy-commit] pypy python-numpy: pass a few tests Message-ID: <20121021205253.3ACD91C00FA@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: python-numpy Changeset: r58329:af767d686834 Date: 2012-10-21 22:51 +0200 http://bitbucket.org/pypy/pypy/changeset/af767d686834/ Log: pass a few tests 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 @@ -33,22 +33,27 @@ umath.ERR_PRINT = 4 umath.ERR_LOG = 5 -umath.UFUNC_SHIFT_DIVIDEBYZERO = 0 -umath.UFUNC_SHIFT_OVERFLOW = 3 -umath.UFUNC_SHIFT_UNDERFLOW = 6 -umath.UFUNC_SHIFT_INVALID = 9 +umath.SHIFT_DIVIDEBYZERO = 0 +umath.SHIFT_OVERFLOW = 3 +umath.SHIFT_UNDERFLOW = 6 +umath.SHIFT_INVALID = 9 umath.UFUNC_BUFSIZE_DEFAULT = 8192 umath.ERR_DEFAULT2 = \ - (umath.ERR_WARN << umath.UFUNC_SHIFT_DIVIDEBYZERO) + \ - (umath.ERR_WARN << umath.UFUNC_SHIFT_OVERFLOW) + \ - (umath.ERR_WARN << umath.UFUNC_SHIFT_INVALID) + (umath.ERR_WARN << umath.SHIFT_DIVIDEBYZERO) + \ + (umath.ERR_WARN << umath.SHIFT_OVERFLOW) + \ + (umath.ERR_WARN << umath.SHIFT_INVALID) _errobj = [10000, 0, None] -def _seterrobj(*args): +def _seterrobj(args): + global _errobj _errobj = args +def _geterrobj(): + return _errobj + umath.seterrobj = _seterrobj +umath.geterrobj = _geterrobj umath.PINF = float('inf') umath.NAN = float('nan') @@ -57,6 +62,7 @@ def not_implemented_func(*args, **kwargs): raise NotImplementedError("implemented yet") + setattr(_numpypy, 'frompyfunc', not_implemented_func) setattr(_numpypy, 'mod', not_implemented_func) setattr(_numpypy, 'conjugate', not_implemented_func) From noreply at buildbot.pypy.org Mon Oct 22 00:33:24 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:33:24 +0200 (CEST) Subject: [pypy-commit] pypy default: cpyext: Add two PyModule_Add* macros, directly copied from CPython. Message-ID: <20121021223324.6A1151C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r58330:d10505b9c736 Date: 2012-10-21 14:28 +0200 http://bitbucket.org/pypy/pypy/changeset/d10505b9c736/ Log: cpyext: Add two PyModule_Add* macros, directly copied from CPython. 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 @@ -35,6 +35,8 @@ int PyModule_AddObject(PyObject *m, const char *name, PyObject *o); int PyModule_AddIntConstant(PyObject *m, const char *name, long value); int PyModule_AddStringConstant(PyObject *m, const char *name, const char *value); +#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c) +#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c) PyObject * Py_BuildValue(const char *, ...); From noreply at buildbot.pypy.org Mon Oct 22 00:33:25 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:33:25 +0200 (CEST) Subject: [pypy-commit] pypy default: cpyext: implement built-in classmethods: METH_CLASS flag. Message-ID: <20121021223325.D7BBE1C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r58331:297db88c1327 Date: 2012-10-21 15:12 +0200 http://bitbucket.org/pypy/pypy/changeset/297db88c1327/ Log: cpyext: implement built-in classmethods: METH_CLASS flag. diff --git a/pypy/module/cpyext/funcobject.py b/pypy/module/cpyext/funcobject.py --- a/pypy/module/cpyext/funcobject.py +++ b/pypy/module/cpyext/funcobject.py @@ -116,10 +116,6 @@ assert isinstance(w_method, Method) return borrow_from(w_method, w_method.w_class) - at cpython_api([PyObject], PyObject) -def PyClassMethod_New(space, w_function): - return space.call_method(space.builtin, "classmethod", w_function) - def unwrap_list_of_strings(space, w_list): return [space.str_w(w_item) for w_item in space.fixedview(w_list)] 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 @@ -4,7 +4,8 @@ from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.function import BuiltinFunction, Method, StaticMethod +from pypy.interpreter.function import ( + BuiltinFunction, Method, StaticMethod, ClassMethod) from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.pyobject import (PyObject, from_ref, make_ref, make_typedescr, Py_DecRef) @@ -128,6 +129,21 @@ PyCFunction_Check, PyCFunction_CheckExact = build_type_checkers("CFunction", W_PyCFunctionObject) +class W_PyCClassMethodObject(W_PyCFunctionObject): + w_self = None + def __init__(self, space, ml, w_type): + self.space = space + self.ml = ml + self.name = rffi.charp2str(ml.c_ml_name) + self.w_objclass = w_type + + def __repr__(self): + return self.space.unwrap(self.descr_method_repr()) + + def descr_method_repr(self): + return self.getrepr(self.space, "built-in method '%s' of '%s' object" % (self.name, self.w_objclass.getname(self.space))) + + class W_PyCWrapperObject(Wrappable): def __init__(self, space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func): @@ -196,6 +212,11 @@ else: return w_function +def cclassmethod_descr_get(space, w_function, w_obj, w_cls=None): + if not w_cls: + w_cls = space.type(w_obj) + return space.wrap(Method(space, w_function, w_cls, space.w_None)) + W_PyCFunctionObject.typedef = TypeDef( 'builtin_function_or_method', @@ -216,6 +237,16 @@ ) W_PyCMethodObject.typedef.acceptable_as_base_class = False +W_PyCClassMethodObject.typedef = TypeDef( + 'classmethod', + __get__ = interp2app(cclassmethod_descr_get), + __call__ = interp2app(cmethod_descr_call), + __name__ = interp_attrproperty('name', cls=W_PyCClassMethodObject), + __objclass__ = interp_attrproperty_w('w_objclass', cls=W_PyCClassMethodObject), + __repr__ = interp2app(W_PyCClassMethodObject.descr_method_repr), + ) +W_PyCClassMethodObject.typedef.acceptable_as_base_class = False + W_PyCWrapperObject.typedef = TypeDef( 'wrapper_descriptor', @@ -243,10 +274,18 @@ def PyStaticMethod_New(space, w_func): return space.wrap(StaticMethod(w_func)) + at cpython_api([PyObject], PyObject) +def PyClassMethod_New(space, w_func): + return space.wrap(ClassMethod(w_func)) + @cpython_api([PyObject, lltype.Ptr(PyMethodDef)], PyObject) def PyDescr_NewMethod(space, w_type, method): return space.wrap(W_PyCMethodObject(space, method, w_type)) + at cpython_api([PyObject, lltype.Ptr(PyMethodDef)], PyObject) +def PyDescr_NewClassMethod(space, w_type, method): + return space.wrap(W_PyCClassMethodObject(space, method, w_type)) + def PyDescr_NewWrapper(space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func): # not exactly the API sig diff --git a/pypy/module/cpyext/modsupport.py b/pypy/module/cpyext/modsupport.py --- a/pypy/module/cpyext/modsupport.py +++ b/pypy/module/cpyext/modsupport.py @@ -5,7 +5,7 @@ from pypy.interpreter.module import Module from pypy.module.cpyext.methodobject import ( W_PyCFunctionObject, PyCFunction_NewEx, PyDescr_NewMethod, - PyMethodDef, PyStaticMethod_New) + PyMethodDef, PyDescr_NewClassMethod, PyStaticMethod_New) from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.module.cpyext.state import State from pypy.interpreter.error import OperationError @@ -97,8 +97,7 @@ if flags & METH_STATIC: raise OperationError(space.w_ValueError, space.wrap("method cannot be both class and static")) - #w_obj = PyDescr_NewClassMethod(space, w_type, method) - w_obj = space.w_Ellipsis # XXX + w_obj = PyDescr_NewClassMethod(space, w_type, method) elif flags & METH_STATIC: w_func = PyCFunction_NewEx(space, method, None, None) w_obj = PyStaticMethod_New(space, w_func) 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 @@ -434,10 +434,6 @@ def PyDescr_NewWrapper(space, type, wrapper, wrapped): raise NotImplementedError - at cpython_api([PyTypeObjectPtr, PyMethodDef], PyObject) -def PyDescr_NewClassMethod(space, type, method): - raise NotImplementedError - @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyDescr_IsData(space, descr): """Return true if the descriptor objects descr describes a data attribute, or diff --git a/pypy/module/cpyext/test/foo.c b/pypy/module/cpyext/test/foo.c --- a/pypy/module/cpyext/test/foo.c +++ b/pypy/module/cpyext/test/foo.c @@ -72,6 +72,13 @@ } static PyObject * +foo_classmeth(PyObject *cls) +{ + Py_INCREF(cls); + return cls; +} + +static PyObject * foo_unset(fooobject *self) { self->foo_string = NULL; @@ -82,6 +89,7 @@ static PyMethodDef foo_methods[] = { {"copy", (PyCFunction)foo_copy, METH_NOARGS, NULL}, {"create", (PyCFunction)foo_create, METH_NOARGS|METH_STATIC, NULL}, + {"classmeth", (PyCFunction)foo_classmeth, METH_NOARGS|METH_CLASS, NULL}, {"unset_string_member", (PyCFunction)foo_unset, METH_NOARGS, NULL}, {NULL, NULL} /* sentinel */ }; diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py --- a/pypy/module/cpyext/test/test_typeobject.py +++ b/pypy/module/cpyext/test/test_typeobject.py @@ -117,6 +117,11 @@ obj2 = obj.create() assert obj2.foo == 42 + def test_classmethod(self): + module = self.import_module(name="foo") + obj = module.fooType.classmeth() + assert obj is module.fooType + def test_new(self): module = self.import_module(name='foo') obj = module.new() From noreply at buildbot.pypy.org Mon Oct 22 00:33:27 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:33:27 +0200 (CEST) Subject: [pypy-commit] pypy default: hg merge default Message-ID: <20121021223327.363141C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r58332:a8952105d742 Date: 2012-10-21 15:13 +0200 http://bitbucket.org/pypy/pypy/changeset/a8952105d742/ Log: hg merge default diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -100,7 +100,7 @@ To translate and run for the CLI you must have the SDK installed: Windows users need the `.NET Framework SDK`_, while Linux and Mac users can use Mono_. To translate and run for the JVM you must have a JDK -installed (at least version 5) and ``java``/``javac`` on your path. +installed (at least version 6) and ``java``/``javac`` on your path. A slightly larger example +++++++++++++++++++++++++ diff --git a/pypy/translator/jvm/genjvm.py b/pypy/translator/jvm/genjvm.py --- a/pypy/translator/jvm/genjvm.py +++ b/pypy/translator/jvm/genjvm.py @@ -2,11 +2,13 @@ Backend for the JVM. """ +from __future__ import with_statement +import os +import re +import subprocess import sys -import os import py -import subprocess from pypy.tool.udir import udir from pypy.translator.translator import TranslationContext from pypy.translator.oosupport.genoo import GenOO @@ -25,6 +27,8 @@ JVMWeakRefConst from pypy.translator.jvm.prebuiltnodes import create_interlink_node +MIN_JAVA_VERSION = '1.6.0' + class JvmError(Exception): """ Indicates an error occurred in JVM backend """ @@ -222,12 +226,35 @@ jvm = GenJvm(tmpdir, t, EntryPoint(main_graph, True, True)) return jvm.generate_source() +_missing_support_programs = None + def detect_missing_support_programs(): - def check(exechelper): - if py.path.local.sysfind(exechelper) is None: - py.test.skip("%s is not on your path" % exechelper) - check(getoption('javac')) - check(getoption('java')) + global _missing_support_programs + if _missing_support_programs is not None: + if _missing_support_programs: + py.test.skip(_missing_support_programs) + return + + def missing(msg): + global _missing_support_programs + _missing_support_programs = msg + py.test.skip(msg) + + for cmd in 'javac', 'java': + if py.path.local.sysfind(getoption(cmd)) is None: + missing("%s is not on your path" % cmd) + if not _check_java_version(MIN_JAVA_VERSION): + missing('Minimum of Java %s required' % MIN_JAVA_VERSION) + _missing_support_programs = False + +def _check_java_version(version): + """Determine if java meets the specified version""" + cmd = [getoption('java'), '-version'] + with open(os.devnull, 'w') as devnull: + stderr = subprocess.Popen(cmd, stdout=devnull, + stderr=subprocess.PIPE).communicate()[1] + search = re.search('[\.0-9]+', stderr) + return search and search.group() >= version class GenJvm(GenOO): From noreply at buildbot.pypy.org Mon Oct 22 00:33:28 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:33:28 +0200 (CEST) Subject: [pypy-commit] pypy default: Merge branch cpyext-PyThreadState_New: implement threadstate-related functions. Message-ID: <20121021223328.5E7AD1C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r58333:6822a5e1abe8 Date: 2012-10-21 15:15 +0200 http://bitbucket.org/pypy/pypy/changeset/6822a5e1abe8/ Log: Merge branch cpyext-PyThreadState_New: implement threadstate-related functions. Should be able to start a thread in C, and have it call back into Python. 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 @@ -1,7 +1,8 @@ from pypy.module.cpyext.api import ( cpython_api, generic_cpy_call, CANNOT_FAIL, CConfig, cpython_struct) -from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, make_ref +from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, make_ref, from_ref from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.thread import ll_thread, os_thread PyInterpreterStateStruct = lltype.ForwardReference() PyInterpreterState = lltype.Ptr(PyInterpreterStateStruct) @@ -43,7 +44,7 @@ @cpython_api([], lltype.Void) def PyEval_InitThreads(space): - return + os_thread.setup_threads(space) @cpython_api([], rffi.INT_real, error=CANNOT_FAIL) def PyEval_ThreadsInitialized(space): @@ -85,10 +86,7 @@ ExecutionContext.cpyext_initialized_threadstate = False def cleanup_cpyext_state(self): - try: - del self.cpyext_threadstate - except AttributeError: - pass + self.cpyext_threadstate = None self.cpyext_initialized_threadstate = False ExecutionContext.cleanup_cpyext_state = cleanup_cpyext_state @@ -182,8 +180,9 @@ tstate, which should not be NULL. The lock must have been created earlier. If this thread already has the lock, deadlock ensues. This function is not available when thread support is disabled at compile time.""" - # All cpyext calls release and acquire the GIL, so this is not necessary. - pass + if rffi.aroundstate.after: + # After external call is before entering Python + rffi.aroundstate.after() @cpython_api([PyThreadState], lltype.Void) def PyEval_ReleaseThread(space, tstate): @@ -193,8 +192,9 @@ that it represents the current thread state --- if it isn't, a fatal error is reported. This function is not available when thread support is disabled at compile time.""" - # All cpyext calls release and acquire the GIL, so this is not necessary. - pass + if rffi.aroundstate.before: + # Before external call is after running Python + rffi.aroundstate.before() PyGILState_STATE = rffi.COpaquePtr('PyGILState_STATE', typedef='PyGILState_STATE', @@ -202,13 +202,16 @@ @cpython_api([], PyGILState_STATE, error=CANNOT_FAIL) def PyGILState_Ensure(space): - # All cpyext calls release and acquire the GIL, so this is not necessary. + if rffi.aroundstate.after: + # After external call is before entering Python + rffi.aroundstate.after() return 0 @cpython_api([PyGILState_STATE], lltype.Void) def PyGILState_Release(space, state): - # All cpyext calls release and acquire the GIL, so this is not necessary. - return + if rffi.aroundstate.before: + # Before external call is after running Python + rffi.aroundstate.before() @cpython_api([], PyInterpreterState, error=CANNOT_FAIL) def PyInterpreterState_Head(space): @@ -222,3 +225,41 @@ such objects. """ return lltype.nullptr(PyInterpreterState.TO) + + at cpython_api([PyInterpreterState], PyThreadState, error=CANNOT_FAIL) +def PyThreadState_New(space, interp): + """Create a new thread state object belonging to the given interpreter + object. The global interpreter lock need not be held, but may be held if + it is necessary to serialize calls to this function.""" + ll_thread.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() + try: + ll_thread.gc_thread_start() + return PyThreadState_Get(space) + finally: + rffi.aroundstate.before() + + at cpython_api([PyThreadState], lltype.Void) +def PyThreadState_Clear(space, tstate): + """Reset all information in a thread state object. The global + interpreter lock must be held.""" + Py_DecRef(space, tstate.c_dict) + tstate.c_dict = lltype.nullptr(PyObject.TO) + space.threadlocals.leave_thread(space) + space.getexecutioncontext().cleanup_cpyext_state() + ll_thread.gc_thread_die() + + at cpython_api([PyThreadState], lltype.Void) +def PyThreadState_Delete(space, tstate): + """Destroy a thread state object. The global interpreter lock need not + be held. The thread state must have been reset with a previous call to + PyThreadState_Clear().""" + + at cpython_api([], lltype.Void) +def PyThreadState_DeleteCurrent(space): + """Destroy a thread state object. The global interpreter lock need not + be held. The thread state must have been reset with a previous call to + PyThreadState_Clear().""" + diff --git a/pypy/module/cpyext/stubsactive.py b/pypy/module/cpyext/stubsactive.py --- a/pypy/module/cpyext/stubsactive.py +++ b/pypy/module/cpyext/stubsactive.py @@ -14,26 +14,6 @@ PyFile_DecUseCount() functions described below as appropriate.""" raise NotImplementedError - at cpython_api([PyInterpreterState], PyThreadState, error=CANNOT_FAIL) -def PyThreadState_New(space, interp): - """Create a new thread state object belonging to the given interpreter object. - The global interpreter lock need not be held, but may be held if it is - necessary to serialize calls to this function.""" - raise NotImplementedError - - at cpython_api([PyThreadState], lltype.Void) -def PyThreadState_Clear(space, tstate): - """Reset all information in a thread state object. The global interpreter lock - must be held.""" - raise NotImplementedError - - at cpython_api([PyThreadState], lltype.Void) -def PyThreadState_Delete(space, tstate): - """Destroy a thread state object. The global interpreter lock need not be held. - The thread state must have been reset with a previous call to - PyThreadState_Clear().""" - raise NotImplementedError - @cpython_api([], rffi.INT_real, error=CANNOT_FAIL) def Py_MakePendingCalls(space): return 0 diff --git a/pypy/module/cpyext/test/callback_in_thread.c b/pypy/module/cpyext/test/callback_in_thread.c new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/test/callback_in_thread.c @@ -0,0 +1,83 @@ +/* A test module that spawns a thread and run a function there */ + +#include +#include + +struct thread_data { + PyInterpreterState *interp; + PyObject *callback; +}; + +static void *thread_function(void* ptr) { + struct thread_data *data = (struct thread_data *)ptr; + PyInterpreterState *interp = data->interp; + /* Assuming you have access to an interpreter object, the typical + * idiom for calling into Python from a C thread is: */ + + PyThreadState *tstate; + PyObject *result; + + /* interp is your reference to an interpreter object. */ + tstate = PyThreadState_New(interp); + PyEval_AcquireThread(tstate); + + /* Perform Python actions here. */ + result = PyObject_CallFunction(data->callback, + "l", (long)pthread_self()); + if (!result) + PyErr_Print(); + else + Py_DECREF(result); + + Py_DECREF(data->callback); + + /* XXX Python examples don't mention it, but docs say that + * PyThreadState_Delete requires it. */ + PyThreadState_Clear(tstate); + + /* Release the thread. No Python API allowed beyond this point. */ + PyEval_ReleaseThread(tstate); + + /* You can either delete the thread state, or save it + until you need it the next time. */ + PyThreadState_Delete(tstate); + + free(data); + return NULL; +} + +static PyObject * +run_callback(PyObject *self, PyObject *callback) +{ + pthread_t thread; + struct thread_data *data = malloc(sizeof(struct thread_data)); + Py_INCREF(callback); + data->interp = PyThreadState_Get()->interp; + data->callback = callback; + pthread_create(&thread, NULL, thread_function, (void*)data); + Py_RETURN_NONE; +} + + +static PyMethodDef module_functions[] = { + {"callInThread", (PyCFunction)run_callback, METH_O, NULL}, + {NULL, NULL} /* Sentinel */ +}; + + +void initcallback_in_thread(void) +{ + PyObject *m; + m = Py_InitModule("callback_in_thread", module_functions); + if (m == NULL) + return; + PyEval_InitThreads(); +} + +/* +cc -g -O0 -c callback_in_thread.c -I /usr/include/python2.6 -fPIC && ld -g -O0 callback_in_thread.o --shared -o callback_in_thread.so && gdb --args ~/python/cpython2.7/python -c "from __future__ import print_function; import threading, time; from callback_in_thread import callInThread; callInThread(print); time.sleep(1)" + + +cc -g -O0 -c callback_in_thread.c -I ~/pypy/pypy/include -fPIC && ld -g -O0 callback_in_thread.o --shared -o callback_in_thread.pypy-19.so && gdb --args ~/pypy/pypy/pypy/pypy-c -c "from __future__ import print_function; import threading, time; from callback_in_thread import callInThread; callInThread(print); time.sleep(1)" + + */ From noreply at buildbot.pypy.org Mon Oct 22 00:33:30 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:33:30 +0200 (CEST) Subject: [pypy-commit] pypy default: hg merge default Message-ID: <20121021223330.3E6DC1C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r58334:7096ba842112 Date: 2012-10-22 00:32 +0200 http://bitbucket.org/pypy/pypy/changeset/7096ba842112/ Log: hg merge default diff too long, truncating to 2000 out of 2768 lines diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -31,21 +31,21 @@ # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', - 'truediv', 'floordiv', 'divmod', 'pow', + 'truediv', 'floordiv', 'divmod', 'and_', 'or_', 'xor', 'lshift', 'rshift', 'getitem', 'setitem', 'delitem', 'getitem_idx', 'getitem_key', 'getitem_idx_key', 'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv', 'inplace_floordiv', 'inplace_div', - 'inplace_mod', 'inplace_pow', + 'inplace_mod', 'inplace_lshift', 'inplace_rshift', 'inplace_and', 'inplace_or', 'inplace_xor', 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'is_', 'cmp', 'coerce', ] +[opname+'_ovf' for opname in - """add sub mul floordiv div mod pow lshift + """add sub mul floordiv div mod lshift """.split() ]) @@ -65,7 +65,6 @@ def inplace_floordiv((obj1, obj2)): return pair(obj1, obj2).floordiv() def inplace_div((obj1, obj2)): return pair(obj1, obj2).div() def inplace_mod((obj1, obj2)): return pair(obj1, obj2).mod() - def inplace_pow((obj1, obj2)): return pair(obj1, obj2).pow(s_None) def inplace_lshift((obj1, obj2)): return pair(obj1, obj2).lshift() def inplace_rshift((obj1, obj2)): return pair(obj1, obj2).rshift() def inplace_and((obj1, obj2)): return pair(obj1, obj2).and_() @@ -301,19 +300,6 @@ return SomeInteger(nonneg=int1.nonneg, knowntype=int1.knowntype) rshift.can_only_throw = [] - def pow((int1, int2), obj3): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - pow.can_only_throw = [ZeroDivisionError] - pow_ovf = _clone(pow, [ZeroDivisionError, OverflowError]) - - def inplace_pow((int1, int2)): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - inplace_pow.can_only_throw = [ZeroDivisionError] - def _compare_helper((int1, int2), opname, operation): r = SomeBool() if int1.is_immutable_constant() and int2.is_immutable_constant(): @@ -500,9 +486,6 @@ div.can_only_throw = [] truediv = div - def pow((flt1, flt2), obj3): - raise NotImplementedError("float power not supported, use math.pow") - # repeat these in order to copy the 'can_only_throw' attribute inplace_div = div inplace_truediv = truediv diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -16,7 +16,7 @@ from pypy.annotation.dictdef import DictDef from pypy.annotation import description from pypy.annotation.signature import annotationoftype -from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.rlib.objectmodel import r_dict, Symbolic from pypy.tool.algo.unionfind import UnionFind from pypy.rpython.lltypesystem import lltype, llmemory @@ -101,7 +101,7 @@ def consider_list_delitem(self, idx): return self.indexrepr(idx) - + def consider_str_join(self, s): if s.is_constant(): return repr(s.const) @@ -224,7 +224,7 @@ check_no_flags(s_value_or_def.listdef.listitem) elif isinstance(s_value_or_def, SomeDict): check_no_flags(s_value_or_def.dictdef.dictkey) - check_no_flags(s_value_or_def.dictdef.dictvalue) + check_no_flags(s_value_or_def.dictdef.dictvalue) elif isinstance(s_value_or_def, SomeTuple): for s_item in s_value_or_def.items: check_no_flags(s_item) @@ -238,9 +238,9 @@ elif isinstance(s_value_or_def, ListItem): if s_value_or_def in seen: return - seen.add(s_value_or_def) + seen.add(s_value_or_def) check_no_flags(s_value_or_def.s_value) - + for clsdef in self.classdefs: check_no_flags(clsdef) @@ -366,14 +366,14 @@ listdef = ListDef(self, s_ImpossibleValue) for e in x: listdef.generalize(self.immutablevalue(e, False)) - result = SomeList(listdef) + result = SomeList(listdef) elif tp is dict or tp is r_dict: if need_const: key = Constant(x) try: return self.immutable_cache[key] except KeyError: - result = SomeDict(DictDef(self, + result = SomeDict(DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict)) @@ -396,7 +396,7 @@ result.const_box = key return result else: - dictdef = DictDef(self, + dictdef = DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict) @@ -545,7 +545,7 @@ return True else: return False - + def getfrozen(self, pyobj): return description.FrozenDesc(self, pyobj) @@ -566,7 +566,7 @@ key = (x.__class__, x) if key in self.seen_mutable: return - clsdef = self.getuniqueclassdef(x.__class__) + clsdef = self.getuniqueclassdef(x.__class__) self.seen_mutable[key] = True self.event('mutable', x) source = InstanceSource(self, x) @@ -586,7 +586,7 @@ except KeyError: access_sets = map[attrname] = UnionFind(description.ClassAttrFamily) return access_sets - + def pbc_getattr(self, pbc, s_attr): assert s_attr.is_constant() attr = s_attr.const @@ -598,7 +598,7 @@ first = descs[0] if len(descs) == 1: return first.s_read_attribute(attr) - + change = first.mergeattrfamilies(descs[1:], attr) attrfamily = first.getattrfamily(attr) @@ -700,7 +700,7 @@ def ondegenerated(self, what, s_value, where=None, called_from_graph=None): self.annotator.ondegenerated(what, s_value, where=where, called_from_graph=called_from_graph) - + def whereami(self): return self.annotator.whereami(self.position_key) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -1,8 +1,7 @@ import types, py from pypy.objspace.flow.model import Constant, FunctionGraph -from pypy.interpreter.pycode import cpython_code_signature -from pypy.interpreter.argument import rawshape -from pypy.interpreter.argument import ArgErr +from pypy.objspace.flow.bytecode import cpython_code_signature +from pypy.objspace.flow.argument import rawshape, ArgErr from pypy.tool.sourcetools import valid_identifier from pypy.tool.pairtype import extendabletype @@ -181,7 +180,7 @@ name = pyobj.func_name if signature is None: if hasattr(pyobj, '_generator_next_method_of_'): - from pypy.interpreter.argument import Signature + from pypy.objspace.flow.argument import Signature signature = Signature(['entry']) # haaaaaack defaults = () else: @@ -260,7 +259,7 @@ try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: - raise TypeError("signature mismatch: %s() %s" % + raise TypeError("signature mismatch: %s() %s" % (self.name, e.getmsg())) return inputcells diff --git a/pypy/annotation/specialize.py b/pypy/annotation/specialize.py --- a/pypy/annotation/specialize.py +++ b/pypy/annotation/specialize.py @@ -6,7 +6,7 @@ from pypy.objspace.flow.model import Block, Link, Variable, SpaceOperation from pypy.objspace.flow.model import Constant, checkgraph from pypy.annotation import model as annmodel -from pypy.interpreter.argument import Signature +from pypy.objspace.flow.argument import Signature def flatten_star_args(funcdesc, args_s): argnames, vararg, kwarg = funcdesc.signature diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -13,7 +13,7 @@ from pypy.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong from pypy.rlib.rarithmetic import r_singlefloat from pypy.rlib import objectmodel -from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.objspace.flow.objspace import FlowObjSpace, FlowingError from pypy.translator.test import snippet @@ -1431,15 +1431,6 @@ assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_pow(self): - def f(n): - n **= 2 - return 2 ** n - a = self.RPythonAnnotator() - s = a.build_types(f, [int]) - # result should be an integer - assert s.knowntype == int - def test_inplace_div(self): def f(n): n /= 2 @@ -3156,10 +3147,9 @@ x **= y return x ** y a = self.RPythonAnnotator() - s = a.build_types(f, [int, int]) - assert isinstance(s, annmodel.SomeInteger) - a = self.RPythonAnnotator() - py.test.raises(NotImplementedError, a.build_types, f, [float, float]) + py.test.raises(FlowingError, a.build_types, f, [int, int]) + a = self.RPythonAnnotator() + py.test.raises(FlowingError, a.build_types, f, [float, float]) def test_intcmp_bug(self): def g(x, y): diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -285,17 +285,14 @@ Miscellaneous ------------- -* Hash randomization is not supported in PyPy. Passing ``-R`` to the - command line, or setting the ``PYTHONHASHSEED`` environment variable - will display a warning message. +* Hash randomization (``-R``) is ignored in PyPy. As documented in + http://bugs.python.org/issue14621 , some of us believe it has no + purpose in CPython either. -* ``sys.setrecursionlimit()`` is ignored (and not needed) on - PyPy. On CPython it would set the maximum number of nested - calls that can occur before a RuntimeError is raised; on PyPy - overflowing the stack also causes RuntimeErrors, but the limit - is checked at a lower level. (The limit is currently hard-coded - at 768 KB, corresponding to roughly 1480 Python calls on - Linux.) +* ``sys.setrecursionlimit(n)`` sets the limit only approximately, + by setting the usable stack space to ``n * 768`` bytes. On Linux, + depending on the compiler settings, the default of 768KB is enough + for about 1400 calls. * assignment to ``__class__`` is limited to the cases where it works on CPython 2.5. On CPython 2.6 and 2.7 it works in a bit diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -504,149 +504,6 @@ w_key = keyword_names_w[i - limit] space.setitem(w_kwds, w_key, keywords_w[i]) -class ArgumentsForTranslation(Arguments): - def __init__(self, space, args_w, keywords=None, keywords_w=None, - w_stararg=None, w_starstararg=None): - self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False - Arguments.__init__(self, space, args_w, keywords, keywords_w) - - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - - def prepend(self, w_firstarg): # used often - "Return a new Arguments with a new argument inserted first." - return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - def copy(self): - return ArgumentsForTranslation(self.space, self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - - - def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None, - blindargs=0): - self.combine_if_necessary() - # _match_signature is destructive - return Arguments._match_signature( - self, w_firstarg, scope_w, signature, - defaults_w, blindargs) - - def unpack(self): - self.combine_if_necessary() - return Arguments.unpack(self) - - def match_signature(self, signature, defaults_w): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - return self._parse(None, signature, defaults_w) - - def unmatch_signature(self, signature, data_w): - """kind of inverse of match_signature""" - args_w, kwds_w = self.unpack() - need_cnt = len(args_w) - need_kwds = kwds_w.keys() - space = self.space - argnames, varargname, kwargname = signature - cnt = len(argnames) - data_args_w = data_w[:cnt] - if varargname: - data_w_stararg = data_w[cnt] - cnt += 1 - else: - data_w_stararg = space.newtuple([]) - - unfiltered_kwds_w = {} - if kwargname: - data_w_starargarg = data_w[cnt] - for w_key in space.unpackiterable(data_w_starargarg): - key = space.str_w(w_key) - w_value = space.getitem(data_w_starargarg, w_key) - unfiltered_kwds_w[key] = w_value - cnt += 1 - assert len(data_w) == cnt - - ndata_args_w = len(data_args_w) - if ndata_args_w >= need_cnt: - 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) - else: - stararg_w = space.unpackiterable(data_w_stararg) - datalen = len(data_args_w) - args_w = [None] * (datalen + len(stararg_w)) - for i in range(0, datalen): - args_w[i] = data_args_w[i] - for i in range(0, len(stararg_w)): - args_w[i + datalen] = stararg_w[i] - assert len(args_w) == need_cnt - - keywords = [] - keywords_w = [] - for key in need_kwds: - keywords.append(key) - keywords_w.append(unfiltered_kwds_w[key]) - - return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) - - @staticmethod - def frompacked(space, w_args=None, w_kwds=None): - raise NotImplementedError("go away") - - @staticmethod - def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w): - args_w = data_w[:shape_cnt] - p = end_keys = shape_cnt + len(shape_keys) - if shape_star: - w_star = data_w[p] - p += 1 - else: - w_star = None - if shape_stst: - w_starstar = data_w[p] - p += 1 - else: - w_starstar = None - return ArgumentsForTranslation(space, args_w, list(shape_keys), - data_w[shape_cnt:end_keys], w_star, - w_starstar) - - def flatten(self): - """ Argument <-> list of w_objects together with "shape" information """ - shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape() - data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)] - for key in shape_keys] - if shape_star: - data_w.append(self.w_stararg) - if shape_stst: - data_w.append(self.w_starstararg) - return (shape_cnt, shape_keys, shape_star, shape_stst), data_w - - def _rawshape(self, nextra=0): - assert not self.combine_has_happened - shape_cnt = len(self.arguments_w)+nextra # Number of positional args - if self.keywords: - shape_keys = self.keywords[:] # List of keywords (strings) - shape_keys.sort() - else: - shape_keys = [] - shape_star = self.w_stararg is not None # Flag: presence of *arg - shape_stst = self.w_starstararg is not None # Flag: presence of **kwds - return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted - -def rawshape(args, nextra=0): - return args._rawshape(nextra) - - # # ArgErr family of exceptions raised in case of argument mismatch. # We try to give error messages following CPython's, which are very informative. 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 @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- import py -from pypy.interpreter.argument import (Arguments, ArgumentsForTranslation, - ArgErr, ArgErrUnknownKwds, ArgErrMultipleValues, ArgErrCount, rawshape, - Signature) +from pypy.interpreter.argument import (Arguments, ArgErr, ArgErrUnknownKwds, + ArgErrMultipleValues, ArgErrCount, Signature) from pypy.interpreter.error import OperationError @@ -687,206 +686,3 @@ def f(x): pass e = raises(TypeError, "f(**{u'ü' : 19})") assert "?" in str(e.value) - -def make_arguments_for_translation(space, args_w, keywords_w={}, - w_stararg=None, w_starstararg=None): - return ArgumentsForTranslation(space, args_w, keywords_w.keys(), - keywords_w.values(), w_stararg, - w_starstararg) - -class TestArgumentsForTranslation(object): - - def test_prepend(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ["0"]) - args1 = args.prepend("thingy") - assert args1 is not args - assert args1.arguments_w == ["thingy", "0"] - assert args1.keywords is args.keywords - assert args1.keywords_w is args.keywords_w - - def test_unmatch_signature(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - sig = Signature(['a', 'b', 'c'], 'r', None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - def test_rawshape(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert rawshape(args) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1]) - assert rawshape(args, 2) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert rawshape(args) == (5, (), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert rawshape(args) == (1, ('b', 'c'), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert rawshape(args) == (1, ('c', ), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert rawshape(args) == (1, ('c', 'd'), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert rawshape(args) == (5, ('d', 'e'), False, False) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert rawshape(args) == (0, (), True, True) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert rawshape(args) == (2, ('g', ), True, True) - - def test_copy_and_shape(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ['a'], ['x'], [1], - ['w1'], {'y': 'w2'}) - args1 = args.copy() - args.combine_if_necessary() - assert rawshape(args1) == (1, ('x',), True, True) - - - def test_flatten(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert args.flatten() == ((3, (), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1]) - assert args.flatten() == ((1, (), False, False), [1]) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert args.flatten() == ((5, (), False, False), [1,2,3,4,5]) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert args.flatten() == ((1, ('c', ), False, False), [1, 5]) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7]) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert args.flatten() == ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert args.flatten() == ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - - def test_stararg_flowspace_variable(self): - space = DummySpace() - var = object() - shape = ((2, ('g', ), True, False), [1, 2, 9, var]) - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=var) - assert args.flatten() == shape - - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - - def test_fromshape(self): - space = DummySpace() - shape = ((3, (), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, (), False, False), [1]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, (), False, False), [1,2,3,4,5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('b', 'c'), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', ), False, False), [1, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', 'd'), False, False), [1, 5, 7]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/flow/argument.py @@ -0,0 +1,498 @@ +""" +Arguments objects. +""" + +class Signature(object): + _immutable_ = True + _immutable_fields_ = ["argnames[*]"] + __slots__ = ("argnames", "varargname", "kwargname") + + def __init__(self, argnames, varargname=None, kwargname=None): + self.argnames = argnames + self.varargname = varargname + self.kwargname = kwargname + + def find_argname(self, name): + try: + return self.argnames.index(name) + except ValueError: + return -1 + + def num_argnames(self): + return len(self.argnames) + + def has_vararg(self): + return self.varargname is not None + + def has_kwarg(self): + return self.kwargname is not None + + def scope_length(self): + scopelen = len(self.argnames) + scopelen += self.has_vararg() + scopelen += self.has_kwarg() + return scopelen + + def getallvarnames(self): + argnames = self.argnames + if self.varargname is not None: + argnames = argnames + [self.varargname] + if self.kwargname is not None: + argnames = argnames + [self.kwargname] + return argnames + + def __repr__(self): + return "Signature(%r, %r, %r)" % ( + self.argnames, self.varargname, self.kwargname) + + def __eq__(self, other): + if not isinstance(other, Signature): + return NotImplemented + return (self.argnames == other.argnames and + self.varargname == other.varargname and + self.kwargname == other.kwargname) + + def __ne__(self, other): + if not isinstance(other, Signature): + return NotImplemented + return not self == other + + + # make it look tuply for its use in the annotator + + def __len__(self): + return 3 + + def __getitem__(self, i): + if i == 0: + return self.argnames + if i == 1: + return self.varargname + if i == 2: + return self.kwargname + raise IndexError + +class ArgumentsForTranslation(object): + def __init__(self, space, args_w, keywords=None, keywords_w=None, + w_stararg=None, w_starstararg=None): + self.w_stararg = w_stararg + self.w_starstararg = w_starstararg + self.combine_has_happened = False + self.space = space + assert isinstance(args_w, list) + self.arguments_w = args_w + self.keywords = keywords + self.keywords_w = keywords_w + self.keyword_names_w = None + + def __repr__(self): + """ NOT_RPYTHON """ + name = self.__class__.__name__ + if not self.keywords: + return '%s(%s)' % (name, self.arguments_w,) + else: + return '%s(%s, %s, %s)' % (name, self.arguments_w, + self.keywords, self.keywords_w) + + def _combine_wrapped(self, w_stararg, w_starstararg): + "unpack the *arg and **kwd into arguments_w and keywords_w" + if w_stararg is not None: + self._combine_starargs_wrapped(w_stararg) + if w_starstararg is not None: + self._combine_starstarargs_wrapped(w_starstararg) + + def _combine_starargs_wrapped(self, w_stararg): + # unpack the * arguments + space = self.space + args_w = space.unpackiterable(w_stararg) + self.arguments_w = self.arguments_w + args_w + + def _combine_starstarargs_wrapped(self, w_starstararg): + # unpack the ** arguments + space = self.space + keywords, values_w = space.view_as_kwargs(w_starstararg) + if keywords is not None: # this path also taken for empty dicts + if self.keywords is None: + self.keywords = keywords + self.keywords_w = values_w + else: + if set(keywords) & set(self.keywords): + raise TypeError("got multiple values for keyword arguments '%s'", set(keywords) & set(self.keywords)) + self.keywords = self.keywords + keywords + self.keywords_w = self.keywords_w + values_w + return + if space.isinstance_w(w_starstararg, space.w_dict): + keys_w = space.unpackiterable(w_starstararg) + else: + w_keys = space.call_method(w_starstararg, "keys") + keys_w = space.unpackiterable(w_keys) + keywords_w = [None] * len(keys_w) + keywords = [None] * len(keys_w) + for i, w_key in enumerate(keys_w): + key = space.str_w(w_key) + if key in self.keywords: + raise TypeError("got multiple values for keyword argument '%s'" % key) + keywords[i] = key + keywords_w[i] = space.getitem(w_starstararg, w_key) + self.keyword_names_w = keys_w + if self.keywords is None: + self.keywords = keywords + self.keywords_w = keywords_w + else: + self.keywords = self.keywords + keywords + self.keywords_w = self.keywords_w + keywords_w + + + def fixedunpack(self, argcount): + """The simplest argument parsing: get the 'argcount' arguments, + or raise a real ValueError if the length is wrong.""" + if self.keywords: + raise ValueError, "no keyword arguments expected" + if len(self.arguments_w) > argcount: + raise ValueError, "too many arguments (%d expected)" % argcount + elif len(self.arguments_w) < argcount: + raise ValueError, "not enough arguments (%d expected)" % argcount + return self.arguments_w + + def combine_if_necessary(self): + if self.combine_has_happened: + return + self._combine_wrapped(self.w_stararg, self.w_starstararg) + self.combine_has_happened = True + + def prepend(self, w_firstarg): # used often + "Return a new Arguments with a new argument inserted first." + return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, + self.keywords, self.keywords_w, self.w_stararg, + self.w_starstararg) + + def copy(self): + return ArgumentsForTranslation(self.space, self.arguments_w, + self.keywords, self.keywords_w, self.w_stararg, + self.w_starstararg) + + def _match_signature(self, scope_w, signature, defaults_w=None): + """Parse args and kwargs according to the signature of a code object, + or raise an ArgErr in case of failure. + """ + # args_w = list of the normal actual parameters, wrapped + # scope_w = resulting list of wrapped values + # + self.combine_if_necessary() + co_argcount = signature.num_argnames() # expected formal arguments, without */** + + args_w = self.arguments_w + num_args = len(args_w) + keywords = self.keywords or [] + num_kwds = len(keywords) + + # put as many positional input arguments into place as available + take = min(num_args, co_argcount) + scope_w[:take] = args_w[:take] + input_argcount = take + + # collect extra positional arguments into the *vararg + if signature.has_vararg(): + if num_args > co_argcount: + starargs_w = args_w[co_argcount:] + else: + starargs_w = [] + scope_w[co_argcount] = self.space.newtuple(starargs_w) + elif num_args > co_argcount: + raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) + + # if a **kwargs argument is needed, create the dict + w_kwds = None + if signature.has_kwarg(): + w_kwds = self.space.newdict(kwargs=True) + scope_w[co_argcount + signature.has_vararg()] = w_kwds + + # handle keyword arguments + num_remainingkwds = 0 + keywords_w = self.keywords_w + kwds_mapping = None + if num_kwds: + # kwds_mapping maps target indexes in the scope (minus input_argcount) + # to positions in the keywords_w list + kwds_mapping = [-1] * (co_argcount - input_argcount) + # match the keywords given at the call site to the argument names + # the called function takes + # this function must not take a scope_w, to make the scope not + # escape + num_remainingkwds = len(keywords) + for i, name in enumerate(keywords): + # If name was not encoded as a string, it could be None. In that + # case, it's definitely not going to be in the signature. + if name is None: + continue + j = signature.find_argname(name) + # if j == -1 nothing happens + if j < input_argcount: + # check that no keyword argument conflicts with these. + if j >= 0: + raise ArgErrMultipleValues(name) + else: + kwds_mapping[j - input_argcount] = i # map to the right index + num_remainingkwds -= 1 + + if num_remainingkwds: + if w_kwds is not None: + # collect extra keyword arguments into the **kwarg + limit = len(keywords) + if self.keyword_names_w is not None: + limit -= len(self.keyword_names_w) + for i in range(len(keywords)): + if i in kwds_mapping: + continue + if i < limit: + w_key = self.space.wrap(keywords[i]) + else: + w_key = self.keyword_names_w[i - limit] + self.space.setitem(w_kwds, w_key, keywords_w[i]) + else: + if co_argcount == 0: + raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) + raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords, + kwds_mapping, self.keyword_names_w) + + # check for missing arguments and fill them from the kwds, + # or with defaults, if available + missing = 0 + if input_argcount < co_argcount: + def_first = co_argcount - (0 if defaults_w is None else len(defaults_w)) + j = 0 + kwds_index = -1 + for i in range(input_argcount, co_argcount): + if kwds_mapping is not None: + kwds_index = kwds_mapping[j] + j += 1 + if kwds_index >= 0: + scope_w[i] = keywords_w[kwds_index] + continue + defnum = i - def_first + if defnum >= 0: + scope_w[i] = defaults_w[defnum] + else: + missing += 1 + if missing: + raise ArgErrCount(num_args, num_kwds, signature, defaults_w, missing) + + def unpack(self): + "Return a ([w1,w2...], {'kw':w3...}) pair." + self.combine_if_necessary() + kwds_w = {} + if self.keywords: + for i in range(len(self.keywords)): + kwds_w[self.keywords[i]] = self.keywords_w[i] + return self.arguments_w, kwds_w + + + def match_signature(self, signature, defaults_w): + """Parse args and kwargs according to the signature of a code object, + or raise an ArgErr in case of failure. + """ + scopelen = signature.scope_length() + scope_w = [None] * scopelen + self._match_signature(scope_w, signature, defaults_w) + return scope_w + + def unmatch_signature(self, signature, data_w): + """kind of inverse of match_signature""" + args_w, kwds_w = self.unpack() + need_cnt = len(args_w) + need_kwds = kwds_w.keys() + space = self.space + argnames, varargname, kwargname = signature + cnt = len(argnames) + data_args_w = data_w[:cnt] + if varargname: + data_w_stararg = data_w[cnt] + cnt += 1 + else: + data_w_stararg = space.newtuple([]) + + unfiltered_kwds_w = {} + if kwargname: + data_w_starargarg = data_w[cnt] + for w_key in space.unpackiterable(data_w_starargarg): + key = space.str_w(w_key) + w_value = space.getitem(data_w_starargarg, w_key) + unfiltered_kwds_w[key] = w_value + cnt += 1 + assert len(data_w) == cnt + + ndata_args_w = len(data_args_w) + if ndata_args_w >= need_cnt: + 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) + else: + stararg_w = space.unpackiterable(data_w_stararg) + datalen = len(data_args_w) + args_w = [None] * (datalen + len(stararg_w)) + for i in range(0, datalen): + args_w[i] = data_args_w[i] + for i in range(0, len(stararg_w)): + args_w[i + datalen] = stararg_w[i] + assert len(args_w) == need_cnt + + keywords = [] + keywords_w = [] + for key in need_kwds: + keywords.append(key) + keywords_w.append(unfiltered_kwds_w[key]) + + return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) + + @staticmethod + def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w): + args_w = data_w[:shape_cnt] + p = end_keys = shape_cnt + len(shape_keys) + if shape_star: + w_star = data_w[p] + p += 1 + else: + w_star = None + if shape_stst: + w_starstar = data_w[p] + p += 1 + else: + w_starstar = None + return ArgumentsForTranslation(space, args_w, list(shape_keys), + data_w[shape_cnt:end_keys], w_star, + w_starstar) + + def flatten(self): + """ Argument <-> list of w_objects together with "shape" information """ + shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape() + data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)] + for key in shape_keys] + if shape_star: + data_w.append(self.w_stararg) + if shape_stst: + data_w.append(self.w_starstararg) + return (shape_cnt, shape_keys, shape_star, shape_stst), data_w + + def _rawshape(self, nextra=0): + assert not self.combine_has_happened + shape_cnt = len(self.arguments_w)+nextra # Number of positional args + if self.keywords: + shape_keys = self.keywords[:] # List of keywords (strings) + shape_keys.sort() + else: + shape_keys = [] + shape_star = self.w_stararg is not None # Flag: presence of *arg + shape_stst = self.w_starstararg is not None # Flag: presence of **kwds + return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted + +def rawshape(args, nextra=0): + return args._rawshape(nextra) + + +# +# ArgErr family of exceptions raised in case of argument mismatch. +# We try to give error messages following CPython's, which are very informative. +# + +class ArgErr(Exception): + + def getmsg(self): + raise NotImplementedError + +class ArgErrCount(ArgErr): + + def __init__(self, got_nargs, nkwds, signature, + defaults_w, missing_args): + self.signature = signature + + self.num_defaults = 0 if defaults_w is None else len(defaults_w) + self.missing_args = missing_args + self.num_args = got_nargs + self.num_kwds = nkwds + + def getmsg(self): + n = self.signature.num_argnames() + if n == 0: + msg = "takes no arguments (%d given)" % ( + self.num_args + self.num_kwds) + else: + defcount = self.num_defaults + has_kwarg = self.signature.has_kwarg() + num_args = self.num_args + num_kwds = self.num_kwds + if defcount == 0 and not self.signature.has_vararg(): + msg1 = "exactly" + if not has_kwarg: + num_args += num_kwds + num_kwds = 0 + elif not self.missing_args: + msg1 = "at most" + else: + msg1 = "at least" + has_kwarg = False + n -= defcount + if n == 1: + plural = "" + else: + plural = "s" + if has_kwarg or num_kwds > 0: + msg2 = " non-keyword" + else: + msg2 = "" + msg = "takes %s %d%s argument%s (%d given)" % ( + msg1, + n, + msg2, + plural, + num_args) + return msg + +class ArgErrMultipleValues(ArgErr): + + def __init__(self, argname): + self.argname = argname + + def getmsg(self): + msg = "got multiple values for keyword argument '%s'" % ( + self.argname) + return msg + +class ArgErrUnknownKwds(ArgErr): + + def __init__(self, space, num_remainingkwds, keywords, kwds_mapping, + keyword_names_w): + name = '' + self.num_kwds = num_remainingkwds + if num_remainingkwds == 1: + for i in range(len(keywords)): + if i not in kwds_mapping: + name = keywords[i] + if name is None: + # We'll assume it's unicode. Encode it. + # Careful, I *think* it should not be possible to + # get an IndexError here but you never know. + try: + if keyword_names_w is None: + raise IndexError + # note: negative-based indexing from the end + w_name = keyword_names_w[i - len(keywords)] + except IndexError: + name = '?' + else: + w_enc = space.wrap(space.sys.defaultencoding) + w_err = space.wrap("replace") + w_name = space.call_method(w_name, "encode", w_enc, + w_err) + name = space.str_w(w_name) + break + self.kwd_name = name + + def getmsg(self): + if self.num_kwds == 1: + msg = "got an unexpected keyword argument '%s'" % ( + self.kwd_name) + else: + msg = "got %d unexpected keyword arguments" % ( + self.num_kwds) + return msg diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py --- a/pypy/objspace/flow/bytecode.py +++ b/pypy/objspace/flow/bytecode.py @@ -1,11 +1,30 @@ """ Bytecode handling classes and functions for use by the flow space. """ -from pypy.interpreter.pycode import (BytecodeCorruption, - cpython_code_signature) from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG, HAVE_ARGUMENT) -from pypy.interpreter.astcompiler.consts import CO_GENERATOR +from pypy.objspace.flow.argument import Signature +from pypy.objspace.flow.flowcontext import BytecodeCorruption + +CO_GENERATOR = 0x0020 +CO_VARARGS = 0x0004 +CO_VARKEYWORDS = 0x0008 + +def cpython_code_signature(code): + "([list-of-arg-names], vararg-name-or-None, kwarg-name-or-None)." + argcount = code.co_argcount + argnames = list(code.co_varnames[:argcount]) + if code.co_flags & CO_VARARGS: + varargname = code.co_varnames[argcount] + argcount += 1 + else: + varargname = None + if code.co_flags & CO_VARKEYWORDS: + kwargname = code.co_varnames[argcount] + argcount += 1 + else: + kwargname = None + return Signature(argnames, varargname, kwargname) class HostCode(object): """ diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -6,9 +6,8 @@ import collections from pypy.tool.error import source_lines -from pypy.interpreter import pyframe -from pypy.interpreter.argument import ArgumentsForTranslation -from pypy.interpreter.pyopcode import Return, BytecodeCorruption +from pypy.tool.stdlib_opcode import host_bytecode_spec +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.objspace.flow.model import (Constant, Variable, Block, Link, UnwrapException, c_last_exception) from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten, @@ -31,6 +30,10 @@ class StopFlowing(Exception): pass +class Return(Exception): + def __init__(self, value): + self.value = value + class FSException(Exception): def __init__(self, w_type, w_value): assert w_type is not None @@ -46,6 +49,9 @@ class ImplicitOperationError(FSException): pass +class BytecodeCorruption(Exception): + pass + class SpamBlock(Block): # make slots optional, for debugging if hasattr(Block, '__slots__'): @@ -206,6 +212,83 @@ # ____________________________________________________________ +_unary_ops = [('UNARY_POSITIVE', "pos"), + ('UNARY_NEGATIVE', "neg"), + ('UNARY_NOT', "not_"), + ('UNARY_CONVERT', "repr"), + ('UNARY_INVERT', "invert"),] + +def unaryoperation(OPCODE, op): + def UNARY_OP(self, *ignored): + operation = getattr(self.space, op) + w_1 = self.popvalue() + w_result = operation(w_1) + self.pushvalue(w_result) + UNARY_OP.unaryop = op + UNARY_OP.func_name = OPCODE + return UNARY_OP + +_binary_ops = [ + ('BINARY_MULTIPLY', "mul"), + ('BINARY_TRUE_DIVIDE', "truediv"), + ('BINARY_FLOOR_DIVIDE', "floordiv"), + ('BINARY_DIVIDE', "div"), + ('BINARY_MODULO', "mod"), + ('BINARY_ADD', "add"), + ('BINARY_SUBTRACT', "sub"), + ('BINARY_SUBSCR', "getitem"), + ('BINARY_LSHIFT', "lshift"), + ('BINARY_RSHIFT', "rshift"), + ('BINARY_AND', "and_"), + ('BINARY_XOR', "xor"), + ('BINARY_OR', "or_"), + ('INPLACE_MULTIPLY', "inplace_mul"), + ('INPLACE_TRUE_DIVIDE', "inplace_truediv"), + ('INPLACE_FLOOR_DIVIDE', "inplace_floordiv"), + ('INPLACE_DIVIDE', "inplace_div"), + ('INPLACE_MODULO', "inplace_mod"), + ('INPLACE_ADD', "inplace_add"), + ('INPLACE_SUBTRACT', "inplace_sub"), + ('INPLACE_LSHIFT', "inplace_lshift"), + ('INPLACE_RSHIFT', "inplace_rshift"), + ('INPLACE_AND', "inplace_and"), + ('INPLACE_XOR', "inplace_xor"), + ('INPLACE_OR', "inplace_or"), +] + +def binaryoperation(OPCODE, op): + """NOT_RPYTHON""" + def BINARY_OP(self, *ignored): + operation = getattr(self.space, op) + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = operation(w_1, w_2) + self.pushvalue(w_result) + BINARY_OP.binop = op + BINARY_OP.func_name = OPCODE + return BINARY_OP + +_unsupported_ops = [ + ('BINARY_POWER', "a ** b"), + ('BUILD_CLASS', 'creating new classes'), + ('EXEC_STMT', 'exec statement'), + ('STOP_CODE', '???'), + ('STORE_NAME', 'modifying globals'), + ('INPLACE_POWER', 'a **= b'), + ('LOAD_LOCALS', 'locals()'), + ('IMPORT_STAR', 'import *'), + ('MISSING_OPCODE', '???'), + ('DELETE_GLOBAL', 'modifying globals'), + ('DELETE_NAME', 'modifying globals'), + ('DELETE_ATTR', 'deleting attributes'), +] + +def unsupportedoperation(OPCODE, msg): + def UNSUPPORTED(self, *ignored): + raise FlowingError(self, "%s is not RPython" % (msg,)) + UNSUPPORTED.func_name = OPCODE + return UNSUPPORTED + compare_method = [ "cmp_lt", # "<" "cmp_le", # "<=" @@ -220,7 +303,8 @@ "cmp_exc_match", ] -class FlowSpaceFrame(pyframe.CPythonFrame): +class FlowSpaceFrame(object): + opcode_method_names = host_bytecode_spec.method_names def __init__(self, space, graph, code): self.graph = graph @@ -228,7 +312,7 @@ self.pycode = code self.space = space self.w_globals = Constant(func.func_globals) - self.lastblock = None + self.blockstack = [] self.init_closure(func.func_closure) self.f_lineno = code.co_firstlineno @@ -255,6 +339,63 @@ self.valuestackdepth = code.co_nlocals self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals) + def pushvalue(self, w_object): + depth = self.valuestackdepth + self.locals_stack_w[depth] = w_object + self.valuestackdepth = depth + 1 + + def popvalue(self): + depth = self.valuestackdepth - 1 + assert depth >= self.pycode.co_nlocals, "pop from empty value stack" + w_object = self.locals_stack_w[depth] + self.locals_stack_w[depth] = None + self.valuestackdepth = depth + return w_object + + def peekvalue(self, index_from_top=0): + # NOTE: top of the stack is peekvalue(0). + index = self.valuestackdepth + ~index_from_top + assert index >= self.pycode.co_nlocals, ( + "peek past the bottom of the stack") + return self.locals_stack_w[index] + + def pushrevvalues(self, n, values_w): # n should be len(values_w) + assert len(values_w) == n + for i in range(n - 1, -1, -1): + self.pushvalue(values_w[i]) + + def settopvalue(self, w_object, index_from_top=0): + index = self.valuestackdepth + ~index_from_top + assert index >= self.pycode.co_nlocals, ( + "settop past the bottom of the stack") + self.locals_stack_w[index] = w_object + + def popvalues(self, n): + values_w = [self.popvalue() for i in range(n)] + values_w.reverse() + return values_w + + def peekvalues(self, n): + values_w = [None] * n + base = self.valuestackdepth - n + while True: + n -= 1 + if n < 0: + break + values_w[n] = self.locals_stack_w[base+n] + return values_w + + def dropvalues(self, n): + finaldepth = self.valuestackdepth - n + for n in range(finaldepth, self.valuestackdepth): + self.locals_stack_w[n] = None + self.valuestackdepth = finaldepth + + def dropvaluesuntil(self, finaldepth): + for n in range(finaldepth, self.valuestackdepth): + self.locals_stack_w[n] = None + self.valuestackdepth = finaldepth + def save_locals_stack(self): return self.locals_stack_w[:self.valuestackdepth] @@ -262,6 +403,20 @@ 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): # getfastscope() can return real None, for undefined locals data = self.save_locals_stack() @@ -272,7 +427,7 @@ data.append(self.last_exception.w_type) data.append(self.last_exception.w_value) recursively_flatten(self.space, data) - return FrameState(data, self.get_blocklist(), self.last_instr) + return FrameState(data, self.blockstack[:], self.last_instr) def setstate(self, state): """ Reset the frame to the given state. """ @@ -285,7 +440,7 @@ else: self.last_exception = FSException(data[-2], data[-1]) self.last_instr = state.next_instr - self.set_blocklist(state.blocklist) + self.blockstack = state.blocklist[:] def recording(self, block): """ Setup recording of the block and return the recorder. """ @@ -336,7 +491,6 @@ block = self.pendingblocks.popleft() try: self.recorder = self.recording(block) - self.frame_finished_execution = False while True: self.last_instr = self.handle_bytecode(self.last_instr) self.recorder.final_state = self.getstate() @@ -362,9 +516,8 @@ except StopFlowing: pass - except Return: - w_result = self.popvalue() - assert w_result is not None + except Return as exc: + w_result = exc.value link = Link([w_result], graph.returnblock) self.recorder.crnt_block.closeblock(link) @@ -540,8 +693,7 @@ w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: - self.pushvalue(w_returnvalue) # XXX ping pong - raise Return + raise Return(w_returnvalue) else: unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) @@ -561,31 +713,25 @@ if w_top == self.space.w_None: # finally: block with no unroller active return - try: - unroller = self.space.unwrap(w_top) - except UnwrapException: - pass + elif isinstance(w_top, SuspendedUnroller): + # case of a finally: block + return self.unroll_finally(w_top) else: - if isinstance(unroller, SuspendedUnroller): - # case of a finally: block - return self.unroll_finally(unroller) - # case of an except: block. We popped the exception type - self.popvalue() # Now we pop the exception value - unroller = self.space.unwrap(self.popvalue()) - return self.unroll_finally(unroller) + # case of an except: block. We popped the exception type + self.popvalue() # Now we pop the exception value + unroller = self.popvalue() + return self.unroll_finally(unroller) def unroll_finally(self, unroller): # go on unrolling the stack block = self.unrollstack(unroller.kind) if block is None: - w_result = unroller.nomoreblocks() - self.pushvalue(w_result) - raise Return + unroller.nomoreblocks() else: return block.handle(self, unroller) def POP_BLOCK(self, oparg, next_instr): - block = self.pop_block() + block = self.blockstack.pop() block.cleanupstack(self) # the block knows how to clean up the value stack def JUMP_ABSOLUTE(self, jumpto, next_instr): @@ -611,6 +757,55 @@ def PRINT_NEWLINE(self, oparg, next_instr): self.space.appcall(rpython_print_newline) + def JUMP_FORWARD(self, jumpby, next_instr): + next_instr += jumpby + return next_instr + + def JUMP_IF_FALSE(self, stepby, next_instr): + # Python <= 2.6 only + 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): + # Python <= 2.6 only + w_cond = self.peekvalue() + if self.space.is_true(w_cond): + next_instr += stepby + return next_instr + + def POP_JUMP_IF_FALSE(self, target, next_instr): + w_value = self.popvalue() + if not self.space.is_true(w_value): + return target + return next_instr + + def POP_JUMP_IF_TRUE(self, target, next_instr): + w_value = self.popvalue() + if self.space.is_true(w_value): + return target + return next_instr + + def JUMP_IF_FALSE_OR_POP(self, target, next_instr): + w_value = self.peekvalue() + if not self.space.is_true(w_value): + return target + self.popvalue() + return next_instr + + def JUMP_IF_TRUE_OR_POP(self, target, next_instr): + w_value = self.peekvalue() + if self.space.is_true(w_value): + return target + self.popvalue() + return next_instr + + def GET_ITER(self, oparg, next_instr): + w_iterable = self.popvalue() + w_iterator = self.space.iter(w_iterable) + self.pushvalue(w_iterator) + def FOR_ITER(self, jumpby, next_instr): w_iterator = self.peekvalue() try: @@ -626,16 +821,16 @@ return next_instr def SETUP_LOOP(self, offsettoend, next_instr): - block = LoopBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = LoopBlock(self, next_instr + offsettoend) + self.blockstack.append(block) def SETUP_EXCEPT(self, offsettoend, next_instr): - block = ExceptBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = ExceptBlock(self, next_instr + offsettoend) + self.blockstack.append(block) def SETUP_FINALLY(self, offsettoend, next_instr): - block = FinallyBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = FinallyBlock(self, next_instr + offsettoend) + self.blockstack.append(block) def SETUP_WITH(self, offsettoend, next_instr): # A simpler version than the 'real' 2.7 one: @@ -645,8 +840,8 @@ w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__")) self.settopvalue(w_exit) w_result = self.space.call_method(w_manager, "__enter__") - block = WithBlock(self, next_instr + offsettoend, self.lastblock) - self.lastblock = block + block = WithBlock(self, next_instr + offsettoend) + self.blockstack.append(block) self.pushvalue(w_result) def WITH_CLEANUP(self, oparg, next_instr): @@ -654,14 +849,13 @@ # and cannot suppress the exception. # This opcode changed a lot between CPython versions if sys.version_info >= (2, 6): - w_unroller = self.popvalue() + unroller = self.popvalue() w_exitfunc = self.popvalue() - self.pushvalue(w_unroller) + self.pushvalue(unroller) else: w_exitfunc = self.popvalue() - w_unroller = self.peekvalue(0) + unroller = self.peekvalue(0) - unroller = self.space.unwrap(w_unroller) w_None = self.space.w_None if isinstance(unroller, SApplicationException): operr = unroller.operr @@ -678,9 +872,14 @@ raise FlowingError(self, "Local variable referenced before assignment") self.pushvalue(w_value) + def LOAD_CONST(self, constindex, next_instr): + w_const = self.getconstant_w(constindex) + self.pushvalue(w_const) + def LOAD_GLOBAL(self, nameindex, next_instr): w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex)) self.pushvalue(w_result) + LOAD_NAME = LOAD_GLOBAL def LOAD_ATTR(self, nameindex, next_instr): "obj.attributename" @@ -693,6 +892,65 @@ def LOAD_DEREF(self, varindex, next_instr): self.pushvalue(self.closure[varindex]) + def STORE_FAST(self, varindex, next_instr): + w_newvalue = self.popvalue() + assert w_newvalue is not None + self.locals_stack_w[varindex] = w_newvalue + + def STORE_GLOBAL(self, nameindex, next_instr): + varname = self.getname_u(nameindex) + raise FlowingError(self, + "Attempting to modify global variable %r." % (varname)) + + def POP_TOP(self, oparg, next_instr): + self.popvalue() + + def ROT_TWO(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_2) + + def ROT_THREE(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + w_3 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_3) + self.pushvalue(w_2) + + def ROT_FOUR(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + w_3 = self.popvalue() + w_4 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_4) + self.pushvalue(w_3) + self.pushvalue(w_2) + + def DUP_TOP(self, oparg, next_instr): + w_1 = self.peekvalue() + self.pushvalue(w_1) + + def DUP_TOPX(self, itemcount, next_instr): + delta = itemcount - 1 + while True: + itemcount -= 1 + if itemcount < 0: + break + w_value = self.peekvalue(delta) + self.pushvalue(w_value) + + for OPCODE, op in _unary_ops: + locals()[OPCODE] = unaryoperation(OPCODE, op) + + for OPCODE, op in _binary_ops: + locals()[OPCODE] = binaryoperation(OPCODE, op) + + for OPCODE, op in _unsupported_ops: + locals()[OPCODE] = unsupportedoperation(OPCODE, op) + def BUILD_LIST_FROM_ARG(self, _, next_instr): # This opcode was added with pypy-1.8. Here is a simpler # version, enough for annotation. @@ -700,12 +958,191 @@ self.pushvalue(self.space.newlist([])) self.pushvalue(last_val) + def call_function(self, oparg, w_star=None, w_starstar=None): + n_arguments = oparg & 0xff + n_keywords = (oparg>>8) & 0xff + if n_keywords: + keywords = [None] * n_keywords + keywords_w = [None] * n_keywords + while True: + n_keywords -= 1 + if n_keywords < 0: + break + w_value = self.popvalue() + w_key = self.popvalue() + key = self.space.str_w(w_key) + keywords[n_keywords] = key + keywords_w[n_keywords] = w_value + else: + keywords = None + keywords_w = None + arguments = self.popvalues(n_arguments) + args = self.argument_factory(arguments, keywords, keywords_w, w_star, + w_starstar) + w_function = self.popvalue() + w_result = self.space.call_args(w_function, args) + self.pushvalue(w_result) + + def CALL_FUNCTION(self, oparg, next_instr): + self.call_function(oparg) + CALL_METHOD = CALL_FUNCTION + + def CALL_FUNCTION_VAR(self, oparg, next_instr): + w_varargs = self.popvalue() + self.call_function(oparg, w_varargs) + + def CALL_FUNCTION_KW(self, oparg, next_instr): + w_varkw = self.popvalue() + self.call_function(oparg, None, w_varkw) + + def CALL_FUNCTION_VAR_KW(self, oparg, next_instr): + w_varkw = self.popvalue() + w_varargs = self.popvalue() + self.call_function(oparg, w_varargs, w_varkw) + def MAKE_FUNCTION(self, numdefaults, next_instr): w_codeobj = self.popvalue() defaults = self.popvalues(numdefaults) fn = self.space.newfunction(w_codeobj, self.w_globals, defaults) self.pushvalue(fn) + def STORE_ATTR(self, nameindex, next_instr): + "obj.attributename = newvalue" + w_attributename = self.getname_w(nameindex) + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setattr(w_obj, w_attributename, w_newvalue) + + def UNPACK_SEQUENCE(self, itemcount, next_instr): + w_iterable = self.popvalue() + items = self.space.unpackiterable(w_iterable, itemcount) + self.pushrevvalues(itemcount, items) + + def slice(self, w_start, w_end): + w_obj = self.popvalue() + w_result = self.space.getslice(w_obj, w_start, w_end) + self.pushvalue(w_result) + + def SLICE_0(self, oparg, next_instr): + self.slice(self.space.w_None, self.space.w_None) + + def SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.slice(w_start, self.space.w_None) + + def SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.slice(self.space.w_None, w_end) + + def SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.slice(w_start, w_end) + + def storeslice(self, w_start, w_end): + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setslice(w_obj, w_start, w_end, w_newvalue) + + def STORE_SLICE_0(self, oparg, next_instr): + self.storeslice(self.space.w_None, self.space.w_None) + + def STORE_SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.storeslice(w_start, self.space.w_None) + + def STORE_SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.storeslice(self.space.w_None, w_end) + + def STORE_SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.storeslice(w_start, w_end) + + def deleteslice(self, w_start, w_end): + w_obj = self.popvalue() + self.space.delslice(w_obj, w_start, w_end) + + def DELETE_SLICE_0(self, oparg, next_instr): + self.deleteslice(self.space.w_None, self.space.w_None) + + def DELETE_SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.deleteslice(w_start, self.space.w_None) + + def DELETE_SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.deleteslice(self.space.w_None, w_end) + + def DELETE_SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.deleteslice(w_start, w_end) + + 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) + + def DELETE_FAST(self, varindex, next_instr): + if self.locals_stack_w[varindex] is None: + varname = self.getlocalvarname(varindex) + message = "local variable '%s' referenced before assignment" + raise UnboundLocalError(message, varname) + self.locals_stack_w[varindex] = None + + def STORE_MAP(self, oparg, next_instr): + w_key = self.popvalue() + w_value = self.popvalue() + w_dict = self.peekvalue() + self.space.setitem(w_dict, w_key, w_value) + + def STORE_SUBSCR(self, oparg, next_instr): + "obj[subscr] = newvalue" + w_subscr = self.popvalue() + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setitem(w_obj, w_subscr, w_newvalue) + + def BUILD_SLICE(self, numargs, next_instr): + if numargs == 3: + w_step = self.popvalue() + elif numargs == 2: + w_step = self.space.w_None + else: + raise BytecodeCorruption + w_end = self.popvalue() + w_start = self.popvalue() + w_slice = self.space.newslice(w_start, w_end, w_step) + self.pushvalue(w_slice) + + def DELETE_SUBSCR(self, oparg, next_instr): + "del obj[subscr]" + w_subscr = self.popvalue() + w_obj = self.popvalue() + self.space.delitem(w_obj, w_subscr) + + def BUILD_TUPLE(self, itemcount, next_instr): + items = self.popvalues(itemcount) + w_tuple = self.space.newtuple(items) + self.pushvalue(w_tuple) + + def BUILD_LIST(self, itemcount, next_instr): + items = self.popvalues(itemcount) + w_list = self.space.newlist(items) + self.pushvalue(w_list) + + def BUILD_MAP(self, itemcount, next_instr): + w_dict = self.space.newdict() + self.pushvalue(w_dict) + + def NOP(self, *args): + pass + # XXX Unimplemented 2.7 opcodes ---------------- # Set literals, set comprehensions @@ -765,7 +1202,7 @@ self.w_returnvalue = w_returnvalue def nomoreblocks(self): - return self.w_returnvalue + raise Return(self.w_returnvalue) def state_unpack_variables(self, space): return [self.w_returnvalue] @@ -823,10 +1260,9 @@ """Abstract base class for frame blocks from the blockstack, used by the SETUP_XXX and POP_BLOCK opcodes.""" - def __init__(self, frame, handlerposition, previous): + def __init__(self, frame, handlerposition): self.handlerposition = handlerposition self.valuestackdepth = frame.valuestackdepth - self.previous = previous # this makes a linked list of blocks def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -856,7 +1292,7 @@ # 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 - frame.append_block(self) + frame.blockstack.append(self) return unroller.jump_to else: # jump to the end of the loop @@ -878,7 +1314,7 @@ # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. - frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(unroller) frame.pushvalue(operationerr.get_w_value(frame.space)) frame.pushvalue(operationerr.w_type) frame.last_exception = operationerr @@ -894,7 +1330,7 @@ # any abnormal reason for unrolling a finally: triggers the end of # the block unrolling and the entering the finally: handler. self.cleanupstack(frame) - frame.pushvalue(frame.space.wrap(unroller)) + frame.pushvalue(unroller) return self.handlerposition # jump to the handler diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py --- a/pypy/objspace/flow/framestate.py +++ b/pypy/objspace/flow/framestate.py @@ -6,9 +6,6 @@ self.mergeable = mergeable self.blocklist = blocklist self.next_instr = next_instr - for w1 in self.mergeable: - assert isinstance(w1, (Variable, Constant)) or w1 is None, ( - '%r found in frame state' % w1) def copy(self): "Make a copy of this state in which all Variables are fresh." @@ -109,12 +106,10 @@ from pypy.objspace.flow.flowcontext import SuspendedUnroller i = 0 while i < len(lst): - item = lst[i] - if not (isinstance(item, Constant) and - isinstance(item.value, SuspendedUnroller)): + unroller = lst[i] + if not isinstance(unroller, SuspendedUnroller): i += 1 else: - unroller = item.value vars = unroller.state_unpack_variables(space) key = unroller.__class__, len(vars) try: @@ -132,4 +127,4 @@ arguments = lst[i+1: i+1+argcount] del lst[i+1: i+1+argcount] unroller = unrollerclass.state_pack_variables(space, *arguments) - lst[i] = space.wrap(unroller) + lst[i] = unroller diff --git a/pypy/objspace/flow/generator.py b/pypy/objspace/flow/generator.py --- a/pypy/objspace/flow/generator.py +++ b/pypy/objspace/flow/generator.py @@ -6,7 +6,7 @@ from pypy.translator.unsimplify import split_block from pypy.translator.simplify import eliminate_empty_blocks, simplify_graph from pypy.tool.sourcetools import func_with_new_name -from pypy.interpreter.argument import Signature +from pypy.objspace.flow.argument import Signature class AbstractPosition(object): diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py --- a/pypy/objspace/flow/objspace.py +++ b/pypy/objspace/flow/objspace.py @@ -7,8 +7,7 @@ import types From noreply at buildbot.pypy.org Mon Oct 22 00:34:06 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:06 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Add timeout to RLock.acquire() Message-ID: <20121021223406.5A21F1C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58335:475f3eb6c7d7 Date: 2012-10-21 06:10 +0200 http://bitbucket.org/pypy/pypy/changeset/475f3eb6c7d7/ Log: Add timeout to RLock.acquire() 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 @@ -31,6 +31,26 @@ ## sys.stderr.write(msg) +def parse_acquire_args(space, blocking, timeout): + if not blocking and timeout != -1.0: + raise OperationError(space.w_ValueError, space.wrap( + "can't specify a timeout for a non-blocking call")) + if timeout < 0.0 and timeout != -1.0: + raise OperationError(space.w_ValueError, space.wrap( + "timeout value must be strictly positive")) + if not blocking: + microseconds = 0 + elif timeout == -1.0: + microseconds = -1 + else: + timeout *= 1e6 + if timeout > float(TIMEOUT_MAX): + raise OperationError(space.w_ValueError, space.wrap( + "timeout value is too large")) + microseconds = r_longlong(timeout) + return microseconds + + class Lock(Wrappable): "A wrappable box around an interp-level lock object." @@ -49,22 +69,7 @@ With an argument, this will only block if the argument is true, and the return value reflects whether the lock is acquired. The blocking operation is interruptible.""" - if not blocking and timeout != -1.0: - raise OperationError(space.w_ValueError, space.wrap( - "can't specify a timeout for a non-blocking call")) - if timeout < 0.0 and timeout != -1.0: - raise OperationError(space.w_ValueError, space.wrap( - "timeout value must be strictly positive")) - if not blocking: - microseconds = 0 - elif timeout == -1.0: - microseconds = -1 - else: - timeout *= 1e6 - if timeout > float(TIMEOUT_MAX): - raise OperationError(space.w_ValueError, space.wrap( - "timeout value is too large")) - microseconds = r_longlong(timeout) + microseconds = parse_acquire_args(space, blocking, timeout) mylock = self.lock result = mylock.acquire_timed(microseconds) return space.newbool(result) @@ -150,8 +155,8 @@ return space.wrap("<%s owner=%d count=%d>" % ( typename, self.rlock_owner, self.rlock_count)) - @unwrap_spec(blocking=bool) - def acquire_w(self, space, blocking=True): + @unwrap_spec(blocking=bool, timeout=float) + def acquire_w(self, space, blocking=True, timeout=-1.0): """Lock the lock. `blocking` indicates whether we should wait for the lock to be available or not. If `blocking` is False and another thread holds the lock, the method will return False @@ -164,6 +169,7 @@ Precisely, if the current thread already holds the lock, its internal counter is simply incremented. If nobody holds the lock, the lock is taken and its internal counter initialized to 1.""" + microseconds = parse_acquire_args(space, blocking, timeout) tid = thread.get_ident() if self.rlock_count > 0 and tid == self.rlock_owner: try: @@ -177,7 +183,7 @@ if self.rlock_count > 0 or not self.lock.acquire(False): if not blocking: return space.w_False - r = self.lock.acquire(True) + r = self.lock.acquire_timed(microseconds) if r: assert self.rlock_count == 0 self.rlock_owner = tid @@ -212,9 +218,12 @@ else: return space.w_False - @unwrap_spec(count=int, owner=int) - def acquire_restore_w(self, space, count, owner): + def acquire_restore_w(self, space, w_saved_state): """For internal use by `threading.Condition`.""" + # saved_state is the value returned by release_save() + w_count, w_owner = space.unpackiterable(w_saved_state, 2) + count = space.int_w(w_count) + owner = space.int_w(w_owner) r = True if not self.lock.acquire(False): r = self.lock.acquire(True) diff --git a/pypy/module/thread/test/test_lock.py b/pypy/module/thread/test/test_lock.py --- a/pypy/module/thread/test/test_lock.py +++ b/pypy/module/thread/test/test_lock.py @@ -128,3 +128,9 @@ with lock: assert lock._is_owned() is True + def test_timeout(self): + import _thread + lock = _thread.RLock() + assert lock.acquire() is True + assert lock.acquire(False) is True + assert lock.acquire(True, timeout=.1) is True From noreply at buildbot.pypy.org Mon Oct 22 00:34:07 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:07 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Add a bunch of gc.collect() to test_weakref. Message-ID: <20121021223407.8B68F1C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58336:c653b66ed86e Date: 2012-10-21 06:37 +0200 http://bitbucket.org/pypy/pypy/changeset/c653b66ed86e/ Log: Add a bunch of gc.collect() to test_weakref. Copied from the 2.7 branch. diff --git a/lib-python/3.2/test/test_weakref.py b/lib-python/3.2/test/test_weakref.py --- a/lib-python/3.2/test/test_weakref.py +++ b/lib-python/3.2/test/test_weakref.py @@ -8,6 +8,7 @@ import copy from test import support +from test.support import gc_collect # Used in ReferencesTestCase.test_ref_created_during_del() . ref_from_del = None @@ -67,6 +68,7 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del o + gc_collect() self.assertTrue(ref1() is None, "expected reference to be invalidated") self.assertTrue(ref2() is None, @@ -98,13 +100,16 @@ ref1 = weakref.proxy(o, self.callback) ref2 = weakref.proxy(o, self.callback) del o + gc_collect() def check(proxy): proxy.bar self.assertRaises(ReferenceError, check, ref1) self.assertRaises(ReferenceError, check, ref2) - self.assertRaises(ReferenceError, bool, weakref.proxy(C())) + ref3 = weakref.proxy(C()) + gc_collect() + self.assertRaises(ReferenceError, bool, ref3) self.assertEqual(self.cbcalled, 2) def check_basic_ref(self, factory): @@ -121,6 +126,7 @@ o = factory() ref = weakref.ref(o, self.callback) del o + gc_collect() self.assertTrue(self.cbcalled == 1, "callback did not properly set 'cbcalled'") self.assertTrue(ref() is None, @@ -145,6 +151,7 @@ self.assertTrue(weakref.getweakrefcount(o) == 2, "wrong weak ref count for object") del proxy + gc_collect() self.assertTrue(weakref.getweakrefcount(o) == 1, "wrong weak ref count for object after deleting proxy") @@ -320,6 +327,7 @@ "got wrong number of weak reference objects") del ref1, ref2, proxy1, proxy2 + gc_collect() self.assertTrue(weakref.getweakrefcount(o) == 0, "weak reference objects not unlinked from" " referent when discarded.") @@ -333,6 +341,7 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del ref1 + gc_collect() self.assertTrue(weakref.getweakrefs(o) == [ref2], "list of refs does not match") @@ -340,10 +349,12 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del ref2 + gc_collect() self.assertTrue(weakref.getweakrefs(o) == [ref1], "list of refs does not match") del ref1 + gc_collect() self.assertTrue(weakref.getweakrefs(o) == [], "list of refs not cleared") @@ -709,6 +720,7 @@ self.assertTrue(mr.called) self.assertEqual(mr.value, 24) del o + gc_collect() self.assertTrue(mr() is None) self.assertTrue(mr.called) @@ -838,12 +850,14 @@ self.assertEqual(len(dict), self.COUNT - 1, "deleting object did not cause dictionary update") del objects, o + gc_collect() self.assertEqual(len(dict), 0, "deleting the values did not clear the dictionary") # regression on SF bug #447152: dict = weakref.WeakValueDictionary() self.assertRaises(KeyError, dict.__getitem__, 1) dict[2] = C() + gc_collect() self.assertRaises(KeyError, dict.__getitem__, 2) def test_weak_keys(self): @@ -864,9 +878,11 @@ del items1, items2 self.assertEqual(len(dict), self.COUNT) del objects[0] + gc_collect() self.assertTrue(len(dict) == (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o + gc_collect() self.assertTrue(len(dict) == 0, "deleting the keys did not clear the dictionary") o = Object(42) @@ -1225,6 +1241,7 @@ for o in objs: count += 1 del d[o] + gc_collect() self.assertEqual(len(d), 0) self.assertEqual(count, 2) @@ -1317,6 +1334,7 @@ >>> id2obj(a_id) is a True >>> del a +>>> gc_collect() >>> try: ... id2obj(a_id) ... except KeyError: From noreply at buildbot.pypy.org Mon Oct 22 00:34:08 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:08 +0200 (CEST) Subject: [pypy-commit] pypy py3k: __eq__ should be called even when the object is compared with itself. Message-ID: <20121021223408.BD9721C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58337:8d08cc91b583 Date: 2012-10-21 08:36 +0200 http://bitbucket.org/pypy/pypy/changeset/8d08cc91b583/ Log: __eq__ should be called even when the object is compared with itself. This accounts for at least two failures, in test_weakref.py and test_decimal.py diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -543,12 +543,6 @@ left, right = specialnames op = getattr(operator, left) def comparison_impl(space, w_obj1, w_obj2): - # for == and !=, we do a quick check for identity. This also - # guarantees that identity implies equality. - if left == '__eq__' or left == '__ne__': - if space.is_w(w_obj1, w_obj2): - return space.wrap(left == '__eq__') - # w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, left) @@ -582,12 +576,11 @@ # we did not find any special method, let's do the default logic for # == and != if left == '__eq__': - # they are not identical, else it would have been caught by the if - # at the top of the function - assert not space.is_w(w_obj1, w_obj2) - return space.w_False + if space.is_w(w_obj1, w_obj2): + return space.w_True + else: + return space.w_False elif left == '__ne__': - assert not space.is_w(w_obj1, w_obj2) return space.not_(space.eq(w_obj1, w_obj2)) # # if we arrived here, they are unorderable diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py --- a/pypy/objspace/test/test_descroperation.py +++ b/pypy/objspace/test/test_descroperation.py @@ -396,6 +396,16 @@ assert res1 == res2 == 123 assert l == [A, B, B, A] + def test__eq__called(self): + l = [] + class A(object): + def __eq__(self, other): + l.append((self, other)) + return True + a = A() + a == a + assert l == [(a, a)] + def test_subclass_comparison(self): # the __eq__ *is* called with reversed arguments l = [] From noreply at buildbot.pypy.org Mon Oct 22 00:34:10 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:10 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix own tests in module/_codecs Message-ID: <20121021223410.027ED1C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58338:82d0647b840c Date: 2012-10-21 09:12 +0200 http://bitbucket.org/pypy/pypy/changeset/82d0647b840c/ Log: Fix own tests in module/_codecs diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -454,7 +454,7 @@ make_decoder_wrapper('mbcs_decode') # utf-8 functions are not regular, because we have to pass -# "allow_surrogates=True" +# "allow_surrogates=False" @unwrap_spec(uni=unicode, errors='str_or_None') def utf_8_encode(space, uni, errors="strict"): if errors is None: @@ -462,7 +462,7 @@ state = space.fromcache(CodecState) result = runicode.unicode_encode_utf_8( uni, len(uni), errors, state.encode_error_handler, - allow_surrogates=True) + allow_surrogates=False) return space.newtuple([space.wrapbytes(result), space.wrap(len(uni))]) @unwrap_spec(string='bufferstr', errors='str_or_None', @@ -475,7 +475,7 @@ result, consumed = runicode.str_decode_utf_8( string, len(string), errors, final, state.decode_error_handler, - allow_surrogates=True) + allow_surrogates=False) return space.newtuple([space.wrap(result), space.wrap(consumed)]) @unwrap_spec(data="bufferstr", errors='str_or_None', byteorder=int, diff --git a/pypy/rlib/runicode.py b/pypy/rlib/runicode.py --- a/pypy/rlib/runicode.py +++ b/pypy/rlib/runicode.py @@ -295,13 +295,7 @@ r, pos = errorhandler(errors, 'utf-8', 'surrogates not allowed', s, pos-1, pos) - for ch in r: - if ord(ch) < 0x80: - result.append(chr(ord(ch))) - else: - errorhandler('strict', 'utf-8', - 'surrogates not allowed', - s, pos-1, pos) + result.append(r) continue # else: Fall through and handles isolated high surrogates result.append((chr((0xe0 | (ch >> 12))))) From noreply at buildbot.pypy.org Mon Oct 22 00:34:11 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:11 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Use 'surrogateescape' error handling in fsencode/fsdecode functions. Message-ID: <20121021223411.68E131C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58339:9c5666c6a8e9 Date: 2012-10-21 09:26 +0200 http://bitbucket.org/pypy/pypy/changeset/9c5666c6a8e9/ Log: Use 'surrogateescape' error handling in fsencode/fsdecode functions. diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -39,9 +39,16 @@ def fsencode_w(space, w_obj): if space.isinstance_w(w_obj, space.w_unicode): w_obj = space.call_method(w_obj, 'encode', - getfilesystemencoding(space)) + getfilesystemencoding(space), + space.wrap('surrogateescape')) return space.bytes0_w(w_obj) +def fsdecode(space, w_obj): + w_unicode = space.call_method(w_obj, 'decode', + getfilesystemencoding(space), + space.wrap('surrogateescape')) + return w_unicode + class FileEncoder(object): def __init__(self, space, w_obj): self.space = space @@ -63,8 +70,7 @@ def as_unicode(self): space = self.space - w_unicode = space.call_method(self.w_obj, 'decode', - getfilesystemencoding(space)) + w_unicode = fsdecode(space, self.w_obj) return space.unicode0_w(w_unicode) @specialize.memo() @@ -544,17 +550,11 @@ if space.isinstance_w(w_dirname, space.w_unicode): dirname = FileEncoder(space, w_dirname) result = rposix.listdir(dirname) - w_fs_encoding = getfilesystemencoding(space) len_result = len(result) result_w = [None] * len_result for i in range(len_result): w_bytes = space.wrapbytes(result[i]) - try: - result_w[i] = space.call_method(w_bytes, - "decode", w_fs_encoding) - except OperationError, e: - # fall back to the original byte string - result_w[i] = w_bytes + result_w[i] = fsdecode(space, w_bytes) else: dirname = space.str0_w(w_dirname) result = rposix.listdir(dirname) diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -292,10 +292,17 @@ u = b"caf\xe9".decode(sys.getfilesystemencoding()) except UnicodeDecodeError: # Could not decode, listdir returned the byte string - assert (bytes, b"caf\xe9") in typed_result + assert (str, 'caf\udce9') in typed_result else: assert (str, u) in typed_result + def test_undecodable_filename(self): + posix = self.posix + assert posix.access('caf\xe9', posix.R_OK) is False + assert posix.access(b'caf\xe9', posix.R_OK) is False + assert posix.access('caf\udcc0', posix.R_OK) is False + assert posix.access(b'caf\xc3', posix.R_OK) is False + def test_access(self): pdir = self.pdir + '/file1' posix = self.posix From noreply at buildbot.pypy.org Mon Oct 22 00:34:12 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:12 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix two CPython specific tests Message-ID: <20121021223412.8C6F41C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58340:7ad662acdaac Date: 2012-10-21 09:41 +0200 http://bitbucket.org/pypy/pypy/changeset/7ad662acdaac/ Log: Fix two CPython specific tests diff --git a/lib-python/3.2/test/test_weakref.py b/lib-python/3.2/test/test_weakref.py --- a/lib-python/3.2/test/test_weakref.py +++ b/lib-python/3.2/test/test_weakref.py @@ -640,9 +640,11 @@ gc.collect() self.assertEqual(alist, []) + @support.impl_detail(pypy=False) def test_gc_during_ref_creation(self): self.check_gc_during_creation(weakref.ref) + @support.impl_detail(pypy=False) def test_gc_during_proxy_creation(self): self.check_gc_during_creation(weakref.proxy) From noreply at buildbot.pypy.org Mon Oct 22 00:34:13 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:13 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Implement the %a format code. Message-ID: <20121021223413.C11C21C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58341:82b2f6045665 Date: 2012-10-21 10:17 +0200 http://bitbucket.org/pypy/pypy/changeset/82b2f6045665/ Log: Implement the %a format code. diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -19,11 +19,8 @@ object, but escape the non-ASCII characters in the string returned by repr() using \\x, \\u or \\U escapes. This generates a string similar to that returned by repr() in Python 2.""" - from pypy.objspace.std.unicodetype import decode_object, encode_object - # repr is guaranteed to be unicode - w_repr = space.repr(w_obj) - w_encoded = encode_object(space, w_repr, 'ascii', 'backslashreplace') - return decode_object(space, w_encoded, 'ascii', None) + from pypy.objspace.std.unicodetype import ascii_from_object + return ascii_from_object(space, w_obj) @unwrap_spec(code=int) def chr(space, code): diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py --- a/pypy/objspace/std/formatting.py +++ b/pypy/objspace/std/formatting.py @@ -2,7 +2,8 @@ String formatting routines. """ from pypy.interpreter.error import OperationError -from pypy.objspace.std.unicodetype import unicode_from_object +from pypy.objspace.std.unicodetype import ( + unicode_from_object, ascii_from_object) from pypy.rlib import jit from pypy.rlib.rarithmetic import ovfcheck from pypy.rlib.rfloat import formatd, DTSF_ALT, isnan, isinf @@ -449,6 +450,10 @@ def fmt_r(self, w_value): self.std_wp(self.space.unicode_w(self.space.repr(w_value))) + def fmt_a(self, w_value): + w_value = ascii_from_object(self.space, w_value) + self.std_wp(self.space.unicode_w(w_value)) + def fmt_c(self, w_value): self.prec = -1 # just because space = self.space diff --git a/pypy/objspace/std/test/test_stringformat.py b/pypy/objspace/std/test/test_stringformat.py --- a/pypy/objspace/std/test/test_stringformat.py +++ b/pypy/objspace/std/test/test_stringformat.py @@ -281,3 +281,9 @@ def test_invalid_char(self): f = 4 raises(ValueError, '"%\u1234" % (f,)') + + def test_ascii(self): + assert "<%a>" % "test" == "<'test'>" + assert "<%a>" % "\t\x80" == "<'\\t\\x80'>" + assert "<%r>" % "\xe9" == "<'\xe9'>" + assert "<%a>" % "\xe9" == "<'\\xe9'>" diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -265,6 +265,14 @@ w_unicode_method = space.lookup(w_obj, "__str__") return space.repr(w_obj) if w_unicode_method is None else space.str(w_obj) +def ascii_from_object(space, w_obj): + """Implements builtins.ascii()""" + # repr is guaranteed to be unicode + w_repr = space.repr(w_obj) + w_encoded = encode_object(space, w_repr, 'ascii', 'backslashreplace') + return decode_object(space, w_encoded, 'ascii', None) + + @unwrap_spec(w_object = WrappedDefault(u'')) def descr_new_(space, w_unicodetype, w_object=None, w_encoding=None, w_errors=None): From noreply at buildbot.pypy.org Mon Oct 22 00:34:14 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:14 +0200 (CEST) Subject: [pypy-commit] pypy py3k: csv: fix tests when run with -A, then fix the implementation. Message-ID: <20121021223414.D65E81C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58342:b59013f9587e Date: 2012-10-21 12:29 +0200 http://bitbucket.org/pypy/pypy/changeset/b59013f9587e/ Log: csv: fix tests when run with -A, then fix the implementation. diff --git a/pypy/module/_csv/interp_reader.py b/pypy/module/_csv/interp_reader.py --- a/pypy/module/_csv/interp_reader.py +++ b/pypy/module/_csv/interp_reader.py @@ -40,6 +40,7 @@ def save_field(self, field_builder): field = field_builder.build() + print "AFA SAVE FIELD", field if self.numeric_field: from pypy.objspace.std.strutil import ParseStringError from pypy.objspace.std.strutil import string_to_float @@ -71,11 +72,7 @@ state != START_RECORD and state != EAT_CRNL and (len(field_builder.build()) > 0 or state == IN_QUOTED_FIELD)): - if dialect.strict: - raise self.error(u"newline inside string") - else: - self.save_field(field_builder) - break + raise self.error(u"newline inside string") raise self.line_num += 1 line = space.unicode_w(w_line) diff --git a/pypy/module/_csv/test/test_reader.py b/pypy/module/_csv/test/test_reader.py --- a/pypy/module/_csv/test/test_reader.py +++ b/pypy/module/_csv/test/test_reader.py @@ -28,7 +28,7 @@ def test_cannot_read_bytes(self): import _csv reader = _csv.reader([b'foo']) - raises(TypeError, "next(reader)") + raises((TypeError, _csv.Error), next, reader) def test_read_oddinputs(self): self._read_test([], []) @@ -107,9 +107,9 @@ self._read_test(['12,12,1",'], [['12', '12', '1"', '']]) def test_read_eof(self): - self._read_test(['a,"'], [['a', '']]) - self._read_test(['"a'], [['a']]) - self._read_test(['^'], [['\n']], escapechar='^') - self._read_test(['a,"'], 'Error', strict=True) + self._read_test(['a,"'], []) + self._read_test(['"a'], 'Error') + self._read_test(['^'], 'Error', escapechar='^') + self._read_test(['a,"'], [], strict=True) self._read_test(['"a'], 'Error', strict=True) self._read_test(['^'], 'Error', escapechar='^', strict=True) From noreply at buildbot.pypy.org Mon Oct 22 00:34:16 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:16 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Add support for the __bytes__ special method. Message-ID: <20121021223416.1381C1C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58343:12c883a639bb Date: 2012-10-21 12:48 +0200 http://bitbucket.org/pypy/pypy/changeset/12c883a639bb/ Log: Add support for the __bytes__ special method. diff --git a/pypy/objspace/std/stringtype.py b/pypy/objspace/std/stringtype.py --- a/pypy/objspace/std/stringtype.py +++ b/pypy/objspace/std/stringtype.py @@ -310,6 +310,12 @@ else: return [c for c in string] + w_bytes_method = space.lookup(w_source, "__bytes__") + if w_bytes_method: + w_bytes = space.call_function(w_bytes_method, w_source) + # XXX a bit inefficient + return space.bytes_w(w_bytes) + # sequence of bytes data = [] w_iter = space.iter(w_source) diff --git a/pypy/objspace/std/test/test_stringobject.py b/pypy/objspace/std/test/test_stringobject.py --- a/pypy/objspace/std/test/test_stringobject.py +++ b/pypy/objspace/std/test/test_stringobject.py @@ -702,6 +702,12 @@ assert b[1:0] == b"" raises(TypeError, "b[3] = 'x'") + def test_fromobject(self): + class S: + def __bytes__(self): + return b"bytes" + assert bytes(S()) == b"bytes" + def test_getnewargs(self): assert b"foo".__getnewargs__() == (b"foo",) From noreply at buildbot.pypy.org Mon Oct 22 00:34:17 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:17 +0200 (CEST) Subject: [pypy-commit] pypy py3k: __unicode__ don't exist anymore. __bytes__ is now the space method that wekrefs have to forward. Message-ID: <20121021223417.4C5B51C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58344:4ab60a17cf03 Date: 2012-10-21 12:51 +0200 http://bitbucket.org/pypy/pypy/changeset/4ab60a17cf03/ Log: __unicode__ don't exist anymore. __bytes__ is now the space method that wekrefs have to forward. 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 @@ -376,12 +376,12 @@ proxy_typedef_dict[special_method] = interp2app(func) callable_proxy_typedef_dict[special_method] = interp2app(func) -# __unicode__ is not yet a space operation +# __bytes__ is not yet a space operation def proxy_unicode(space, w_obj): w_obj = force(space, w_obj) - return space.call_method(w_obj, '__unicode__') -proxy_typedef_dict['__unicode__'] = interp2app(proxy_unicode) -callable_proxy_typedef_dict['__unicode__'] = interp2app(proxy_unicode) + return space.call_method(w_obj, '__bytes__') +proxy_typedef_dict['__bytes__'] = interp2app(proxy_unicode) +callable_proxy_typedef_dict['__bytes__'] = interp2app(proxy_unicode) W_Proxy.typedef = TypeDef("weakproxy", diff --git a/pypy/module/_weakref/test/test_weakref.py b/pypy/module/_weakref/test/test_weakref.py --- a/pypy/module/_weakref/test/test_weakref.py +++ b/pypy/module/_weakref/test/test_weakref.py @@ -419,14 +419,14 @@ print(s) assert "dead" in s - def test_unicode(self): + def test_bytes(self): import _weakref class C(object): - def __str__(self): - return "string" + def __bytes__(self): + return b"string" instance = C() - assert "__str__" in dir(_weakref.proxy(instance)) - assert str(_weakref.proxy(instance)) == "string" + assert "__bytes__" in dir(_weakref.proxy(instance)) + assert bytes(_weakref.proxy(instance)) == b"string" def test_eq(self): import _weakref From noreply at buildbot.pypy.org Mon Oct 22 00:34:18 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:18 +0200 (CEST) Subject: [pypy-commit] pypy py3k: One more collect() to fix the test. Message-ID: <20121021223418.785A91C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58345:084eca8026f9 Date: 2012-10-21 12:52 +0200 http://bitbucket.org/pypy/pypy/changeset/084eca8026f9/ Log: One more collect() to fix the test. diff --git a/lib-python/3.2/test/test_weakref.py b/lib-python/3.2/test/test_weakref.py --- a/lib-python/3.2/test/test_weakref.py +++ b/lib-python/3.2/test/test_weakref.py @@ -849,6 +849,7 @@ del items1, items2 self.assertEqual(len(dict), self.COUNT) del objects[0] + gc_collect() self.assertEqual(len(dict), self.COUNT - 1, "deleting object did not cause dictionary update") del objects, o From noreply at buildbot.pypy.org Mon Oct 22 00:34:19 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:19 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Some fixes in the pure-python version of _sha512. Message-ID: <20121021223419.9E5331C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58346:d27c11018443 Date: 2012-10-21 13:38 +0200 http://bitbucket.org/pypy/pypy/changeset/d27c11018443/ Log: Some fixes in the pure-python version of _sha512. diff --git a/lib_pypy/_sha512.py b/lib_pypy/_sha512.py --- a/lib_pypy/_sha512.py +++ b/lib_pypy/_sha512.py @@ -32,10 +32,10 @@ W = [] d = sha_info['data'] - for i in xrange(0,16): + for i in range(0,16): W.append( (d[8*i]<<56) + (d[8*i+1]<<48) + (d[8*i+2]<<40) + (d[8*i+3]<<32) + (d[8*i+4]<<24) + (d[8*i+5]<<16) + (d[8*i+6]<<8) + d[8*i+7]) - for i in xrange(16,80): + for i in range(16,80): W.append( (Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]) & 0xffffffffffffffff ) ss = sha_info['digest'][:] @@ -152,14 +152,6 @@ sha_info['digestsize'] = 48 return sha_info -def getbuf(s): - if isinstance(s, str): - return s - elif isinstance(s, unicode): - return str(s) - else: - return buffer(s) - def sha_update(sha_info, buffer): count = len(buffer) buffer_idx = 0 @@ -199,7 +191,7 @@ # copy buffer pos = sha_info['local'] - sha_info['data'][pos:pos+count] = [struct.unpack('B',c)[0] for c in buffer[buffer_idx:buffer_idx + count]] + sha_info['data'][pos:pos+count] = buffer[buffer_idx:buffer_idx + count] sha_info['local'] = count def sha_final(sha_info): @@ -240,7 +232,7 @@ dig = [] for i in sha_info['digest']: dig.extend([ ((i>>56) & 0xff), ((i>>48) & 0xff), ((i>>40) & 0xff), ((i>>32) & 0xff), ((i>>24) & 0xff), ((i>>16) & 0xff), ((i>>8) & 0xff), (i & 0xff) ]) - return ''.join([chr(i) for i in dig]) + return bytes(dig) class sha512(object): digest_size = digestsize = SHA_DIGESTSIZE @@ -249,10 +241,10 @@ def __init__(self, s=None): self._sha = sha_init() if s: - sha_update(self._sha, getbuf(s)) + sha_update(self._sha, s) def update(self, s): - sha_update(self._sha, getbuf(s)) + sha_update(self._sha, s) def digest(self): return sha_final(self._sha.copy())[:self._sha['digestsize']] @@ -271,7 +263,7 @@ def __init__(self, s=None): self._sha = sha384_init() if s: - sha_update(self._sha, getbuf(s)) + sha_update(self._sha, s) def copy(self): new = sha384.__new__(sha384) From noreply at buildbot.pypy.org Mon Oct 22 00:34:20 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:20 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix tests when run with python3 and -A. Message-ID: <20121021223420.CDA7F1C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58347:974a36237099 Date: 2012-10-21 15:50 +0200 http://bitbucket.org/pypy/pypy/changeset/974a36237099/ Log: Fix tests when run with python3 and -A. diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -94,14 +94,14 @@ ltime = rctime.localtime() rctime.accept2dyear == 0 ltime = list(ltime) - ltime[0] = 1899 + ltime[0] = -1 raises(ValueError, rctime.mktime, tuple(ltime)) rctime.accept2dyear == 1 ltime = list(ltime) ltime[0] = 67 ltime = tuple(ltime) - if os.name != "nt" and sys.maxint < 1<<32: # time_t may be 64bit + if os.name != "nt" and sys.maxsize < 1<<32: # time_t may be 64bit raises(OverflowError, rctime.mktime, ltime) ltime = list(ltime) @@ -255,10 +255,13 @@ # of the time tuple. # check year - raises(ValueError, rctime.strftime, '', (1899, 1, 1, 0, 0, 0, 0, 1, -1)) if rctime.accept2dyear: raises(ValueError, rctime.strftime, '', (-1, 1, 1, 0, 0, 0, 0, 1, -1)) raises(ValueError, rctime.strftime, '', (100, 1, 1, 0, 0, 0, 0, 1, -1)) + else: + rctime.strftime('', (1899, 1, 1, 0, 0, 0, 0, 1, -1)) + rctime.strftime('', (0, 1, 1, 0, 0, 0, 0, 1, -1)) + # check month raises(ValueError, rctime.strftime, '', (1900, 13, 1, 0, 0, 0, 0, 1, -1)) # check day of month @@ -282,8 +285,8 @@ # check day of the year raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 367, -1)) # check daylight savings flag - raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 1, -2)) - raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 1, 2)) + rctime.strftime('', (1900, 1, 1, 0, 0, 0, 0, 1, -2)) + rctime.strftime('', (1900, 1, 1, 0, 0, 0, 0, 1, 2)) def test_strptime(self): import time as rctime From noreply at buildbot.pypy.org Mon Oct 22 00:34:22 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 00:34:22 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix time module to pass tests. Message-ID: <20121021223422.0F5D81C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58348:256ceebd14f3 Date: 2012-10-21 16:00 +0200 http://bitbucket.org/pypy/pypy/changeset/256ceebd14f3/ Log: Fix time module to pass tests. 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 @@ -436,17 +436,14 @@ accept2dyear = space.int_w(w_accept2dyear) if y < 1900: - if not accept2dyear: - raise OperationError(space.w_ValueError, - space.wrap("year >= 1900 required")) - - if 69 <= y <= 99: - y += 1900 - elif 0 <= y <= 68: - y += 2000 - else: - raise OperationError(space.w_ValueError, - space.wrap("year out of range")) + if accept2dyear: + if 69 <= y <= 99: + y += 1900 + elif 0 <= y <= 68: + y += 2000 + else: + raise OperationError(space.w_ValueError, + space.wrap("year out of range")) if rffi.getintfield(glob_buf, 'c_tm_wday') < 0: raise OperationError(space.w_ValueError, @@ -625,9 +622,13 @@ if rffi.getintfield(buf_value, 'c_tm_yday') < 0 or rffi.getintfield(buf_value, 'c_tm_yday') > 365: raise OperationError(space.w_ValueError, space.wrap("day of year out of range")) - if rffi.getintfield(buf_value, 'c_tm_isdst') < -1 or rffi.getintfield(buf_value, 'c_tm_isdst') > 1: - raise OperationError(space.w_ValueError, - space.wrap("daylight savings flag out of range")) + # Normalize tm_isdst just in case someone foolishly implements %Z + # based on the assumption that tm_isdst falls within the range of + # [-1, 1] + if rffi.getintfield(buf_value, 'c_tm_isdst') < -1: + rffi.setintfield(buf_value, 'c_tm_isdst', -1) + elif rffi.getintfield(buf_value, 'c_tm_isdst') > 1: + rffi.setintfield(buf_value, 'c_tm_isdst', 1) if _WIN: # check that the format string contains only valid directives From noreply at buildbot.pypy.org Mon Oct 22 03:27:44 2012 From: noreply at buildbot.pypy.org (Justin Peel) Date: Mon, 22 Oct 2012 03:27:44 +0200 (CEST) Subject: [pypy-commit] pypy default: speed up deleting a simple slice (step=1) of an array.array by a generous order of magnitude. Also add more tests for deleting slices of an array.array. Message-ID: <20121022012744.3E0511C1C8C@cobra.cs.uni-duesseldorf.de> Author: Justin Peel Branch: Changeset: r58349:aa1ab56ff708 Date: 2012-10-21 19:27 -0600 http://bitbucket.org/pypy/pypy/changeset/aa1ab56ff708/ Log: speed up deleting a simple slice (step=1) of an array.array by a generous order of magnitude. Also add more tests for deleting slices of an array.array. 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 @@ -467,7 +467,35 @@ self.fromsequence(w_lst) def delslice__Array_ANY_ANY(space, self, w_i, w_j): - return space.delitem(self, space.newslice(w_i, w_j, space.w_None)) + i = space.int_w(w_i) + if i < 0: + i += self.len + if i < 0: + i = 0 + j = space.int_w(w_j) + if j < 0: + j += self.len + if j < 0: + j = 0 + if j > self.len: + j = self.len + if i >= j: + return None + oldbuffer = self.buffer + self.buffer = lltype.malloc(mytype.arraytype, + max(self.len - (j - i), 0), flavor='raw', + add_memory_pressure=True) + for k in range(0, i): + self.buffer[k] = oldbuffer[k] + m = i + for k in range(j, self.len): + self.buffer[m] = oldbuffer[k] + m += 1 + self.len -= j - i + self.allocated = self.len + if oldbuffer: + lltype.free(oldbuffer, flavor='raw') + # Add and mul methods 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 @@ -681,6 +681,22 @@ a.__delslice__(0, 2) assert repr(a) == "array('i', [5])" + a = self.array('i', [1, 2, 3, 4, 5]) + del a[3:1] + assert repr(a) == "array('i', [1, 2, 3, 4, 5])" + + del a[-100:1] + assert repr(a) == "array('i', [2, 3, 4, 5])" + + del a[3:] + assert repr(a) == "array('i', [2, 3, 4])" + + del a[-1:] + assert repr(a) == "array('i', [2, 3])" + + del a[1:100] + assert repr(a) == "array('i', [2])" + def test_iter(self): a = self.array('i', [1, 2, 3]) assert 1 in a From noreply at buildbot.pypy.org Mon Oct 22 03:36:37 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 22 Oct 2012 03:36:37 +0200 (CEST) Subject: [pypy-commit] pypy default: Use memcopy for more faster in array.__delslice__ Message-ID: <20121022013637.9DBA31C1C8C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r58350:20de76d6fc41 Date: 2012-10-21 18:36 -0700 http://bitbucket.org/pypy/pypy/changeset/20de76d6fc41/ Log: Use memcopy for more faster in array.__delslice__ 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 @@ -485,8 +485,12 @@ self.buffer = lltype.malloc(mytype.arraytype, max(self.len - (j - i), 0), flavor='raw', add_memory_pressure=True) - for k in range(0, i): - self.buffer[k] = oldbuffer[k] + if i: + rffi.c_memcpy( + rffi.cast(rffi.VOIDP, self.buffer), + rffi.cast(rffi.VOIDP, oldbuffer), + i * mytype.bytes + ) m = i for k in range(j, self.len): self.buffer[m] = oldbuffer[k] From noreply at buildbot.pypy.org Mon Oct 22 07:35:27 2012 From: noreply at buildbot.pypy.org (Justin Peel) Date: Mon, 22 Oct 2012 07:35:27 +0200 (CEST) Subject: [pypy-commit] pypy default: use memcpy one more time in array.__delslice__ for extra speediness Message-ID: <20121022053527.02FE81C0246@cobra.cs.uni-duesseldorf.de> Author: Justin Peel Branch: Changeset: r58351:4ffa41843837 Date: 2012-10-21 23:35 -0600 http://bitbucket.org/pypy/pypy/changeset/4ffa41843837/ Log: use memcpy one more time in array.__delslice__ for extra speediness 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 @@ -491,10 +491,11 @@ rffi.cast(rffi.VOIDP, oldbuffer), i * mytype.bytes ) - m = i - for k in range(j, self.len): - self.buffer[m] = oldbuffer[k] - m += 1 + if j < self.len: + rffi.c_memcpy( + rffi.cast(rffi.VOIDP, rffi.ptradd(self.buffer, i)), + rffi.cast(rffi.VOIDP, rffi.ptradd(oldbuffer, j)), + (self.len - j) * mytype.bytes) self.len -= j - i self.allocated = self.len if oldbuffer: From noreply at buildbot.pypy.org Mon Oct 22 08:42:21 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 08:42:21 +0200 (CEST) Subject: [pypy-commit] pypy py3k: In "raise exc from cause", cause can be a exception type, Message-ID: <20121022064221.5E6A01C01F9@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58352:6c43fd71ae59 Date: 2012-10-22 08:28 +0200 http://bitbucket.org/pypy/pypy/changeset/6c43fd71ae59/ Log: In "raise exc from cause", cause can be a exception type, and must be normalized: call it to create an instance. diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -817,7 +817,17 @@ def f(): try: raise TypeError() from ValueError() - except TypeError: + except TypeError as e: + assert isinstance(e.__cause__, ValueError) + return 42 + """ + yield self.st, test, "f()", 42 + test = """if 1: + def f(): + try: + raise TypeError from ValueError + except TypeError as e: + assert isinstance(e.__cause__, ValueError) return 42 """ yield self.st, test, "f()", 42 diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -484,6 +484,8 @@ w_value = w_cause = space.w_None if nbargs == 2: w_cause = self.popvalue() + if space.exception_is_valid_obj_as_class_w(w_cause): + w_cause = space.call_function(w_cause) w_value = self.popvalue() if space.exception_is_valid_obj_as_class_w(w_value): w_type = w_value From noreply at buildbot.pypy.org Mon Oct 22 08:42:22 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 08:42:22 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Implement "Barry as BDFL" compile flag. Message-ID: <20121022064222.792241C01F9@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58353:22744399aa71 Date: 2012-10-22 08:31 +0200 http://bitbucket.org/pypy/pypy/changeset/22744399aa71/ Log: Implement "Barry as BDFL" compile flag. It's not only a joke: this is how <> is now disallowed in normal Python3 code. diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py --- a/pypy/interpreter/astcompiler/astbuilder.py +++ b/pypy/interpreter/astcompiler/astbuilder.py @@ -853,6 +853,11 @@ elif comp_type == tokens.GREATEREQUAL: return ast.GtE elif comp_type == tokens.NOTEQUAL: + flufl = self.compile_info.flags & consts.CO_FUTURE_BARRY_AS_BDFL + if flufl and comp_node.value == '!=': + self.error('message', comp_node) + elif not flufl and comp_node.value == '<>': + self.error('message', comp_node) return ast.NotEq elif comp_type == tokens.NAME: if comp_node.value == "is": @@ -1118,7 +1123,6 @@ elif first_child_type == tokens.STRING: space = self.space encoding = self.compile_info.encoding - flags = self.compile_info.flags try: sub_strings_w = [parsestring.parsestr(space, encoding, s.value) for s in atom_node.children] diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py --- a/pypy/interpreter/astcompiler/consts.py +++ b/pypy/interpreter/astcompiler/consts.py @@ -15,6 +15,7 @@ CO_FUTURE_WITH_STATEMENT = 0x8000 CO_FUTURE_PRINT_FUNCTION = 0x10000 CO_FUTURE_UNICODE_LITERALS = 0x20000 +CO_FUTURE_BARRY_AS_BDFL = 0x40000 CO_CONTAINSGLOBALS = 0x80000 # pypy-specific: need to check that it's not used # by any other flag diff --git a/pypy/interpreter/pycompiler.py b/pypy/interpreter/pycompiler.py --- a/pypy/interpreter/pycompiler.py +++ b/pypy/interpreter/pycompiler.py @@ -101,7 +101,7 @@ """ def __init__(self, space, override_version=None): PyCodeCompiler.__init__(self, space) - self.future_flags = future.futureFlags_2_7 + self.future_flags = future.futureFlags_3_2 self.parser = pyparse.PythonParser(space, self.future_flags) self.additional_rules = {} self.compiler_flags = self.future_flags.allowed_flags diff --git a/pypy/interpreter/pyparser/future.py b/pypy/interpreter/pyparser/future.py --- a/pypy/interpreter/pyparser/future.py +++ b/pypy/interpreter/pyparser/future.py @@ -24,8 +24,9 @@ the "in" comparisons with explicit numeric comparisons. """ -from pypy.interpreter.astcompiler.consts import CO_GENERATOR_ALLOWED, \ - CO_FUTURE_DIVISION, CO_FUTURE_WITH_STATEMENT, CO_FUTURE_ABSOLUTE_IMPORT +from pypy.interpreter.astcompiler.consts import ( + CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION, CO_FUTURE_WITH_STATEMENT, + CO_FUTURE_ABSOLUTE_IMPORT, CO_FUTURE_BARRY_AS_BDFL) def get_futures(future_flags, source): futures = FutureAutomaton(future_flags, source) 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 @@ -778,6 +778,22 @@ for case in cases: raises(SyntaxError, compile, case, "", "exec") + def test_barry_as_bdfl(self): + # from test_flufl.py :-) + import __future__ + code = "from __future__ import barry_as_FLUFL; 2 {0} 3" + compile(code.format('<>'), '', 'exec', + __future__.CO_FUTURE_BARRY_AS_BDFL) + raises(SyntaxError, compile, code.format('!='), + '', 'exec', + __future__.CO_FUTURE_BARRY_AS_BDFL) + + def test_guido_as_bdfl(self): + # from test_flufl.py :-) + code = '2 {0} 3' + compile(code.format('!='), '', 'exec') + raises(SyntaxError, compile, code.format('<>'), + '', 'exec') class AppTestOptimizer: From noreply at buildbot.pypy.org Mon Oct 22 08:42:23 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 22 Oct 2012 08:42:23 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Implement {:a} format spec for str.format(). Message-ID: <20121022064223.B9A651C01F9@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58354:4e789b0f78b2 Date: 2012-10-22 08:41 +0200 http://bitbucket.org/pypy/pypy/changeset/4e789b0f78b2/ Log: Implement {:a} format spec for str.format(). diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -7,6 +7,7 @@ from pypy.rlib.objectmodel import specialize from pypy.rlib.rfloat import copysign, formatd from pypy.tool import sourcetools +from pypy.objspace.std.unicodetype import ascii_from_object @specialize.argtype(1) @@ -312,6 +313,8 @@ if self.is_unicode: return space.call_function(space.w_unicode, w_obj) return space.str(w_obj) + elif conv == "a": + return ascii_from_object(space, w_obj) else: raise OperationError(self.space.w_ValueError, self.space.wrap("invalid conversion")) diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -80,6 +80,8 @@ assert self.s('{0!s:15s}').format('Hello') == 'Hello ' assert self.s('{0!r}').format('Hello') == "'Hello'" assert self.s('{0!r:}').format('Hello') == "'Hello'" + assert self.s('{0!r}').format('Caf\xe9') == "'Caf\xe9'" + assert self.s('{0!a}').format('Caf\xe9') == "'Caf\\xe9'" def test_invalid_conversion(self): raises(ValueError, self.s("{!x}").format, 3) From noreply at buildbot.pypy.org Mon Oct 22 14:09:33 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 14:09:33 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: resolve conflicts and remove ootypesystem support Message-ID: <20121022120933.D5DD61C0236@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58355:7ea786d5c8fe Date: 2012-10-22 14:09 +0200 http://bitbucket.org/pypy/pypy/changeset/7ea786d5c8fe/ Log: resolve conflicts and remove ootypesystem support diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -129,7 +129,6 @@ return loop.inputargs, loop.operations, JitCellToken() def test_compile_linear_loop(self): -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr = BasicFailDescr(1) inputargs, ops, token = self.parse(""" [i0] @@ -137,33 +136,8 @@ finish(i1, descr=faildescr) """, namespace=locals()) self.cpu.compile_loop(inputargs, ops, token) - fail = self.cpu.execute_token(token, 2) - res = self.cpu.get_latest_value_int(0) -||||||| /tmp/runner_test.py~base._aMykN - i0 = BoxInt() - i1 = BoxInt() - operations = [ - ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), - ResOperation(rop.FINISH, [i1], None, descr=BasicFailDescr(1)) - ] - inputargs = [i0] - looptoken = JitCellToken() - self.cpu.compile_loop(inputargs, operations, looptoken) - fail = self.cpu.execute_token(looptoken, 2) - res = self.cpu.get_latest_value_int(0) -======= - i0 = BoxInt() - i1 = BoxInt() - operations = [ - ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), - ResOperation(rop.FINISH, [i1], None, descr=BasicFailDescr(1)) - ] - inputargs = [i0] - looptoken = JitCellToken() - self.cpu.compile_loop(inputargs, operations, looptoken) - frame = self.cpu.execute_token(looptoken, 2) + frame = self.cpu.execute_token(token, 2) res = self.cpu.get_finish_value_int(frame) ->>>>>>> /tmp/runner_test.py~other.b8EcdI assert res == 3 assert self.cpu.get_latest_descr(frame).identifier == 1 @@ -213,19 +187,9 @@ """, namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - fail = self.cpu.execute_token(looptoken, 44) - assert fail.identifier == 3 - res = self.cpu.get_latest_value_int(2) -||||||| /tmp/runner_test.py~base._aMykN - fail = self.cpu.execute_token(looptoken, 44) - assert fail.identifier == 2 - res = self.cpu.get_latest_value_int(2) -======= frame = self.cpu.execute_token(looptoken, 44) - assert self.cpu.get_latest_descr(frame).identifier == 2 + assert self.cpu.get_latest_descr(frame).identifier == 3 res = self.cpu.get_latest_value_int(frame, 2) ->>>>>>> /tmp/runner_test.py~other.b8EcdI assert res == 10 def test_backends_dont_keep_loops_alive(self): @@ -277,19 +241,9 @@ self.cpu.compile_bridge(faildescr4, inputargs, bridge_ops, looptoken) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - fail = self.cpu.execute_token(looptoken, 2) - assert fail.identifier == 5 - res = self.cpu.get_latest_value_int(0) -||||||| /tmp/runner_test.py~base._aMykN - fail = self.cpu.execute_token(looptoken, 2) - assert fail.identifier == 2 - res = self.cpu.get_latest_value_int(0) -======= frame = self.cpu.execute_token(looptoken, 2) - assert self.cpu.get_latest_descr(frame).identifier == 2 + assert self.cpu.get_latest_descr(frame).identifier == 5 res = self.cpu.get_latest_value_int(frame, 0) ->>>>>>> /tmp/runner_test.py~other.b8EcdI assert res == 20 assert self.cpu.total_compiled_loops == 1 @@ -344,27 +298,11 @@ namespace=locals()) self.cpu.compile_bridge(faildescr1, inputargs, bridge, looptoken) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - fail = self.cpu.execute_token(looptoken, 1) - assert fail.identifier == 2 -||||||| /tmp/runner_test.py~base._aMykN - fail = self.cpu.execute_token(looptoken, 1) - assert fail.identifier == 3 -======= frame = self.cpu.execute_token(looptoken, 1) - assert self.cpu.get_latest_descr(frame).identifier == 3 ->>>>>>> /tmp/runner_test.py~other.b8EcdI + assert self.cpu.get_latest_descr(frame).identifier == 2 for i in range(1000): -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - res = self.cpu.get_latest_value_int(i) + res = self.cpu.get_latest_value_int(frame, i) assert res == 1 + i -||||||| /tmp/runner_test.py~base._aMykN - res = self.cpu.get_latest_value_int(i) - assert res == 2 + i -======= - res = self.cpu.get_latest_value_int(frame, i) - assert res == 2 + i ->>>>>>> /tmp/runner_test.py~other.b8EcdI def test_get_latest_value_count(self): faildescr1 = BasicFailDescr(1) @@ -394,65 +332,25 @@ return AbstractFailDescr.__setattr__(self, name, value) py.test.fail("finish descrs should not be touched") faildescr = UntouchableFailDescr() # to check that is not touched -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py namespace = {'faildescr': faildescr} inputargs, operations, looptoken = self.parse(""" [i0] finish(i0, descr=faildescr) """, namespace=namespace) self.cpu.compile_loop(inputargs, operations, looptoken) - fail = self.cpu.execute_token(looptoken, 99) - assert fail is faildescr - res = self.cpu.get_latest_value_int(0) -||||||| /tmp/runner_test.py~base._aMykN - looptoken = JitCellToken() - operations = [ - ResOperation(rop.FINISH, [i0], None, descr=faildescr) - ] - self.cpu.compile_loop([i0], operations, looptoken) - fail = self.cpu.execute_token(looptoken, 99) - assert fail is faildescr - res = self.cpu.get_latest_value_int(0) -======= - looptoken = JitCellToken() - operations = [ - ResOperation(rop.FINISH, [i0], None, descr=faildescr) - ] - self.cpu.compile_loop([i0], operations, looptoken) frame = self.cpu.execute_token(looptoken, 99) assert self.cpu.get_latest_descr(frame) is faildescr res = self.cpu.get_finish_value_int(frame) ->>>>>>> /tmp/runner_test.py~other.b8EcdI assert res == 99 -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, looptoken = self.parse(""" [] finish(42, descr=faildescr) """, namespace=namespace) self.cpu.compile_loop(inputargs, operations, looptoken) - fail = self.cpu.execute_token(looptoken) - assert fail is faildescr - res = self.cpu.get_latest_value_int(0) -||||||| /tmp/runner_test.py~base._aMykN - looptoken = JitCellToken() - operations = [ - ResOperation(rop.FINISH, [ConstInt(42)], None, descr=faildescr) - ] - self.cpu.compile_loop([], operations, looptoken) - fail = self.cpu.execute_token(looptoken) - assert fail is faildescr - res = self.cpu.get_latest_value_int(0) -======= - looptoken = JitCellToken() - operations = [ - ResOperation(rop.FINISH, [ConstInt(42)], None, descr=faildescr) - ] - self.cpu.compile_loop([], operations, looptoken) frame = self.cpu.execute_token(looptoken) assert self.cpu.get_latest_descr(frame) is faildescr res = self.cpu.get_finish_value_int(frame) ->>>>>>> /tmp/runner_test.py~other.b8EcdI assert res == 42 _, operations, looptoken = self.parse(""" @@ -487,7 +385,6 @@ def test_execute_operations_in_env(self): cpu = self.cpu -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, looptoken = self.parse(""" [ix, iy] label(iy, ix, descr=targettoken) @@ -498,54 +395,9 @@ jump(it, iz, descr=targettoken) """, None) cpu.compile_loop(inputargs, operations, looptoken) - self.cpu.execute_token(looptoken, 0, 10) - assert self.cpu.get_latest_value_int(0) == 0 - assert self.cpu.get_latest_value_int(1) == 55 -||||||| /tmp/runner_test.py~base._aMykN - x = BoxInt(123) - y = BoxInt(456) - z = BoxInt(579) - t = BoxInt(455) - u = BoxInt(0) # False - looptoken = JitCellToken() - targettoken = TargetToken() - operations = [ - ResOperation(rop.LABEL, [y, x], None, descr=targettoken), - ResOperation(rop.INT_ADD, [x, y], z), - ResOperation(rop.INT_SUB, [y, ConstInt(1)], t), - ResOperation(rop.INT_EQ, [t, ConstInt(0)], u), - ResOperation(rop.GUARD_FALSE, [u], None, - descr=BasicFailDescr()), - ResOperation(rop.JUMP, [t, z], None, descr=targettoken), - ] - operations[-2].setfailargs([t, z]) - cpu.compile_loop([x, y], operations, looptoken) - res = self.cpu.execute_token(looptoken, 0, 10) - assert self.cpu.get_latest_value_int(0) == 0 - assert self.cpu.get_latest_value_int(1) == 55 -======= - x = BoxInt(123) - y = BoxInt(456) - z = BoxInt(579) - t = BoxInt(455) - u = BoxInt(0) # False - looptoken = JitCellToken() - targettoken = TargetToken() - operations = [ - ResOperation(rop.LABEL, [y, x], None, descr=targettoken), - ResOperation(rop.INT_ADD, [x, y], z), - ResOperation(rop.INT_SUB, [y, ConstInt(1)], t), - ResOperation(rop.INT_EQ, [t, ConstInt(0)], u), - ResOperation(rop.GUARD_FALSE, [u], None, - descr=BasicFailDescr()), - ResOperation(rop.JUMP, [t, z], None, descr=targettoken), - ] - operations[-2].setfailargs([t, z]) - cpu.compile_loop([x, y], operations, looptoken) frame = self.cpu.execute_token(looptoken, 0, 10) assert self.cpu.get_latest_value_int(frame, 0) == 0 assert self.cpu.get_latest_value_int(frame, 1) == 55 ->>>>>>> /tmp/runner_test.py~other.b8EcdI def test_int_operations(self): from pypy.jit.metainterp.test.test_executor import get_int_tests @@ -582,7 +434,6 @@ """ % op, namespace={'faildescr1': BasicFailDescr(1), 'faildescr2': BasicFailDescr(2)}) else: -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, looptoken = self.parse(""" [i1, i2] ires = %s(i1, i2) @@ -590,25 +441,6 @@ finish(descr=faildescr2) """ % op, namespace={'faildescr1': BasicFailDescr(1), 'faildescr2': BasicFailDescr(2)}) -||||||| /tmp/runner_test.py~base._aMykN - v_exc = self.cpu.ts.BoxRef() - ops = [ - ResOperation(opnum, [v1, v2], v_res), - ResOperation(rop.GUARD_OVERFLOW, [], None, - descr=BasicFailDescr(1)), - ResOperation(rop.FINISH, [], None, descr=BasicFailDescr(2)), - ] - ops[1].setfailargs([v_res]) -======= - v_exc = BoxPtr() - ops = [ - ResOperation(opnum, [v1, v2], v_res), - ResOperation(rop.GUARD_OVERFLOW, [], None, - descr=BasicFailDescr(1)), - ResOperation(rop.FINISH, [], None, descr=BasicFailDescr(2)), - ] - ops[1].setfailargs([v_res]) ->>>>>>> /tmp/runner_test.py~other.b8EcdI # self.cpu.compile_loop(inputargs, operations, looptoken) for x, y, z in testcases: @@ -710,13 +542,7 @@ EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) args = ([boxfloat(.1) for i in range(7)] + -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - [boxint(1), boxint(2), boxfloat(.2), boxfloat(.3), -||||||| /tmp/runner_test.py~base._aMykN - [BoxInt(1), BoxInt(2), boxfloat(.2), boxfloat(.3), -======= - [BoxInt(1), boxfloat(.2), BoxInt(2), boxfloat(.3), ->>>>>>> /tmp/runner_test.py~other.b8EcdI + [boxint(1), boxfloat(.2), boxint(2), boxfloat(.3), boxfloat(.4)]) res = self.execute_operation(rop.CALL_f, [funcbox] + args, @@ -1136,17 +962,9 @@ 'void', descr=kdescr) f = self.cpu.bh_getinteriorfield_gc_f(a_box.getref_base(), 3, kdescr) assert longlong.getrealfloat(f) == 1.5 -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, kdescr, longlong.getfloatstorage(2.5)) - r = self.execute_operation(rop.GETINTERIORFIELD_GC_f, [a_box, boxint(3)], -||||||| /tmp/runner_test.py~base._aMykN - self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, kdescr, longlong.getfloatstorage(2.5)) - r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], -======= self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, longlong.getfloatstorage(2.5), kdescr) - r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], ->>>>>>> /tmp/runner_test.py~other.b8EcdI - 'float', descr=kdescr) + r = self.execute_operation(rop.GETINTERIORFIELD_GC_f, + [a_box, boxint(3)], 'float', descr=kdescr) assert r == 2.5 # NUMBER_FIELDS = [('vs', lltype.Signed), @@ -1183,35 +1001,19 @@ 'void', descr=pdescr) r = self.cpu.bh_getinteriorfield_gc_r(a_box.getref_base(), 4, pdescr) assert r == s_box.getref_base() -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, pdescr, - s_box.getref_base()) + self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, + s_box.getref_base(), pdescr) r = self.execute_operation(rop.GETINTERIORFIELD_GC_r, [a_box, boxint(3)], -||||||| /tmp/runner_test.py~base._aMykN - self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, pdescr, - s_box.getref_base()) - r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], -======= - self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, - s_box.getref_base(), pdescr) - r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)], ->>>>>>> /tmp/runner_test.py~other.b8EcdI 'ref', descr=pdescr) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py assert r == s_box.getref_base() -||||||| /tmp/runner_test.py~base._aMykN - assert r.getref_base() == s_box.getref_base() -======= - assert r.getref_base() == s_box.getref_base() # # test a corner case that used to fail on x86 - i4 = BoxInt(4) + i4 = boxint(4) self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, i4, i4], 'void', descr=vsdescr) r = self.cpu.bh_getinteriorfield_gc_i(a_box.getref_base(), 4, vsdescr) assert r == 4 ->>>>>>> /tmp/runner_test.py~other.b8EcdI def test_string_basic(self): s_box = self.alloc_string("hello\xfe") @@ -1355,13 +1157,7 @@ retvalues.insert(kk, y) # operations.append( -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - create_resop(rop.FINISH, None, retboxes, descr=faildescr) -||||||| /tmp/runner_test.py~base._aMykN - ResOperation(rop.FINISH, retboxes, None, descr=faildescr) -======= - ResOperation(rop.FINISH, [], None, descr=faildescr) ->>>>>>> /tmp/runner_test.py~other.b8EcdI + create_resop(rop.FINISH, None, [], descr=faildescr) ) operations[-1].setfailargs(retboxes) print inputargs @@ -1373,16 +1169,8 @@ assert self.cpu.get_latest_descr(frame).identifier == 42 # for k in range(len(retvalues)): -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py if retboxes[k].type == 'i': - got = self.cpu.get_latest_value_int(k) -||||||| /tmp/runner_test.py~base._aMykN - if isinstance(retboxes[k], BoxInt): - got = self.cpu.get_latest_value_int(k) -======= - if isinstance(retboxes[k], BoxInt): got = self.cpu.get_latest_value_int(frame, k) ->>>>>>> /tmp/runner_test.py~other.b8EcdI else: got = self.cpu.get_latest_value_float(frame, k) assert got == retvalues[k] @@ -1450,16 +1238,9 @@ assert 0 values[index_counter] = 11 # -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - fail = self.cpu.execute_token(looptoken, *values) - assert fail.identifier == 1 -||||||| /tmp/runner_test.py~base._aMykN - fail = self.cpu.execute_token(looptoken, *values) - assert fail.identifier == 15 -======= frame = self.cpu.execute_token(looptoken, *values) assert self.cpu.get_latest_descr(frame).identifier == 15 ->>>>>>> /tmp/runner_test.py~other.b8EcdI + assert fail.identifier == 1 # dstvalues = values[:] for _ in range(11): @@ -1471,26 +1252,12 @@ # assert dstvalues[index_counter] == 11 dstvalues[index_counter] = 0 -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py for i, (box, val) in enumerate(zip(inpargs, dstvalues)): - if isinstance(box, boxint): - got = self.cpu.get_latest_value_int(i) - elif isinstance(box, boxptr): - got = self.cpu.get_latest_value_ref(i) -||||||| /tmp/runner_test.py~base._aMykN - for i, (box, val) in enumerate(zip(inputargs, dstvalues)): - if isinstance(box, BoxInt): - got = self.cpu.get_latest_value_int(i) - elif isinstance(box, BoxPtr): - got = self.cpu.get_latest_value_ref(i) -======= - for i, (box, val) in enumerate(zip(inputargs, dstvalues)): - if isinstance(box, BoxInt): + if box.type == 'i': got = self.cpu.get_latest_value_int(frame, i) - elif isinstance(box, BoxPtr): + elif box.type == 'r': got = self.cpu.get_latest_value_ref(frame, i) ->>>>>>> /tmp/runner_test.py~other.b8EcdI - elif isinstance(box, BoxFloat): + elif box.type == 'f': got = self.cpu.get_latest_value_float(frame, i) else: assert 0 @@ -1503,40 +1270,17 @@ fboxes = "f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11" faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py targettoken = TargetToken() inputargs, operations, looptoken = self.parse(""" [%(fboxes)s] label(%(fboxes)s, descr=targettoken) i2 = float_le(f0, 9.2) guard_true(i2, descr=faildescr1) [%(fboxes)s] - finish(%(fboxes)s, descr=faildescr2) + finish(descr=faildescr2) [%(fboxes)s] """ % {'fboxes': fboxes}, {'faildescr1': faildescr1, 'faildescr2': faildescr2, 'targettoken': targettoken}) self.cpu.compile_loop(inputargs, operations, looptoken) -||||||| /tmp/runner_test.py~base._aMykN - operations = [ - ResOperation(rop.LABEL, fboxes, None, descr=targettoken), - ResOperation(rop.FLOAT_LE, [fboxes[0], constfloat(9.2)], i2), - ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1), - ResOperation(rop.FINISH, fboxes, None, descr=faildescr2), - ] - operations[-2].setfailargs(fboxes) - looptoken = JitCellToken() - self.cpu.compile_loop(fboxes, operations, looptoken) -======= - operations = [ - ResOperation(rop.LABEL, fboxes, None, descr=targettoken), - ResOperation(rop.FLOAT_LE, [fboxes[0], constfloat(9.2)], i2), - ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1), - ResOperation(rop.FINISH, [], None, descr=faildescr2), - ] - operations[-2].setfailargs(fboxes) - operations[-1].setfailargs(fboxes) - looptoken = JitCellToken() - self.cpu.compile_loop(fboxes, operations, looptoken) ->>>>>>> /tmp/runner_test.py~other.b8EcdI inputargs, operations, _ = self.parse(""" [%s] @@ -1554,16 +1298,8 @@ assert self.cpu.get_latest_descr(frame).identifier == 2 res = self.cpu.get_latest_value_float(frame, 0) assert longlong.getrealfloat(res) == 8.5 -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py for i in range(1, len(fboxes.split(","))): - got = longlong.getrealfloat(self.cpu.get_latest_value_float(i)) -||||||| /tmp/runner_test.py~base._aMykN - for i in range(1, len(fboxes)): - got = longlong.getrealfloat(self.cpu.get_latest_value_float(i)) -======= - for i in range(1, len(fboxes)): got = longlong.getrealfloat(self.cpu.get_latest_value_float(frame, i)) ->>>>>>> /tmp/runner_test.py~other.b8EcdI assert got == 13.5 + 6.73 * i def test_compile_bridge_spilled_float(self): @@ -2075,15 +1811,11 @@ assert res == -19 def test_convert_float_bytes(self): -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - box = boxfloat(2.5) -||||||| /tmp/runner_test.py~base._aMykN -======= if not self.cpu.supports_floats: py.test.skip("requires floats") - if not self.cpu.supports_longlong: - py.test.skip("longlong test") ->>>>>>> /tmp/runner_test.py~other.b8EcdI + #if not self.cpu.supports_longlong: + # py.test.skip("longlong test") + box = boxfloat(2.5) t = 'int' if longlong.is_64_bit else 'float' res = self.execute_operation(rop.CONVERT_FLOAT_BYTES_TO_LONGLONG, [box], t) @@ -2142,16 +1874,8 @@ assert s.parent.chr2 == chr(150) r = self.cpu.bh_getfield_gc_i(r1, descrshort) assert r == 1313 -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - self.cpu.bh_setfield_gc_i(r1, descrshort, 1333) + self.cpu.bh_setfield_gc_i(r1, 1333, descrshort) r = self.cpu.bh_getfield_gc_i(r1, descrshort) -||||||| /tmp/runner_test.py~base._aMykN - self.cpu.bh_setfield_gc_i(r1.value, descrshort, 1333) - r = self.cpu.bh_getfield_gc_i(r1.value, descrshort) -======= - self.cpu.bh_setfield_gc_i(r1.value, 1333, descrshort) - r = self.cpu.bh_getfield_gc_i(r1.value, descrshort) ->>>>>>> /tmp/runner_test.py~other.b8EcdI assert r == 1333 r = self.execute_operation(rop.GETFIELD_GC_i, [boxptr(r1)], 'int', descr=descrshort) @@ -2194,22 +1918,10 @@ ops = ''' [i0] -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py i1 = same_as_i(1) call_n(ConstClass(fptr), i0, descr=calldescr) p0 = guard_exception(ConstClass(xtp), descr=faildescr2) [i1] - finish(0, p0, descr=faildescr1) -||||||| /tmp/runner_test.py~base._aMykN - i1 = same_as(1) - call(ConstClass(fptr), i0, descr=calldescr) - p0 = guard_exception(ConstClass(xtp)) [i1] - finish(0, p0) -======= - i1 = same_as(1) - call(ConstClass(fptr), i0, descr=calldescr) - p0 = guard_exception(ConstClass(xtp)) [i1] - finish(p0) [] ->>>>>>> /tmp/runner_test.py~other.b8EcdI + finish(0, p0, descr=faildescr1) [] ''' FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) fptr = llhelper(FPTR, func) @@ -2261,22 +1973,10 @@ exc_ptr = xptr ops = ''' [i0] -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py i1 = same_as_i(1) call_n(ConstClass(fptr), i0, descr=calldescr) guard_no_exception(descr=faildescr1) [i1] - finish(0, descr=faildescr2) -||||||| /tmp/runner_test.py~base._aMykN - i1 = same_as(1) - call(ConstClass(fptr), i0, descr=calldescr) - guard_no_exception() [i1] - finish(0) -======= - i1 = same_as(1) - call(ConstClass(fptr), i0, descr=calldescr) - guard_no_exception() [i1] - finish(-100) [] ->>>>>>> /tmp/runner_test.py~other.b8EcdI + finish(-100, descr=faildescr2) [] ''' loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() @@ -2457,18 +2157,7 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) cpu = self.cpu -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py -||||||| /tmp/runner_test.py~base._aMykN - i0 = BoxInt() - i1 = BoxInt() - tok = BoxInt() -======= - i0 = BoxInt() - i1 = BoxInt() - tok = BoxPtr() ->>>>>>> /tmp/runner_test.py~other.b8EcdI faildescr = BasicFailDescr(1) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr0 = BasicFailDescr(0) inputargs, operations, looptoken = self.parse(""" [i0, i1] @@ -2478,38 +2167,9 @@ finish(i0, descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, operations, looptoken) - fail = self.cpu.execute_token(looptoken, 20, 0) - assert fail.identifier == 0 - assert self.cpu.get_latest_value_int(0) == 20 -||||||| /tmp/runner_test.py~base._aMykN - ops = [ - ResOperation(rop.FORCE_TOKEN, [], tok), - ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], None, - descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [i0], None, descr=BasicFailDescr(0)) - ] - ops[2].setfailargs([i1, i0]) - looptoken = JitCellToken() - self.cpu.compile_loop([i0, i1], ops, looptoken) - fail = self.cpu.execute_token(looptoken, 20, 0) - assert fail.identifier == 0 - assert self.cpu.get_latest_value_int(0) == 20 -======= - ops = [ - ResOperation(rop.JIT_FRAME, [], tok), - ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], None, - descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [i0], None, descr=BasicFailDescr(0)) - ] - ops[2].setfailargs([i1, i0]) - looptoken = JitCellToken() - self.cpu.compile_loop([i0, i1], ops, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 assert self.cpu.get_finish_value_int(frame) == 20 ->>>>>>> /tmp/runner_test.py~other.b8EcdI assert values == [] frame = self.cpu.execute_token(looptoken, 10, 1) @@ -2534,21 +2194,7 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) cpu = self.cpu -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr0 = BasicFailDescr(0) -||||||| /tmp/runner_test.py~base._aMykN - i0 = BoxInt() - i1 = BoxInt() - i2 = BoxInt() - tok = BoxInt() -======= - i0 = BoxInt() - i1 = BoxInt() - i2 = BoxInt() - tok = BoxPtr() ->>>>>>> /tmp/runner_test.py~other.b8EcdI - faildescr = BasicFailDescr(1) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, ops, looptoken = self.parse(""" [i0, i1] itok = force_token() @@ -2557,38 +2203,9 @@ finish(i2, descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) - fail = self.cpu.execute_token(looptoken, 20, 0) - assert fail.identifier == 0 - assert self.cpu.get_latest_value_int(0) == 42 -||||||| /tmp/runner_test.py~base._aMykN - ops = [ - ResOperation(rop.FORCE_TOKEN, [], tok), - ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], i2, - descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [i2], None, descr=BasicFailDescr(0)) - ] - ops[2].setfailargs([i1, i2, i0]) - looptoken = JitCellToken() - self.cpu.compile_loop([i0, i1], ops, looptoken) - fail = self.cpu.execute_token(looptoken, 20, 0) - assert fail.identifier == 0 - assert self.cpu.get_latest_value_int(0) == 42 -======= - ops = [ - ResOperation(rop.JIT_FRAME, [], tok), - ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], i2, - descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [i2], None, descr=BasicFailDescr(0)) - ] - ops[2].setfailargs([i1, i2, i0]) - looptoken = JitCellToken() - self.cpu.compile_loop([i0, i1], ops, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 assert self.cpu.get_finish_value_int(frame) == 42 ->>>>>>> /tmp/runner_test.py~other.b8EcdI assert values == [] frame = self.cpu.execute_token(looptoken, 10, 1) @@ -2615,61 +2232,19 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) cpu = self.cpu -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py -||||||| /tmp/runner_test.py~base._aMykN - i0 = BoxInt() - i1 = BoxInt() - f2 = BoxFloat() - tok = BoxInt() -======= - i0 = BoxInt() - i1 = BoxInt() - f2 = BoxFloat() - tok = BoxPtr() ->>>>>>> /tmp/runner_test.py~other.b8EcdI faildescr = BasicFailDescr(1) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr0 = BasicFailDescr(0) inputargs, ops, looptoken = self.parse(""" [i0, i1] itok = force_token() f0 = call_may_force_f(ConstClass(func_ptr), itok, i1, descr=calldescr) guard_not_forced(descr=faildescr) [i1, f0, i0] - finish(f0, descr=faildescr0) + finish(f0, descr=faildescr0) [] """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) - fail = self.cpu.execute_token(looptoken, 20, 0) - assert fail.identifier == 0 - x = self.cpu.get_latest_value_float(0) -||||||| /tmp/runner_test.py~base._aMykN - ops = [ - ResOperation(rop.FORCE_TOKEN, [], tok), - ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], f2, - descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [f2], None, descr=BasicFailDescr(0)) - ] - ops[2].setfailargs([i1, f2, i0]) - looptoken = JitCellToken() - self.cpu.compile_loop([i0, i1], ops, looptoken) - fail = self.cpu.execute_token(looptoken, 20, 0) - assert fail.identifier == 0 - x = self.cpu.get_latest_value_float(0) -======= - ops = [ - ResOperation(rop.JIT_FRAME, [], tok), - ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], f2, - descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [f2], None, descr=BasicFailDescr(0)) - ] - ops[2].setfailargs([i1, f2, i0]) - looptoken = JitCellToken() - self.cpu.compile_loop([i0, i1], ops, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 x = self.cpu.get_finish_value_float(frame) ->>>>>>> /tmp/runner_test.py~other.b8EcdI assert longlong.getrealfloat(x) == 42.5 assert values == [] @@ -2707,55 +2282,18 @@ cpu = self.cpu func_adr = c_tolower.funcsym calldescr = cpu._calldescr_dynamic_for_tests([types.uchar], types.sint) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py -||||||| /tmp/runner_test.py~base._aMykN - i1 = BoxInt() - i2 = BoxInt() - tok = BoxInt() -======= - i1 = BoxInt() - i2 = BoxInt() ->>>>>>> /tmp/runner_test.py~other.b8EcdI faildescr = BasicFailDescr(1) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr0 = BasicFailDescr(0) inputargs, operations, looptoken = self.parse(""" [i1] i2 = call_release_gil_i(ConstClass(func_adr), i1, descr=calldescr) guard_not_forced(descr=faildescr) [i1, i2] - finish(i2, descr=faildescr0) + finish(i2, descr=faildescr0) [] """, locals()) self.cpu.compile_loop(inputargs, operations, looptoken) - fail = self.cpu.execute_token(looptoken, ord('G')) - assert fail.identifier == 0 - assert self.cpu.get_latest_value_int(0) == ord('g') -||||||| /tmp/runner_test.py~base._aMykN - ops = [ - ResOperation(rop.CALL_RELEASE_GIL, [funcbox, i1], i2, - descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [i2], None, descr=BasicFailDescr(0)) - ] - ops[1].setfailargs([i1, i2]) - looptoken = JitCellToken() - self.cpu.compile_loop([i1], ops, looptoken) - fail = self.cpu.execute_token(looptoken, ord('G')) - assert fail.identifier == 0 - assert self.cpu.get_latest_value_int(0) == ord('g') -======= - ops = [ - ResOperation(rop.CALL_RELEASE_GIL, [funcbox, i1], i2, - descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [i2], None, descr=BasicFailDescr(0)) - ] - ops[1].setfailargs([i1, i2]) - looptoken = JitCellToken() - self.cpu.compile_loop([i1], ops, looptoken) frame = self.cpu.execute_token(looptoken, ord('G')) assert self.cpu.get_latest_descr(frame).identifier == 0 assert self.cpu.get_finish_value_int(frame) == ord('g') ->>>>>>> /tmp/runner_test.py~other.b8EcdI def test_call_to_c_function_with_callback(self): from pypy.rlib.libffi import CDLL, types, ArgChain, clibffi @@ -2794,19 +2332,6 @@ calldescr = cpu._calldescr_dynamic_for_tests( [types.pointer, types_size_t, types_size_t, types.pointer], types.void) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py -||||||| /tmp/runner_test.py~base._aMykN - i0 = BoxInt() - i1 = BoxInt() - i2 = BoxInt() - i3 = BoxInt() - tok = BoxInt() -======= - i0 = BoxInt() - i1 = BoxInt() - i2 = BoxInt() - i3 = BoxInt() ->>>>>>> /tmp/runner_test.py~other.b8EcdI faildescr = BasicFailDescr(1) faildescr0 = BasicFailDescr(0) inputargs, ops, looptoken = self.parse(""" @@ -2937,7 +2462,6 @@ # the guard, jumping to the label will hit the invalidation code too faildescr = BasicFailDescr(1) labeldescr = TargetToken() -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py faildescr3 = BasicFailDescr(3) inputargs, ops, looptoken = self.parse(""" [i0] @@ -2946,26 +2470,6 @@ finish(i0, descr=faildescr3) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) -||||||| /tmp/runner_test.py~base._aMykN - ops = [ - ResOperation(rop.GUARD_NOT_INVALIDATED, [], None, descr=faildescr), - ResOperation(rop.LABEL, [i0], None, descr=labeldescr), - ResOperation(rop.FINISH, [i0], None, descr=BasicFailDescr(3)), - ] - ops[0].setfailargs([]) - looptoken = JitCellToken() - self.cpu.compile_loop([i0], ops, looptoken) -======= - finishdescr = BasicFailDescr(3) - ops = [ - ResOperation(rop.GUARD_NOT_INVALIDATED, [], None, descr=faildescr), - ResOperation(rop.LABEL, [i0], None, descr=labeldescr), - ResOperation(rop.FINISH, [i0], None, descr=finishdescr), - ] - ops[0].setfailargs([]) - looptoken = JitCellToken() - self.cpu.compile_loop([i0], ops, looptoken) ->>>>>>> /tmp/runner_test.py~other.b8EcdI # mark as failing self.cpu.invalidate_loop(looptoken) # attach a bridge @@ -3175,17 +2679,9 @@ i16 = int_add(i15, i7) i17 = int_add(i16, i8) i18 = int_add(i17, i9) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - finish(i18, descr=faildescr1)''' + finish(i18, descr=faildescr1) []''' loop = parse(ops, namespace={'faildescr1': BasicFailDescr(1)}) -||||||| /tmp/runner_test.py~base._aMykN - finish(i18)''' - loop = parse(ops) -======= - finish(i18) []''' - loop = parse(ops) loop.operations[-1].getdescr().fast_path_done = True ->>>>>>> /tmp/runner_test.py~other.b8EcdI looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() fail_number = self.cpu.get_fail_descr_number( @@ -3202,19 +2698,9 @@ ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] i10 = int_add(i0, 42) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py i11 = call_assembler_i(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, descr=looptoken) guard_not_forced(descr=faildescr1)[] - finish(i11, descr=faildescr2) -||||||| /tmp/runner_test.py~base._aMykN - i11 = call_assembler(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, descr=looptoken) - guard_not_forced()[] - finish(i11) -======= - i11 = call_assembler(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, descr=looptoken) - guard_not_forced()[] - finish(i11) [] ->>>>>>> /tmp/runner_test.py~other.b8EcdI + finish(i11, descr=faildescr2) [] ''' faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) @@ -3264,21 +2750,11 @@ i0 = float_eq(f0, -1.0) guard_false(i0) [] f2 = float_add(f0, f1) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - finish(f2, descr=faildescr)''' + finish(f2, descr=faildescr) []''' loop = parse(ops, namespace={'faildescr': BasicFailDescr(1)}) - done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr()) -||||||| /tmp/runner_test.py~base._aMykN - finish(f2)''' - loop = parse(ops) - done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr()) -======= - finish(f2) []''' - loop = parse(ops) loop.operations[-1].getdescr().fast_path_done = True fail_number = self.cpu.get_fail_descr_number( loop.operations[1].getdescr()) ->>>>>>> /tmp/runner_test.py~other.b8EcdI looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) @@ -3289,19 +2765,9 @@ assert longlong.getrealfloat(x) == 1.2 + 2.3 ops = ''' [f4, f5] -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py f3 = call_assembler_f(f4, f5, descr=looptoken) guard_not_forced(descr=faildescr1)[] - finish(f3, descr=faildescr2) -||||||| /tmp/runner_test.py~base._aMykN - f3 = call_assembler(f4, f5, descr=looptoken) - guard_not_forced()[] - finish(f3) -======= - f3 = call_assembler(f4, f5, descr=looptoken) - guard_not_forced()[] - finish(f3) [] ->>>>>>> /tmp/runner_test.py~other.b8EcdI + finish(f3, descr=faildescr2) [] ''' faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) @@ -3431,17 +2897,9 @@ i0 = float_eq(f0, -1.0) guard_false(i0) [] f2 = float_add(f0, f1) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - finish(f2, descr=faildescr1)''' + finish(f2, descr=faildescr1) []''' loop = parse(ops, namespace={'faildescr1': BasicFailDescr(1)}) -||||||| /tmp/runner_test.py~base._aMykN - finish(f2)''' - loop = parse(ops) -======= - finish(f2) []''' - loop = parse(ops) loop.operations[-1].getdescr().fast_path_done = True ->>>>>>> /tmp/runner_test.py~other.b8EcdI looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) @@ -3456,19 +2914,9 @@ ops = ''' [f4, f5] -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py f3 = call_assembler_f(f4, f5, descr=looptoken) guard_not_forced(descr=faildescr1)[] - finish(f3, descr=faildescr2) -||||||| /tmp/runner_test.py~base._aMykN - f3 = call_assembler(f4, f5, descr=looptoken) - guard_not_forced()[] - finish(f3) -======= - f3 = call_assembler(f4, f5, descr=looptoken) - guard_not_forced()[] - finish(f3) [] ->>>>>>> /tmp/runner_test.py~other.b8EcdI + finish(f3, descr=faildescr2) [] ''' faildescr2 = BasicFailDescr(2) faildescr1 = BasicFailDescr(1) @@ -3497,17 +2945,9 @@ i0 = float_eq(f0, -2.0) guard_false(i0) [] f2 = float_sub(f0, f1) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - finish(f2, descr=faildescr)''' - loop = parse(ops, namespace={'faildescr': BasicFailDescr(1)}) -||||||| /tmp/runner_test.py~base._aMykN - finish(f2)''' - loop = parse(ops) -======= - finish(f2) []''' - loop2 = parse(ops2) + finish(f2, descr=faildescr) []''' + loop2 = parse(ops2, namespace={'faildescr': BasicFailDescr(1)}) loop2.operations[-1].getdescr().fast_path_done = True ->>>>>>> /tmp/runner_test.py~other.b8EcdI looptoken2 = JitCellToken() looptoken2.outermost_jitdriver_sd = FakeJitDriverSD() self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) @@ -3930,28 +3370,12 @@ res = self.cpu.get_latest_value_int(frame, 0) assert res == 10 -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, _ = self.parse(""" [i0] i2 = int_sub(i0, 20) jump(i2, descr=targettoken2) """, locals()) self.cpu.compile_bridge(faildescr, inputargs, operations, looptoken) -||||||| /tmp/runner_test.py~base._aMykN - inputargs = [i0] - operations = [ - ResOperation(rop.INT_SUB, [i0, ConstInt(20)], i2), - ResOperation(rop.JUMP, [i2], None, descr=targettoken2), - ] - self.cpu.compile_bridge(faildescr, inputargs, operations, looptoken) -======= - inputargs2 = [i0] - operations2 = [ - ResOperation(rop.INT_SUB, [i0, ConstInt(20)], i2), - ResOperation(rop.JUMP, [i2], None, descr=targettoken2), - ] - self.cpu.compile_bridge(faildescr, inputargs2, operations2, looptoken) ->>>>>>> /tmp/runner_test.py~other.b8EcdI frame = self.cpu.execute_token(looptoken, 2) assert self.cpu.get_latest_descr(frame).identifier == 3 @@ -3962,13 +3386,7 @@ ops = """ [i0] i1 = int_force_ge_zero(i0) # but forced to be in a register -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - finish(i1, descr=faildescr1) -||||||| /tmp/runner_test.py~base._aMykN - finish(i1, descr=1) -======= - finish(i1, descr=1) [] ->>>>>>> /tmp/runner_test.py~other.b8EcdI + finish(i1, descr=faildescr1) [] """ faildescr1 = BasicFailDescr(1) loop = parse(ops, self.cpu, namespace=locals()) @@ -4061,7 +3479,6 @@ cpu = self.cpu calldescr = cpu.calldescrof(deref(FPTR), (lltype.Signed,)*9, lltype.Void, EffectInfo.MOST_GENERAL) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, looptoken = self.parse(""" [i0] label(i0, descr=targettoken1) @@ -4091,121 +3508,15 @@ jump(i19, descr=targettoken1) """, locals()) self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken1) -||||||| /tmp/runner_test.py~base._aMykN - funcbox = self.get_funcbox(cpu, func_ptr) - i0 = BoxInt(); i1 = BoxInt(); i2 = BoxInt(); i3 = BoxInt(); i4 = BoxInt() - i5 = BoxInt(); i6 = BoxInt(); i7 = BoxInt(); i8 = BoxInt(); i9 = BoxInt() - i10 = BoxInt(); i11 = BoxInt(); i12 = BoxInt(); i13 = BoxInt(); i14 = BoxInt() - i15 = BoxInt(); i16 = BoxInt(); i17 = BoxInt(); i18 = BoxInt(); i19 = BoxInt() - i20 = BoxInt() - inputargs = [i0] - operations = [ - ResOperation(rop.LABEL, [i0], None, descr=targettoken1), - ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), - ResOperation(rop.INT_ADD, [i1, ConstInt(1)], i2), - ResOperation(rop.INT_ADD, [i2, ConstInt(1)], i3), - ResOperation(rop.INT_ADD, [i3, ConstInt(1)], i4), - ResOperation(rop.INT_ADD, [i4, ConstInt(1)], i5), - ResOperation(rop.INT_ADD, [i5, ConstInt(1)], i6), - ResOperation(rop.INT_ADD, [i6, ConstInt(1)], i7), - ResOperation(rop.INT_ADD, [i7, ConstInt(1)], i8), - ResOperation(rop.INT_ADD, [i8, ConstInt(1)], i9), - ResOperation(rop.INT_ADD, [i9, ConstInt(1)], i10), - ResOperation(rop.INT_ADD, [i10, ConstInt(1)], i11), - ResOperation(rop.INT_ADD, [i11, ConstInt(1)], i12), - ResOperation(rop.INT_ADD, [i12, ConstInt(1)], i13), - ResOperation(rop.INT_ADD, [i13, ConstInt(1)], i14), - ResOperation(rop.INT_ADD, [i14, ConstInt(1)], i15), - ResOperation(rop.INT_ADD, [i15, ConstInt(1)], i16), - ResOperation(rop.INT_ADD, [i16, ConstInt(1)], i17), - ResOperation(rop.INT_ADD, [i17, ConstInt(1)], i18), - ResOperation(rop.INT_ADD, [i18, ConstInt(1)], i19), - ResOperation(rop.CALL, [funcbox, i2, i4, i6, i8, i10, i12, i14, i16, i18], - None, descr=calldescr), - ResOperation(rop.CALL, [funcbox, i2, i4, i6, i8, i10, i12, i14, i16, i18], - None, descr=calldescr), - ResOperation(rop.INT_LT, [i19, ConstInt(100)], i20), - ResOperation(rop.GUARD_TRUE, [i20], None, descr=BasicFailDescr(42)), - ResOperation(rop.JUMP, [i19], None, descr=targettoken1), - ] - operations[-2].setfailargs([]) - self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken1) -======= - funcbox = self.get_funcbox(cpu, func_ptr) - - i0 = BoxInt(); i1 = BoxInt(); i2 = BoxInt(); i3 = BoxInt(); i4 = BoxInt() - i5 = BoxInt(); i6 = BoxInt(); i7 = BoxInt(); i8 = BoxInt(); i9 = BoxInt() - i10 = BoxInt(); i11 = BoxInt(); i12 = BoxInt(); i13 = BoxInt(); i14 = BoxInt() - i15 = BoxInt(); i16 = BoxInt(); i17 = BoxInt(); i18 = BoxInt(); i19 = BoxInt() - i20 = BoxInt() - inputargs2 = [i0] - operations2 = [ - ResOperation(rop.LABEL, [i0], None, descr=targettoken1), - ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), - ResOperation(rop.INT_ADD, [i1, ConstInt(1)], i2), - ResOperation(rop.INT_ADD, [i2, ConstInt(1)], i3), - ResOperation(rop.INT_ADD, [i3, ConstInt(1)], i4), - ResOperation(rop.INT_ADD, [i4, ConstInt(1)], i5), - ResOperation(rop.INT_ADD, [i5, ConstInt(1)], i6), - ResOperation(rop.INT_ADD, [i6, ConstInt(1)], i7), - ResOperation(rop.INT_ADD, [i7, ConstInt(1)], i8), - ResOperation(rop.INT_ADD, [i8, ConstInt(1)], i9), - ResOperation(rop.INT_ADD, [i9, ConstInt(1)], i10), - ResOperation(rop.INT_ADD, [i10, ConstInt(1)], i11), - ResOperation(rop.INT_ADD, [i11, ConstInt(1)], i12), - ResOperation(rop.INT_ADD, [i12, ConstInt(1)], i13), - ResOperation(rop.INT_ADD, [i13, ConstInt(1)], i14), - ResOperation(rop.INT_ADD, [i14, ConstInt(1)], i15), - ResOperation(rop.INT_ADD, [i15, ConstInt(1)], i16), - ResOperation(rop.INT_ADD, [i16, ConstInt(1)], i17), - ResOperation(rop.INT_ADD, [i17, ConstInt(1)], i18), - ResOperation(rop.INT_ADD, [i18, ConstInt(1)], i19), - ResOperation(rop.CALL, [funcbox, i2, i4, i6, i8, i10, i12, i14, i16, i18], - None, descr=calldescr), - ResOperation(rop.CALL, [funcbox, i2, i4, i6, i8, i10, i12, i14, i16, i18], - None, descr=calldescr), - ResOperation(rop.INT_LT, [i19, ConstInt(100)], i20), - ResOperation(rop.GUARD_TRUE, [i20], None, descr=BasicFailDescr(42)), - ResOperation(rop.JUMP, [i19], None, descr=targettoken1), - ] - operations2[-2].setfailargs([]) - self.cpu.compile_bridge(faildescr1, inputargs2, operations2, - looptoken1) ->>>>>>> /tmp/runner_test.py~other.b8EcdI - -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py inputargs, operations, looptoken2 = self.parse(""" [i0] jump(0, descr=targettoken1) """, locals()) self.cpu.compile_loop(inputargs, operations, looptoken2) -||||||| /tmp/runner_test.py~base._aMykN - looptoken2 = JitCellToken() - inputargs = [BoxInt()] - operations = [ - ResOperation(rop.JUMP, [ConstInt(0)], None, descr=targettoken1), - ] - self.cpu.compile_loop(inputargs, operations, looptoken2) -======= - looptoken2 = JitCellToken() - inputargs3 = [BoxInt()] - operations3 = [ - ResOperation(rop.JUMP, [ConstInt(0)], None, descr=targettoken1), - ] - self.cpu.compile_loop(inputargs3, operations3, looptoken2) - frame = self.cpu.execute_token(looptoken2, -9) assert self.cpu.get_latest_descr(frame).identifier == 42 ->>>>>>> /tmp/runner_test.py~other.b8EcdI -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - fail = self.cpu.execute_token(looptoken2, -9) - assert fail.identifier == 1 -||||||| /tmp/runner_test.py~base._aMykN - fail = self.cpu.execute_token(looptoken2, -9) - assert fail.identifier == 42 -======= def test_wrong_guard_nonnull_class(self): t_box, T_box = self.alloc_instance(self.T) null_box = self.null_instance() @@ -4224,7 +3535,6 @@ self.cpu.compile_bridge(faildescr, [], operations, looptoken) frame = self.cpu.execute_token(looptoken, null_box.getref_base()) assert self.cpu.get_latest_descr(frame).identifier == 99 ->>>>>>> /tmp/runner_test.py~other.b8EcdI def test_raw_load_int(self): from pypy.rlib import rawstorage @@ -4234,16 +3544,8 @@ rffi.ULONG, rffi.LONG]: ops = """ [i0, i1] -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py i2 = raw_load_i(i0, i1, descr=arraydescr) - finish(i2, descr=faildescr1) -||||||| /tmp/runner_test.py~base._aMykN - i2 = raw_load(i0, i1, descr=arraydescr) - finish(i2) -======= - i2 = raw_load(i0, i1, descr=arraydescr) - finish(i2) [] ->>>>>>> /tmp/runner_test.py~other.b8EcdI + finish(i2, descr=faildescr1) [] """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -4268,16 +3570,8 @@ for T in [rffi.DOUBLE]: ops = """ [i0, i1] -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py f2 = raw_load_f(i0, i1, descr=arraydescr) - finish(f2, descr=faildescr1) -||||||| /tmp/runner_test.py~base._aMykN - f2 = raw_load(i0, i1, descr=arraydescr) - finish(f2) -======= - f2 = raw_load(i0, i1, descr=arraydescr) - finish(f2) [] ->>>>>>> /tmp/runner_test.py~other.b8EcdI + finish(f2, descr=faildescr1) [] """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -4305,13 +3599,7 @@ ops = """ [i0, i1, i2] raw_store(i0, i1, i2, descr=arraydescr) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - finish(descr=faildescr1) -||||||| /tmp/runner_test.py~base._aMykN - finish() -======= - finish() [] ->>>>>>> /tmp/runner_test.py~other.b8EcdI + finish(descr=faildescr1) [] """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -4336,13 +3624,7 @@ ops = """ [i0, i1, f2] raw_store(i0, i1, f2, descr=arraydescr) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py - finish(descr=faildescr1) -||||||| /tmp/runner_test.py~base._aMykN - finish() -======= - finish() [] ->>>>>>> /tmp/runner_test.py~other.b8EcdI + finish(descr=faildescr1) [] """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -4359,51 +3641,6 @@ result = rawstorage.raw_storage_getitem(T, p, 16) assert result == rffi.cast(T, value) rawstorage.free_raw_storage(p) -<<<<<<< /64/home/arigo/hg/pypy/result-in-resops/pypy/jit/backend/test/runner_test.py -||||||| /tmp/runner_test.py~base._aMykN - -class OOtypeBackendTest(BaseBackendTest): - - type_system = 'ootype' - Ptr = staticmethod(lambda x: x) - FuncType = ootype.StaticMethod - malloc = staticmethod(ootype.new) - nullptr = staticmethod(ootype.null) - - def setup_class(cls): - py.test.skip("ootype tests skipped") - - @classmethod - def get_funcbox(cls, cpu, func_ptr): - return BoxObj(ootype.cast_to_object(func_ptr)) - - S = ootype.Instance('S', ootype.ROOT, {'value': ootype.Signed, - 'chr1': ootype.Char, - 'chr2': ootype.Char}) - S._add_fields({'next': S}) - T = ootype.Instance('T', S) - U = ootype.Instance('U', T) - - def alloc_instance(self, T): - t = ootype.new(T) - cls = ootype.classof(t) - t_box = BoxObj(ootype.cast_to_object(t)) - T_box = ConstObj(ootype.cast_to_object(cls)) - return t_box, T_box - - def null_instance(self): - return BoxObj(ootype.NULL) - - def alloc_array_of(self, ITEM, length): - py.test.skip("implement me") - - def alloc_string(self, string): - py.test.skip("implement me") - - def alloc_unicode(self, unicode): - py.test.skip("implement me") - -======= def test_forcing_op_with_fail_arg_in_reg(self): values = [] @@ -4440,46 +3677,3 @@ # memory assert values[0] == 0 assert values[1] == frame - -class OOtypeBackendTest(BaseBackendTest): - - type_system = 'ootype' - Ptr = staticmethod(lambda x: x) - FuncType = ootype.StaticMethod - malloc = staticmethod(ootype.new) - nullptr = staticmethod(ootype.null) - - def setup_class(cls): - py.test.skip("ootype tests skipped") - - @classmethod - def get_funcbox(cls, cpu, func_ptr): - return BoxObj(ootype.cast_to_object(func_ptr)) - - S = ootype.Instance('S', ootype.ROOT, {'value': ootype.Signed, - 'chr1': ootype.Char, - 'chr2': ootype.Char}) - S._add_fields({'next': S}) - T = ootype.Instance('T', S) - U = ootype.Instance('U', T) - - def alloc_instance(self, T): - t = ootype.new(T) - cls = ootype.classof(t) - t_box = BoxObj(ootype.cast_to_object(t)) - T_box = ConstObj(ootype.cast_to_object(cls)) - return t_box, T_box - - def null_instance(self): - return BoxObj(ootype.NULL) - - def alloc_array_of(self, ITEM, length): - py.test.skip("implement me") - - def alloc_string(self, string): - py.test.skip("implement me") - - def alloc_unicode(self, unicode): - py.test.skip("implement me") - ->>>>>>> /tmp/runner_test.py~other.b8EcdI From noreply at buildbot.pypy.org Mon Oct 22 15:55:47 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 15:55:47 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: Kill the monkeypatch that poses a serious performance problem for large files Message-ID: <20121022135547.CD42B1C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58356:5cfbe71644a6 Date: 2012-10-22 14:32 +0200 http://bitbucket.org/pypy/pypy/changeset/5cfbe71644a6/ Log: Kill the monkeypatch that poses a serious performance problem for large files diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -20,15 +20,6 @@ option = None -def braindead_deindent(self): - """monkeypatch that wont end up doing stupid in the python tokenizer""" - text = '\n'.join(self.lines) - short = py.std.textwrap.dedent(text) - newsource = py.code.Source() - newsource.lines[:] = short.splitlines() - return newsource - -py.code.Source.deindent = braindead_deindent def pytest_report_header(): return "pytest-%s from %s" %(pytest.__version__, pytest.__file__) From noreply at buildbot.pypy.org Mon Oct 22 15:55:49 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 15:55:49 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: fix a lot of imports Message-ID: <20121022135549.133531C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58357:139a66be1b94 Date: 2012-10-22 14:33 +0200 http://bitbucket.org/pypy/pypy/changeset/139a66be1b94/ Log: fix a lot of imports diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -1,8 +1,9 @@ import weakref from pypy.jit.backend import model from pypy.jit.backend.llgraph import support -from pypy.jit.metainterp.history import Const, getkind, AbstractDescr -from pypy.jit.metainterp.history import INT, REF, FLOAT, VOID +from pypy.jit.metainterp.history import AbstractDescr +from pypy.jit.metainterp.resoperation import Const, getkind +from pypy.jit.metainterp.resoperation import INT, REF, FLOAT, VOID from pypy.jit.metainterp.resoperation import rop from pypy.jit.codewriter import longlong, heaptracker from pypy.jit.codewriter.effectinfo import EffectInfo diff --git a/pypy/jit/backend/llgraph/support.py b/pypy/jit/backend/llgraph/support.py --- a/pypy/jit/backend/llgraph/support.py +++ b/pypy/jit/backend/llgraph/support.py @@ -2,7 +2,7 @@ from pypy.jit.codewriter import longlong from pypy.jit.codewriter import heaptracker -from pypy.jit.metainterp.history import getkind, INT, REF +from pypy.jit.metainterp.resoperation import getkind from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint from pypy.rpython.lltypesystem import lltype, rffi, llmemory diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -12,7 +12,6 @@ ConstPtr from pypy.jit.metainterp.history import TreeLoop, JitCellToken, TargetToken from pypy.jit.metainterp.history import AbstractFailDescr -from pypy.jit.metainterp.resoperation import BoxPtr, BoxFloat, Box, BoxInt from pypy.jit.metainterp import resoperation from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.resume import NUMBERING, PENDINGFIELDSP diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -1394,7 +1394,6 @@ is_guard = name.startswith('GUARD') if is_guard or name == 'FINISH': - assert withdescr baseclass = GuardResOp elif withdescr: baseclass = ResOpWithDescr diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py --- a/pypy/jit/metainterp/resume.py +++ b/pypy/jit/metainterp/resume.py @@ -1,5 +1,4 @@ from pypy.jit.metainterp.resoperation import Const, ConstInt, getkind -from pypy.jit.metainterp.resoperation import BoxInt, BoxPtr, BoxFloat from pypy.jit.metainterp.resoperation import INT, REF, FLOAT from pypy.jit.metainterp.history import AbstractDescr from pypy.jit.metainterp.resoperation import rop From noreply at buildbot.pypy.org Mon Oct 22 15:55:50 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 15:55:50 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: start hacking. pass test_resoperation at least Message-ID: <20121022135550.3FA2A1C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58358:b0f8a9f0cec4 Date: 2012-10-22 15:55 +0200 http://bitbucket.org/pypy/pypy/changeset/b0f8a9f0cec4/ Log: start hacking. pass test_resoperation at least diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -22,6 +22,11 @@ # We need to clone the list of operations because the # front-end will mutate them under our feet again. We also # need to make sure things get freed. + + # XXX for now + self.operations = operations + self.inputargs = inputargs + return def mapping(box, _cache={}): if isinstance(box, Const) or box is None: return box @@ -673,22 +678,19 @@ self.do_renaming(self.lltrace.inputargs, newargs) continue raise - if op.result is not None: + if op.type == INT: # typecheck the result - if op.result.type == INT: - if isinstance(resval, bool): - resval = int(resval) - assert lltype.typeOf(resval) == lltype.Signed - elif op.result.type == REF: - assert lltype.typeOf(resval) == llmemory.GCREF - elif op.result.type == FLOAT: - assert lltype.typeOf(resval) == longlong.FLOATSTORAGE - else: - raise AssertionError(op.result.type) - # - self.env[op.result] = resval + if isinstance(resval, bool): + resval = int(resval) + assert lltype.typeOf(resval) == lltype.Signed + elif op.type == REF: + assert lltype.typeOf(resval) == llmemory.GCREF + elif op.type == FLOAT: + assert lltype.typeOf(resval) == longlong.FLOATSTORAGE else: + assert op.type == VOID assert resval is None + self.env[op] = resval i += 1 def _getfailargs(self, op=None, skip=None): @@ -919,9 +921,10 @@ def _getdescr(op): d = op.getdescr() - if d is not None: - d = d.realdescrref() - assert d is not None, "the descr disappeared: %r" % (op,) + # XXX for now + #if d is not None: + # d = d.realdescrref() + # assert d is not None, "the descr disappeared: %r" % (op,) return d def _setup(): diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -498,7 +498,7 @@ def __hash__(self): import sys co_fname = sys._getframe(1).f_code.co_filename - if co_fname.endswith('resume.py') or co_fname.endswith('optimizeopt/util.py'): + if co_fname.endswith('resume.py') or co_fname.endswith('optimizeopt/util.py') or 'backend/llgraph' in co_fname: return object.__hash__(self) raise Exception("Should not hash resops, use get/set extra instead") @@ -1393,7 +1393,7 @@ } is_guard = name.startswith('GUARD') - if is_guard or name == 'FINISH': + if is_guard: baseclass = GuardResOp elif withdescr: baseclass = ResOpWithDescr diff --git a/pypy/jit/metainterp/test/test_resoperation.py b/pypy/jit/metainterp/test/test_resoperation.py --- a/pypy/jit/metainterp/test/test_resoperation.py +++ b/pypy/jit/metainterp/test/test_resoperation.py @@ -135,8 +135,8 @@ assert ope._get_hash_() == op._get_hash_() assert ope.eq(op) - op = rop.create_resop_0(rop.rop.FORCE_TOKEN, 13) - op1 = rop.create_resop_0(rop.rop.FORCE_TOKEN, 15) + op = rop.create_resop_0(rop.rop.INPUT_i, 13) + op1 = rop.create_resop_0(rop.rop.INPUT_i, 15) assert op._get_hash_() != op1._get_hash_() assert not op.eq(op1) S = lltype.GcStruct('S') From noreply at buildbot.pypy.org Mon Oct 22 16:23:32 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 16:23:32 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: pass the first backend test Message-ID: <20121022142332.A18F81C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58359:057749160f2e Date: 2012-10-22 16:04 +0200 http://bitbucket.org/pypy/pypy/changeset/057749160f2e/ Log: pass the first backend test diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -47,8 +47,8 @@ map(mapping, op.getarglist()), mapping(op.result), newdescr) - if op.getfailargs() is not None: - newop.setfailargs(map(mapping, op.getfailargs())) + if op.get_failargs() is not None: + newop.setfailargs(map(mapping, op.get_failargs())) self.operations.append(newop) class WeakrefDescr(AbstractDescr): @@ -674,7 +674,7 @@ i = 0 self.lltrace = gf.descr._llgraph_bridge newargs = [self.env[arg] for arg in - self.current_op.getfailargs() if arg is not None] + self.current_op.get_failargs() if arg is not None] self.do_renaming(self.lltrace.inputargs, newargs) continue raise @@ -697,7 +697,7 @@ if op is None: op = self.current_op r = [] - for arg in op.getfailargs(): + for arg in op.get_failargs(): if arg is None: r.append(None) elif arg is skip: @@ -719,7 +719,7 @@ raise GuardFailed(self._getfailargs(), descr) def execute_finish(self, descr, arg=None): - if self.current_op.getfailargs() is not None: + if self.current_op.get_failargs() is not None: failargs = self._getfailargs() else: failargs = None # compatibility diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -9,7 +9,6 @@ from pypy.jit.metainterp.typesystem import deref from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass -from pypy.rpython.ootypesystem import ootype from pypy.rpython.annlowlevel import llhelper from pypy.rpython.llinterp import LLException from pypy.jit.codewriter import heaptracker, longlong @@ -125,7 +124,7 @@ namespace['faildescr3'] = BasicFailDescr(3) if 'faildescr4' not in namespace: namespace['faildescr4'] = BasicFailDescr(4) - loop = parse(s, namespace=namespace) + loop = parse(s, namespace=namespace, guards_with_failargs=True) return loop.inputargs, loop.operations, JitCellToken() def test_compile_linear_loop(self): @@ -133,7 +132,7 @@ inputargs, ops, token = self.parse(""" [i0] i1 = int_add(i0, 1) - finish(i1, descr=faildescr) + finish(i1, descr=faildescr) [] """, namespace=locals()) self.cpu.compile_loop(inputargs, ops, token) frame = self.cpu.execute_token(token, 2) diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -3,7 +3,7 @@ """ from pypy.tool.sourcetools import func_with_new_name -from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable +from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable, rop def create_mutable_subclasses(): def addattr(cls, attr, default_value=None): @@ -21,7 +21,7 @@ else: class Mutable(cls): is_mutable = True - if cls.is_guard(): + if cls.is_guard() or cls.getopnum() == rop.FINISH: addattr(Mutable, 'failargs') Mutable.__name__ = cls.__name__ + '_mutable' assert len(opclasses_mutable) == i From noreply at buildbot.pypy.org Mon Oct 22 16:23:33 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 16:23:33 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: fix one more test Message-ID: <20121022142333.D094E1C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58360:39e70d282074 Date: 2012-10-22 16:20 +0200 http://bitbucket.org/pypy/pypy/changeset/39e70d282074/ Log: fix one more test diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -141,18 +141,16 @@ assert self.cpu.get_latest_descr(frame).identifier == 1 def test_compile_linear_float_loop(self): - i0 = BoxFloat() - i1 = BoxFloat() - operations = [ - ResOperation(rop.FLOAT_ADD, [i0, constfloat(2.3)], i1), - ResOperation(rop.FINISH, [i1], None, descr=BasicFailDescr(1)) - ] - inputargs = [i0] - looptoken = JitCellToken() - self.cpu.compile_loop(inputargs, operations, looptoken) - frame = self.cpu.execute_token(looptoken, longlong.getfloatstorage(2.8)) - res = self.cpu.get_finish_value_int(frame) - assert longlong.getrealfloat(res) == 5.1 + faildescr = BasicFailDescr(1) + inputargs, ops, token = self.parse(""" + [f0] + f1 = float_add(f0, 1.) + finish(f1, descr=faildescr) [] + """, namespace=locals()) + self.cpu.compile_loop(inputargs, ops, token) + frame = self.cpu.execute_token(token, longlong.getfloatstorage(2.8)) + res = self.cpu.get_finish_value_float(frame) + assert longlong.getrealfloat(res) == 3.8 assert self.cpu.get_latest_descr(frame).identifier == 1 def test_compile_loop(self): From noreply at buildbot.pypy.org Mon Oct 22 16:49:57 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 16:49:57 +0200 (CEST) Subject: [pypy-commit] pypy default: try to mitigate "it takes forever" on py.test Message-ID: <20121022144957.3E0571C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58361:f8388bb30d71 Date: 2012-10-22 16:27 +0200 http://bitbucket.org/pypy/pypy/changeset/f8388bb30d71/ Log: try to mitigate "it takes forever" on py.test diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -118,7 +118,7 @@ # 1. find the start of the statement from codeop import compile_command end = None - for start in range(lineno, -1, -1): + for start in range(lineno, -1, max(-1, lineno - 10)): if assertion: line = self.lines[start] # the following lines are not fully tested, change with care @@ -135,9 +135,9 @@ compile_command(trysource) except (SyntaxError, OverflowError, ValueError): continue - + # 2. find the end of the statement - for end in range(lineno+1, len(self)+1): + for end in range(lineno+1, min(len(self)+1, lineno + 10)): trysource = self[start:end] if trysource.isparseable(): return start, end From noreply at buildbot.pypy.org Mon Oct 22 16:49:58 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 16:49:58 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: (arigo, fijal) consistently pass descr as last Message-ID: <20121022144958.742FC1C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58362:981f578b1731 Date: 2012-10-22 16:44 +0200 http://bitbucket.org/pypy/pypy/changeset/981f578b1731/ Log: (arigo, fijal) consistently pass descr as last diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py --- a/pypy/jit/codewriter/jtransform.py +++ b/pypy/jit/codewriter/jtransform.py @@ -580,8 +580,8 @@ kind = getkind(op.result.concretetype) return [SpaceOperation('-live-', [], None), SpaceOperation('getarrayitem_vable_%s' % kind[0], - [v_base, arrayfielddescr, arraydescr, - op.args[1]], op.result)] + [v_base, op.args[1], arrayfielddescr, + arraydescr], op.result)] # normal case follows pure = '' immut = ARRAY._immutable_field(None) @@ -604,12 +604,12 @@ kind = getkind(op.args[2].concretetype) return [SpaceOperation('-live-', [], None), SpaceOperation('setarrayitem_vable_%s' % kind[0], - [v_base, arrayfielddescr, arraydescr, - op.args[1], op.args[2]], None)] + [v_base, op.args[1], op.args[2], + arrayfielddescr, arraydescr], None)] arraydescr = self.cpu.arraydescrof(ARRAY) kind = getkind(op.args[2].concretetype) return SpaceOperation('setarrayitem_%s_%s' % (ARRAY._gckind, kind[0]), - [op.args[0], arraydescr, op.args[1], op.args[2]], + [op.args[0], op.args[1], op.args[2], arraydescr], None) def rewrite_op_getarraysize(self, op): @@ -1535,13 +1535,13 @@ kind = getkind(args[2].concretetype) return [SpaceOperation('-live-', [], None), SpaceOperation('setarrayitem_vable_%s' % kind[0], - [v_base, arrayfielddescr, arraydescr, - args[1], args[2]], None)] + [v_base, args[1], args[2], + arrayfielddescr, arraydescr], None)] v_index, extraop = self._prepare_list_getset(op, arraydescr, args, 'check_neg_index') kind = getkind(args[2].concretetype)[0] op = SpaceOperation('setarrayitem_gc_%s' % kind, - [args[0], arraydescr, v_index, args[2]], None) + [args[0], v_index, args[2], arraydescr], None) return extraop + [op] def do_fixed_list_ll_arraycopy(self, op, args, arraydescr): diff --git a/pypy/jit/codewriter/test/test_call.py b/pypy/jit/codewriter/test/test_call.py --- a/pypy/jit/codewriter/test/test_call.py +++ b/pypy/jit/codewriter/test/test_call.py @@ -173,7 +173,7 @@ py.test.skip("XXX add a test for CallControl.getcalldescr() -> EF_xxx") def test_releases_gil_analyzer(): - from pypy.jit.backend.llgraph.runner import LLtypeCPU + from pypy.jit.backend.llgraph.runner import LLGraphCPU T = rffi.CArrayPtr(rffi.TIME_T) external = rffi.llexternal("time", [T], rffi.TIME_T, threadsafe=True) @@ -184,7 +184,7 @@ rtyper = support.annotate(f, []) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) - cc = CallControl(LLtypeCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) + 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] @@ -194,7 +194,7 @@ assert call_descr.extrainfo.has_random_effects() def test_random_effects_on_stacklet_switch(): - from pypy.jit.backend.llgraph.runner import LLtypeCPU + from pypy.jit.backend.llgraph.runner import LLGraphCPU from pypy.translator.platform import CompilationError try: from pypy.rlib._rffi_stacklet import switch, thread_handle, handle @@ -209,7 +209,7 @@ rtyper = support.annotate(f, []) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) - cc = CallControl(LLtypeCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) + 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] diff --git a/pypy/jit/codewriter/test/test_flatten.py b/pypy/jit/codewriter/test/test_flatten.py --- a/pypy/jit/codewriter/test/test_flatten.py +++ b/pypy/jit/codewriter/test/test_flatten.py @@ -688,7 +688,7 @@ return array[2] + len(array) self.encoding_test(f, [], """ new_array $5, -> %r0 - setarrayitem_gc_i %r0, , $2, $5 + setarrayitem_gc_i %r0, $2, $5, getarrayitem_gc_i %r0, $2, -> %i0 arraylen_gc %r0, -> %i1 int_add %i0, %i1 -> %i2 diff --git a/pypy/jit/codewriter/test/test_jtransform.py b/pypy/jit/codewriter/test/test_jtransform.py --- a/pypy/jit/codewriter/test/test_jtransform.py +++ b/pypy/jit/codewriter/test/test_jtransform.py @@ -1,21 +1,9 @@ import py import random -try: - from itertools import product -except ImportError: - # Python 2.5, this is taken from the CPython docs, but simplified. - def product(*args): - # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy - # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 - pools = map(tuple, args) - result = [[]] - for pool in pools: - result = [x+[y] for x in result for y in pool] - for prod in result: - yield tuple(prod) +from itertools import product -from pypy.objspace.flow.model import FunctionGraph, Block, Link +from pypy.objspace.flow.model import Block, Link from pypy.objspace.flow.model import SpaceOperation, Variable, Constant from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr, rffi from pypy.rpython.lltypesystem.module import ll_math diff --git a/pypy/jit/codewriter/test/test_list.py b/pypy/jit/codewriter/test/test_list.py --- a/pypy/jit/codewriter/test/test_list.py +++ b/pypy/jit/codewriter/test/test_list.py @@ -144,7 +144,7 @@ varoftype(lltype.Signed), varoftype(lltype.Signed)], lltype.Void, """ - setarrayitem_gc_i %r0, , %i0, %i1 + setarrayitem_gc_i %r0, %i0, %i1, """) builtin_test('list.setitem/NEG', [varoftype(FIXEDLIST), varoftype(lltype.Signed), @@ -152,7 +152,7 @@ lltype.Void, """ -live- check_neg_index %r0, , %i0 -> %i1 - setarrayitem_gc_i %r0, , %i1, %i2 + setarrayitem_gc_i %r0, %i1, %i2, """) def test_fixed_len(): From noreply at buildbot.pypy.org Mon Oct 22 16:49:59 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 16:49:59 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: pass few more tests Message-ID: <20121022144959.AB77D1C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58363:f87ec8cadc4f Date: 2012-10-22 16:45 +0200 http://bitbucket.org/pypy/pypy/changeset/f87ec8cadc4f/ Log: pass few more tests diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -47,8 +47,8 @@ map(mapping, op.getarglist()), mapping(op.result), newdescr) - if op.get_failargs() is not None: - newop.setfailargs(map(mapping, op.get_failargs())) + if op.getfailargs() is not None: + newop.setfailargs(map(mapping, op.getfailargs())) self.operations.append(newop) class WeakrefDescr(AbstractDescr): @@ -674,7 +674,7 @@ i = 0 self.lltrace = gf.descr._llgraph_bridge newargs = [self.env[arg] for arg in - self.current_op.get_failargs() if arg is not None] + self.current_op.getfailargs() if arg is not None] self.do_renaming(self.lltrace.inputargs, newargs) continue raise @@ -697,7 +697,7 @@ if op is None: op = self.current_op r = [] - for arg in op.get_failargs(): + for arg in op.getfailargs(): if arg is None: r.append(None) elif arg is skip: @@ -719,7 +719,7 @@ raise GuardFailed(self._getfailargs(), descr) def execute_finish(self, descr, arg=None): - if self.current_op.get_failargs() is not None: + if self.current_op.getfailargs() is not None: failargs = self._getfailargs() else: failargs = None # compatibility diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -1137,11 +1137,11 @@ bhimpl_getarrayitem_gc_r_pure = bhimpl_getarrayitem_gc_r bhimpl_getarrayitem_gc_f_pure = bhimpl_getarrayitem_gc_f - @arguments("cpu", "i", "d", "i", returns="i") - def bhimpl_getarrayitem_raw_i(cpu, array, arraydescr, index): + @arguments("cpu", "i", "i", "d", returns="i") + def bhimpl_getarrayitem_raw_i(cpu, array, index, arraydescr): return cpu.bh_getarrayitem_raw_i(array, index, arraydescr) - @arguments("cpu", "i", "d", "i", returns="f") - def bhimpl_getarrayitem_raw_f(cpu, array, arraydescr, index): + @arguments("cpu", "i", "i", "d", returns="f") + def bhimpl_getarrayitem_raw_f(cpu, array, index, arraydescr): return cpu.bh_getarrayitem_raw_f(array, index, arraydescr) bhimpl_getarrayitem_raw_i_pure = bhimpl_getarrayitem_raw_i diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py --- a/pypy/jit/metainterp/executor.py +++ b/pypy/jit/metainterp/executor.py @@ -319,16 +319,11 @@ if func is not None: execute[value] = func continue -<<<<<<< local - if value in (rop.FORCE_TOKEN, + if value in (rop.JIT_FRAME, rop.CALL_ASSEMBLER_i, rop.CALL_ASSEMBLER_r, rop.CALL_ASSEMBLER_f, rop.CALL_ASSEMBLER_N, -======= - if value in (rop.JIT_FRAME, - rop.CALL_ASSEMBLER, ->>>>>>> other rop.COND_CALL_GC_WB, rop.COND_CALL_GC_WB_ARRAY, rop.DEBUG_MERGE_POINT, diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -12,8 +12,8 @@ def setter(self, value): setattr(self, '_' + attr, value) setattr(cls, '_' + attr, default_value) - setattr(cls, 'get_' + attr, func_with_new_name(getter, 'get_' + attr)) - setattr(cls, 'set_' + attr, func_with_new_name(setter, 'set_' + attr)) + setattr(cls, 'get' + attr, func_with_new_name(getter, 'get' + attr)) + setattr(cls, 'set' + attr, func_with_new_name(setter, 'set' + attr)) for i, cls in enumerate(opclasses): if cls is None: @@ -23,6 +23,8 @@ is_mutable = True if cls.is_guard() or cls.getopnum() == rop.FINISH: addattr(Mutable, 'failargs') + if cls.is_guard(): + addattr(Mutable, 'descr') # mutable guards have descrs Mutable.__name__ = cls.__name__ + '_mutable' assert len(opclasses_mutable) == i opclasses_mutable.append(Mutable) diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -246,7 +246,7 @@ i = line.find('[', endnum) + 1 j = line.find(']', i) if i <= 0 or j <= 0: - if self.guards_with_failargs: + if self.guards_with_failargs and opnum != rop.FINISH: raise ParseError("missing fail_args for guard operation") fail_args = None else: @@ -301,14 +301,14 @@ opres = self.create_op(opnum, result, args, descr) self.vars[res] = opres if fail_args is not None: - opres.set_failargs(fail_args) + opres.setfailargs(fail_args) return opres def parse_op_no_result(self, line): opnum, args, descr, fail_args = self.parse_op(line) res = self.create_op(opnum, None, args, descr) if fail_args is not None: - res.set_failargs(fail_args) + res.setfailargs(fail_args) return res def parse_next_op(self, line, num): From noreply at buildbot.pypy.org Mon Oct 22 16:50:00 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 16:50:00 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: (arigo, fijal) fix fix fix argument order issues Message-ID: <20121022145000.BFAB61C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58364:c004f1922229 Date: 2012-10-22 16:49 +0200 http://bitbucket.org/pypy/pypy/changeset/c004f1922229/ Log: (arigo, fijal) fix fix fix argument order issues diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -1123,14 +1123,14 @@ def bhimpl_new_array(cpu, arraydescr, length): return cpu.bh_new_array(length, arraydescr) - @arguments("cpu", "r", "d", "i", returns="i") - def bhimpl_getarrayitem_gc_i(cpu, array, arraydescr, index): + @arguments("cpu", "r", "i", "d", returns="i") + def bhimpl_getarrayitem_gc_i(cpu, array, index, arraydescr): return cpu.bh_getarrayitem_gc_i(array, index, arraydescr) - @arguments("cpu", "r", "d", "i", returns="r") - def bhimpl_getarrayitem_gc_r(cpu, array, arraydescr, index): + @arguments("cpu", "r", "i", "d", returns="r") + def bhimpl_getarrayitem_gc_r(cpu, array, index, arraydescr): return cpu.bh_getarrayitem_gc_r(array, index, arraydescr) - @arguments("cpu", "r", "d", "i", returns="f") - def bhimpl_getarrayitem_gc_f(cpu, array, arraydescr, index): + @arguments("cpu", "r", "i", "d", returns="f") + def bhimpl_getarrayitem_gc_f(cpu, array, index, arraydescr): return cpu.bh_getarrayitem_gc_f(array, index, arraydescr) bhimpl_getarrayitem_gc_i_pure = bhimpl_getarrayitem_gc_i @@ -1147,21 +1147,21 @@ bhimpl_getarrayitem_raw_i_pure = bhimpl_getarrayitem_raw_i bhimpl_getarrayitem_raw_f_pure = bhimpl_getarrayitem_raw_f - @arguments("cpu", "r", "d", "i", "i") - def bhimpl_setarrayitem_gc_i(cpu, array, arraydescr, index, newvalue): + @arguments("cpu", "r", "i", "i", "d") + def bhimpl_setarrayitem_gc_i(cpu, array, index, newvalue, arraydescr): cpu.bh_setarrayitem_gc_i(array, index, newvalue, arraydescr) - @arguments("cpu", "r", "d", "i", "r") - def bhimpl_setarrayitem_gc_r(cpu, array, arraydescr, index, newvalue): + @arguments("cpu", "r", "i", "r", "d") + def bhimpl_setarrayitem_gc_r(cpu, array, index, newvalue, arraydescr): cpu.bh_setarrayitem_gc_r(array, index, newvalue, arraydescr) - @arguments("cpu", "r", "d", "i", "f") - def bhimpl_setarrayitem_gc_f(cpu, array, arraydescr, index, newvalue): + @arguments("cpu", "r", "i", "f", "d") + def bhimpl_setarrayitem_gc_f(cpu, array, index, newvalue, arraydescr): cpu.bh_setarrayitem_gc_f(array, index, newvalue, arraydescr) - @arguments("cpu", "i", "d", "i", "i") - def bhimpl_setarrayitem_raw_i(cpu, array, arraydescr, index, newvalue): + @arguments("cpu", "i", "i", "i", "d") + def bhimpl_setarrayitem_raw_i(cpu, array, index, newvalue, arraydescr): cpu.bh_setarrayitem_raw_i(array, index, newvalue, arraydescr) - @arguments("cpu", "i", "d", "i", "f") - def bhimpl_setarrayitem_raw_f(cpu, array, arraydescr, index, newvalue): + @arguments("cpu", "i", "i", "f", "d") + def bhimpl_setarrayitem_raw_f(cpu, array, index, newvalue, arraydescr): cpu.bh_setarrayitem_raw_f(array, index, newvalue, arraydescr) # note, there is no 'r' here, since it can't happen @@ -1170,40 +1170,40 @@ def bhimpl_arraylen_gc(cpu, array, arraydescr): return cpu.bh_arraylen_gc(array, arraydescr) - @arguments("cpu", "vinfo", "r", "d", "d", "i", returns="i") - def bhimpl_getarrayitem_vable_i(cpu, vinfo, vable, fielddescr, arraydescr, - index): + @arguments("cpu", "vinfo", "r", "i", "d", "d", returns="i") + def bhimpl_getarrayitem_vable_i(cpu, vinfo, vable, index, fielddescr, + arraydescr): bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fielddescr) return cpu.bh_getarrayitem_gc_i(array, index, arraydescr) - @arguments("cpu", "vinfo", "r", "d", "d", "i", returns="r") - def bhimpl_getarrayitem_vable_r(cpu, vinfo, vable, fielddescr, arraydescr, - index): + @arguments("cpu", "vinfo", "r", "i", "d", "d", returns="r") + def bhimpl_getarrayitem_vable_r(cpu, vinfo, vable, index, fielddescr, + arraydescr): bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fielddescr) return cpu.bh_getarrayitem_gc_r(array, index, arraydescr) - @arguments("cpu", "r", "d", "d", "i", returns="f") - def bhimpl_getarrayitem_vable_f(cpu, vinfo, vable, fielddescr, arraydescr, - index): + @arguments("cpu", "r", "i", "d", "d", returns="f") + def bhimpl_getarrayitem_vable_f(cpu, vinfo, vable, index, fielddescr, + arraydescr): bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fielddescr) return cpu.bh_getarrayitem_gc_f(array, index, arraydescr) - @arguments("cpu", "vinfo", "r", "d", "d", "i", "i") - def bhimpl_setarrayitem_vable_i(cpu, vinfo, vable, fdescr, adescr, index, - newval): + @arguments("cpu", "vinfo", "r", "i", "i", "d", "d") + def bhimpl_setarrayitem_vable_i(cpu, vinfo, vable, index, newval, + fdescr, adescr): bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fdescr) cpu.bh_setarrayitem_gc_i(array, index, newval, adescr) - @arguments("cpu", "vinfo", "r", "d", "d", "i", "r") - def bhimpl_setarrayitem_vable_r(cpu, vinfo, vable, fdescr, adescr, index, - newval): + @arguments("cpu", "vinfo", "r", "i", "r", "d", "d") + def bhimpl_setarrayitem_vable_r(cpu, vinfo, vable, index, newval, + fdescr, adescr): bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fdescr) cpu.bh_setarrayitem_gc_r(array, index, newval, adescr) - @arguments("cpu", "vinfo", "r", "d", "d", "i", "f") - def bhimpl_setarrayitem_vable_f(cpu, vinfo, vable, fdescr, adescr, index, - newval): + @arguments("cpu", "vinfo", "r", "i", "f", "d", "d") + def bhimpl_setarrayitem_vable_f(cpu, vinfo, vable, index, newval, + fdescr, adescr): bh_force_vable(vinfo, vable) array = cpu.bh_getfield_gc_r(vable, fdescr) cpu.bh_setarrayitem_gc_f(array, index, newval, adescr) From noreply at buildbot.pypy.org Mon Oct 22 17:52:05 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 17:52:05 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: (arigo, fijal) fix fix fix Message-ID: <20121022155205.D3B961C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58365:4c8286636abf Date: 2012-10-22 17:51 +0200 http://bitbucket.org/pypy/pypy/changeset/4c8286636abf/ Log: (arigo, fijal) fix fix fix diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -654,9 +654,6 @@ while True: assert not self.lltrace.has_been_freed op = self.lltrace.operations[i] - if op.getopnum() == -124: # force_spill, for tests - i += 1 - continue args = [self.lookup(arg) for arg in op.getarglist()] self.current_op = op # for label self.current_index = i @@ -718,6 +715,9 @@ def fail_guard(self, descr): raise GuardFailed(self._getfailargs(), descr) + def execute_force_spill(self, _, arg): + pass + def execute_finish(self, descr, arg=None): if self.current_op.getfailargs() is not None: failargs = self._getfailargs() @@ -855,6 +855,10 @@ self.last_exception = lle res = _example_res[getkind(TP.RESULT)[0]] return res + execute_call_i = execute_call + execute_call_r = execute_call + execute_call_f = execute_call + execute_call_v = execute_call def execute_call_may_force(self, calldescr, func, *args): call_op = self.lltrace.operations[self.current_index] @@ -866,6 +870,10 @@ del self.latest_descr del self.latest_values return res + execute_call_may_force_i = execute_call_may_force + execute_call_may_force_r = execute_call_may_force + execute_call_may_force_f = execute_call_may_force + execute_call_may_force_v = execute_call_may_force def execute_call_release_gil(self, descr, func, *args): call_args = support.cast_call_args_in_order(descr.ARGS, args) @@ -900,8 +908,10 @@ del self.latest_values return support.cast_result(lltype.typeOf(result), result) - def execute_same_as(self, _, x): + def execute_same_as_i(self, _, x): return x + execute_same_as_f = execute_same_as_i + execute_same_as_r = execute_same_as_i def execute_debug_merge_point(self, descr, *args): from pypy.jit.metainterp.warmspot import get_stats diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -5,7 +5,7 @@ JitCellToken, TargetToken) from pypy.jit.metainterp.resoperation import rop, create_resop_dispatch,\ create_resop, ConstInt, ConstPtr, ConstFloat, create_resop_2,\ - create_resop_1, create_resop_0, INT, REF, FLOAT + create_resop_1, create_resop_0, INT, REF, FLOAT, example_for_opnum from pypy.jit.metainterp.typesystem import deref from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass @@ -18,7 +18,9 @@ from pypy.jit.tool.oparser import parse -def boxfloat(x): +def boxfloat(x=None): + if x is None: + x = example_for_opnum(rop.INPUT_f) return create_resop_0(rop.INPUT_f, longlong.getfloatstorage(x)) def boxint(x=0): @@ -88,19 +90,21 @@ result = 0.0 else: raise ValueError(result_type) - op0 = create_resop_dispatch(opnum, result, valueboxes) + op0 = create_resop_dispatch(opnum, result, valueboxes, + mutable=True) if result is None: results = [] else: results = [op0] - op1 = create_resop(rop.FINISH, None, results, descr=BasicFailDescr(0)) + op1 = create_resop(rop.FINISH, None, results, descr=BasicFailDescr(0), + mutable=True) if op0.is_guard(): - op0.set_extra("failargs", []) + op0.setfailargs([]) if not descr: descr = BasicFailDescr(1) if descr is not None: op0.setdescr(descr) - inputargs = [] + inputargs = [box for box in valueboxes if not box.is_constant()] return inputargs, [op0, op1] class BaseBackendTest(Runner): @@ -521,10 +525,10 @@ # last, try it with one constant argument calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) - res = self.execute_operation(rop.CALL, - [funcbox, ConstInt(num), BoxInt(num)], + res = self.execute_operation(rop.CALL_i, + [funcbox, ConstInt(num), boxint(num)], 'int', descr=calldescr) - assert res.value == 2 * num + assert res == 2 * num if cpu.supports_floats: @@ -579,8 +583,8 @@ FPTR = self.Ptr(self.FuncType([TP, TP], TP)) func_ptr = llhelper(FPTR, f) FUNC = deref(FPTR) - funcconst = self.get_funcbox(self.cpu, func_ptr) - funcbox = funcconst.nonconstbox() + funcbox = create_resop_0(rop.INPUT_i, + rffi.cast(lltype.Signed, func_ptr)) calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) res = self.execute_operation(rop.CALL_i, @@ -671,7 +675,7 @@ assert res is None res = self.execute_operation(rop.GETFIELD_GC_r, [t_box], 'ref', descr=fielddescr2) - assert res == u_box.value + assert res == u_box.getref_base() # null_const = self.null_instance().constbox() res = self.execute_operation(rop.SETFIELD_GC, [t_box, null_const], @@ -754,7 +758,7 @@ def test_ooops(self): def clone(box): - return boxptr(box.value) + return boxptr(box.getref_base()) u1_box, U_box = self.alloc_instance(self.U) u2_box, U_box = self.alloc_instance(self.U) @@ -788,9 +792,9 @@ # These operations are supposed to be the same as PTR_EQ/PTR_NE # just checking that the operations are defined in the backend. r = self.execute_operation(rop.INSTANCE_PTR_EQ, [u1_box, u2_box], 'int') - assert r.value == 0 + assert r == 0 r = self.execute_operation(rop.INSTANCE_PTR_NE, [u2_box, u1_box], 'int') - assert r.value == 1 + assert r == 1 def test_array_basic(self): a_box, A = self.alloc_array_of(rffi.SHORT, 342) @@ -859,7 +863,7 @@ assert r is None r = self.execute_operation(rop.GETARRAYITEM_GC_r, [b_box, boxint(1)], 'ref', descr=arraydescr) - assert r == a_box.value + assert r == a_box.getref_base() # # Unsigned should work the same as Signed a_box, A = self.alloc_array_of(lltype.Unsigned, 342) @@ -1090,9 +1094,9 @@ assert r == 5 u_box = self.alloc_unicode(u"hello\u1234") r = self.execute_operation(rop.SAME_AS_r, [u_box.constbox()], 'ref') - assert r == u_box.value + assert r == u_box.getref_base() r = self.execute_operation(rop.SAME_AS_r, [u_box], 'ref') - assert r == u_box.value + assert r == u_box.getref_base() if self.cpu.supports_floats: r = self.execute_operation(rop.SAME_AS_f, [constfloat(5.5)], 'float') @@ -1122,7 +1126,7 @@ inputargs.append(boxint()) values.append(r.randrange(-100000, 100000)) else: - inputargs.append(BoxFloat()) + inputargs.append(boxfloat()) values.append(longlong.getfloatstorage(r.random())) # looptoken = JitCellToken() @@ -1134,7 +1138,7 @@ ks = range(nb_args) random.shuffle(ks) for k in ks: - if isinstance(inputargs[k], boxint): + if inputargs[k].type == INT: x = r.randrange(-100000, 100000) operations.append( create_resop_2(rop.INT_ADD, 0, inputargs[k], @@ -1154,7 +1158,8 @@ retvalues.insert(kk, y) # operations.append( - create_resop(rop.FINISH, None, [], descr=faildescr) + create_resop(rop.FINISH, None, [], descr=faildescr, + mutable=True) ) operations[-1].setfailargs(retboxes) print inputargs @@ -1224,20 +1229,19 @@ values = [] S = lltype.GcStruct('S') for box in inpargs: - if isinstance(box, boxint): + if box.type == INT: values.append(r.randrange(-10000, 10000)) - elif isinstance(box, boxptr): + elif box.type == REF: p = lltype.malloc(S) values.append(lltype.cast_opaque_ptr(llmemory.GCREF, p)) - elif isinstance(box, BoxFloat): + elif box.type == FLOAT: values.append(longlong.getfloatstorage(r.random())) else: assert 0 values[index_counter] = 11 # frame = self.cpu.execute_token(looptoken, *values) - assert self.cpu.get_latest_descr(frame).identifier == 15 - assert fail.identifier == 1 + assert self.cpu.get_latest_descr(frame).identifier == 1 # dstvalues = values[:] for _ in range(11): @@ -1302,7 +1306,7 @@ def test_compile_bridge_spilled_float(self): if not self.cpu.supports_floats: py.test.skip("requires floats") - fboxes = [BoxFloat() for i in range(3)] + fboxes = [boxfloat() for i in range(3)] faildescr1 = BasicFailDescr(100) loopops = """ [i0,f1, f2] @@ -1310,9 +1314,10 @@ force_spill(f3) force_spill(f1) force_spill(f2) - guard_false(i0) [f1, f2, f3] + guard_false(i0, descr=faildescr0) [f1, f2, f3] finish() []""" - loop = parse(loopops) + loop = parse(loopops, guards_with_failargs=True, + namespace={'faildescr0': BasicFailDescr(1)}) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) args = [1] @@ -1328,7 +1333,8 @@ assert longlong.getrealfloat(f3) == 133.0 bridgeops = [ - ResOperation(rop.FINISH, [], None, descr=faildescr1), + create_resop(rop.FINISH, None, [], descr=faildescr1, + mutable=True), ] bridgeops[-1].setfailargs(fboxes) self.cpu.compile_bridge(loop.operations[-2].getdescr(), fboxes, @@ -1353,19 +1359,18 @@ (rop.GUARD_FALSE, False), (rop.GUARD_TRUE, True), ]: - box = BoxInt() - res = BoxInt() + box = boxint() faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) inputargs = [box] - operations = [ - ResOperation(opname, [box], res), - ResOperation(opguard, [res], None, descr=faildescr1), - ResOperation(rop.FINISH, [], None, descr=faildescr2), - ] - operations[1].setfailargs([]) + op0 = create_resop_1(opname, 0, box) + op1 = create_resop_1(opguard, None, op0, mutable=True) + op1.setdescr(faildescr1) + op1.setfailargs([]) + op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, + mutable=True) looptoken = JitCellToken() - self.cpu.compile_loop(inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, [op0, op1, op2], looptoken) # cpu = self.cpu for value in [-42, 0, 1, 10]: @@ -1402,12 +1407,13 @@ faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) inputargs = [ib for ib in [ibox1, ibox2] - if isinstance(ib, boxint)] + if not ib.is_constant()] op0 = create_resop_2(opname, 0, ibox1, ibox2) - op1 = create_resop_1(opguard, None, op0) + op1 = create_resop_1(opguard, None, op0, mutable=True) op1.setdescr(faildescr1) - op2 = create_resop(rop.FINISH, None, [], descr=faildescr2) - op1.set_extra("failargs", []) + op1.setfailargs([]) + op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, + mutable=True) operations = [op0, op1, op2] looptoken = JitCellToken() self.cpu.compile_loop(inputargs, operations, looptoken) @@ -1443,26 +1449,25 @@ for combinaison in ["bb", "bc", "cb"]: # if combinaison[0] == 'b': - ibox1 = BoxInt() + ibox1 = boxint() else: ibox1 = ConstInt(42) if combinaison[1] == 'b': - ibox2 = BoxInt() + ibox2 = boxint() else: ibox2 = ConstInt(42) - b1 = BoxInt() faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) inputargs = [ib for ib in [ibox1, ibox2] - if isinstance(ib, BoxInt)] - operations = [ - ResOperation(opname, [ibox1, ibox2], b1), - ResOperation(opguard, [b1], None, descr=faildescr1), - ResOperation(rop.FINISH, [], None, descr=faildescr2), - ] - operations[-2].setfailargs([]) + if not ib.is_constant()] + op0 = create_resop_2(opname, 0, ibox1, ibox2) + op1 = create_resop_1(opguard, None, op0, descr=faildescr1, + mutable=True) + op1.setfailargs([]) + op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, + mutable=True) looptoken = JitCellToken() - self.cpu.compile_loop(inputargs, operations, looptoken) + self.cpu.compile_loop(inputargs, [op0, op1, op2], looptoken) # cpu = self.cpu for test1 in [65, 42, 11, 0, 1]: @@ -1499,22 +1504,23 @@ for combinaison in ["bb", "bc", "cb"]: # if combinaison[0] == 'b': - fbox1 = BoxFloat() + fbox1 = boxfloat() else: fbox1 = constfloat(-4.5) if combinaison[1] == 'b': - fbox2 = BoxFloat() + fbox2 = boxfloat() else: fbox2 = constfloat(-4.5) faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) inputargs = [fb for fb in [fbox1, fbox2] - if isinstance(fb, BoxFloat)] + if not fb.is_constant()] op0 = create_resop_2(opname, 0, fbox1, fbox2) - op1 = create_resop_1(opguard, None, op0) + op1 = create_resop_1(opguard, None, op0, mutable=True) op1.setdescr(faildescr1) - op1.set_extra("failargs", []) - op2 = create_resop(rop.FINISH, None, [], descr=faildescr2) + op1.setfailargs([]) + op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, + mutable=True) operations = [op0, op1, op2] looptoken = JitCellToken() self.cpu.compile_loop(inputargs, operations, looptoken) @@ -1561,28 +1567,29 @@ inputargs = [] operations = [] for opnum, boxargs, rettype, retvalue in tests: - inputargs += [box for box in boxargs if isinstance(box, Box)] + inputargs += [box for box in boxargs if not box.is_constant()] if rettype == 'int': res = 0 elif rettype == 'float': res = 0.0 else: assert 0 - operations.append(create_resop_dispatch(opnum, res, boxargs)) + operations.append(create_resop_dispatch(opnum, res, boxargs, + mutable=True)) # Unique-ify inputargs inputargs = list(set(inputargs)) faildescr = BasicFailDescr(1) operations.append(create_resop(rop.FINISH, None, [], - descr=faildescr)) + descr=faildescr, mutable=True)) looptoken = JitCellToken() # self.cpu.compile_loop(inputargs, operations, looptoken) # args = [] for box in inputargs: - if isinstance(box, boxint): + if box.type == INT: args.append(box.getint()) - elif isinstance(box, BoxFloat): + elif box.type == FLOAT: args.append(box.getfloatstorage()) else: assert 0 @@ -1624,8 +1631,6 @@ ok = isnan(got) elif isinf(expected): ok = isinf(got) - elif isinstance(got, BoxFloat): - ok = got == expected else: ok = got == expected if not ok: @@ -1638,11 +1643,13 @@ for guard_opnum, expected_id in [(rop.GUARD_TRUE, 1), (rop.GUARD_FALSE, 0)]: op0 = create_resop_2(opnum, 0, *testcase) - op1 = create_resop_1(guard_opnum, None, op0) + op1 = create_resop_1(guard_opnum, None, op0, + mutable=True) + op1.setfailargs([]) op1.setdescr(BasicFailDescr(4)) op2 = create_resop(rop.FINISH, None, [], - descr=BasicFailDescr(5)) - op1.set_extra("failargs", []) + descr=BasicFailDescr(5), + mutable=True) operations = [op0, op1, op2] looptoken = JitCellToken() # Use "set" to unique-ify inputargs @@ -1877,7 +1884,7 @@ r = self.execute_operation(rop.GETFIELD_GC_i, [boxptr(r1)], 'int', descr=descrshort) assert r == 1333 - t = lltype.cast_opaque_ptr(lltype.Ptr(self.T), t_box.value) + t = lltype.cast_opaque_ptr(lltype.Ptr(self.T), t_box.getref_base()) assert s.parent.parent.typeptr == t.parent.parent.typeptr def test_new_array(self): @@ -1916,7 +1923,7 @@ ops = ''' [i0] i1 = same_as_i(1) - call_n(ConstClass(fptr), i0, descr=calldescr) + call_v(ConstClass(fptr), i0, descr=calldescr) p0 = guard_exception(ConstClass(xtp), descr=faildescr2) [i1] finish(0, p0, descr=faildescr1) [] ''' @@ -1937,7 +1944,8 @@ exc_ptr = xptr faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) - loop = parse(ops, self.cpu, namespace=locals()) + loop = parse(ops, self.cpu, namespace=locals(), + guards_with_failargs=True) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) @@ -3222,7 +3230,7 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(self.cpu, f) - res = self.execute_operation(rop.CALL, [funcbox, BoxFloat(value)], + res = self.execute_operation(rop.CALL, [funcbox, boxfloat(value)], 'float', descr=calldescr) assert res.getfloatstorage() == expected diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py --- a/pypy/jit/codewriter/jtransform.py +++ b/pypy/jit/codewriter/jtransform.py @@ -1492,7 +1492,7 @@ v = Variable('new_length') v.concretetype = lltype.Signed ops.append(SpaceOperation('int_force_ge_zero', [v_length], v)) - ops.append(SpaceOperation('new_array', [arraydescr, v], op.result)) + ops.append(SpaceOperation('new_array', [v, arraydescr], op.result)) return ops def do_fixed_list_len(self, op, args, arraydescr): diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -1119,8 +1119,8 @@ return cpu.bh_call_v(jitcode.get_fnaddr_as_int(), args_i, args_r, args_f, jitcode.calldescr) - @arguments("cpu", "d", "i", returns="r") - def bhimpl_new_array(cpu, arraydescr, length): + @arguments("cpu", "i", "d", returns="r") + def bhimpl_new_array(cpu, length, arraydescr): return cpu.bh_new_array(length, arraydescr) @arguments("cpu", "r", "i", "d", returns="i") diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py --- a/pypy/jit/metainterp/executor.py +++ b/pypy/jit/metainterp/executor.py @@ -80,19 +80,19 @@ do_call_i = new_do_call(rop.CALL_i, 'i') do_call_f = new_do_call(rop.CALL_f, 'f') do_call_r = new_do_call(rop.CALL_r, 'r') -do_call_n = new_do_call(rop.CALL_N, 'N') +do_call_v = new_do_call(rop.CALL_v, 'v') do_call_loopinvariant_i = new_do_call(rop.CALL_LOOPINVARIANT_i, 'i') do_call_loopinvariant_f = new_do_call(rop.CALL_LOOPINVARIANT_f, 'f') do_call_loopinvariant_r = new_do_call(rop.CALL_LOOPINVARIANT_r, 'r') -do_call_loopinvariant_n = new_do_call(rop.CALL_LOOPINVARIANT_N, 'N') +do_call_loopinvariant_v = new_do_call(rop.CALL_LOOPINVARIANT_v, 'v') do_call_may_force_i = new_do_call(rop.CALL_MAY_FORCE_i, 'i') do_call_may_force_f = new_do_call(rop.CALL_MAY_FORCE_f, 'f') do_call_may_force_r = new_do_call(rop.CALL_MAY_FORCE_r, 'r') -do_call_may_force_n = new_do_call(rop.CALL_MAY_FORCE_N, 'N') +do_call_may_force_v = new_do_call(rop.CALL_MAY_FORCE_v, 'v') do_call_pure_i = new_do_call(rop.CALL_PURE_i, 'i') do_call_pure_f = new_do_call(rop.CALL_PURE_f, 'f') do_call_pure_r = new_do_call(rop.CALL_PURE_r, 'r') -do_call_pure_n = new_do_call(rop.CALL_PURE_N, 'N') +do_call_pure_v = new_do_call(rop.CALL_PURE_v, 'v') def do_setarrayitem_gc(cpu, _, arraybox, indexbox, itembox, arraydescr): array = arraybox.getref_base() @@ -323,40 +323,25 @@ rop.CALL_ASSEMBLER_i, rop.CALL_ASSEMBLER_r, rop.CALL_ASSEMBLER_f, - rop.CALL_ASSEMBLER_N, + rop.CALL_ASSEMBLER_v, rop.COND_CALL_GC_WB, rop.COND_CALL_GC_WB_ARRAY, rop.DEBUG_MERGE_POINT, rop.JIT_DEBUG, rop.SETARRAYITEM_RAW, rop.GETINTERIORFIELD_RAW_i, - rop.GETINTERIORFIELD_RAW_r, rop.GETINTERIORFIELD_RAW_f, - rop.GETINTERIORFIELD_RAW_N, rop.SETINTERIORFIELD_RAW, rop.CALL_RELEASE_GIL_i, rop.CALL_RELEASE_GIL_r, rop.CALL_RELEASE_GIL_f, - rop.CALL_RELEASE_GIL_N, + rop.CALL_RELEASE_GIL_v, rop.QUASIIMMUT_FIELD, rop.CALL_MALLOC_GC, rop.CALL_MALLOC_NURSERY, rop.LABEL, - rop.GETARRAYITEM_RAW_PURE_N, - rop.GETFIELD_RAW_r, - rop.GETARRAYITEM_RAW_PURE_r, - rop.SAME_AS_N, - rop.GETINTERIORFIELD_GC_N, - rop.GETFIELD_RAW_N, - rop.GETFIELD_RAW_PURE_N, - rop.GETFIELD_RAW_PURE_r, - rop.GETARRAYITEM_RAW_N, - rop.GETFIELD_GC_PURE_N, - rop.GETARRAYITEM_GC_PURE_N, - rop.GETARRAYITEM_GC_N, - rop.GETFIELD_GC_N, - rop.GETARRAYITEM_RAW_r, - rop.RAW_LOAD_N, + rop.INPUT_i, rop.INPUT_r, rop.INPUT_f, + rop.FORCE_SPILL, rop.ESCAPE, ): # list of opcodes never executed by pyjitpl continue raise AssertionError("missing %r" % (orig_key,)) diff --git a/pypy/jit/metainterp/logger.py b/pypy/jit/metainterp/logger.py --- a/pypy/jit/metainterp/logger.py +++ b/pypy/jit/metainterp/logger.py @@ -2,7 +2,7 @@ from pypy.rlib.debug import debug_start, debug_stop, debug_print from pypy.rlib.objectmodel import we_are_translated from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.jit.metainterp.resoperation import rop, ConstInt, BoxInt, BoxFloat +from pypy.jit.metainterp.resoperation import rop, ConstInt from pypy.jit.metainterp.history import TargetToken class Logger(object): diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -13,8 +13,7 @@ from pypy.jit.metainterp import jitprof, resume, compile from pypy.jit.metainterp.executor import execute_nonspec -from pypy.jit.metainterp.resoperation import BoxInt, BoxFloat, REF, INT,\ - create_resop_1 +from pypy.jit.metainterp.resoperation import REF, INT, create_resop_1 from pypy.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded, \ ImmutableIntUnbounded, \ IntLowerBound, MININT, MAXINT diff --git a/pypy/jit/metainterp/optimizeopt/pure.py b/pypy/jit/metainterp/optimizeopt/pure.py --- a/pypy/jit/metainterp/optimizeopt/pure.py +++ b/pypy/jit/metainterp/optimizeopt/pure.py @@ -77,7 +77,7 @@ optimize_CALL_PURE_i = _new_optimize_call_pure(rop.CALL_i) optimize_CALL_PURE_f = _new_optimize_call_pure(rop.CALL_f) optimize_CALL_PURE_r = _new_optimize_call_pure(rop.CALL_r) - optimize_CALL_PURE_N = _new_optimize_call_pure(rop.CALL_N) + optimize_CALL_PURE_v = _new_optimize_call_pure(rop.CALL_v) def optimize_GUARD_NO_EXCEPTION(self, op): if self.last_emitted_operation is REMOVED: diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -349,7 +349,7 @@ optimize_CALL_LOOPINVARIANT_i = _new_optimize_call_loopinvariant(rop.CALL_i) optimize_CALL_LOOPINVARIANT_r = _new_optimize_call_loopinvariant(rop.CALL_r) optimize_CALL_LOOPINVARIANT_f = _new_optimize_call_loopinvariant(rop.CALL_f) - optimize_CALL_LOOPINVARIANT_N = _new_optimize_call_loopinvariant(rop.CALL_N) + optimize_CALL_LOOPINVARIANT_v = _new_optimize_call_loopinvariant(rop.CALL_v) def _optimize_nullness(self, op, box, expect_nonnull): value = self.getvalue(box) @@ -434,7 +434,7 @@ self.emit_operation(op) optimize_CALL_p = optimize_CALL_i optimize_CALL_f = optimize_CALL_i - optimize_CALL_N = optimize_CALL_i + optimize_CALL_v = optimize_CALL_i def _optimize_CALL_ARRAYCOPY(self, op): source_value = self.getvalue(op.getarg(1)) @@ -482,7 +482,7 @@ self.emit_operation(op) optimize_CALL_PURE_f = optimize_CALL_PURE_i optimize_CALL_PURE_p = optimize_CALL_PURE_i - optimize_CALL_PURE_N = optimize_CALL_PURE_i + optimize_CALL_PURE_v = optimize_CALL_PURE_i def optimize_GUARD_NO_EXCEPTION(self, op): if self.last_emitted_operation is REMOVED: diff --git a/pypy/jit/metainterp/optimizeopt/simplify.py b/pypy/jit/metainterp/optimizeopt/simplify.py --- a/pypy/jit/metainterp/optimizeopt/simplify.py +++ b/pypy/jit/metainterp/optimizeopt/simplify.py @@ -14,12 +14,12 @@ self.emit_operation(op.copy_and_change(getattr(rop, 'CALL_' + tp))) optimize_CALL_PURE_i = _new_optimize_call('i') optimize_CALL_PURE_f = _new_optimize_call('f') - optimize_CALL_PURE_N = _new_optimize_call('N') - optimize_CALL_PURE_p = _new_optimize_call('p') + optimize_CALL_PURE_v = _new_optimize_call('v') + optimize_CALL_PURE_r = _new_optimize_call('r') optimize_CALL_LOOPINVARIANT_i = _new_optimize_call('i') optimize_CALL_LOOPINVARIANT_f = _new_optimize_call('f') - optimize_CALL_LOOPINVARIANT_N = _new_optimize_call('N') - optimize_CALL_LOOPINVARIANT_p = _new_optimize_call('p') + optimize_CALL_LOOPINVARIANT_v = _new_optimize_call('v') + optimize_CALL_LOOPINVARIANT_r = _new_optimize_call('r') def optimize_VIRTUAL_REF_FINISH(self, op): pass diff --git a/pypy/jit/metainterp/optimizeopt/util.py b/pypy/jit/metainterp/optimizeopt/util.py --- a/pypy/jit/metainterp/optimizeopt/util.py +++ b/pypy/jit/metainterp/optimizeopt/util.py @@ -32,11 +32,7 @@ def make_dispatcher_method(Class, name_prefix, op_prefix=None, default=None): ops = _findall(Class, name_prefix, op_prefix) def dispatch(self, op, *args): -<<<<<<< local - if we_are_translated() or op.getopnum() < 0: -======= if we_are_translated(): ->>>>>>> other opnum = op.getopnum() for value, cls, func in ops: if opnum == value: @@ -45,20 +41,12 @@ if default: return default(self, op, *args) else: -<<<<<<< local name = resoperation.opname[op.getopnum()] func = getattr(Class, name_prefix + name, None) -======= - func = getattr(Class, name_prefix + op.getopname().upper(), None) ->>>>>>> other if func is not None: return func(self, op, *args) if default: return default(self, op, *args) -<<<<<<< local - -======= ->>>>>>> other dispatch.func_name = "dispatch_" + name_prefix return dispatch diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py --- a/pypy/jit/metainterp/optimizeopt/virtualize.py +++ b/pypy/jit/metainterp/optimizeopt/virtualize.py @@ -3,7 +3,7 @@ from pypy.jit.metainterp.optimizeopt import optimizer from pypy.jit.metainterp.optimizeopt.util import (make_dispatcher_method, descrlist_dict, sort_descrs) -from pypy.jit.metainterp.resoperation import rop, Const, ConstInt, BoxInt,\ +from pypy.jit.metainterp.resoperation import rop, Const, ConstInt,\ create_resop_2, create_resop_3, create_resop_1, create_resop_0 from pypy.rlib.objectmodel import we_are_translated from pypy.jit.metainterp.optimizeopt.optimizer import OptValue @@ -387,21 +387,13 @@ # Replace the VIRTUAL_REF operation with a virtual structure of type # 'jit_virtual_ref'. The jit_virtual_ref structure may be forced soon, # but the point is that doing so does not force the original structure. -<<<<<<< local new_op = create_resop_1(rop.NEW_WITH_VTABLE, llhelper.NULLREF, c_cls) self.replace(op, new_op) vrefvalue = self.make_virtual(c_cls, new_op) - token_op = create_resop_0(rop.FORCE_TOKEN, 0) + token_op = create_resop_0(rop.JIT_FRAME, 0) self.emit_operation(token_op) - vrefvalue.setfield(descr_virtual_token, self.getvalue(token_op)) -======= - op = ResOperation(rop.NEW_WITH_VTABLE, [c_cls], op.result) - vrefvalue = self.make_virtual(c_cls, op.result, op) - tokenbox = BoxPtr() - self.emit_operation(ResOperation(rop.JIT_FRAME, [], tokenbox)) - vrefvalue.setfield(descr_jit_frame, self.getvalue(tokenbox)) ->>>>>>> other + vrefvalue.setfield(descr_jit_frame, self.getvalue(token_op)) def optimize_VIRTUAL_REF_FINISH(self, op): # This operation is used in two cases. In normal cases, it @@ -426,17 +418,10 @@ seo(create_resop_2(rop.SETFIELD_GC, None, op.getarg(0), op.getarg(1), descr=vrefinfo.descr_forced)) -<<<<<<< local - # - set 'virtual_token' to TOKEN_NONE + # - set 'virtual_token' to TOKEN_NONE (== NULL) seo(create_resop_2(rop.SETFIELD_GC, None, op.getarg(0), ConstInt(vrefinfo.TOKEN_NONE), - descr = vrefinfo.descr_virtual_token)) -======= - # - set 'virtual_token' to TOKEN_NONE (== NULL) - args = [op.getarg(0), self.optimizer.cpu.ts.CONST_NULL] - seo(ResOperation(rop.SETFIELD_GC, args, None, - descr = vrefinfo.descr_jit_frame)) ->>>>>>> other + descr = vrefinfo.descr_jit_frame)) # Note that in some cases the virtual in op.getarg(1) has been forced # already. This is fine. In that case, and *if* a residual # CALL_MAY_FORCE suddenly turns out to access it, then it will diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py b/pypy/jit/metainterp/optimizeopt/virtualstate.py --- a/pypy/jit/metainterp/optimizeopt/virtualstate.py +++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py @@ -6,8 +6,7 @@ LEVEL_UNKNOWN from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntUnbounded -from pypy.jit.metainterp.resoperation import rop, Const, ConstInt, BoxInt,\ - BoxPtr +from pypy.jit.metainterp.resoperation import rop, Const, ConstInt from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import debug_start, debug_stop, debug_print diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -541,12 +541,12 @@ self.emit_operation(op) optimize_CALL_f = optimize_CALL_i optimize_CALL_r = optimize_CALL_i - optimize_CALL_N = optimize_CALL_i + optimize_CALL_v = optimize_CALL_i optimize_CALL_PURE_i = optimize_CALL_i optimize_CALL_PURE_f = optimize_CALL_i optimize_CALL_PURE_p = optimize_CALL_i - optimize_CALL_PURE_N = optimize_CALL_i + optimize_CALL_PURE_v = optimize_CALL_i def optimize_GUARD_NO_EXCEPTION(self, op): if self.last_emitted_operation is REMOVED: diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -11,7 +11,7 @@ ConstFloat from pypy.jit.metainterp.history import TargetToken from pypy.jit.metainterp.resoperation import rop, create_resop, create_resop_0,\ - create_resop_1, create_resop_2, Box + create_resop_1, create_resop_2 from pypy.jit.metainterp import resoperation from pypy.jit.metainterp import executor from pypy.jit.metainterp.logger import Logger @@ -1538,25 +1538,6 @@ self.callinfocollection = codewriter.callcontrol.callinfocollection self.has_libffi_call = codewriter.callcontrol.has_libffi_call # -<<<<<<< local - # store this information for fastpath of call_assembler - # (only the paths that can actually be taken) - for jd in self.jitdrivers_sd: - name = {resoperation.INT: 'int', - resoperation.REF: 'ref', - resoperation.FLOAT: 'float', - resoperation.VOID: 'void'}[jd.result_type] - tokens = getattr(self, 'loop_tokens_done_with_this_frame_%s' % name) - jd.portal_finishtoken = tokens[0].finishdescr - num = self.cpu.get_fail_descr_number(tokens[0].finishdescr) - setattr(self.cpu, 'done_with_this_frame_%s_v' % name, num) - # -======= ->>>>>>> other - exc_descr = compile.PropagateExceptionDescr() - num = self.cpu.get_fail_descr_number(exc_descr) - self.cpu.propagate_exception_v = num - # self.globaldata = MetaInterpGlobalData(self) def _setup_once(self): @@ -2248,19 +2229,6 @@ result_type = self.jitdriver_sd.result_type if result_type == resoperation.VOID: assert exitbox is None -<<<<<<< local - exits = [] - loop_tokens = sd.loop_tokens_done_with_this_frame_void - elif result_type == resoperation.INT: - exits = [exitbox] - loop_tokens = sd.loop_tokens_done_with_this_frame_int - elif result_type == resoperation.REF: - exits = [exitbox] - loop_tokens = sd.loop_tokens_done_with_this_frame_ref - elif result_type == resoperation.FLOAT: - exits = [exitbox] - loop_tokens = sd.loop_tokens_done_with_this_frame_float -======= self.compile_done([], compile.DoneWithThisFrameDescrVoid) elif result_type == history.INT: self.compile_done([exitbox], compile.DoneWithThisFrameDescrInt) @@ -2268,15 +2236,8 @@ self.compile_done([exitbox], compile.DoneWithThisFrameDescrRef) elif result_type == history.FLOAT: self.compile_done([exitbox], compile.DoneWithThisFrameDescrFloat) ->>>>>>> other else: assert False -<<<<<<< local - # FIXME: kill TerminatingLoopToken? - # FIXME: can we call compile_trace? - token = loop_tokens[0].finishdescr - self.history.record(create_resop(rop.FINISH, None, exits, descr=token)) -======= def compile_exit_frame_with_exception(self, valuebox): self.compile_done([valuebox], compile.ExitFrameWithExceptionDescrRef) @@ -2291,7 +2252,6 @@ token = DoneCls(self.staticdata, self.jitdriver_sd) resume.capture_resumedata([], virtualizable_boxes, [], token) self.history.record(rop.FINISH, exits, None, descr=token) ->>>>>>> other target_token = compile.compile_trace(self, self.resumekey) if target_token is None: compile.giveup() diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -72,8 +72,6 @@ assert _arg.type != VOID op._args = args if descr is not None: - assert isinstance(op, ResOpWithDescr) - assert not op.is_guard() op.setdescr(descr) return op @@ -88,8 +86,6 @@ else: op = cls(result) if descr is not None: - assert isinstance(op, ResOpWithDescr) - assert not op.is_guard() op.setdescr(descr) return op @@ -110,8 +106,6 @@ assert arg0.type != VOID op._arg0 = arg0 if descr is not None: - assert isinstance(op, ResOpWithDescr) - assert not op.is_guard() op.setdescr(descr) return op @@ -133,8 +127,6 @@ op._arg0 = arg0 op._arg1 = arg1 if descr is not None: - assert isinstance(op, ResOpWithDescr) - assert not op.is_guard() op.setdescr(descr) return op @@ -158,8 +150,6 @@ op._arg1 = arg1 op._arg2 = arg2 if descr is not None: - assert isinstance(op, ResOpWithDescr) - assert not op.is_guard() op.setdescr(descr) return op @@ -211,12 +201,6 @@ """ raise NotImplementedError - def nonconstbox(self): - """ Return a box value of the current constant wrapped in an - apropriate box class - """ - raise NotImplementedError - def getaddr(self): raise NotImplementedError @@ -351,9 +335,6 @@ assert isinstance(value, Symbolic) self.value = value - def nonconstbox(self): - return BoxInt(self.value) - def getint(self): return self.value @@ -392,9 +373,6 @@ assert lltype.typeOf(valuestorage) is longlong.FLOATSTORAGE self.value = valuestorage - def nonconstbox(self): - return BoxFloat(self.value) - def getfloatstorage(self): return self.value @@ -430,9 +408,6 @@ assert lltype.typeOf(value) == llmemory.GCREF self.value = value - def nonconstbox(self): - return BoxPtr(self.value) - def getref_base(self): return self.value @@ -496,9 +471,10 @@ return cls.opnum def __hash__(self): + # XXX this is a hack kill me import sys co_fname = sys._getframe(1).f_code.co_filename - if co_fname.endswith('resume.py') or co_fname.endswith('optimizeopt/util.py') or 'backend/llgraph' in co_fname: + if co_fname.endswith('resume.py') or co_fname.endswith('optimizeopt/util.py') or 'backend/llgraph' in co_fname or 'backend/test' in co_fname: return object.__hash__(self) raise Exception("Should not hash resops, use get/set extra instead") @@ -702,7 +678,11 @@ type = INT def __init__(self, intval): - assert isinstance(intval, int) + if not we_are_translated(): + if is_valid_int(intval): + intval = int(intval) + else: + assert isinstance(intval, Symbolic) self.intval = intval def getint(self): @@ -1136,30 +1116,42 @@ # ____________________________________________________________ _oplist = [ + # key: + # _ means just a marker + # OPNAME/[d]/T + # where: + # "*" in parameter list means any number + # "d" means if there is a descr associated with a resop + # T can be one of "r", "i", "f", "v", "*" or "?" + # "r", "i", "f" - normal return, appropriate type + # "v" - void return type + # "*" - four variants will be generated, "r", "i", "f", "v" + # "?" - three variants will be generated, "r", "i", "f" + '_FINAL_FIRST', - 'JUMP/*d/N', - 'FINISH/*d/N', + 'JUMP/*d/v', + 'FINISH/*d/v', '_FINAL_LAST', - 'LABEL/*d/N', - 'INPUT/0/*', + 'LABEL/*d/v', + 'INPUT/0/?', '_GUARD_FIRST', '_GUARD_FOLDABLE_FIRST', - 'GUARD_TRUE/1/N', - 'GUARD_FALSE/1/N', - 'GUARD_VALUE/2/N', - 'GUARD_CLASS/2/N', - 'GUARD_NONNULL/1/N', - 'GUARD_ISNULL/1/N', - 'GUARD_NONNULL_CLASS/2/N', + 'GUARD_TRUE/1/v', + 'GUARD_FALSE/1/v', + 'GUARD_VALUE/2/v', + 'GUARD_CLASS/2/v', + 'GUARD_NONNULL/1/v', + 'GUARD_ISNULL/1/v', + 'GUARD_NONNULL_CLASS/2/v', '_GUARD_FOLDABLE_LAST', - 'GUARD_NO_EXCEPTION/0/N', # may be called with an exception currently set + 'GUARD_NO_EXCEPTION/0/v', # may be called with an exception currently set 'GUARD_EXCEPTION/1/r', # may be called with an exception currently set - 'GUARD_NO_OVERFLOW/0/N', - 'GUARD_OVERFLOW/0/N', - 'GUARD_NOT_FORCED/0/N', # may be called with an exception currently set - 'GUARD_NOT_INVALIDATED/0/N', + 'GUARD_NO_OVERFLOW/0/v', + 'GUARD_OVERFLOW/0/v', + 'GUARD_NOT_FORCED/0/v', # may be called with an exception currently set + 'GUARD_NOT_INVALIDATED/0/v', '_GUARD_LAST', # ----- end of guard operations ----- '_NOSIDEEFFECT_FIRST', # ----- start of no_side_effect operations ----- @@ -1212,7 +1204,7 @@ 'INT_INVERT/1/i', 'INT_FORCE_GE_ZERO/1/i', # - 'SAME_AS/1/*', # gets a Const or a Box, turns it into another Box + 'SAME_AS/1/?', # gets a Const or a Box, turns it into another Box '_ALWAYS_PURE_NO_PTR_LAST', 'CAST_PTR_TO_INT/1/i', 'CAST_INT_TO_PTR/1/r', @@ -1225,10 +1217,11 @@ 'ARRAYLEN_GC/1d/i', 'STRLEN/1/i', 'STRGETITEM/2/i', - 'GETFIELD_GC_PURE/1d/*', - 'GETFIELD_RAW_PURE/1d/*', - 'GETARRAYITEM_GC_PURE/2d/*', - 'GETARRAYITEM_RAW_PURE/2d/*', + 'GETFIELD_GC_PURE/1d/?', + 'GETFIELD_RAW_PURE/1d/?', + 'GETARRAYITEM_GC_PURE/2d/?', + 'GETARRAYITEM_RAW_PURE_i/2d/i', + 'GETARRAYITEM_RAW_PURE_f/2d/f', 'UNICODELEN/1/i', 'UNICODEGETITEM/2/i', # @@ -1238,13 +1231,17 @@ # '_ALWAYS_PURE_LAST', # ----- end of always_pure operations ----- - 'GETARRAYITEM_GC/2d/*', - 'GETARRAYITEM_RAW/2d/*', - 'GETINTERIORFIELD_GC/2d/*', - 'GETINTERIORFIELD_RAW/2d/*', - 'RAW_LOAD/2d/*', - 'GETFIELD_GC/1d/*', - 'GETFIELD_RAW/1d/*', + 'GETARRAYITEM_GC/2d/?', + 'GETARRAYITEM_RAW_i/2d/i', + 'GETARRAYITEM_RAW_f/2d/f', + 'GETINTERIORFIELD_GC/2d/?', + 'GETINTERIORFIELD_RAW_i/2d/i', + 'GETINTERIORFIELD_RAW_f/2d/f', + 'RAW_LOAD_i/2d/i', + 'RAW_LOAD_f/2d/f', + 'GETFIELD_GC/1d/?', + 'GETFIELD_RAW_i/1d/i', + 'GETFIELD_RAW_f/1d/f', '_MALLOC_FIRST', 'NEW/0d/r', 'NEW_WITH_VTABLE/1/r', @@ -1255,28 +1252,31 @@ 'JIT_FRAME/0/r', 'VIRTUAL_REF/2/i', # removed before it's passed to the backend 'READ_TIMESTAMP/0/L', # float on 32bit, int on 64bit - 'MARK_OPAQUE_PTR/1b/N', + 'MARK_OPAQUE_PTR/1b/v', '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- - 'SETARRAYITEM_GC/3d/N', - 'SETARRAYITEM_RAW/3d/N', - 'SETINTERIORFIELD_GC/3d/N', - 'SETINTERIORFIELD_RAW/3d/N', # only used by llsupport/rewrite.py - 'RAW_STORE/3d/N', - 'SETFIELD_GC/2d/N', - 'SETFIELD_RAW/2d/N', - 'STRSETITEM/3/N', - 'UNICODESETITEM/3/N', + 'ESCAPE/1/v', # tests + 'FORCE_SPILL/1/v', # tests + + 'SETARRAYITEM_GC/3d/v', + 'SETARRAYITEM_RAW/3d/v', + 'SETINTERIORFIELD_GC/3d/v', + 'SETINTERIORFIELD_RAW/3d/v', # only used by llsupport/rewrite.py + 'RAW_STORE/3d/v', + 'SETFIELD_GC/2d/v', + 'SETFIELD_RAW/2d/v', + 'STRSETITEM/3/v', + 'UNICODESETITEM/3/v', #'RUNTIMENEW/1', # ootype operation - 'COND_CALL_GC_WB/2d/N', # [objptr, newvalue] (for the write barrier) - 'COND_CALL_GC_WB_ARRAY/3d/N', # [objptr, arrayindex, newvalue] (write barr.) - 'DEBUG_MERGE_POINT/*/N', # debugging only - 'JIT_DEBUG/*/N', # debugging only - 'VIRTUAL_REF_FINISH/2/N', # removed before it's passed to the backend - 'COPYSTRCONTENT/5/N', # src, dst, srcstart, dststart, length - 'COPYUNICODECONTENT/5/N', - 'QUASIIMMUT_FIELD/1d/N', # [objptr], descr=SlowMutateDescr - 'RECORD_KNOWN_CLASS/2/N', # [objptr, clsptr] + 'COND_CALL_GC_WB/2d/v', # [objptr, newvalue] (for the write barrier) + 'COND_CALL_GC_WB_ARRAY/3d/v', # [objptr, arrayindex, newvalue] (write barr.) + 'DEBUG_MERGE_POINT/*/v', # debugging only + 'JIT_DEBUG/*/v', # debugging only + 'VIRTUAL_REF_FINISH/2/v', # removed before it's passed to the backend + 'COPYSTRCONTENT/5/v', # src, dst, srcstart, dststart, length + 'COPYUNICODECONTENT/5/v', + 'QUASIIMMUT_FIELD/1d/v', # [objptr], descr=SlowMutateDescr + 'RECORD_KNOWN_CLASS/2/v', # [objptr, clsptr] '_CANRAISE_FIRST', # ----- start of can_raise operations ----- '_CALL_FIRST', @@ -1336,7 +1336,7 @@ else: arity = int(arity) else: - arity, withdescr, boolresult, tp = -1, True, False, "N" # default + arity, withdescr, boolresult, tp = -1, True, False, "v" # default if not basename.startswith('_'): clss = create_classes_for_op(basename, i, arity, withdescr, tp) else: @@ -1386,7 +1386,7 @@ 3: TernaryOp } tpmixin = { - 'N': ResOpNone, + 'v': ResOpNone, 'i': ResOpInt, 'f': ResOpFloat, 'r': ResOpPointer, @@ -1401,15 +1401,19 @@ baseclass = PlainResOp mixin = arity2mixin.get(arity, N_aryOp) - if tp == '*': + if tp in '*?': res = [] - for tp in ['f', 'r', 'i', 'N']: + if tp == '*': + lst = ['i', 'r', 'f', 'v'] + else: + lst = ['i', 'r', 'f'] + for tp in lst: cls_name = '%s_OP_%s' % (name, tp) bases = (get_base_class(mixin, tpmixin[tp], baseclass),) dic = {'opnum': opnum} res.append((type(cls_name, bases, dic), name + '_' + tp, tp)) opnum += 1 - return res + return res else: if tp == 'L': if longlong.is_64_bit: diff --git a/pypy/jit/metainterp/test/test_executor.py b/pypy/jit/metainterp/test/test_executor.py --- a/pypy/jit/metainterp/test/test_executor.py +++ b/pypy/jit/metainterp/test/test_executor.py @@ -7,7 +7,7 @@ from pypy.jit.metainterp.resoperation import rop, opboolinvers, opboolreflex, opname from pypy.jit.metainterp.history import AbstractDescr from pypy.jit.metainterp.resoperation import ConstInt, ConstPtr, ConstFloat,\ - BoxInt, BoxPtr, BoxFloat + create_resop_0, example_for_opnum from pypy.jit.metainterp import history from pypy.jit.codewriter import longlong from pypy.jit.backend.model import AbstractCPU @@ -69,27 +69,34 @@ return 13 def boxfloat(x): - return BoxFloat(longlong.getfloatstorage(x)) + return create_resop_0(rop.INPUT_f, longlong.getfloatstorage(x)) def constfloat(x): return ConstFloat(longlong.getfloatstorage(x)) +def boxint(x): + return create_resop_0(rop.INPUT_i, x) + +def boxptr(x=None): + if x is None: + x = example_for_opnum(rop.INPUT_r) + return create_resop_0(rop.INPUT_r, x) def test_execute(): cpu = FakeCPU() descr = FakeDescr() - resop = execute(cpu, None, rop.INT_ADD, None, BoxInt(40), ConstInt(2)) + resop = execute(cpu, None, rop.INT_ADD, None, boxint(40), ConstInt(2)) assert resop.intval == 42 resop = execute(cpu, None, rop.NEW, descr) assert resop.pval.fakeargs == ('new', descr) - execute(cpu, None, rop.JIT_DEBUG, None, BoxInt(1), BoxInt(2), BoxInt(3), - BoxInt(4)) + execute(cpu, None, rop.JIT_DEBUG, None, boxint(1), boxint(2), boxint(3), + boxint(4)) def test_execute_varargs(): cpu = FakeCPU() descr = FakeCallDescr() - argboxes = [BoxInt(99999), BoxInt(321), constfloat(2.25), ConstInt(123), - BoxPtr(), boxfloat(5.5)] + argboxes = [boxint(99999), boxint(321), constfloat(2.25), ConstInt(123), + boxptr(), boxfloat(5.5)] box = execute_varargs(cpu, FakeMetaInterp(), rop.CALL_f, argboxes, descr) assert box.getfloat() == 42.5 assert cpu.fakecalled == (99999, descr, [321, 123], @@ -102,7 +109,7 @@ descr = FakeDescr() # cases with a descr # arity == -1 - argboxes = [BoxInt(321), ConstInt(123)] + argboxes = [boxint(321), ConstInt(123)] box = execute_nonspec(cpu, FakeMetaInterp(), rop.CALL_f, argboxes, FakeCallDescr()) assert box.getfloat() == 42.5 @@ -110,7 +117,7 @@ box = execute_nonspec(cpu, None, rop.NEW, [], descr) assert box.pval.fakeargs == ('new', descr) # arity == 1 - box1 = BoxPtr() + box1 = boxptr() box = execute_nonspec(cpu, None, rop.ARRAYLEN_GC, [box1], descr) assert box.intval == 55 # arity == 2 @@ -119,7 +126,7 @@ execute_nonspec(cpu, None, rop.SETFIELD_GC, [box1, box2], fielddescr) assert cpu.fakesetfield == (box1.value, box2.value, fielddescr) # arity == 3 - box3 = BoxInt(33) + box3 = boxint(33) arraydescr = FakeArrayDescr() execute_nonspec(cpu, None, rop.SETARRAYITEM_GC, [box1, box3, box2], arraydescr) @@ -130,16 +137,16 @@ box = execute_nonspec(cpu, None, rop.INT_INVERT, [box3]) assert box.intval == ~33 # arity == 2 - box = execute_nonspec(cpu, None, rop.INT_LSHIFT, [box3, BoxInt(3)]) + box = execute_nonspec(cpu, None, rop.INT_LSHIFT, [box3, boxint(3)]) assert box.intval == 33 << 3 # arity == 3 - execute_nonspec(cpu, None, rop.STRSETITEM, [box1, BoxInt(3), box3]) + execute_nonspec(cpu, None, rop.STRSETITEM, [box1, boxint(3), box3]) assert cpu.fakestrsetitem == (box1.value, 3, box3.value) def test_getarrayitems(): cpu = FakeCPU() resop = execute_nonspec(cpu, None, rop.GETARRAYITEM_GC_i, - [BoxPtr(), BoxInt(12)], FakeArrayDescr()) + [boxptr(), boxint(12)], FakeArrayDescr()) assert resop.intval == 13 # ints @@ -197,7 +204,6 @@ yield opnum, [x, y], z def _int_comparison_operations(): - cpu = FakeCPU() random_numbers = [-sys.maxint-1, -1, 0, 1, sys.maxint] def pick(): r = random.randrange(-99999, 100000) @@ -205,7 +211,6 @@ return r else: return random_numbers[r % len(random_numbers)] - minint = -sys.maxint-1 for opnum, operation in [ (rop.INT_LT, lambda x, y: x < y), (rop.INT_LE, lambda x, y: x <= y), @@ -243,13 +248,13 @@ list(_int_binary_operations()) + list(_int_comparison_operations()) + list(_int_unary_operations())): - yield opnum, [BoxInt(x) for x in args], retvalue + yield opnum, [boxint(x) for x in args], retvalue if len(args) > 1: assert len(args) == 2 - yield opnum, [BoxInt(args[0]), ConstInt(args[1])], retvalue - yield opnum, [ConstInt(args[0]), BoxInt(args[1])], retvalue + yield opnum, [boxint(args[0]), ConstInt(args[1])], retvalue + yield opnum, [ConstInt(args[0]), boxint(args[1])], retvalue if args[0] == args[1]: - commonbox = BoxInt(args[0]) + commonbox = boxint(args[0]) yield opnum, [commonbox, commonbox], retvalue @@ -311,7 +316,7 @@ if isinstance(x, float): boxargs.append(boxfloat(x)) else: - boxargs.append(BoxInt(x)) + boxargs.append(boxint(x)) yield opnum, boxargs, rettype, retvalue if len(args) > 1: assert len(args) == 2 diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -14,59 +14,6 @@ class ParseError(Exception): pass -class ESCAPE_OP(N_aryOp, ResOpNone, ResOpWithDescr): - - OPNUM = -123 - - def __init__(self, opnum, args, result, descr=None): - assert opnum == self.OPNUM - self.result = result - self._args = args - self.setdescr(descr) - - @classmethod - def getopnum(cls): - return cls.OPNUM - - def copy_if_modified_by_optimization(self, opt): - newargs = None - for i, arg in enumerate(self._args): - new_arg = opt.get_value_replacement(arg) - if new_arg is not None: - if newargs is None: - newargs = [] - for k in range(i): - newargs.append(self._args[k]) - self._args[:i] - newargs.append(new_arg) - elif newargs is not None: - newargs.append(arg) - if newargs is None: - return self - return ESCAPE_OP(self.OPNUM, newargs, self.getresult(), - self.getdescr()) - -class FORCE_SPILL(UnaryOp, ResOpNone, PlainResOp): - - OPNUM = -124 - - def __init__(self, opnum, args, result=None, descr=None): - assert result is None - assert descr is None - assert opnum == self.OPNUM - self.result = result - self.initarglist(args) - - def getopnum(self): - return self.OPNUM - - def clone(self): - return FORCE_SPILL(self.OPNUM, self.getarglist()[:]) - - def copy_and_change(self, opnum, args, result, descr): - return FORCE_SPILL(opnum, args, result, descr) - - class OpParser(object): use_mock_model = False @@ -231,12 +178,7 @@ try: opnum = getattr(rop_lowercase, opname) except AttributeError: - if opname == 'escape': - opnum = ESCAPE_OP.OPNUM - elif opname == 'force_spill': - opnum = FORCE_SPILL.OPNUM - else: - raise ParseError("unknown op: %s" % opname) + raise ParseError("unknown op: %s" % opname) endnum = line.rfind(')') if endnum == -1: raise ParseError("invalid line: %s" % line) @@ -276,16 +218,11 @@ return opnum, args, descr, fail_args def create_op(self, opnum, result, args, descr): - if opnum == ESCAPE_OP.OPNUM: - return ESCAPE_OP(opnum, args, result, descr) - if opnum == FORCE_SPILL.OPNUM: - return FORCE_SPILL(opnum, args, result, descr) - else: - r = create_resop_dispatch(opnum, result, args, - mutable=self.guards_with_failargs) - if descr is not None: - r.setdescr(descr) - return r + r = create_resop_dispatch(opnum, result, args, + mutable=self.guards_with_failargs) + if descr is not None: + r.setdescr(descr) + return r def parse_result_op(self, line, num): res, op = line.split("=", 1) diff --git a/pypy/jit/tool/test/test_oparser.py b/pypy/jit/tool/test/test_oparser.py --- a/pypy/jit/tool/test/test_oparser.py +++ b/pypy/jit/tool/test/test_oparser.py @@ -24,7 +24,7 @@ # a comment i2 = int_add(i0, i1) i3 = int_sub(i2, 3) # another comment - finish() [] # (tricky) + finish() # (tricky) """ loop = self.parse(x) assert len(loop.operations) == 3 @@ -40,7 +40,7 @@ [p0] finish(descr=f) [p0] """ - loop = self.parse(x, None, {'f': d}) + loop = self.parse(x, None, {'f': d}, guards_with_failargs=True) assert loop.operations[0].getdescr() is d assert loop.operations[0].getfailargs() == loop.inputargs @@ -90,7 +90,7 @@ def test_getvar_const_ptr(self): x = ''' [] - call_n(ConstPtr(func_ptr)) + call_v(ConstPtr(func_ptr)) ''' TP = lltype.GcArray(lltype.Signed) NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP)) @@ -163,7 +163,7 @@ def test_attach_comment_to_loop(self): loop = self.parse(self.example_loop_log, guards_with_failargs=True) assert loop.comment == ' # bridge out of Guard12, 6 ops' - assert loop.operations[-3].get_failargs() + assert loop.operations[-3].getfailargs() def test_parse_new_with_comma(self): # this is generated by PYPYJITLOG, check that we can handle it From noreply at buildbot.pypy.org Mon Oct 22 18:33:09 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 22 Oct 2012 18:33:09 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: (fijal, arigo) fix fix fix fix done in this file Message-ID: <20121022163309.04CF51C0236@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: result-in-resops Changeset: r58366:d5826f6730c1 Date: 2012-10-22 18:32 +0200 http://bitbucket.org/pypy/pypy/changeset/d5826f6730c1/ Log: (fijal, arigo) fix fix fix fix done in this file diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -864,7 +864,7 @@ call_op = self.lltrace.operations[self.current_index] guard_op = self.lltrace.operations[self.current_index + 1] assert guard_op.getopnum() == rop.GUARD_NOT_FORCED - self.latest_values = self._getfailargs(guard_op, skip=call_op.result) + self.latest_values = self._getfailargs(guard_op, skip=call_op) self.latest_descr = _getdescr(guard_op) res = self.execute_call(calldescr, func, *args) del self.latest_descr @@ -881,12 +881,16 @@ func_to_call = rffi.cast(lltype.Ptr(FUNC), func) result = func_to_call(*call_args) return support.cast_result(descr.RESULT, result) + execute_call_release_gil_i = execute_call_release_gil + execute_call_release_gil_r = execute_call_release_gil + execute_call_release_gil_f = execute_call_release_gil + execute_call_release_gil_v = execute_call_release_gil def execute_call_assembler(self, descr, *args): call_op = self.lltrace.operations[self.current_index] guard_op = self.lltrace.operations[self.current_index + 1] assert guard_op.getopnum() == rop.GUARD_NOT_FORCED - self.latest_values = self._getfailargs(guard_op, skip=call_op.result) + self.latest_values = self._getfailargs(guard_op, skip=call_op) self.latest_descr = _getdescr(guard_op) # frame = self.cpu._execute_token(descr, *args) @@ -907,11 +911,16 @@ del self.latest_descr del self.latest_values return support.cast_result(lltype.typeOf(result), result) + execute_call_assembler_i = execute_call_assembler + execute_call_assembler_r = execute_call_assembler + execute_call_assembler_f = execute_call_assembler + execute_call_assembler_v = execute_call_assembler - def execute_same_as_i(self, _, x): + def execute_same_as(self, _, x): return x - execute_same_as_f = execute_same_as_i - execute_same_as_r = execute_same_as_i + execute_same_as_i = execute_same_as + execute_same_as_r = execute_same_as + execute_same_as_f = execute_same_as def execute_debug_merge_point(self, descr, *args): from pypy.jit.metainterp.warmspot import get_stats diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -15,7 +15,7 @@ from pypy.rlib import longlong2float from pypy.rlib.rarithmetic import intmask, is_valid_int from pypy.jit.backend.detect_cpu import autodetect_main_model_and_size -from pypy.jit.tool.oparser import parse +from pypy.jit.tool import oparser def boxfloat(x=None): @@ -23,6 +23,9 @@ x = example_for_opnum(rop.INPUT_f) return create_resop_0(rop.INPUT_f, longlong.getfloatstorage(x)) +def boxlonglong_on_32bit(x): + return create_resop_0(rop.INPUT_f, x) + def boxint(x=0): return create_resop_0(rop.INPUT_i, x) @@ -72,6 +75,10 @@ elif result_type == 'ref': return self.cpu.get_finish_value_ref(frame) elif result_type == 'float': + x = self.cpu.get_finish_value_float(frame) + return longlong.getrealfloat(x) + elif result_type == 'longlong': + assert longlong.supports_longlong return self.cpu.get_finish_value_float(frame) elif result_type == 'void': return None @@ -86,7 +93,7 @@ result = 0 elif result_type == 'ref': result = lltype.nullptr(llmemory.GCREF.TO) - elif result_type == 'float': + elif result_type == 'float' or result_type == 'longlong': result = 0.0 else: raise ValueError(result_type) @@ -128,7 +135,7 @@ namespace['faildescr3'] = BasicFailDescr(3) if 'faildescr4' not in namespace: namespace['faildescr4'] = BasicFailDescr(4) - loop = parse(s, namespace=namespace, guards_with_failargs=True) + loop = oparser.parse(s, namespace=namespace, guards_with_failargs=True) return loop.inputargs, loop.operations, JitCellToken() def test_compile_linear_loop(self): @@ -1316,15 +1323,14 @@ force_spill(f2) guard_false(i0, descr=faildescr0) [f1, f2, f3] finish() []""" - loop = parse(loopops, guards_with_failargs=True, - namespace={'faildescr0': BasicFailDescr(1)}) - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + inputargs, operations, looptoken = self.parse( + loopops, namespace={'faildescr0': BasicFailDescr(1)}) + self.cpu.compile_loop(inputargs, operations, looptoken) args = [1] args.append(longlong.getfloatstorage(132.25)) args.append(longlong.getfloatstorage(0.75)) frame = self.cpu.execute_token(looptoken, *args) #xxx check - assert loop.operations[-2].getdescr()== self.cpu.get_latest_descr(frame) + assert operations[-2].getdescr()== self.cpu.get_latest_descr(frame) f1 = self.cpu.get_latest_value_float(frame, 0) f2 = self.cpu.get_latest_value_float(frame, 1) f3 = self.cpu.get_latest_value_float(frame, 2) @@ -1337,8 +1343,8 @@ mutable=True), ] bridgeops[-1].setfailargs(fboxes) - self.cpu.compile_bridge(loop.operations[-2].getdescr(), fboxes, - bridgeops, looptoken) + self.cpu.compile_bridge(operations[-2].getdescr(), fboxes, + bridgeops, looptoken) args = [1, longlong.getfloatstorage(132.25), longlong.getfloatstorage(0.75)] @@ -1713,15 +1719,12 @@ def wait_a_bit(): pass if longlong.is_64_bit: - res1 = self.execute_operation(rop.READ_TIMESTAMP, [], 'int') - wait_a_bit() - res2 = self.execute_operation(rop.READ_TIMESTAMP, [], 'int') + restype = 'int' else: - got1 = self.execute_operation(rop.READ_TIMESTAMP, [], 'float') - wait_a_bit() - got2 = self.execute_operation(rop.READ_TIMESTAMP, [], 'float') - res1 = got1.getlonglong() - res2 = got2.getlonglong() + restype = 'float' + res1 = self.execute_operation(rop.READ_TIMESTAMP, [], restype) + wait_a_bit() + res2 = self.execute_operation(rop.READ_TIMESTAMP, [], restype) assert res1 < res2 < res1 + 2**32 @@ -1823,11 +1826,11 @@ t = 'int' if longlong.is_64_bit else 'float' res = self.execute_operation(rop.CONVERT_FLOAT_BYTES_TO_LONGLONG, [box], t) - assert res == longlong2float.float2longlong(2.5) + assert res == 2.5 res = self.execute_operation(rop.CONVERT_LONGLONG_BYTES_TO_FLOAT, [boxlonglong(res)], 'float') - assert longlong.getrealfloat(res) == 2.5 + assert res == 2.5 def test_ooops_non_gc(self): x = lltype.malloc(lltype.Struct('x'), flavor='raw') @@ -1925,7 +1928,7 @@ i1 = same_as_i(1) call_v(ConstClass(fptr), i0, descr=calldescr) p0 = guard_exception(ConstClass(xtp), descr=faildescr2) [i1] - finish(0, p0, descr=faildescr1) [] + finish(p0, descr=faildescr1) [] ''' FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) fptr = llhelper(FPTR, func) @@ -1944,10 +1947,8 @@ exc_ptr = xptr faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) - loop = parse(ops, self.cpu, namespace=locals(), - guards_with_failargs=True) - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + inputargs, operations, looptoken = self.parse(ops, namespace=locals()) + self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_finish_value_ref(frame) == xptr frame = self.cpu.execute_token(looptoken, 0) @@ -1966,9 +1967,8 @@ # guard_exception uses an exact match exc_tp = ytp exc_ptr = yptr - loop = parse(ops, self.cpu, namespace=locals()) - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + inputargs, operations, looptoken = self.parse(ops, namespace=locals()) + self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_latest_value_int(frame, 0) == 1 excvalue = self.cpu.grab_exc_value(frame) @@ -1979,13 +1979,12 @@ ops = ''' [i0] i1 = same_as_i(1) - call_n(ConstClass(fptr), i0, descr=calldescr) + call_v(ConstClass(fptr), i0, descr=calldescr) guard_no_exception(descr=faildescr1) [i1] finish(-100, descr=faildescr2) [] ''' - loop = parse(ops, self.cpu, namespace=locals()) - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + inputargs, operations, looptoken = self.parse(ops, namespace=locals()) + self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_latest_value_int(frame, 0) == 1 excvalue = self.cpu.grab_exc_value(frame) @@ -2166,8 +2165,8 @@ faildescr0 = BasicFailDescr(0) inputargs, operations, looptoken = self.parse(""" [i0, i1] - itok = force_token() - call_may_force_n(ConstClass(func_ptr), itok, i1, descr=calldescr) + ptok = jit_frame() + call_may_force_v(ConstClass(func_ptr), ptok, i1, descr=calldescr) guard_not_forced(descr=faildescr) [i1, i0] finish(i0, descr=faildescr0) """, locals()) @@ -2202,8 +2201,8 @@ faildescr0 = BasicFailDescr(0) inputargs, ops, looptoken = self.parse(""" [i0, i1] - itok = force_token() - i2 = call_may_force_i(ConstClass(func_ptr), itok, i1) + ptok = jit_frame() + i2 = call_may_force_i(ConstClass(func_ptr), ptok, i1, descr=calldescr) guard_not_forced(descr=faildescr) [i1, i2, i0] finish(i2, descr=faildescr0) """, locals()) @@ -2241,8 +2240,8 @@ faildescr0 = BasicFailDescr(0) inputargs, ops, looptoken = self.parse(""" [i0, i1] - itok = force_token() - f0 = call_may_force_f(ConstClass(func_ptr), itok, i1, descr=calldescr) + ptok = jit_frame() + f0 = call_may_force_f(ConstClass(func_ptr), ptok, i1, descr=calldescr) guard_not_forced(descr=faildescr) [i1, f0, i0] finish(f0, descr=faildescr0) [] """, locals()) @@ -2263,13 +2262,12 @@ def test_force_from_finish(self): finishdescr = BasicFailDescr(1) - loop = parse(''' + inputargs, operations, looptoken = self.parse(''' [i1, i2] p0 = jit_frame() finish(p0, descr=faildescr1) [i1, i2] ''', namespace={'faildescr1': finishdescr}) - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) self.cpu.force(frame) assert self.cpu.get_latest_descr(frame) is finishdescr @@ -2341,7 +2339,7 @@ faildescr0 = BasicFailDescr(0) inputargs, ops, looptoken = self.parse(""" [i0, i1, i2, i3] - call_release_gil_n(ConstClass(func_ptr), i0, i1, i2, i3, descr=calldescr) + call_release_gil_v(ConstClass(func_ptr), i0, i1, i2, i3, descr=calldescr) guard_not_forced(descr=faildescr) [] finish(descr=faildescr0) """, locals()) @@ -2675,7 +2673,7 @@ ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] i10 = int_add_ovf(i0, i1) - guard_no_overflow() [] + guard_no_overflow(descr=faildescr2) [] i11 = int_add(i10, i2) i12 = int_add(i11, i3) i13 = int_add(i12, i4) @@ -2685,13 +2683,13 @@ i17 = int_add(i16, i8) i18 = int_add(i17, i9) finish(i18, descr=faildescr1) []''' - loop = parse(ops, namespace={'faildescr1': BasicFailDescr(1)}) - loop.operations[-1].getdescr().fast_path_done = True - looptoken = JitCellToken() + inputargs, operations, looptoken = self.parse( + ops, namespace={'faildescr1': BasicFailDescr(1)}) + operations[-1].getdescr().fast_path_done = True looptoken.outermost_jitdriver_sd = FakeJitDriverSD() fail_number = self.cpu.get_fail_descr_number( - loop.operations[1].getdescr()) - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + operations[1].getdescr()) + self.cpu.compile_loop(inputargs, operations, looptoken) ARGS = [lltype.Signed] * 10 RES = lltype.Signed FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( @@ -2709,11 +2707,11 @@ ''' faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) - loop = parse(ops, namespace=locals()) - othertoken = JitCellToken() + otherargs, otheroperations, othertoken = self.parse( + ops, namespace=locals()) # test the fast path, which should not call assembler_helper() - self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + self.cpu.compile_loop(otherargs, otheroperations, othertoken) args = [i+1 for i in range(10)] frame = self.cpu.execute_token(othertoken, *args) res = self.cpu.get_finish_value_int(frame) @@ -2753,16 +2751,16 @@ ops = ''' [f0, f1] i0 = float_eq(f0, -1.0) - guard_false(i0) [] + guard_false(i0, descr=faildescr3) [] f2 = float_add(f0, f1) finish(f2, descr=faildescr) []''' - loop = parse(ops, namespace={'faildescr': BasicFailDescr(1)}) - loop.operations[-1].getdescr().fast_path_done = True + inputargs, operations, looptoken = self.parse( + ops, namespace={'faildescr': BasicFailDescr(1)}) + operations[-1].getdescr().fast_path_done = True fail_number = self.cpu.get_fail_descr_number( - loop.operations[1].getdescr()) - looptoken = JitCellToken() + operations[1].getdescr()) looptoken.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) args = [longlong.getfloatstorage(1.2), longlong.getfloatstorage(2.3)] frame = self.cpu.execute_token(looptoken, *args) @@ -2776,9 +2774,8 @@ ''' faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) - loop = parse(ops, namespace=locals()) - othertoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + inputargs, operations, othertoken = self.parse(ops, namespace=locals()) + self.cpu.compile_loop(inputargs, operations, othertoken) # test the fast path, which should not call assembler_helper() args = [longlong.getfloatstorage(1.2), @@ -2820,13 +2817,12 @@ ops = ''' [p0] - call(ConstClass(fptr2), p0, descr=calldescr2) - finish(p0) []''' - loop = parse(ops, namespace=locals()) + call_v(ConstClass(fptr2), p0, descr=calldescr2) + finish(p0, descr=faildescr1) []''' + inputargs, operations, looptoken = self.parse(ops, namespace=locals()) # not a fast_path finish! - looptoken = JitCellToken() looptoken.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) ARGS = [llmemory.GCREF] RES = llmemory.GCREF FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( @@ -2837,14 +2833,13 @@ ops = ''' [] p0 = jit_frame() - p1 = call_assembler(p0, descr=looptoken) + p1 = call_assembler_r(p0, descr=looptoken) guard_not_forced(descr=foodescr) [] - finish() [] + finish(descr=faildescr2) [] ''' - loop2 = parse(ops, namespace=locals()) - othertoken = JitCellToken() - self.cpu.compile_loop(loop2.inputargs, loop2.operations, othertoken) - + inputargs, operations, othertoken = self.parse(ops, namespace=locals()) + self.cpu.compile_loop(inputargs, operations, othertoken) + frame = self.cpu.execute_token(othertoken) assert not self.cpu.get_finish_value_ref(frame) assert called == [foodescr] * 2 @@ -2900,16 +2895,16 @@ ops = ''' [f0, f1] i0 = float_eq(f0, -1.0) - guard_false(i0) [] + guard_false(i0, descr=faildescr2) [] f2 = float_add(f0, f1) finish(f2, descr=faildescr1) []''' - loop = parse(ops, namespace={'faildescr1': BasicFailDescr(1)}) - loop.operations[-1].getdescr().fast_path_done = True - looptoken = JitCellToken() + inputargs, operations, looptoken = self.parse( + ops, namespace={'faildescr1': BasicFailDescr(1)}) + operations[-1].getdescr().fast_path_done = True looptoken.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + self.cpu.compile_loop(inputargs, operations, looptoken) fail_number = self.cpu.get_fail_descr_number( - loop.operations[1].getdescr()) + operations[1].getdescr()) args = [longlong.getfloatstorage(1.25), longlong.getfloatstorage(2.35)] frame = self.cpu.execute_token(looptoken, *args) @@ -2925,9 +2920,8 @@ ''' faildescr2 = BasicFailDescr(2) faildescr1 = BasicFailDescr(1) - loop = parse(ops, namespace=locals()) - othertoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + inputargs, operations, othertoken = self.parse(ops, namespace=locals()) + self.cpu.compile_loop(inputargs, operations, othertoken) # normal call_assembler: goes to looptoken args = [longlong.getfloatstorage(1.25), @@ -2948,16 +2942,16 @@ ops2 = ''' [f0, f1] i0 = float_eq(f0, -2.0) - guard_false(i0) [] + guard_false(i0, descr=faildescr3) [] f2 = float_sub(f0, f1) finish(f2, descr=faildescr) []''' - loop2 = parse(ops2, namespace={'faildescr': BasicFailDescr(1)}) - loop2.operations[-1].getdescr().fast_path_done = True - looptoken2 = JitCellToken() + inputargs2, operations2, looptoken2 = self.parse( + ops2, namespace={'faildescr': BasicFailDescr(1)}) + operations2[-1].getdescr().fast_path_done = True looptoken2.outermost_jitdriver_sd = FakeJitDriverSD() - self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) + self.cpu.compile_loop(inputargs2, operations2, looptoken2) fail_number = self.cpu.get_fail_descr_number( - loop2.operations[1].getdescr()) + operations2[1].getdescr()) # install it self.cpu.redirect_call_assembler(looptoken, looptoken2) @@ -3230,9 +3224,10 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(self.cpu, f) - res = self.execute_operation(rop.CALL, [funcbox, boxfloat(value)], - 'float', descr=calldescr) - assert res.getfloatstorage() == expected + res = self.execute_operation(rop.CALL_f, [funcbox, + boxlonglong_on_32bit(value)], + 'longlong', descr=calldescr) + assert res == expected def test_singlefloat_result_of_call_direct(self): if not self.cpu.supports_singlefloats: @@ -3347,10 +3342,10 @@ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, effectinfo) testcases = [(4.0, 2.0), (6.25, 2.5)] for arg, expected in testcases: - res = self.execute_operation(rop.CALL, + res = self.execute_operation(rop.CALL_f, [funcbox, boxfloat(arg)], 'float', descr=calldescr) - assert res.getfloat() == expected + assert res == expected def test_compile_loop_with_target(self): looptoken = JitCellToken() @@ -3394,10 +3389,10 @@ finish(i1, descr=faildescr1) [] """ faildescr1 = BasicFailDescr(1) - loop = parse(ops, self.cpu, namespace=locals()) - descr = loop.operations[-1].getdescr() - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + inputargs, operations, looptoken = self.parse( + ops, namespace=locals()) + descr = operations[-1].getdescr() + self.cpu.compile_loop(inputargs, operations, looptoken) for inp, outp in [(2,2), (-3, 0)]: frame = self.cpu.execute_token(looptoken, inp) assert outp == self.cpu.get_finish_value_int(frame) @@ -3484,6 +3479,7 @@ cpu = self.cpu calldescr = cpu.calldescrof(deref(FPTR), (lltype.Signed,)*9, lltype.Void, EffectInfo.MOST_GENERAL) + faildescr42 = BasicFailDescr(42) inputargs, operations, looptoken = self.parse(""" [i0] label(i0, descr=targettoken1) @@ -3506,10 +3502,10 @@ i17 = int_add(i16, 1) i18 = int_add(i17, 1) i19 = int_add(i18, 1) - call_n(ConstClass(func_ptr), i2, i4, i6, i8, i10, i12, i14, i16, i18, descr=calldescr) - call_n(ConstClass(func_ptr), i2, i4, i6, i8, i10, i12, i14, i16, i18, descr=calldescr) + call_v(ConstClass(func_ptr), i2, i4, i6, i8, i10, i12, i14, i16, i18, descr=calldescr) + call_v(ConstClass(func_ptr), i2, i4, i6, i8, i10, i12, i14, i16, i18, descr=calldescr) i20 = int_lt(i19, 100) - guard_true(i20, descr=faildescr) [] + guard_true(i20, descr=faildescr42) [] jump(i19, descr=targettoken1) """, locals()) self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken1) @@ -3524,21 +3520,22 @@ def test_wrong_guard_nonnull_class(self): t_box, T_box = self.alloc_instance(self.T) - null_box = self.null_instance() + the_class = T_box.getint() faildescr = BasicFailDescr(42) - operations = [ - ResOperation(rop.GUARD_NONNULL_CLASS, [t_box, T_box], None, - descr=faildescr), - ResOperation(rop.FINISH, [], None, descr=BasicFailDescr(1))] - operations[0].setfailargs([]) - looptoken = JitCellToken() - inputargs = [t_box] + faildescr99 = BasicFailDescr(99) + inputargs, operations, looptoken = self.parse(""" + [p0] + guard_nonnull_class(p0, ConstClass(the_class), descr=faildescr) [] + finish(descr=faildescr1) [] + """, namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) - operations = [ - ResOperation(rop.FINISH, [], None, descr=BasicFailDescr(99)) - ] + _, operations, _ = self.parse(""" + [] + finish(descr=faildescr99) [] + """, namespace=locals()) self.cpu.compile_bridge(faildescr, [], operations, looptoken) - frame = self.cpu.execute_token(looptoken, null_box.getref_base()) + frame = self.cpu.execute_token(looptoken, + lltype.nullptr(llmemory.GCREF.TO)) assert self.cpu.get_latest_descr(frame).identifier == 99 def test_raw_load_int(self): @@ -3559,9 +3556,9 @@ value = rffi.cast(T, 0x4243444546474849) rawstorage.raw_storage_setitem(p, 16, value) faildescr1 = BasicFailDescr(1) - loop = parse(ops, self.cpu, namespace=locals()) - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + inputargs, operations, looptoken = self.parse( + ops, namespace=locals()) + self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16) result = self.cpu.get_finish_value_int(frame) @@ -3585,9 +3582,9 @@ value = rffi.cast(T, 1.12e20) rawstorage.raw_storage_setitem(p, 16, value) faildescr1 = BasicFailDescr(1) - loop = parse(ops, self.cpu, namespace=locals()) - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + inputargs, operations, looptoken = self.parse( + ops, namespace=locals()) + self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16) result = self.cpu.get_finish_value_float(frame) @@ -3612,9 +3609,9 @@ p[i] = '\xDD' value = 0x4243444546474849 & sys.maxint faildescr1 = BasicFailDescr(1) - loop = parse(ops, self.cpu, namespace=locals()) - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + inputargs, operations, looptoken = self.parse( + ops, namespace=locals()) + self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16, value) result = rawstorage.raw_storage_getitem(T, p, 16) @@ -3637,9 +3634,9 @@ p[i] = '\xDD' value = 1.23e20 faildescr1 = BasicFailDescr(1) - loop = parse(ops, self.cpu, namespace=locals()) - looptoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + inputargs, operations, looptoken = self.parse( + ops, namespace=locals()) + self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, rffi.cast(lltype.Signed, p), 16, longlong.getfloatstorage(value)) @@ -3657,24 +3654,17 @@ FUNC = self.FuncType([self.cpu.JITFRAMEPTR, lltype.Signed], lltype.Signed) func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force) - funcbox = self.get_funcbox(self.cpu, func_ptr).constbox() calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) - i0 = BoxInt() - i1 = BoxInt() - i2 = BoxInt() - tok = BoxPtr() faildescr = BasicFailDescr(23) - ops = [ - ResOperation(rop.JIT_FRAME, [], tok), - ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], i2, - descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [i2], None, descr=BasicFailDescr(0)) - ] - ops[2].setfailargs([i2]) - looptoken = JitCellToken() - self.cpu.compile_loop([i0, i1], ops, looptoken) + inputargs, operations, looptoken = self.parse(''' + [i0, i1] + ptok = jit_frame() + i2 = call_may_force_i(ConstClass(func_ptr), ptok, i1, descr=calldescr) + guard_not_forced(descr=faildescr) [i2] + finish(i2, descr=faildescr2) [] + ''', namespace=locals()) + self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 23 assert self.cpu.get_latest_value_int(frame, 0) == 42 diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -21,6 +21,7 @@ from pypy.jit.metainterp.resoperation import rop, AbstractResOp, opgroups,\ Const, ConstInt, ConstFloat, AbstractValue from pypy.jit.metainterp.typesystem import llhelper +from pypy.jit.codewriter import longlong from pypy.rlib.objectmodel import specialize, we_are_translated from pypy.tool.pairtype import extendabletype @@ -289,7 +290,7 @@ CONST_0 = ConstInt(0) CONST_1 = ConstInt(1) CVAL_ZERO = ConstantValue(CONST_0) -CVAL_ZERO_FLOAT = ConstantValue(ConstFloat(0.0)) +CVAL_ZERO_FLOAT = ConstantValue(ConstFloat(longlong.getfloatstorage(0.0))) CVAL_NULLREF = ConstantValue(llhelper.CONST_NULL) llhelper.CVAL_NULLREF = CVAL_NULLREF REMOVED = AbstractResOp() diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -10,6 +10,7 @@ ResOpNone, create_resop_0, example_for_opnum from pypy.jit.metainterp import optmodel from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rlib.objectmodel import Symbolic class ParseError(Exception): pass @@ -45,7 +46,9 @@ return self.model.ConstPtr(obj) else: assert typ == 'class' - return self.model.ConstInt(self.model.ptr_to_int(obj)) + if not isinstance(obj, Symbolic): + obj = self.model.ptr_to_int(obj) + return self.model.ConstInt(obj) else: if typ == 'ptr': return self.model.ConstObj(obj) From noreply at buildbot.pypy.org Mon Oct 22 18:38:23 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 18:38:23 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: shit stuff to support Message-ID: <20121022163823.B827D1C0236@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58367:485628fc23c0 Date: 2012-10-22 18:38 +0200 http://bitbucket.org/pypy/pypy/changeset/485628fc23c0/ Log: shit stuff to support diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -6,42 +6,19 @@ from pypy.jit.metainterp.resoperation import rop, create_resop_dispatch,\ create_resop, ConstInt, ConstPtr, ConstFloat, create_resop_2,\ create_resop_1, create_resop_0, INT, REF, FLOAT, example_for_opnum +from pypy.jit.metainterp.test.support import boxint, boxfloat,\ + boxlonglong_on_32bit, boxptr, constfloat from pypy.jit.metainterp.typesystem import deref from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass from pypy.rpython.annlowlevel import llhelper from pypy.rpython.llinterp import LLException from pypy.jit.codewriter import heaptracker, longlong -from pypy.rlib import longlong2float from pypy.rlib.rarithmetic import intmask, is_valid_int from pypy.jit.backend.detect_cpu import autodetect_main_model_and_size from pypy.jit.tool import oparser -def boxfloat(x=None): - if x is None: - x = example_for_opnum(rop.INPUT_f) - return create_resop_0(rop.INPUT_f, longlong.getfloatstorage(x)) - -def boxlonglong_on_32bit(x): - return create_resop_0(rop.INPUT_f, x) - -def boxint(x=0): - return create_resop_0(rop.INPUT_i, x) - -def boxptr(x=lltype.nullptr(llmemory.GCREF.TO)): - return create_resop_0(rop.INPUT_r, x) - -def constfloat(x): - return ConstFloat(longlong.getfloatstorage(x)) - -def boxlonglong(ll): - if longlong.is_64_bit: - return boxint(ll) - else: - return boxfloat(ll) - - class Runner(object): add_loop_instruction = ['overload for a specific cpu'] diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py b/pypy/jit/metainterp/optimizeopt/test/test_util.py --- a/pypy/jit/metainterp/optimizeopt/test/test_util.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py @@ -16,8 +16,8 @@ from pypy.jit.metainterp import compile, resume from pypy.jit.metainterp.jitprof import EmptyProfiler from pypy.config.pypyoption import get_pypy_config -from pypy.jit.metainterp.resoperation import rop, create_resop, BoxPtr,\ - create_resop_0, REF, INT, FLOAT, create_resop_2, BoxInt +from pypy.jit.metainterp.resoperation import rop, create_resop,\ + create_resop_0, REF, INT, FLOAT, create_resop_2 def test_sort_descrs(): class PseudoDescr(AbstractDescr): @@ -409,12 +409,6 @@ def teardown_method(self, meth): del self.oparsers - def process_guard(self, guard_op, oparser): - fail_args = guard_op.get_extra("failargs") - guard_op.set_rd_frame_info_list(resume.FrameInfo(None, "code", 11)) - guard_op.set_rd_snapshot(resume.Snapshot(None, _sortboxes(fail_args))) - self.oparsers.append(oparser) - def assert_equal(self, optimized, expected, text_right=None): from pypy.jit.metainterp.optimizeopt.util import equaloplists assert len(optimized.inputargs) == len(expected.inputargs) @@ -436,11 +430,6 @@ if hasattr(self, 'callinfocollection'): metainterp_sd.callinfocollection = self.callinfocollection # - for op in loop.operations: - if op.is_guard(): - fail_args = op.get_extra("failargs") - op._rd_frame_info_list = resume.FrameInfo(None, "code", 11) - op._rd_snapshot = resume.Snapshot(None, _sortboxes(fail_args)) optimize_trace(jitdriver_sd, metainterp_sd, loop, self.enable_opts) def unroll_and_optimize(self, loop): diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py --- a/pypy/jit/metainterp/test/support.py +++ b/pypy/jit/metainterp/test/support.py @@ -1,16 +1,40 @@ -import py, sys +import sys from pypy.rpython.lltypesystem import lltype, llmemory -from pypy.rpython.ootypesystem import ootype from pypy.jit.backend.llgraph import runner from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats from pypy.jit.metainterp.warmstate import unspecialize_value from pypy.jit.metainterp.optimizeopt import ALL_OPTS_DICT +from pypy.jit.metainterp.resoperation import example_for_opnum, create_resop_0,\ + rop, ConstFloat from pypy.jit.metainterp import pyjitpl, history from pypy.jit.codewriter.policy import JitPolicy from pypy.jit.codewriter import codewriter, longlong from pypy.rlib.rfloat import isnan +def boxfloat(x=None): + if x is None: + x = example_for_opnum(rop.INPUT_f) + return create_resop_0(rop.INPUT_f, longlong.getfloatstorage(x)) + +def boxlonglong_on_32bit(x): + return create_resop_0(rop.INPUT_f, x) + +def boxint(x=0): + return create_resop_0(rop.INPUT_i, x) + +def boxptr(x=lltype.nullptr(llmemory.GCREF.TO)): + return create_resop_0(rop.INPUT_r, x) + +def constfloat(x): + return ConstFloat(longlong.getfloatstorage(x)) + +def boxlonglong(ll): + if longlong.is_64_bit: + return boxint(ll) + else: + return boxfloat(ll) + def _get_jitcodes(testself, CPUClass, func, values, type_system, supports_longlong=False, translationoptions={}, **kwds): from pypy.jit.codewriter import support From noreply at buildbot.pypy.org Mon Oct 22 18:40:06 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 18:40:06 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: fix one more import Message-ID: <20121022164006.426F81C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58368:8c0f05055511 Date: 2012-10-22 18:39 +0200 http://bitbucket.org/pypy/pypy/changeset/8c0f05055511/ Log: fix one more import diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -7,7 +7,7 @@ create_resop, ConstInt, ConstPtr, ConstFloat, create_resop_2,\ create_resop_1, create_resop_0, INT, REF, FLOAT, example_for_opnum from pypy.jit.metainterp.test.support import boxint, boxfloat,\ - boxlonglong_on_32bit, boxptr, constfloat + boxlonglong_on_32bit, boxptr, constfloat, boxlonglong from pypy.jit.metainterp.typesystem import deref from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass From noreply at buildbot.pypy.org Mon Oct 22 18:49:16 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 22 Oct 2012 18:49:16 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: 64-bit support Message-ID: <20121022164916.332591C01F9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: result-in-resops Changeset: r58369:c98f84d0dc84 Date: 2012-10-22 18:49 +0200 http://bitbucket.org/pypy/pypy/changeset/c98f84d0dc84/ Log: 64-bit support diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -7,7 +7,7 @@ create_resop, ConstInt, ConstPtr, ConstFloat, create_resop_2,\ create_resop_1, create_resop_0, INT, REF, FLOAT, example_for_opnum from pypy.jit.metainterp.test.support import boxint, boxfloat,\ - boxlonglong_on_32bit, boxptr, constfloat, boxlonglong + boxlonglong_on_32bit, boxptr, constfloat from pypy.jit.metainterp.typesystem import deref from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass @@ -1797,16 +1797,18 @@ def test_convert_float_bytes(self): if not self.cpu.supports_floats: py.test.skip("requires floats") - #if not self.cpu.supports_longlong: - # py.test.skip("longlong test") box = boxfloat(2.5) t = 'int' if longlong.is_64_bit else 'float' res = self.execute_operation(rop.CONVERT_FLOAT_BYTES_TO_LONGLONG, [box], t) - assert res == 2.5 + assert longlong.longlong2floatstorage(res) == 2.5 + if longlong.is_64_bit: + box = boxint(res) + else: + box = boxfloat(res) res = self.execute_operation(rop.CONVERT_LONGLONG_BYTES_TO_FLOAT, - [boxlonglong(res)], 'float') + [box], 'float') assert res == 2.5 def test_ooops_non_gc(self): diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py --- a/pypy/jit/metainterp/test/support.py +++ b/pypy/jit/metainterp/test/support.py @@ -29,12 +29,6 @@ def constfloat(x): return ConstFloat(longlong.getfloatstorage(x)) -def boxlonglong(ll): - if longlong.is_64_bit: - return boxint(ll) - else: - return boxfloat(ll) - def _get_jitcodes(testself, CPUClass, func, values, type_system, supports_longlong=False, translationoptions={}, **kwds): from pypy.jit.codewriter import support From noreply at buildbot.pypy.org Mon Oct 22 19:12:51 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 19:12:51 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: fix fix fix Message-ID: <20121022171251.105C21C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58370:377145707965 Date: 2012-10-22 18:56 +0200 http://bitbucket.org/pypy/pypy/changeset/377145707965/ Log: fix fix fix diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py --- a/pypy/jit/metainterp/executor.py +++ b/pypy/jit/metainterp/executor.py @@ -341,7 +341,8 @@ rop.CALL_MALLOC_NURSERY, rop.LABEL, rop.INPUT_i, rop.INPUT_r, rop.INPUT_f, - rop.FORCE_SPILL, rop.ESCAPE, + rop.FORCE_SPILL, rop.ESCAPE, rop.ESCAPE_r, + rop.ESCAPE_f, ): # list of opcodes never executed by pyjitpl continue raise AssertionError("missing %r" % (orig_key,)) diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -628,11 +628,9 @@ self._newoperations.append(op) def store_final_boxes_in_guard(self, op): - if op.getdescr() is not None: - # means we need to copy the op and attach a new descr - xxx - op = op.copy_and_change(op.getopnum(), descr=None) + assert op.getdescr() is None descr = op.invent_descr(self.jitdriver_sd, self.metainterp_sd) + op.setdescr(descr) modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo) try: newboxes = modifier.finish(self, self.pendingfields) diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -8,17 +8,18 @@ from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.history import get_const_ptr_for_string from pypy.jit.metainterp import executor, compile, resume -from pypy.jit.metainterp.resoperation import rop, opname, ConstInt, BoxInt,\ +from pypy.jit.metainterp.resoperation import rop, opname, ConstInt,\ create_resop_1, create_resop +from pypy.jit.metainterp.test.support import boxint from pypy.rlib.rarithmetic import LONG_BIT def test_store_final_boxes_in_guard(): from pypy.jit.metainterp.resume import tag, TAGBOX - b0 = BoxInt() - b1 = BoxInt() + b0 = boxint() + b1 = boxint() opt = optimizeopt.Optimizer(None, FakeMetaInterpStaticData(LLtypeMixin.cpu), None) - op = create_resop_1(rop.GUARD_TRUE, None, BoxInt(0)) + op = create_resop_1(rop.GUARD_TRUE, None, boxint(0), mutable=True) # setup rd data fi0 = resume.FrameInfo(None, "code0", 11) op._rd_frame_info_list = resume.FrameInfo(fi0, "code1", 33) @@ -186,7 +187,6 @@ def test_constfold_all(self): from pypy.jit.backend.llgraph.llimpl import TYPES # xxx fish from pypy.jit.metainterp.executor import execute_nonspec - from pypy.jit.metainterp.resoperation import BoxInt import random for opnum in [rop._ALWAYS_PURE_FIRST, rop._ALWAYS_PURE_NO_PTR_LAST]: try: @@ -209,7 +209,7 @@ escape(i1) jump() """ % (op.lower(), ', '.join(map(str, args))) - argboxes = [BoxInt(a) for a in args] + argboxes = [boxint(a) for a in args] expected_value = execute_nonspec(self.cpu, None, opnum, argboxes).getint() expected = """ @@ -1463,7 +1463,7 @@ ops = """ [p1] i1 = getfield_gc_i(p1, descr=valuedescr) - escape() + escape(0) i2 = getfield_gc_i(p1, descr=valuedescr) escape(i1) escape(i2) @@ -1475,7 +1475,7 @@ ops = """ [p1, i1] setfield_gc(p1, i1, descr=valuedescr) - escape() + escape(0) i2 = getfield_gc_i(p1, descr=valuedescr) escape(i2) jump(p1, i1) @@ -1581,7 +1581,7 @@ ops = """ [p1, i1, i2] setfield_gc(p1, i1, descr=valuedescr) - escape() + escape(0) setfield_gc(p1, i2, descr=valuedescr) jump(p1, i1, i2) """ @@ -1866,7 +1866,7 @@ escape(p4) # p2 = new_with_vtable(ConstClass(node_vtable)) - p3 = escape() + p3 = escape(0) setfield_gc(p2, p3, descr=nextdescr) jump(i0, p2) """ @@ -1875,7 +1875,7 @@ guard_nonnull(p4) [] escape(p4) # - p3 = escape() + p3 = escape(0) jump(i0, p3) """ py.test.skip("XXX") @@ -1890,7 +1890,7 @@ escape(p4) # p2 = new_array(1, descr=arraydescr2) - p3 = escape() + p3 = escape(0) setarrayitem_gc(p2, 0, p3, descr=arraydescr2) jump(i0, p2) """ @@ -1899,7 +1899,7 @@ guard_nonnull(p4) [] escape(p4) # - p3 = escape() + p3 = escape(0) jump(i0, p3) """ py.test.skip("XXX") diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -135,9 +135,9 @@ def test_simple(self): ops = """ [] - f = escape() + f = escape_f(0) f0 = float_sub(f, 1.0) - guard_value(f0, 0.0) [f0] + guard_value(f0, 0.0) escape(f) jump() """ diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py b/pypy/jit/metainterp/optimizeopt/test/test_util.py --- a/pypy/jit/metainterp/optimizeopt/test/test_util.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py @@ -9,6 +9,7 @@ JitCellToken, TargetToken) from pypy.jit.metainterp.optimizeopt.util import sort_descrs, equaloplists,\ ArgsDict, ArgsSet +from pypy.jit.metainterp.test.support import boxptr from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.jit.codewriter.heaptracker import register_known_gctype from pypy.jit.tool.oparser import parse, pure_parse @@ -124,11 +125,11 @@ node.parent.typeptr = node_vtable node2 = lltype.malloc(NODE2) node2.parent.parent.typeptr = node_vtable2 - nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node)) - myptr = nodebox.value + myptr = lltype.cast_opaque_ptr(llmemory.GCREF, node) + nodebox = boxptr(myptr) myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(NODE)) nullptr = lltype.nullptr(llmemory.GCREF.TO) - nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node2)) + nodebox2 = boxptr(lltype.cast_opaque_ptr(llmemory.GCREF, node2)) nodesize = cpu.sizeof(NODE) nodesize2 = cpu.sizeof(NODE2) valuedescr = cpu.fielddescrof(NODE, 'value') @@ -145,8 +146,8 @@ quasi = lltype.malloc(QUASI, immortal=True) quasi.inst_field = -4247 quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field') - quasibox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, quasi)) - quasiptr = quasibox.value + quasiptr = lltype.cast_opaque_ptr(llmemory.GCREF, quasi) + quasibox = boxptr(quasiptr) quasiimmutdescr = QuasiImmutDescr(cpu, quasibox, quasifielddescr, cpu.fielddescrof(QUASI, 'mutate_field')) @@ -181,7 +182,7 @@ ssize = cpu.sizeof(S) adescr = cpu.fielddescrof(S, 'a') bdescr = cpu.fielddescrof(S, 'b') - sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S))) + sbox = boxptr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S))) arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S))) T = lltype.GcStruct('TUPLE', @@ -397,11 +398,10 @@ class BaseTest(object): - def parse(self, s, boxkinds=None, results=None): + def parse(self, s, results=None): return parse(s, self.cpu, self.namespace, type_system=self.type_system, - boxkinds=boxkinds, - results=results, process_guard=self.process_guard) + results=results) def setup_method(self, meth): self.oparsers = [] diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -843,7 +843,6 @@ descr = compile.ResumeGuardDescr() descr.rd_snapshot = self._rd_snapshot descr.rd_frame_info_list = self._rd_frame_info_list - self.setdescr(descr) return descr # ============ @@ -1256,6 +1255,8 @@ '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- 'ESCAPE/1/v', # tests + 'ESCAPE_r/1/r', # tests + 'ESCAPE_f/1/f', # tests 'FORCE_SPILL/1/v', # tests 'SETARRAYITEM_GC/3d/v', From noreply at buildbot.pypy.org Mon Oct 22 19:12:52 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 19:12:52 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: rename mutable_copy to make_forwarded_copy. fix tests Message-ID: <20121022171252.369681C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58371:b336bf42d0c9 Date: 2012-10-22 19:12 +0200 http://bitbucket.org/pypy/pypy/changeset/b336bf42d0c9/ Log: rename mutable_copy to make_forwarded_copy. fix tests diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -280,19 +280,13 @@ assert self.level == LEVEL_CONSTANT return '' % self.op -class ConstantValue(OptValue): - def __init__(self, box): - self.make_constant(box) - - def __repr__(self): - return 'Constant(%r)' % (self.op,) - CONST_0 = ConstInt(0) CONST_1 = ConstInt(1) -CVAL_ZERO = ConstantValue(CONST_0) -CVAL_ZERO_FLOAT = ConstantValue(ConstFloat(longlong.getfloatstorage(0.0))) -CVAL_NULLREF = ConstantValue(llhelper.CONST_NULL) -llhelper.CVAL_NULLREF = CVAL_NULLREF +#CVAL_ZERO = ConstantValue(CONST_0) +#CVAL_ZERO_FLOAT = ConstantValue(ConstFloat(longlong.getfloatstorage(0.0))) +#CVAL_NULLREF = ConstantValue(llhelper.CONST_NULL) +CONST_NULL = llhelper.CONST_NULL +#llhelper.CVAL_NULLREF = CVAL_NULLREF REMOVED = AbstractResOp() @@ -447,34 +441,25 @@ self.metainterp_sd.profiler.count(jitprof.Counters.OPT_FORCINGS) self.resumedata_memo.forget_numberings(virtualbox) - def getvalue(self, box, create=True): - try: - while True: - box = box.get_extra("optimize_replace") - except KeyError: - pass + def getvalue(self, box): if box.is_constant(): if box.type == REF: if not box.getref_base(): - return CVAL_NULLREF + return CONST_NULL try: return self.interned_refs[box.getref_base()] except KeyError: - val = ConstantValue(box) - self.interned_refs[box.getref_base()] = val - return val - return ConstantValue(box) - try: - value = box.get_extra("optimize_value") - except KeyError: - if not create: - return None - value = OptValue(box) - box.set_extra("optimize_value", value) - self.ensure_imported(value) + self.interned_refs[box.getref_base()] = box + return box + return box + value = box._forwarded + if value is None: + value = box.make_forwarded_copy() + #self.ensure_imported(value) return value def setvalue(self, box, value): + xxx assert not box.is_constant() assert not box.has_extra("optimize_value") box.set_extra("optimize_value", value) diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -867,7 +867,7 @@ pass @specialize.arg(1) - def mutable_copy(self, newopnum=-1, descr=None): + def make_forwarded_copy(self, newopnum=-1, descr=None): if newopnum == -1: newopnum = self.getopnum() res = create_resop_0(newopnum, self.getresult(), @@ -875,6 +875,9 @@ if self.is_guard(): res.set_rd_frame_info_list(self.get_rd_frame_info_list()) res.set_rd_snapshot(self.get_rd_snapshot()) + assert not self.is_mutable + assert not self._forwarded + self._forwarded = res return res def get_key_op(self, opt): @@ -917,7 +920,7 @@ return res @specialize.arg(1) - def mutable_copy(self, newopnum=-1, arg0=None, descr=None): + def make_forwarded_copy(self, newopnum=-1, arg0=None, descr=None): if newopnum == -1: newopnum = self.getopnum() res = create_resop_1(newopnum, self.getresult(), arg0 or self._arg0, @@ -925,6 +928,9 @@ if self.is_guard(): res.set_rd_frame_info_list(self.get_rd_frame_info_list()) res.set_rd_snapshot(self.get_rd_snapshot()) + assert not self.is_mutable + assert not self._forwarded + self._forwarded = res return res def get_arg_hash(self): @@ -970,7 +976,7 @@ new_arg0, new_arg1, self.getdescr()) @specialize.arg(1) - def mutable_copy(self, newopnum=-1, arg0=None, arg1=None, descr=None): + def make_forwarded_copy(self, newopnum=-1, arg0=None, arg1=None, descr=None): if newopnum == -1: newopnum = self.getopnum() res = create_resop_2(newopnum, self.getresult(), arg0 or self._arg0, @@ -980,6 +986,9 @@ if self.is_guard(): res.set_rd_frame_info_list(self.get_rd_frame_info_list()) res.set_rd_snapshot(self.get_rd_snapshot()) + assert not self._forwarded + assert not self.is_mutable + self._forwarded = res return res def get_arg_hash(self): @@ -1032,7 +1041,7 @@ new_arg0, new_arg1, new_arg2, self.getdescr()) @specialize.arg(1) - def mutable_copy(self, newopnum=-1, arg0=None, arg1=None, arg2=None, + def make_forwarded_copy(self, newopnum=-1, arg0=None, arg1=None, arg2=None, descr=None): if newopnum == -1: newopnum = self.getopnum() @@ -1040,6 +1049,9 @@ arg1 or self._arg1, arg2 or self._arg2, descr or self.getdescr(), mutable=True) assert not r.is_guard() + assert not self._forwarded + assert not self.is_mutable + self._forwarded = r return r def get_arg_hash(self): @@ -1091,13 +1103,16 @@ newargs, self.getdescr()) @specialize.arg(1) - def mutable_copy(self, newopnum=-1, newargs=None, descr=None): + def make_forwarded_copy(self, newopnum=-1, newargs=None, descr=None): if newopnum == -1: newopnum = self.getopnum() r = create_resop(newopnum, self.getresult(), newargs or self.getarglist(), descr or self.getdescr(), mutable=True) assert not r.is_guard() + assert not self._forwarded + assert not self.is_mutable + self._forwarded = r return r def get_arg_hash(self): diff --git a/pypy/jit/metainterp/test/test_optmodel.py b/pypy/jit/metainterp/test/test_optmodel.py --- a/pypy/jit/metainterp/test/test_optmodel.py +++ b/pypy/jit/metainterp/test/test_optmodel.py @@ -6,40 +6,44 @@ from pypy.jit.metainterp import resoperation as rop from pypy.jit.metainterp import optmodel -def test_mutable_copy(): +def test_make_forwarded_copy(): op = rop.create_resop_1(rop.rop.INT_IS_ZERO, 1, FakeBox('a')) assert not op.is_mutable - op2 = op.mutable_copy(rop.rop.INT_IS_TRUE) + op2 = op.make_forwarded_copy(rop.rop.INT_IS_TRUE) assert op2.opnum == rop.rop.INT_IS_TRUE assert op2.getarg(0) == FakeBox('a') - op2 = op.mutable_copy(rop.rop.INT_IS_TRUE, FakeBox('b')) + op._forwarded = None + op2 = op.make_forwarded_copy(rop.rop.INT_IS_TRUE, FakeBox('b')) assert op2.is_mutable assert op2.opnum == rop.rop.INT_IS_TRUE assert op2.getarg(0) == FakeBox('b') assert op2 is not op op = rop.create_resop_2(rop.rop.INT_ADD, 3, FakeBox("a"), FakeBox("b")) - op2 = op.mutable_copy(rop.rop.INT_SUB) + op2 = op.make_forwarded_copy(rop.rop.INT_SUB) assert op2.opnum == rop.rop.INT_SUB assert op2.getarglist() == [FakeBox("a"), FakeBox("b")] - op2 = op.mutable_copy(rop.rop.INT_SUB, None, FakeBox("c")) + op._forwarded = None + op2 = op.make_forwarded_copy(rop.rop.INT_SUB, None, FakeBox("c")) assert op2.opnum == rop.rop.INT_SUB assert op2.getarglist() == [FakeBox("a"), FakeBox("c")] op = rop.create_resop_3(rop.rop.STRSETITEM, None, FakeBox('a'), FakeBox('b'), FakeBox('c')) - op2 = op.mutable_copy(rop.rop.UNICODESETITEM, None, FakeBox("c")) + op2 = op.make_forwarded_copy(rop.rop.UNICODESETITEM, None, FakeBox("c")) assert op2.opnum == rop.rop.UNICODESETITEM assert op2.getarglist() == [FakeBox("a"), FakeBox("c"), FakeBox("c")] mydescr = FakeDescr() op = rop.create_resop(rop.rop.CALL_PURE_i, 13, [FakeBox('a'), FakeBox('b'), FakeBox('c')], descr=mydescr) - op2 = op.mutable_copy(rop.rop.CALL_i) + op2 = op.make_forwarded_copy(rop.rop.CALL_i) assert op2.getarglist() == ['a', 'b', 'c'] - op2 = op.mutable_copy(rop.rop.CALL_i, [FakeBox('a')]) + op._forwarded = None + op2 = op.make_forwarded_copy(rop.rop.CALL_i, [FakeBox('a')]) assert op2.getarglist() == ['a'] def test_failargs(): op = rop.create_resop_0(rop.rop.GUARD_NO_OVERFLOW, None) assert not hasattr(op, 'set_failargs') - op2 = op.mutable_copy() - op2.set_failargs([1, 2, 3]) - assert op2.get_failargs() == [1, 2, 3] + op2 = op.make_forwarded_copy() + assert op._forwarded is op2 + op2.setfailargs([1, 2, 3]) + assert op2.getfailargs() == [1, 2, 3] From noreply at buildbot.pypy.org Mon Oct 22 19:12:53 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 19:12:53 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: merge Message-ID: <20121022171253.5890C1C01F9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58372:2ec90c4840d4 Date: 2012-10-22 19:12 +0200 http://bitbucket.org/pypy/pypy/changeset/2ec90c4840d4/ Log: merge diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -7,7 +7,7 @@ create_resop, ConstInt, ConstPtr, ConstFloat, create_resop_2,\ create_resop_1, create_resop_0, INT, REF, FLOAT, example_for_opnum from pypy.jit.metainterp.test.support import boxint, boxfloat,\ - boxlonglong_on_32bit, boxptr, constfloat, boxlonglong + boxlonglong_on_32bit, boxptr, constfloat from pypy.jit.metainterp.typesystem import deref from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass @@ -1797,16 +1797,18 @@ def test_convert_float_bytes(self): if not self.cpu.supports_floats: py.test.skip("requires floats") - #if not self.cpu.supports_longlong: - # py.test.skip("longlong test") box = boxfloat(2.5) t = 'int' if longlong.is_64_bit else 'float' res = self.execute_operation(rop.CONVERT_FLOAT_BYTES_TO_LONGLONG, [box], t) - assert res == 2.5 + assert longlong.longlong2floatstorage(res) == 2.5 + if longlong.is_64_bit: + box = boxint(res) + else: + box = boxfloat(res) res = self.execute_operation(rop.CONVERT_LONGLONG_BYTES_TO_FLOAT, - [boxlonglong(res)], 'float') + [box], 'float') assert res == 2.5 def test_ooops_non_gc(self): diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py --- a/pypy/jit/metainterp/test/support.py +++ b/pypy/jit/metainterp/test/support.py @@ -29,12 +29,6 @@ def constfloat(x): return ConstFloat(longlong.getfloatstorage(x)) -def boxlonglong(ll): - if longlong.is_64_bit: - return boxint(ll) - else: - return boxfloat(ll) - def _get_jitcodes(testself, CPUClass, func, values, type_system, supports_longlong=False, translationoptions={}, **kwds): from pypy.jit.codewriter import support From noreply at buildbot.pypy.org Mon Oct 22 19:58:56 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Mon, 22 Oct 2012 19:58:56 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: some figures Message-ID: <20121022175856.7F2011C0246@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4890:a0f8b5c350d6 Date: 2012-10-22 07:56 -0700 http://bitbucket.org/pypy/extradoc/changeset/a0f8b5c350d6/ Log: some figures diff --git a/talk/dls2012/presentation/figures/all_numbers.png b/talk/dls2012/presentation/figures/all_numbers.png new file mode 100644 index 0000000000000000000000000000000000000000..9076ac193fc9ba1954e24e2ae372ec7e1e1f44e6 GIT binary patch [cut] diff --git a/talk/dls2012/presentation/figures/optimization.svg b/talk/dls2012/presentation/figures/optimization.svg new file mode 100644 --- /dev/null +++ b/talk/dls2012/presentation/figures/optimization.svg @@ -0,0 +1,1136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + w + + + 0 + + + = + + + a + + + 0 + + + +0 + + + x + + + 0 + + + = + + + w + + + 0 + + + +1 + + + y + + + 0 + + + = + + + a + + + 0 + + + +1 + + + z + + + 0 + + + = + + + x + + + 0 + + + + + + + y + + + 0 + + + ... + jump( + + + L + + + 0 + + + , + + + z + + + 0 + + + , + + + b + + + 0 + + + ) + + + + rename to + + + + + + + w + + + 0 + + + a + + + 0 + + + + + + + + in + + + + + a + + + 0 + + + a + + + 0 + + + +1 + + + x + + + 0 + + + + + + + + + rename to + + y + + + 0 + + + x + + + 0 + + + + + + + + in + + + + + + x + + + 0 + + + + x + + + 0 + + + + + + + x + + + 0 + + + z + + + 0 + + + z + + + 0 + + + diff --git a/talk/dls2012/presentation/figures/optimization1.pdf b/talk/dls2012/presentation/figures/optimization1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8afc9f635e2741be5eaf57ba24f0312ba7ff47c7 GIT binary patch [cut] diff --git a/talk/dls2012/presentation/figures/optimization2.pdf b/talk/dls2012/presentation/figures/optimization2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..731ac4f40e6be34d86ff877220d45d38c4c557ff GIT binary patch [cut] diff --git a/talk/dls2012/presentation/figures/optimization3.pdf b/talk/dls2012/presentation/figures/optimization3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7270c4e32f441c75d40fd32170199a0b84745a8d GIT binary patch [cut] diff --git a/talk/dls2012/presentation/figures/optimization4.pdf b/talk/dls2012/presentation/figures/optimization4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3b913c841d2471be913feecf3e5d339cf97ad310 GIT binary patch [cut] diff --git a/talk/dls2012/presentation/figures/optimization5.pdf b/talk/dls2012/presentation/figures/optimization5.pdf new file mode 100644 index 0000000000000000000000000000000000000000..695e997cbb19b1796ccd9387606396fea3f183ab GIT binary patch [cut] From noreply at buildbot.pypy.org Mon Oct 22 19:58:57 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Mon, 22 Oct 2012 19:58:57 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: add more slides, probably too many Message-ID: <20121022175857.ADF2A1C0246@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4891:ca954a5d1364 Date: 2012-10-22 10:52 -0700 http://bitbucket.org/pypy/extradoc/changeset/ca954a5d1364/ Log: add more slides, probably too many diff --git a/talk/dls2012/presentation/talk.tex b/talk/dls2012/presentation/talk.tex --- a/talk/dls2012/presentation/talk.tex +++ b/talk/dls2012/presentation/talk.tex @@ -56,7 +56,7 @@ \title{Loop-Aware Optimizations in PyPy’s Tracing JIT} -\author[Ardö, Bolz, Fijałkowski]{Håkan Ardö$^1$ \and \emph{Carl Friedrich Bolz}$^2$ \and Maciej Fijałkowski} +\author[Ardö, Bolz, Fijałkowski]{\emph{Håkan Ardö}$^1$ \and \emph{Carl Friedrich Bolz}$^2$ \and Maciej Fijałkowski} % - Give the names in the same order as the appear in the paper. % - Use the \inst{?} command only if the authors have different % affiliation. @@ -103,11 +103,36 @@ \end{frame} \begin{frame} + \frametitle{RPython and PyPy} + \begin{itemize} + \item Context: RPython + \item a language for writing interpreters for dynamic languages + \item a generic tracing JIT, applicable to many languages + \item used to implement PyPy, an efficient Python interpreter + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{How fast is PyPy?} + \includegraphics[scale=0.3]{figures/all_numbers.png} +\end{frame} + +\begin{frame} + \frametitle{Tracing JITs Compile by Observing an Interpreter} + \begin{itemize} + \item VM contains both an interpreter and the tracing JIT compiler + \item JIT works by observing and logging what the interpreter does + \item for interesting, commonly executed code paths + \item produces a linear list of operations (trace) + \end{itemize} +\end{frame} + +\begin{frame} \frametitle{Why do tracing JITs work?} \begin{itemize} \item They are good at selecting interesting and common code paths - \item both through user program and through the runtime - \item the latter is particularly important for dynamic languages + \item both through the user program and through the runtime + \item the latter is particularly important for dynamic languages with a big runtime like Python \pause \item traces are trivial to optimize \end{itemize} @@ -117,10 +142,11 @@ \frametitle{Optimizing traces} \begin{itemize} \item A trace is an extended basic block + \item (it has one entry and several exits) \item traces are easy to optime due to lack of control flow merges \item most optimizations are one forward pass \item optimizers are often like symbolic executors - \item can do optimizations that are untractable with full control flow + \item can do optimizations that are expensive or even untractable with full control flow \end{itemize} \end{frame} @@ -168,6 +194,220 @@ \end{frame} \begin{frame} + \frametitle{Loop Peeling} +\begin{center} +\includegraphics[width=\columnwidth]{../figures/overview} +\end{center} +\end{frame} + + +\begin{frame}[fragile] + \frametitle{Loop Peeling} + \begin{columns} + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_0$, $i_0$) + $$ + $$ + $$ + $$ + $$ + \end{lstlisting} + \end{column} + \pause + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_1$, $i_0$) + + $L_1$($i_{0}$): + $i_2$ = $i_0$ + 1 + print($i_2$) + jump($L_1$, $i_0$) + \end{lstlisting} + \end{column} + \end{columns} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Apply Optimizations} + \begin{columns} + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_1$, $i_0$) + + $L_1$($i_{0}$): + $i_2$ = $i_0$ + 1 + print($i_2$) + jump($L_1$, $i_0$) + \end{lstlisting} + \end{column} + \pause + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_1$, $i_0$) + + $L_1$($i_{0}$): + print($i_1$) + jump($L_1$, $i_0$) + \end{lstlisting} + \end{column} + \end{columns} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Add extra arguments} + \begin{columns} + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_1$, $i_0$) + + $L_1$($i_{0}$): + print($i_1$) + jump($L_1$, $i_0$) + \end{lstlisting} + \end{column} + \pause + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_1$, $i_0$, $i_1$) + + $L_1$($i_{0}$, $i_1$): + print($i_1$) + jump($L_1$, $i_0$, $i_1$) + \end{lstlisting} + \end{column} + \end{columns} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Larger example} + \begin{columns} + \begin{column}{0.5\textwidth} + \begin{lstlisting} + while True: + y = y + 1 + \end{lstlisting} + \end{column} + \pause + \begin{column}{0.5\textwidth} +\begin{lstlisting}[mathescape] +$L_0$($p_{0}$, $p_{1}$): +guard_class($p_{1}$, BoxedInteger) +$i_{2}$ = get($p_{1}$, intval) +guard_class($p_{0}$, BoxedInteger) +$i_{3}$ = get($p_{0}$, intval) +$i_{4}$ = $i_{2} + i_{3}$ +$p_{5}$ = new(BoxedInteger) +set($p_{5}$, intval, $i_{4}$) +jump($L_0$, $p_{0}$, $p_{5}$) +\end{lstlisting} + \end{column} + \end{columns} +\end{frame} + + +\begin{frame}[fragile] + \frametitle{Peeled trace} +\begin{lstlisting}[mathescape] +$L_0$($p_{0}$, $p_{1}$): +guard_class($p_{1}$, BoxedInteger) +$i_{2}$ = get($p_{1}$, intval) +guard_class($p_{0}$, BoxedInteger) +$i_{3}$ = get($p_{0}$, intval) +$i_{4}$ = $i_{2}+i_{3}$ +$p_{5}$ = new(BoxedInteger) +set($p_{5}$, intval, $i_{4}$) +jump($L_1$, $p_{0}$, $p_{5}$) + +$L_1$($p_{0}$, $p_{5}$): +guard_class($p_{5}$, BoxedInteger) +$i_{6}$ = get($p_{5}$, intval) +guard_class($p_{0}$, BoxedInteger) +$i_{7}$ = get($p_{0}$, intval) +$i_{8}$ = $i_{6}+i_{7}$ +$p_{9}$ = new(BoxedInteger) +set($p_{9}$, intval, $i_{8}$) +jump($L_1$, $p_{0}$, $p_{9}$) +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Final trace} +\begin{lstlisting}[mathescape] +$L_0$($p_{0}$, $p_{1}$): +guard_class($p_{1}$, BoxedInteger) +$i_{2}$ = get($p_{1}$, intval) +guard_class($p_{0}$, BoxedInteger) +$i_{3}$ = get($p_{0}$, intval) +$i_{4}$ = $i_{2}+i_{3}$ +jump($L_1$, $p_{0}$, $i_{4}$) + +$L_1$($p_{0}$, $i_{3}$, $i_{4}$): +$i_{8}$ = $i_{4}+i_{3}$ +jump($L_1$, $p_{0}$, $i_{3}$, $i_8$) +\end{lstlisting} +\end{frame} + + + +\begin{frame} + \frametitle{Results} + \begin{itemize} + \item a number of numeric kernels + \item some for image processing + \item some from SciMark + \item comparison against GCC and LuaJIT + \pause + \item geometric mean of speedups of loop peeling is 70\% + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Benchmark Results} + \includegraphics[width=0.7\textwidth,angle=90]{../benchmarks/result} +\end{frame} + +\begin{frame} + \frametitle{Conclusion} + \begin{itemize} + \item a simple preprocessing step on traces enables loop-aware optimizations for tracing JITs + \item no changes to the existing optimizations necessary + \end{itemize} +\end{frame} + + + +\begin{frame} \frametitle{Demo} \vfill \begin{itemize} From noreply at buildbot.pypy.org Mon Oct 22 22:01:09 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 22:01:09 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix unused code (but used by other people) Message-ID: <20121022200109.1897A1C0236@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58373:c3aabbc07075 Date: 2012-10-22 22:00 +0200 http://bitbucket.org/pypy/pypy/changeset/c3aabbc07075/ Log: Fix unused code (but used by other people) diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -204,7 +204,7 @@ # if a **kwargs argument is needed, create the dict w_kwds = None if signature.has_kwarg(): - w_kwds = self.space.newdict(kwargs=True) + w_kwds = self.space.newdict() scope_w[co_argcount + signature.has_vararg()] = w_kwds # handle keyword arguments From noreply at buildbot.pypy.org Mon Oct 22 22:13:38 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 22 Oct 2012 22:13:38 +0200 (CEST) Subject: [pypy-commit] pypy default: make it rather a fatal error Message-ID: <20121022201338.2CDC11C0236@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58374:536910e79306 Date: 2012-10-22 22:05 +0200 http://bitbucket.org/pypy/pypy/changeset/536910e79306/ Log: make it rather a fatal error diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -204,8 +204,7 @@ # if a **kwargs argument is needed, create the dict w_kwds = None if signature.has_kwarg(): - w_kwds = self.space.newdict() - scope_w[co_argcount + signature.has_vararg()] = w_kwds + raise TypeError("Keyword arguments as **kwargs is not supported by RPython") # handle keyword arguments num_remainingkwds = 0 From noreply at buildbot.pypy.org Mon Oct 22 23:09:07 2012 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 22 Oct 2012 23:09:07 +0200 (CEST) Subject: [pypy-commit] pypy default: Kill unneeded .make_arguments() and .argument_factory() Message-ID: <20121022210907.BF6091C01F9@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: Changeset: r58375:952cce31989d Date: 2012-10-22 22:08 +0100 http://bitbucket.org/pypy/pypy/changeset/952cce31989d/ Log: Kill unneeded .make_arguments() and .argument_factory() diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -977,8 +977,8 @@ keywords = None keywords_w = None arguments = self.popvalues(n_arguments) - args = self.argument_factory(arguments, keywords, keywords_w, w_star, - w_starstar) + args = ArgumentsForTranslation(self.space, arguments, keywords, + keywords_w, w_star, w_starstar) w_function = self.popvalue() w_result = self.space.call_args(w_function, args) self.pushvalue(w_result) @@ -1164,11 +1164,6 @@ LOAD_CLOSURE = BAD_OPCODE MAKE_CLOSURE = BAD_OPCODE - def make_arguments(self, nargs): - return ArgumentsForTranslation(self.space, self.peekvalues(nargs)) - def argument_factory(self, *args): - return ArgumentsForTranslation(self.space, *args) - ### Frame blocks ### class SuspendedUnroller(object): From noreply at buildbot.pypy.org Mon Oct 22 23:16:24 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 22 Oct 2012 23:16:24 +0200 (CEST) Subject: [pypy-commit] pypy default: test, fix for 'take' raising exception Message-ID: <20121022211624.471BD1C01F9@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r58376:c50358f493a3 Date: 2012-10-22 23:16 +0200 http://bitbucket.org/pypy/pypy/changeset/c50358f493a3/ Log: test, fix for 'take' raising exception 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 @@ -307,7 +307,8 @@ def descr_take(self, space, w_obj, w_axis=None, w_out=None): # if w_axis is None and w_out is Nont this is an equivalent to # fancy indexing - raise Exception("unsupported for now") + raise OperationError(space.w_NotImplementedError, + space.wrap("unsupported for now")) if not space.is_none(w_axis): raise OperationError(space.w_NotImplementedError, space.wrap("axis unsupported for take")) 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 @@ -1961,8 +1961,11 @@ assert (arange(6).reshape(2, 3).T.ravel() == [0, 3, 1, 4, 2, 5]).all() def test_take(self): - skip("we wait for int-based indexing") from _numpypy import arange + try: + arange(10).take([0]) + except NotImplementedError: + skip("we wait for int-based indexing") assert (arange(10).take([1, 2, 1, 1]) == [1, 2, 1, 1]).all() raises(IndexError, "arange(3).take([15])") a = arange(6).reshape(2, 3) From noreply at buildbot.pypy.org Tue Oct 23 11:58:40 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 23 Oct 2012 11:58:40 +0200 (CEST) Subject: [pypy-commit] pypy default: (arigo, fijal) Some simplifications, test and a fix on PyPy Message-ID: <20121023095840.868C21C04CF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58377:91acb9facc77 Date: 2012-10-23 11:56 +0200 http://bitbucket.org/pypy/pypy/changeset/91acb9facc77/ Log: (arigo, fijal) Some simplifications, test and a fix on PyPy diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -404,7 +404,10 @@ BUILTIN_ANALYZERS[unicodedata.decimal] = unicodedata_decimal # xxx # object - just ignore object.__init__ -BUILTIN_ANALYZERS[object.__init__] = object_init +if hasattr(object.__init__, 'im_func'): + BUILTIN_ANALYZERS[object.__init__.im_func] = object_init +else: + BUILTIN_ANALYZERS[object.__init__] = object_init # import BUILTIN_ANALYZERS[__import__] = import_func diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -3805,6 +3805,20 @@ s = a.build_types(f, [annmodel.SomeInteger()]) assert isinstance(s, annmodel.SomeBool) + def test_object_init(self): + class A(object): + pass + + class B(A): + def __init__(self): + A.__init__(self) + + def f(): + B() + + a = self.RPythonAnnotator() + a.build_types(f, []) # assert did not explode + def g(n): return [0,1,2,n] diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py --- a/pypy/objspace/flow/argument.py +++ b/pypy/objspace/flow/argument.py @@ -201,8 +201,7 @@ elif num_args > co_argcount: raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) - # if a **kwargs argument is needed, create the dict - w_kwds = None + # if a **kwargs argument is needed, explode if signature.has_kwarg(): raise TypeError("Keyword arguments as **kwargs is not supported by RPython") @@ -235,24 +234,10 @@ num_remainingkwds -= 1 if num_remainingkwds: - if w_kwds is not None: - # collect extra keyword arguments into the **kwarg - limit = len(keywords) - if self.keyword_names_w is not None: - limit -= len(self.keyword_names_w) - for i in range(len(keywords)): - if i in kwds_mapping: - continue - if i < limit: - w_key = self.space.wrap(keywords[i]) - else: - w_key = self.keyword_names_w[i - limit] - self.space.setitem(w_kwds, w_key, keywords_w[i]) - else: - if co_argcount == 0: - raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) - raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords, - kwds_mapping, self.keyword_names_w) + if co_argcount == 0: + raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) + raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords, + kwds_mapping, self.keyword_names_w) # check for missing arguments and fill them from the kwds, # or with defaults, if available diff --git a/pypy/objspace/flow/test/test_argument.py b/pypy/objspace/flow/test/test_argument.py --- a/pypy/objspace/flow/test/test_argument.py +++ b/pypy/objspace/flow/test/test_argument.py @@ -81,9 +81,7 @@ return [], [] return None, None - def newdict(self, kwargs=False): - if kwargs: - return kwargsdict() + def newdict(self): return {} def newlist(self, l=[]): @@ -199,31 +197,7 @@ args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() + py.test.raises(TypeError, args.match_signature, sig, [2, 3]) def test_rawshape(self): space = DummySpace() From noreply at buildbot.pypy.org Tue Oct 23 11:58:41 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 23 Oct 2012 11:58:41 +0200 (CEST) Subject: [pypy-commit] pypy default: merge Message-ID: <20121023095841.D39681C04CF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58378:5a092f4dfea7 Date: 2012-10-23 11:58 +0200 http://bitbucket.org/pypy/pypy/changeset/5a092f4dfea7/ Log: merge 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 @@ -307,7 +307,8 @@ def descr_take(self, space, w_obj, w_axis=None, w_out=None): # if w_axis is None and w_out is Nont this is an equivalent to # fancy indexing - raise Exception("unsupported for now") + raise OperationError(space.w_NotImplementedError, + space.wrap("unsupported for now")) if not space.is_none(w_axis): raise OperationError(space.w_NotImplementedError, space.wrap("axis unsupported for take")) 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 @@ -1961,8 +1961,11 @@ assert (arange(6).reshape(2, 3).T.ravel() == [0, 3, 1, 4, 2, 5]).all() def test_take(self): - skip("we wait for int-based indexing") from _numpypy import arange + try: + arange(10).take([0]) + except NotImplementedError: + skip("we wait for int-based indexing") assert (arange(10).take([1, 2, 1, 1]) == [1, 2, 1, 1]).all() raises(IndexError, "arange(3).take([15])") a = arange(6).reshape(2, 3) diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py --- a/pypy/objspace/flow/flowcontext.py +++ b/pypy/objspace/flow/flowcontext.py @@ -977,8 +977,8 @@ keywords = None keywords_w = None arguments = self.popvalues(n_arguments) - args = self.argument_factory(arguments, keywords, keywords_w, w_star, - w_starstar) + args = ArgumentsForTranslation(self.space, arguments, keywords, + keywords_w, w_star, w_starstar) w_function = self.popvalue() w_result = self.space.call_args(w_function, args) self.pushvalue(w_result) @@ -1164,11 +1164,6 @@ LOAD_CLOSURE = BAD_OPCODE MAKE_CLOSURE = BAD_OPCODE - def make_arguments(self, nargs): - return ArgumentsForTranslation(self.space, self.peekvalues(nargs)) - def argument_factory(self, *args): - return ArgumentsForTranslation(self.space, *args) - ### Frame blocks ### class SuspendedUnroller(object): From noreply at buildbot.pypy.org Tue Oct 23 12:17:09 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 23 Oct 2012 12:17:09 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: modify 2.0 planning Message-ID: <20121023101709.CE63E1C035C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4892:c365d27cf508 Date: 2012-10-23 12:14 +0200 http://bitbucket.org/pypy/extradoc/changeset/c365d27cf508/ Log: modify 2.0 planning diff --git a/planning/2.0/todo.txt b/planning/2.0/todo.txt --- a/planning/2.0/todo.txt +++ b/planning/2.0/todo.txt @@ -3,8 +3,11 @@ * Fix ctypes performnace for 2.0 beta * result-in-resop (maybe) +* continuelet-jit-3 * NumPy speed for 2.0 final * cffi on pypy on windows * raw malloc virtuals * bug tracker gardening + * 1292, 1090, 1294, 1282, 1289, 1282, 1286 + * numpy: 1143, 1160, 1287 * all green buildbots From noreply at buildbot.pypy.org Tue Oct 23 12:17:11 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 23 Oct 2012 12:17:11 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: (arigo, fijal) za sprint report Message-ID: <20121023101711.4160D1C035C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4893:6cc82be4f16e Date: 2012-10-23 12:14 +0200 http://bitbucket.org/pypy/extradoc/changeset/6cc82be4f16e/ Log: (arigo, fijal) za sprint report diff --git a/blog/draft/za-sprint-report.rst b/blog/draft/za-sprint-report.rst new file mode 100644 --- /dev/null +++ b/blog/draft/za-sprint-report.rst @@ -0,0 +1,70 @@ +Hello. + +We're about to finish a PyPy sprint in Cape Town, South Africa that was +one of the smallest done so far, only having Armin Rigo and Maciej Fijalkowski +with Alex Gaynor joining briefly at the beginning, however also one of the +longest, lasting almost 3 weeks. The sprint theme seems to be predominantly +"no new features" and "spring cleaning". We overall removed about 20k lines +of code in the PyPy source tree. The breakdown of things done and worked on: + +* We killed `SomeObject` support in annotation and rtyper. This is a modest + code saving, however, it reduces the complexity of RPython and also, + hopefully, improves compile errors from RPython. We're far from done + on the path to have comprehensible compile-time errors, but the first + step is always the hardest :) + +* We killed some magic in specifying the interface between builtin functions + and Python code. It used to be possible to write builtin functions like this:: + + def f(space, w_x='xyz'): + + which will magically wrap `'xyz'` into a W_StringObject. Right now, instead, + you have to write:: + + @unwrap_spec(w_x=WrappedDefault('xyz')) + def f(space, w_x): + + which is more verbose, but less magical. + +* We killed the `CExtModuleBuilder` which is the last remaining part of + infamous extension compiler that could in theory build C extensions + for CPython in RPython. This was never working very well and the main + part was killed long ago. + +* We killed various code duplications in the C backend. + +* We killed `microbench` and a bunch of other small-to-medium unused + directories. + +* We killed llgraph JIT backend and rewrote it from scratch. Now the llgraph + backend is not translatable, but this feature was rarely used and caused + a great deal of complexity. + +* We progressed on `continulet-jit-3` branch, up to the point of merging + it into `result-in-resops` branch, which also has seen a bit of progress. + + Purpose of those two branches: + + * `continulet-jit-3`: enable stackless to interact with the JIT by killing + global state while resuming from the JIT into the interpreter. This has + multiple benefits. For example it's one of the stones on the path to + enable STM for PyPy. It also opens new possibilities for other optimizations + including Python-Python calls and generators. + + * `result-in-resops`: the main goal is to speed up the tracing time of PyPy. + We found out the majority of time is spent in the optimizer chain, + which faces an almost complete rewrite. It also simplifies the storage + of the operations as well as the number of implicit invariants that have + to be kept in mind while developing. + +* We finished and merged the excellent work by Ronan Lamy which makes the + flow object space (used for abstract interpretation during RPython + compilation) independent from the Python interpreter. This means + we've achieved an important milestone on the path of separating the RPython + translation toolchain from the PyPy Python interpreter. + +Cheers, +fijal & armin + + + From noreply at buildbot.pypy.org Tue Oct 23 12:17:13 2012 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 23 Oct 2012 12:17:13 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: merge Message-ID: <20121023101713.91DB81C035C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4894:e9f03eaea811 Date: 2012-10-23 12:16 +0200 http://bitbucket.org/pypy/extradoc/changeset/e9f03eaea811/ Log: merge diff too long, truncating to 2000 out of 3827 lines diff --git a/talk/dls2012/demo/analytics.py b/talk/dls2012/demo/analytics.py --- a/talk/dls2012/demo/analytics.py +++ b/talk/dls2012/demo/analytics.py @@ -18,3 +18,4 @@ #view(self.background.image) #view(255 * fg) + diff --git a/talk/dls2012/demo/demo.py b/talk/dls2012/demo/demo.py --- a/talk/dls2012/demo/demo.py +++ b/talk/dls2012/demo/demo.py @@ -38,14 +38,20 @@ def __del__(self): self.close() + +class SkipToEnd(Exception): + pass + def pause(msg=''): print "\n" print msg - raw_input('Press ENTER\n') + res = raw_input('Press ENTER (s)\n') + if res == 's': + raise SkipToEnd def demo(skip1=False): - if not skip1: - with open('analytics.py', 'w') as fd: + with open('analytics.py', 'w') as fd: + if not skip1: print >>fd, """ from reloader import ReloadHack from io import view @@ -54,14 +60,45 @@ def update(self, frame): view(frame) """ + else: + print >>fd, """ +from reloader import ReloadHack +from io import view +from background import Background +from foreground import foreground +from detect import find_objects + +class Tracker(ReloadHack): + def __init__(self): + self.background = Background() + + def update(self, frame): + self.background.update(frame) + fg = foreground(frame, self.background.image) + find_objects(fg) + #view(self.background.image) + view(255 * fg) + +""" + + vim = Vim('analytics.py') + time.sleep(0.1) + vim.send(':winpos 0 30:winsize 75 30') + time.sleep(0.5) runner = Popen([sys.executable, 'run.py', 'demo.avi']) - vim = Vim('analytics.py') - if not skip1: - part1(vim) - part2(vim, skip1) + try: + if not skip1: + part1(vim) + part2(vim, skip1) + except SkipToEnd: + os.system('hg revert analytics.py background.py detect.py foreground.py') + pause("New lets compare this with cpython.") + runner2 = Popen(["python", 'run.py', 'demo.avi']) + pause("That's all! Feel free to make your own adjustments or (to quit),") runner.kill() + runner2.kill() vim.close() def part1(vim): @@ -171,7 +208,7 @@ pause("That's a bit slow, but this operation is separable, let's see\n"+ "if it is faster with two passes.") vim.send(':e detect.py') - vim.type('7ggix9ggixjddOfor dx in xrange(-r, r+1):') + vim.type('7ggix9ggixjddkofor dx in xrange(-r, r+1):') vim.type('11ggix9wix13wxxx', 0.2) vim.type('VkkkkyP5jx', 0.2) vim.type('14ggx7wcwxres') @@ -211,15 +248,15 @@ vim.type('51ggA.labels:w') pause("It still seems to work as before. Now lets add the second pass") - vim.type('Ofor x, y in reversed(seg.indexes()):if seg[x, y]:ll = [labels[x, y], labels[x+1, y], labels[x-1, y+1],labels[x, y+1], labels[x+1, y+1]]labels.update(x, y, ll):w', 0.01) + vim.type('OjOfor x, y in reversed(seg.indexes()):if seg[x, y]:ll = [labels[x, y], labels[x+1, y], labels[x-1, y+1],labels[x, y+1], labels[x+1, y+1]]labels.update(x, y, ll):w', 0.01) pause("That's starting to look good, but in complicated cases we can still\n" + "get multiple lables per segment, so we need to repeat until convergance") vim.type('56ggVkkkkkkkkkk', 0.2) vim.send('>') - vim.type('Owhile not labels.done:labels.done = True') + vim.type('kowhile not labels.done:labels.done = True') vim.type('28ggoself.done = False') - vim.type('43gg39ggOif self.labels[x, y] != l:self.done = False:w') + vim.type('43gg39ggIkaif self.labels[x, y] != l:self.done = False:w') pause("As a final touch, lets renumber the labels be consecutative\n" + "integers.") @@ -227,7 +264,7 @@ vim.type('44ggodef renumber(self):ll = list(set(self.labels))ll.sort()if ll[0] != 0:ll.insert(0, 0)for x, y in self.labels.indexes():self.labels[x, y] = ll.index(self.labels[x, y])self.last_label = len(ll) - 1:w', 0.01) pause("Now, lets find a boudningbox for each segment,") - vim.type("G75ggOclass BoundingBox(object):def __init__(self):self.maxx = self.maxy = float('-Inf')self.minx = self.miny = float('Inf')def add(self, x, y):self.maxx = max(self.maxx, x)self.maxy = max(self.maxy, y)self.minx = min(self.minx, x)self.miny = min(self.miny, y)def extract_boxes(labels):boxes = [BoundingBox() for i in xrange(max(labels))]for x, y in labels.indexes():l = labels[x, y]if l:boxes[int(l-1)].add(x, y)return boxes", 0.01) + vim.type("G75ggOclass BoundingBox(object):def __init__(self):self.maxx = self.maxy = float('-Inf')self.minx = self.miny = float('Inf')def add(self, x, y):self.maxx = max(self.maxx, x)self.maxy = max(self.maxy, y)self.minx = min(self.minx, x)self.miny = min(self.miny, y)def extract_boxes(labels):boxes = [BoundingBox() for i in xrange(int(max(labels)))]for x, y in labels.indexes():l = labels[x, y]if l:boxes[int(l-1)].add(x, y)return boxes", 0.01) vim.type("G98ggOboxes = extract_boxes(labels):w", 0.01) pause("and draw that boudning box.") @@ -246,7 +283,6 @@ vim.send('>=') vim.type(' minarea]:w', 0.01) - pause("That's all! Feel free to make your own adjustments or (to quit),") if __name__ == '__main__': diff --git a/talk/dls2012/demo/detect.py b/talk/dls2012/demo/detect.py --- a/talk/dls2012/demo/detect.py +++ b/talk/dls2012/demo/detect.py @@ -97,7 +97,7 @@ def extract_boxes(labels): - boxes = [BoundingBox() for i in xrange(max(labels))] + boxes = [BoundingBox() for i in xrange(int(max(labels)))] for x, y in labels.indexes(): l = labels[x, y] if l: diff --git a/talk/dls2012/demo/io.py b/talk/dls2012/demo/io.py --- a/talk/dls2012/demo/io.py +++ b/talk/dls2012/demo/io.py @@ -47,7 +47,7 @@ img = out if not self.width: w, h = img.width, img.height - self.mplayer = Popen(['mplayer', '-', '-benchmark', + self.mplayer = Popen(['mplayer', '-', '-fps', '200', #'-benchmark', '-demuxer', 'rawvideo', '-rawvideo', 'w=%d:h=%d:format=y8' % (w, h), '-really-quiet'], diff --git a/talk/dls2012/presentation/figures/all_numbers.png b/talk/dls2012/presentation/figures/all_numbers.png new file mode 100644 index 0000000000000000000000000000000000000000..9076ac193fc9ba1954e24e2ae372ec7e1e1f44e6 GIT binary patch [cut] diff --git a/talk/dls2012/presentation/figures/optimization.svg b/talk/dls2012/presentation/figures/optimization.svg new file mode 100644 --- /dev/null +++ b/talk/dls2012/presentation/figures/optimization.svg @@ -0,0 +1,1136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + w + + + 0 + + + = + + + a + + + 0 + + + +0 + + + x + + + 0 + + + = + + + w + + + 0 + + + +1 + + + y + + + 0 + + + = + + + a + + + 0 + + + +1 + + + z + + + 0 + + + = + + + x + + + 0 + + + + + + + y + + + 0 + + + ... + jump( + + + L + + + 0 + + + , + + + z + + + 0 + + + , + + + b + + + 0 + + + ) + + + + rename to + + + + + + + w + + + 0 + + + a + + + 0 + + + + + + + + in + + + + + a + + + 0 + + + a + + + 0 + + + +1 + + + x + + + 0 + + + + + + + + + rename to + + y + + + 0 + + + x + + + 0 + + + + + + + + in + + + + + + x + + + 0 + + + + x + + + 0 + + + + + + + x + + + 0 + + + z + + + 0 + + + z + + + 0 + + + diff --git a/talk/dls2012/presentation/figures/optimization1.pdf b/talk/dls2012/presentation/figures/optimization1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8afc9f635e2741be5eaf57ba24f0312ba7ff47c7 GIT binary patch [cut] diff --git a/talk/dls2012/presentation/figures/optimization2.pdf b/talk/dls2012/presentation/figures/optimization2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..731ac4f40e6be34d86ff877220d45d38c4c557ff GIT binary patch [cut] diff --git a/talk/dls2012/presentation/figures/optimization3.pdf b/talk/dls2012/presentation/figures/optimization3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7270c4e32f441c75d40fd32170199a0b84745a8d GIT binary patch [cut] diff --git a/talk/dls2012/presentation/figures/optimization4.pdf b/talk/dls2012/presentation/figures/optimization4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3b913c841d2471be913feecf3e5d339cf97ad310 GIT binary patch [cut] diff --git a/talk/dls2012/presentation/figures/optimization5.pdf b/talk/dls2012/presentation/figures/optimization5.pdf new file mode 100644 index 0000000000000000000000000000000000000000..695e997cbb19b1796ccd9387606396fea3f183ab GIT binary patch [cut] diff --git a/talk/dls2012/presentation/talk.tex b/talk/dls2012/presentation/talk.tex --- a/talk/dls2012/presentation/talk.tex +++ b/talk/dls2012/presentation/talk.tex @@ -17,11 +17,32 @@ \usepackage[english]{babel} +\usepackage{fancyvrb} \usepackage{listings} \usepackage{ulem} \usepackage{color} \usepackage{alltt} + +\usepackage[T1]{fontenc} +\usepackage{setspace} +\usepackage[scaled=0.81]{beramono} +\definecolor{gray}{rgb}{0.3,0.3,0.3} + +\lstset{ + basicstyle=\setstretch{1.05}\ttfamily\footnotesize, + language=Python, + keywordstyle=\bfseries, + stringstyle=\color{blue}, + commentstyle=\color{gray}\textit, + fancyvrb=true, + showstringspaces=false, + %keywords={def,while,if,elif,return,class,get,set,new,guard_class} + numberstyle = \tiny, + numbersep = -20pt, +} + + \usepackage[utf8x]{inputenc} @@ -35,7 +56,7 @@ \title{Loop-Aware Optimizations in PyPy’s Tracing JIT} -\author[Ardö, Bolz, Fijałkowski]{Håkan Ardö$^1$ \and \emph{Carl Friedrich Bolz}$^2$ \and Maciej Fijałkowski} +\author[Ardö, Bolz, Fijałkowski]{\emph{Håkan Ardö}$^1$ \and \emph{Carl Friedrich Bolz}$^2$ \and Maciej Fijałkowski} % - Give the names in the same order as the appear in the paper. % - Use the \inst{?} command only if the authors have different % affiliation. @@ -82,11 +103,36 @@ \end{frame} \begin{frame} + \frametitle{RPython and PyPy} + \begin{itemize} + \item Context: RPython + \item a language for writing interpreters for dynamic languages + \item a generic tracing JIT, applicable to many languages + \item used to implement PyPy, an efficient Python interpreter + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{How fast is PyPy?} + \includegraphics[scale=0.3]{figures/all_numbers.png} +\end{frame} + +\begin{frame} + \frametitle{Tracing JITs Compile by Observing an Interpreter} + \begin{itemize} + \item VM contains both an interpreter and the tracing JIT compiler + \item JIT works by observing and logging what the interpreter does + \item for interesting, commonly executed code paths + \item produces a linear list of operations (trace) + \end{itemize} +\end{frame} + +\begin{frame} \frametitle{Why do tracing JITs work?} \begin{itemize} \item They are good at selecting interesting and common code paths - \item both through user program and through the runtime - \item the latter is particularly important for dynamic languages + \item both through the user program and through the runtime + \item the latter is particularly important for dynamic languages with a big runtime like Python \pause \item traces are trivial to optimize \end{itemize} @@ -95,15 +141,21 @@ \begin{frame} \frametitle{Optimizing traces} \begin{itemize} - \item Traces trivial to optimize, because there's no control flow + \item A trace is an extended basic block + \item (it has one entry and several exits) + \item traces are easy to optime due to lack of control flow merges \item most optimizations are one forward pass \item optimizers are often like symbolic executors - \item can do optimizations that are untractable with full control flow - \item XXX example + \item can do optimizations that are expensive or even untractable with full control flow \end{itemize} \end{frame} \begin{frame} + \frametitle{Example} +\end{frame} + + +\begin{frame} \frametitle{Problems with this approach} \begin{itemize} \item most traces actually are loops @@ -125,6 +177,7 @@ \item apply the unchanged forward-pass optimizations \item do some post-processing \item pre-processing is done in such a way that the normal optimizations become loop-aware + \pause \item intuition: give the optimizations a second iteration of context to work with \end{itemize} \end{block} @@ -140,5 +193,282 @@ \end{itemize} \end{frame} +\begin{frame} + \frametitle{Loop Peeling} +\begin{center} +\includegraphics[width=\columnwidth]{../figures/overview} +\end{center} +\end{frame} + + +\begin{frame}[fragile] + \frametitle{Loop Peeling} + \begin{columns} + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_0$, $i_0$) + $$ + $$ + $$ + $$ + $$ + \end{lstlisting} + \end{column} + \pause + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_1$, $i_0$) + + $L_1$($i_{0}$): + $i_2$ = $i_0$ + 1 + print($i_2$) + jump($L_1$, $i_0$) + \end{lstlisting} + \end{column} + \end{columns} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Apply Optimizations} + \begin{columns} + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_1$, $i_0$) + + $L_1$($i_{0}$): + $i_2$ = $i_0$ + 1 + print($i_2$) + jump($L_1$, $i_0$) + \end{lstlisting} + \end{column} + \pause + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_1$, $i_0$) + + $L_1$($i_{0}$): + print($i_1$) + jump($L_1$, $i_0$) + \end{lstlisting} + \end{column} + \end{columns} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Add extra arguments} + \begin{columns} + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_1$, $i_0$) + + $L_1$($i_{0}$): + print($i_1$) + jump($L_1$, $i_0$) + \end{lstlisting} + \end{column} + \pause + \begin{column}{0.5\textwidth} + \centering + \begin{lstlisting}[mathescape]%,numbers = right,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] + abc + $L_0$($i_{0}$): + $i_1$ = $i_0$ + 1 + print($i_1$) + jump($L_1$, $i_0$, $i_1$) + + $L_1$($i_{0}$, $i_1$): + print($i_1$) + jump($L_1$, $i_0$, $i_1$) + \end{lstlisting} + \end{column} + \end{columns} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Larger example} + \begin{columns} + \begin{column}{0.5\textwidth} + \begin{lstlisting} + while True: + y = y + 1 + \end{lstlisting} + \end{column} + \pause + \begin{column}{0.5\textwidth} +\begin{lstlisting}[mathescape] +$L_0$($p_{0}$, $p_{1}$): +guard_class($p_{1}$, BoxedInteger) +$i_{2}$ = get($p_{1}$, intval) +guard_class($p_{0}$, BoxedInteger) +$i_{3}$ = get($p_{0}$, intval) +$i_{4}$ = $i_{2} + i_{3}$ +$p_{5}$ = new(BoxedInteger) +set($p_{5}$, intval, $i_{4}$) +jump($L_0$, $p_{0}$, $p_{5}$) +\end{lstlisting} + \end{column} + \end{columns} +\end{frame} + + +\begin{frame}[fragile] + \frametitle{Peeled trace} +\begin{lstlisting}[mathescape] +$L_0$($p_{0}$, $p_{1}$): +guard_class($p_{1}$, BoxedInteger) +$i_{2}$ = get($p_{1}$, intval) +guard_class($p_{0}$, BoxedInteger) +$i_{3}$ = get($p_{0}$, intval) +$i_{4}$ = $i_{2}+i_{3}$ +$p_{5}$ = new(BoxedInteger) +set($p_{5}$, intval, $i_{4}$) +jump($L_1$, $p_{0}$, $p_{5}$) + +$L_1$($p_{0}$, $p_{5}$): +guard_class($p_{5}$, BoxedInteger) +$i_{6}$ = get($p_{5}$, intval) +guard_class($p_{0}$, BoxedInteger) +$i_{7}$ = get($p_{0}$, intval) +$i_{8}$ = $i_{6}+i_{7}$ +$p_{9}$ = new(BoxedInteger) +set($p_{9}$, intval, $i_{8}$) +jump($L_1$, $p_{0}$, $p_{9}$) +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Final trace} +\begin{lstlisting}[mathescape] +$L_0$($p_{0}$, $p_{1}$): +guard_class($p_{1}$, BoxedInteger) +$i_{2}$ = get($p_{1}$, intval) +guard_class($p_{0}$, BoxedInteger) +$i_{3}$ = get($p_{0}$, intval) +$i_{4}$ = $i_{2}+i_{3}$ +jump($L_1$, $p_{0}$, $i_{4}$) + +$L_1$($p_{0}$, $i_{3}$, $i_{4}$): +$i_{8}$ = $i_{4}+i_{3}$ +jump($L_1$, $p_{0}$, $i_{3}$, $i_8$) +\end{lstlisting} +\end{frame} + + + +\begin{frame} + \frametitle{Results} + \begin{itemize} + \item a number of numeric kernels + \item some for image processing + \item some from SciMark + \item comparison against GCC and LuaJIT + \pause + \item geometric mean of speedups of loop peeling is 70\% + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Benchmark Results} + \includegraphics[width=0.7\textwidth,angle=90]{../benchmarks/result} +\end{frame} + +\begin{frame} + \frametitle{Conclusion} + \begin{itemize} + \item a simple preprocessing step on traces enables loop-aware optimizations for tracing JITs + \item no changes to the existing optimizations necessary + \end{itemize} +\end{frame} + + + +\begin{frame} + \frametitle{Demo} + \vfill + \begin{itemize} + \item Video analytics research example + \item Experimenten driven - prototyping + \item Custom loops over the pixels + \item Good enough performace + \end{itemize} + \vfill + \begin{itemize} + \item Image class with task specific features + \begin{itemize} + \item Zero-padded + \item Clips updates outside border + \end{itemize} + \item @autoreload decorator reloading functions on code change + \item ReloadHack class reloads and reinstanciates on code change + \end{itemize} + \vfill +\end{frame} + +\begin{frame}[fragile] + \frametitle{Image class} +\begin{lstlisting}[mathescape,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] +class Image(object): + def __getitem__(self, (x, y)): + if 0 <= x < self.width and 0 <= y < self.height: + return self.data[y * self.width + x] + return 0 + + def __setitem__(self, (x, y), value): + if 0 <= x < self.width and 0 <= y < self.height: + self.data[y * self.width + x] = value + + __add__ = binop(float.__add__) + __sub__ = binop(float.__sub__) + __mul__ = binop(float.__mul__) + __div__ = binop(float.__div__) + __pow__ = binop(float.__pow__) + + ... +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] + \frametitle{Image class} +\begin{lstlisting}[mathescape,basicstyle=\setstretch{1.05}\ttfamily\scriptsize] +def binop(op): + def f(a, b): + if not isinstance(a, Image): + a = ConstantImage(b.width, b.height, a) + if not isinstance(b, Image): + b = ConstantImage(a.width, a.height, b) + + out = a.new(typecode='d') + for x, y in a.indexes(): + out[x, y] = op(float(a[x, y]), float(b[x, y])) + + return out + return f +\end{lstlisting} +\end{frame} \end{document} diff --git a/talk/vmil2012/presentation/Makefile b/talk/vmil2012/presentation/Makefile --- a/talk/vmil2012/presentation/Makefile +++ b/talk/vmil2012/presentation/Makefile @@ -1,4 +1,4 @@ -talk.pdf: talk.tex figures/data.tex figures/go_data.tex tool/data.py +talk.pdf: talk.tex figures/data.tex figures/go_data.tex tool/data.py figures/*.pdf figures/*.graffle pdflatex talk.tex &> /dev/null UNAME := $(shell "uname") diff --git a/talk/vmil2012/presentation/bolz-vmil-guards-talk.pdf b/talk/vmil2012/presentation/bolz-vmil-guards-talk.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0dc1e6fc97efe3b5904d8e11578eb19e3cc6494a GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/charts.ods b/talk/vmil2012/presentation/charts.ods index 94300512c367f6ea2553953adde39281e950b27c..4fd468078b9b08ae1d44cfec04c3a39495a85945 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/all_numbers.png b/talk/vmil2012/presentation/figures/all_numbers.png new file mode 100644 index 0000000000000000000000000000000000000000..9076ac193fc9ba1954e24e2ae372ec7e1e1f44e6 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/data.tex b/talk/vmil2012/presentation/figures/data.tex --- a/talk/vmil2012/presentation/figures/data.tex +++ b/talk/vmil2012/presentation/figures/data.tex @@ -3,51 +3,51 @@ (0.000000,1.000000) (0.006494,0.148545) (0.012987,0.143156) (0.019481,0.074262) (0.025974,0.070332) (0.032468,0.047160) (0.038961,0.046744) (0.045455,0.041526) (0.051948,0.032187) (0.058442,0.027040) (0.064935,0.020597) (0.071429,0.018534) (0.077922,0.017118) (0.084416,0.016888) (0.090909,0.011212) (0.097403,0.009493) (0.103896,0.007359) (0.110390,0.007268) (0.116883,0.006596) (0.123377,0.005563) (0.129870,0.005529) (0.136364,0.005470) (0.142857,0.003591) (0.149351,0.002948) (0.155844,0.002945) (0.162338,0.002749) (0.168831,0.002558) (0.175325,0.001651) (0.181818,0.001644) (0.188312,0.001592) (0.194805,0.001582) (0.201299,0.001365) (0.207792,0.001362) (0.214286,0.000933) (0.220779,0.000887) (0.227273,0.000871) (0.233766,0.000863) (0.240260,0.000843) (0.246753,0.000726) (0.253247,0.000695) (0.259740,0.000594) (0.266234,0.000558) (0.272727,0.000534) (0.279221,0.000498) (0.285714,0.000389) (0.292208,0.000389) (0.298701,0.000382) (0.305195,0.000381) (0.311688,0.000376) (0.318182,0.000364) (0.324675,0.000340) (0.331169,0.000312) (0.337662,0.000237) (0.344156,0.000219) (0.350649,0.000204) (0.357143,0.000202) (0.363636,0.000202) (0.370130,0.000193) (0.376623,0.000174) (0.383117,0.000162) (0.389610,0.000139) (0.396104,0.000137) (0.402597,0.000135) (0.409091,0.000130) (0.415584,0.000130) (0.422078,0.000122) (0.428571,0.000119) (0.435065,0.000104) (0.441558,0.000101) (0.448052,0.000097) (0.454545,0.000087) (0.461039,0.000079) (0.467532,0.000069) (0.474026,0.000058) (0.480519,0.000051) (0.487013,0.000041) (0.493506,0.000040) (0.500000,0.000035) (0.506494,0.000029) (0.512987,0.000028) (0.519481,0.000028) (0.525974,0.000027) (0.532468,0.000026) (0.538961,0.000026) (0.545455,0.000024) (0.551948,0.000021) (0.558442,0.000018) (0.564935,0.000018) (0.571429,0.000017) (0.577922,0.000016) (0.584416,0.000015) (0.590909,0.000015) (0.597403,0.000014) (0.603896,0.000014) (0.610390,0.000011) (0.616883,0.000011) (0.623377,0.000011) (0.629870,0.000011) (0.636364,0.000011) (0.642857,0.000011) (0.649351,0.000011) (0.655844,0.000011) (0.662338,0.000010) (0.668831,0.000009) (0.675325,0.000007) (0.681818,0.000007) (0.688312,0.000007) (0.694805,0.000007) (0.701299,0.000007) (0.707792,0.000006) (0.714286,0.000006) (0.720779,0.000005) (0.727273,0.000005) (0.733766,0.000005) (0.740260,0.000005) (0.746753,0.000004) (0.753247,0.000004) (0.759740,0.000003) (0.766234,0.000003) (0.772727,0.000003) (0.779221,0.000003) (0.785714,0.000002) (0.792208,0.000002) (0.798701,0.000002) (0.805195,0.000002) (0.811688,0.000002) (0.818182,0.000002) (0.824675,0.000002) (0.831169,0.000002) (0.837662,0.000002) (0.844156,0.000002) (0.850649,0.000002) (0.857143,0.000002) (0.863636,0.000002) (0.870130,0.000001) (0.876623,0.000001) (0.883117,0.000001) (0.889610,0.000001) (0.896104,0.000001) (0.902597,0.000001) (0.909091,0.000001) (0.915584,0.000001) (0.922078,0.000001) (0.928571,0.000001) (0.935065,0.000001) (0.941558,0.000001) (0.948052,0.000000) (0.954545,0.000000) (0.961039,0.000000) (0.967532,0.000000) (0.974026,0.000000) (0.980519,0.000000) (0.987013,0.000000) (0.993506,0.000000) (1.000000,0.000000) }; \addplot[red,only marks,mark=*] coordinates {(0.006494,0.148545) (0.201299,0.001365) (0.415584,0.000130)}; -\addplot[green,only marks,mark=*] coordinates {(0.060976,0.459611) (0.524390,0.006634) (0.756098,0.001243)}; \addplot[green,mark=none] coordinates { (0.000000,1.000000) (0.012195,0.997326) (0.024390,0.701335) (0.036585,0.503352) (0.048780,0.496172) (0.060976,0.459611) (0.073171,0.381570) (0.085366,0.349645) (0.097561,0.315892) (0.109756,0.312117) (0.121951,0.242322) (0.134146,0.213275) (0.146341,0.186336) (0.158537,0.114441) (0.170732,0.077514) (0.182927,0.054374) (0.195122,0.047764) (0.207317,0.043576) (0.219512,0.039644) (0.231707,0.029204) (0.243902,0.029145) (0.256098,0.027214) (0.268293,0.023030) (0.280488,0.016877) (0.292683,0.016283) (0.304878,0.015489) (0.317073,0.014624) (0.329268,0.014572) (0.341463,0.014451) (0.353659,0.009960) (0.365854,0.009811) (0.378049,0.009299) (0.390244,0.009197) (0.402439,0.009182) (0.414634,0.009178) (0.426829,0.007813) (0.439024,0.007797) (0.451220,0.007786) (0.463415,0.007715) (0.475610,0.007381) (0.487805,0.007172) (0.500000,0.006791) (0.512195,0.006783) (0.524390,0.006634) (0.536585,0.006366) (0.548780,0.005879) (0.560976,0.004203) (0.573171,0.004074) (0.585366,0.003983) (0.597561,0.003260) (0.609756,0.003252) (0.621951,0.003181) (0.634146,0.002945) (0.646341,0.002670) (0.658537,0.002399) (0.670732,0.002159) (0.682927,0.002143) (0.695122,0.001817) (0.707317,0.001793) (0.719512,0.001785) (0.731707,0.001577) (0.743902,0.001573) (0.756098,0.001243) (0.768293,0.001073) (0.780488,0.000598) (0.792683,0.000590) (0.804878,0.000492) (0.817073,0.000440) (0.829268,0.000240) (0.841463,0.000201) (0.853659,0.000201) (0.865854,0.000197) (0.878049,0.000177) (0.890244,0.000079) (0.902439,0.000079) (0.914634,0.000067) (0.926829,0.000031) (0.939024,0.000028) (0.951220,0.000024) (0.963415,0.000012) (0.975610,0.000008) (0.987805,0.000004) (1.000000,0.000004) }; -\addplot[blue,only marks,mark=*] coordinates {(0.045045,0.253942) (0.378378,0.003324) (0.585586,0.000480)}; +\addplot[green,only marks,mark=*] coordinates {(0.060976,0.459611) (0.524390,0.006634) (0.756098,0.001243)}; \addplot[blue,mark=none] coordinates { (0.000000,1.000000) (0.009009,0.274799) (0.018018,0.254401) (0.027027,0.254401) (0.036036,0.254400) (0.045045,0.253942) (0.054054,0.176493) (0.063063,0.170575) (0.072072,0.170575) (0.081081,0.166477) (0.090090,0.103439) (0.099099,0.087880) (0.108108,0.085545) (0.117117,0.085441) (0.126126,0.077913) (0.135135,0.075639) (0.144144,0.059419) (0.153153,0.052926) (0.162162,0.051446) (0.171171,0.040551) (0.180180,0.036356) (0.189189,0.031443) (0.198198,0.026162) (0.207207,0.023960) (0.216216,0.020391) (0.225225,0.018926) (0.234234,0.018265) (0.243243,0.018091) (0.252252,0.018011) (0.261261,0.015999) (0.270270,0.011937) (0.279279,0.010101) (0.288288,0.010101) (0.297297,0.009964) (0.306306,0.009956) (0.315315,0.009498) (0.324324,0.006923) (0.333333,0.006919) (0.342342,0.005088) (0.351351,0.004699) (0.360360,0.004400) (0.369369,0.004132) (0.378378,0.003324) (0.387387,0.003266) (0.396396,0.003017) (0.405405,0.002900) (0.414414,0.002389) (0.423423,0.001747) (0.432432,0.001717) (0.441441,0.001660) (0.450450,0.001634) (0.459459,0.001542) (0.468468,0.001353) (0.477477,0.001264) (0.486486,0.001263) (0.495495,0.001131) (0.504505,0.001046) (0.513514,0.000934) (0.522523,0.000928) (0.531532,0.000856) (0.540541,0.000850) (0.549550,0.000821) (0.558559,0.000745) (0.567568,0.000679) (0.576577,0.000581) (0.585586,0.000480) (0.594595,0.000316) (0.603604,0.000260) (0.612613,0.000256) (0.621622,0.000209) (0.630631,0.000195) (0.639640,0.000163) (0.648649,0.000161) (0.657658,0.000145) (0.666667,0.000136) (0.675676,0.000134) (0.684685,0.000128) (0.693694,0.000123) (0.702703,0.000117) (0.711712,0.000100) (0.720721,0.000099) (0.729730,0.000095) (0.738739,0.000088) (0.747748,0.000087) (0.756757,0.000065) (0.765766,0.000058) (0.774775,0.000052) (0.783784,0.000051) (0.792793,0.000045) (0.801802,0.000043) (0.810811,0.000033) (0.819820,0.000031) (0.828829,0.000028) (0.837838,0.000023) (0.846847,0.000019) (0.855856,0.000018) (0.864865,0.000017) (0.873874,0.000017) (0.882883,0.000016) (0.891892,0.000016) (0.900901,0.000016) (0.909910,0.000016) (0.918919,0.000015) (0.927928,0.000015) (0.936937,0.000012) (0.945946,0.000011) (0.954955,0.000009) (0.963964,0.000006) (0.972973,0.000005) (0.981982,0.000003) (0.990991,0.000001) (1.000000,0.000000) }; -\addplot[cyan,only marks,mark=*] coordinates {(0.040541,0.223088) (0.328829,0.004749) (0.563063,0.000352)}; +\addplot[blue,only marks,mark=*] coordinates {(0.045045,0.253942) (0.378378,0.003324) (0.585586,0.000480)}; \addplot[cyan,mark=none] coordinates { (0.000000,1.000000) (0.004505,0.536162) (0.009009,0.533859) (0.013514,0.483711) (0.018018,0.468958) (0.022523,0.385926) (0.027027,0.368855) (0.031532,0.330881) (0.036036,0.273385) (0.040541,0.223088) (0.045045,0.201529) (0.049550,0.188300) (0.054054,0.184877) (0.058559,0.165360) (0.063063,0.160965) (0.067568,0.151293) (0.072072,0.125402) (0.076577,0.121903) (0.081081,0.121395) (0.085586,0.117212) (0.090090,0.117117) (0.094595,0.099425) (0.099099,0.096936) (0.103604,0.096847) (0.108108,0.096552) (0.112613,0.096421) (0.117117,0.083108) (0.121622,0.076876) (0.126126,0.068604) (0.130631,0.064969) (0.135135,0.056385) (0.139640,0.056383) (0.144144,0.049812) (0.148649,0.049576) (0.153153,0.042719) (0.157658,0.042151) (0.162162,0.038817) (0.166667,0.038467) (0.171171,0.038437) (0.175676,0.038161) (0.180180,0.037712) (0.184685,0.037469) (0.189189,0.037434) (0.193694,0.037419) (0.198198,0.037035) (0.202703,0.037000) (0.207207,0.036987) (0.211712,0.035969) (0.216216,0.034370) (0.220721,0.033375) (0.225225,0.031819) (0.229730,0.031613) (0.234234,0.029056) (0.238739,0.028685) (0.243243,0.026102) (0.247748,0.023276) (0.252252,0.018629) (0.256757,0.018545) (0.261261,0.015560) (0.265766,0.013442) (0.270270,0.013322) (0.274775,0.011983) (0.279279,0.011599) (0.283784,0.008508) (0.288288,0.008463) (0.292793,0.008461) (0.297297,0.008456) (0.301802,0.007547) (0.306306,0.007021) (0.310811,0.006568) (0.315315,0.006344) (0.319820,0.005826) (0.324324,0.004751) (0.328829,0.004749) (0.333333,0.004749) (0.337838,0.003794) (0.342342,0.003082) (0.346847,0.002806) (0.351351,0.002767) (0.355856,0.002535) (0.360360,0.002472) (0.364865,0.002390) (0.369369,0.002320) (0.373874,0.002290) (0.378378,0.002275) (0.382883,0.002210) (0.387387,0.002049) (0.391892,0.001854) (0.396396,0.001647) (0.400901,0.001502) (0.405405,0.001322) (0.409910,0.001200) (0.414414,0.001161) (0.418919,0.001159) (0.423423,0.001146) (0.427928,0.001144) (0.432432,0.001116) (0.436937,0.001066) (0.441441,0.001059) (0.445946,0.001018) (0.450450,0.000873) (0.454955,0.000864) (0.459459,0.000840) (0.463964,0.000777) (0.468468,0.000766) (0.472973,0.000747) (0.477477,0.000729) (0.481982,0.000729) (0.486486,0.000621) (0.490991,0.000597) (0.495495,0.000590) (0.500000,0.000582) (0.504505,0.000577) (0.509009,0.000562) (0.513514,0.000558) (0.518018,0.000523) (0.522523,0.000478) (0.527027,0.000469) (0.531532,0.000456) (0.536036,0.000434) (0.540541,0.000432) (0.545045,0.000425) (0.549550,0.000425) (0.554054,0.000417) (0.558559,0.000412) (0.563063,0.000352) (0.567568,0.000332) (0.572072,0.000330) (0.576577,0.000326) (0.581081,0.000313) (0.585586,0.000289) (0.590090,0.000267) (0.594595,0.000247) (0.599099,0.000247) (0.603604,0.000217) (0.608108,0.000204) (0.612613,0.000195) (0.617117,0.000182) (0.621622,0.000165) (0.626126,0.000165) (0.630631,0.000163) (0.635135,0.000137) (0.639640,0.000137) (0.644144,0.000132) (0.648649,0.000130) (0.653153,0.000130) (0.657658,0.000122) (0.662162,0.000122) (0.666667,0.000122) (0.671171,0.000119) (0.675676,0.000115) (0.680180,0.000104) (0.684685,0.000104) (0.689189,0.000100) (0.693694,0.000096) (0.698198,0.000093) (0.702703,0.000087) (0.707207,0.000087) (0.711712,0.000087) (0.716216,0.000085) (0.720721,0.000085) (0.725225,0.000078) (0.729730,0.000074) (0.734234,0.000063) (0.738739,0.000059) (0.743243,0.000059) (0.747748,0.000059) (0.752252,0.000056) (0.756757,0.000056) (0.761261,0.000056) (0.765766,0.000054) (0.770270,0.000052) (0.774775,0.000052) (0.779279,0.000048) (0.783784,0.000046) (0.788288,0.000043) (0.792793,0.000041) (0.797297,0.000039) (0.801802,0.000039) (0.806306,0.000037) (0.810811,0.000037) (0.815315,0.000035) (0.819820,0.000035) (0.824324,0.000035) (0.828829,0.000033) (0.833333,0.000030) (0.837838,0.000030) (0.842342,0.000028) (0.846847,0.000028) (0.851351,0.000026) (0.855856,0.000026) (0.860360,0.000026) (0.864865,0.000024) (0.869369,0.000022) (0.873874,0.000020) (0.878378,0.000020) (0.882883,0.000017) (0.887387,0.000017) (0.891892,0.000017) (0.896396,0.000013) (0.900901,0.000013) (0.905405,0.000013) (0.909910,0.000011) (0.914414,0.000011) (0.918919,0.000011) (0.923423,0.000011) (0.927928,0.000011) (0.932432,0.000009) (0.936937,0.000009) (0.941441,0.000009) (0.945946,0.000009) (0.950450,0.000007) (0.954955,0.000007) (0.959459,0.000007) (0.963964,0.000004) (0.968468,0.000004) (0.972973,0.000004) (0.977477,0.000002) (0.981982,0.000002) (0.986486,0.000002) (0.990991,0.000002) (0.995495,0.000002) (1.000000,0.000002) }; -\addplot[magenta,only marks,mark=*] coordinates {(0.066667,0.333230) (0.300000,0.003317) (0.366667,0.000795)}; +\addplot[cyan,only marks,mark=*] coordinates {(0.040541,0.223088) (0.328829,0.004749) (0.563063,0.000352)}; \addplot[magenta,mark=none] coordinates { (0.000000,1.000000) (0.033333,0.333289) (0.066667,0.333230) (0.100000,0.330941) (0.133333,0.089999) (0.166667,0.087891) (0.200000,0.074485) (0.233333,0.074414) (0.266667,0.074281) (0.300000,0.003317) (0.333333,0.002204) (0.366667,0.000795) (0.400000,0.000294) (0.433333,0.000133) (0.466667,0.000099) (0.500000,0.000099) (0.533333,0.000067) (0.566667,0.000033) (0.600000,0.000032) (0.633333,0.000031) (0.666667,0.000025) (0.700000,0.000019) (0.733333,0.000010) (0.766667,0.000005) (0.800000,0.000003) (0.833333,0.000003) (0.866667,0.000003) (0.900000,0.000001) (0.933333,0.000001) (0.966667,0.000001) (1.000000,0.000001) }; -\addplot[yellow,only marks,mark=*] coordinates {(0.035088,0.506431) (0.070175,0.003334) (0.192982,0.000768)}; +\addplot[magenta,only marks,mark=*] coordinates {(0.066667,0.333230) (0.300000,0.003317) (0.366667,0.000795)}; \addplot[yellow,mark=none] coordinates { (0.000000,1.000000) (0.017544,0.993592) (0.035088,0.506431) (0.052632,0.496860) (0.070175,0.003334) (0.087719,0.003334) (0.105263,0.003290) (0.122807,0.003290) (0.140351,0.003290) (0.157895,0.003289) (0.175439,0.003250) (0.192982,0.000768) (0.210526,0.000464) (0.228070,0.000216) (0.245614,0.000205) (0.263158,0.000137) (0.280702,0.000133) (0.298246,0.000121) (0.315789,0.000105) (0.333333,0.000081) (0.350877,0.000067) (0.368421,0.000058) (0.385965,0.000055) (0.403509,0.000053) (0.421053,0.000052) (0.438596,0.000043) (0.456140,0.000034) (0.473684,0.000030) (0.491228,0.000029) (0.508772,0.000023) (0.526316,0.000022) (0.543860,0.000022) (0.561404,0.000022) (0.578947,0.000020) (0.596491,0.000019) (0.614035,0.000018) (0.631579,0.000014) (0.649123,0.000012) (0.666667,0.000011) (0.684211,0.000010) (0.701754,0.000006) (0.719298,0.000006) (0.736842,0.000005) (0.754386,0.000004) (0.771930,0.000004) (0.789474,0.000004) (0.807018,0.000003) (0.824561,0.000003) (0.842105,0.000002) (0.859649,0.000002) (0.877193,0.000001) (0.894737,0.000001) (0.912281,0.000001) (0.929825,0.000001) (0.947368,0.000000) (0.964912,0.000000) (0.982456,0.000000) (1.000000,0.000000) }; -\addplot[black,only marks,mark=*] coordinates {(0.001953,0.247783) (0.214844,0.000248) (0.519531,0.000021)}; +\addplot[yellow,only marks,mark=*] coordinates {(0.035088,0.506431) (0.070175,0.003334) (0.192982,0.000768)}; \addplot[black,mark=none] coordinates { (0.000000,1.000000) (0.001953,0.247783) (0.003906,0.056979) (0.005859,0.026968) (0.007812,0.019062) (0.009766,0.014136) (0.011719,0.011763) (0.013672,0.009968) (0.015625,0.009263) (0.017578,0.007132) (0.019531,0.006664) (0.021484,0.006547) (0.023438,0.006214) (0.025391,0.006190) (0.027344,0.005569) (0.029297,0.004773) (0.031250,0.004590) (0.033203,0.004576) (0.035156,0.004534) (0.037109,0.004497) (0.039062,0.004348) (0.041016,0.004135) (0.042969,0.003889) (0.044922,0.003631) (0.046875,0.003618) (0.048828,0.003285) (0.050781,0.003143) (0.052734,0.003024) (0.054688,0.003020) (0.056641,0.002903) (0.058594,0.002661) (0.060547,0.002589) (0.062500,0.002268) (0.064453,0.002194) (0.066406,0.002187) (0.068359,0.001941) (0.070312,0.001798) (0.072266,0.001740) (0.074219,0.001716) (0.076172,0.001704) (0.078125,0.001658) (0.080078,0.001649) (0.082031,0.001550) (0.083984,0.001484) (0.085938,0.001468) (0.087891,0.001432) (0.089844,0.001429) (0.091797,0.001423) (0.093750,0.001376) (0.095703,0.001359) (0.097656,0.001281) (0.099609,0.001224) (0.101562,0.001212) (0.103516,0.001182) (0.105469,0.001181) (0.107422,0.001174) (0.109375,0.001089) (0.111328,0.001037) (0.113281,0.001024) (0.115234,0.000993) (0.117188,0.000955) (0.119141,0.000955) (0.121094,0.000954) (0.123047,0.000954) (0.125000,0.000902) (0.126953,0.000889) (0.128906,0.000887) (0.130859,0.000881) (0.132812,0.000856) (0.134766,0.000823) (0.136719,0.000694) (0.138672,0.000676) (0.140625,0.000675) (0.142578,0.000675) (0.144531,0.000625) (0.146484,0.000616) (0.148438,0.000603) (0.150391,0.000591) (0.152344,0.000575) (0.154297,0.000573) (0.156250,0.000553) (0.158203,0.000514) (0.160156,0.000491) (0.162109,0.000467) (0.164062,0.000429) (0.166016,0.000426) (0.167969,0.000426) (0.169922,0.000421) (0.171875,0.000419) (0.173828,0.000418) (0.175781,0.000413) (0.177734,0.000408) (0.179688,0.000408) (0.181641,0.000388) (0.183594,0.000385) (0.185547,0.000355) (0.187500,0.000336) (0.189453,0.000334) (0.191406,0.000324) (0.193359,0.000303) (0.195312,0.000296) (0.197266,0.000291) (0.199219,0.000267) (0.201172,0.000265) (0.203125,0.000264) (0.205078,0.000261) (0.207031,0.000260) (0.208984,0.000259) (0.210938,0.000259) (0.212891,0.000251) (0.214844,0.000248) (0.216797,0.000245) (0.218750,0.000237) (0.220703,0.000215) (0.222656,0.000209) (0.224609,0.000208) (0.226562,0.000204) (0.228516,0.000201) (0.230469,0.000199) (0.232422,0.000197) (0.234375,0.000195) (0.236328,0.000179) (0.238281,0.000178) (0.240234,0.000178) (0.242188,0.000178) (0.244141,0.000178) (0.246094,0.000178) (0.248047,0.000178) (0.250000,0.000178) (0.251953,0.000171) (0.253906,0.000171) (0.255859,0.000170) (0.257812,0.000169) (0.259766,0.000166) (0.261719,0.000164) (0.263672,0.000163) (0.265625,0.000161) (0.267578,0.000160) (0.269531,0.000158) (0.271484,0.000155) (0.273438,0.000152) (0.275391,0.000148) (0.277344,0.000148) (0.279297,0.000148) (0.281250,0.000147) (0.283203,0.000147) (0.285156,0.000147) (0.287109,0.000146) (0.289062,0.000146) (0.291016,0.000145) (0.292969,0.000138) (0.294922,0.000136) (0.296875,0.000135) (0.298828,0.000134) (0.300781,0.000133) (0.302734,0.000132) (0.304688,0.000127) (0.306641,0.000125) (0.308594,0.000125) (0.310547,0.000124) (0.312500,0.000122) (0.314453,0.000121) (0.316406,0.000120) (0.318359,0.000119) (0.320312,0.000118) (0.322266,0.000118) (0.324219,0.000113) (0.326172,0.000110) (0.328125,0.000109) (0.330078,0.000107) (0.332031,0.000106) (0.333984,0.000104) (0.335938,0.000102) (0.337891,0.000097) (0.339844,0.000095) (0.341797,0.000092) (0.343750,0.000091) (0.345703,0.000089) (0.347656,0.000088) (0.349609,0.000086) (0.351562,0.000086) (0.353516,0.000086) (0.355469,0.000085) (0.357422,0.000085) (0.359375,0.000084) (0.361328,0.000083) (0.363281,0.000081) (0.365234,0.000081) (0.367188,0.000081) (0.369141,0.000077) (0.371094,0.000076) (0.373047,0.000076) (0.375000,0.000075) (0.376953,0.000074) (0.378906,0.000074) (0.380859,0.000067) (0.382812,0.000066) (0.384766,0.000065) (0.386719,0.000065) (0.388672,0.000062) (0.390625,0.000060) (0.392578,0.000055) (0.394531,0.000055) (0.396484,0.000051) (0.398438,0.000049) (0.400391,0.000049) (0.402344,0.000048) (0.404297,0.000046) (0.406250,0.000045) (0.408203,0.000044) (0.410156,0.000044) (0.412109,0.000044) (0.414062,0.000043) (0.416016,0.000042) (0.417969,0.000042) (0.419922,0.000041) (0.421875,0.000040) (0.423828,0.000040) (0.425781,0.000040) (0.427734,0.000038) (0.429688,0.000038) (0.431641,0.000037) (0.433594,0.000036) (0.435547,0.000035) (0.437500,0.000035) (0.439453,0.000034) (0.441406,0.000034) (0.443359,0.000034) (0.445312,0.000033) (0.447266,0.000032) (0.449219,0.000031) (0.451172,0.000031) (0.453125,0.000031) (0.455078,0.000029) (0.457031,0.000028) (0.458984,0.000027) (0.460938,0.000027) (0.462891,0.000027) (0.464844,0.000027) (0.466797,0.000026) (0.468750,0.000025) (0.470703,0.000025) (0.472656,0.000025) (0.474609,0.000024) (0.476562,0.000024) (0.478516,0.000023) (0.480469,0.000023) (0.482422,0.000023) (0.484375,0.000023) (0.486328,0.000023) (0.488281,0.000023) (0.490234,0.000023) (0.492188,0.000023) (0.494141,0.000023) (0.496094,0.000023) (0.498047,0.000023) (0.500000,0.000023) (0.501953,0.000023) (0.503906,0.000022) (0.505859,0.000022) (0.507812,0.000022) (0.509766,0.000022) (0.511719,0.000022) (0.513672,0.000021) (0.515625,0.000021) (0.517578,0.000021) (0.519531,0.000021) (0.521484,0.000021) (0.523438,0.000021) (0.525391,0.000021) (0.527344,0.000020) (0.529297,0.000020) (0.531250,0.000019) (0.533203,0.000019) (0.535156,0.000019) (0.537109,0.000019) (0.539062,0.000018) (0.541016,0.000018) (0.542969,0.000018) (0.544922,0.000018) (0.546875,0.000018) (0.548828,0.000018) (0.550781,0.000017) (0.552734,0.000017) (0.554688,0.000017) (0.556641,0.000017) (0.558594,0.000017) (0.560547,0.000016) (0.562500,0.000016) (0.564453,0.000016) (0.566406,0.000015) (0.568359,0.000015) (0.570312,0.000015) (0.572266,0.000015) (0.574219,0.000014) (0.576172,0.000014) (0.578125,0.000014) (0.580078,0.000014) (0.582031,0.000013) (0.583984,0.000013) (0.585938,0.000013) (0.587891,0.000013) (0.589844,0.000013) (0.591797,0.000012) (0.593750,0.000012) (0.595703,0.000012) (0.597656,0.000012) (0.599609,0.000012) (0.601562,0.000012) (0.603516,0.000012) (0.605469,0.000012) (0.607422,0.000011) (0.609375,0.000011) (0.611328,0.000011) (0.613281,0.000011) (0.615234,0.000011) (0.617188,0.000011) (0.619141,0.000011) (0.621094,0.000010) (0.623047,0.000010) (0.625000,0.000009) (0.626953,0.000009) (0.628906,0.000009) (0.630859,0.000009) (0.632812,0.000009) (0.634766,0.000009) (0.636719,0.000009) (0.638672,0.000009) (0.640625,0.000009) (0.642578,0.000009) (0.644531,0.000009) (0.646484,0.000009) (0.648438,0.000009) (0.650391,0.000009) (0.652344,0.000009) (0.654297,0.000009) (0.656250,0.000009) (0.658203,0.000009) (0.660156,0.000009) (0.662109,0.000009) (0.664062,0.000009) (0.666016,0.000009) (0.667969,0.000009) (0.669922,0.000008) (0.671875,0.000008) (0.673828,0.000008) (0.675781,0.000008) (0.677734,0.000008) (0.679688,0.000008) (0.681641,0.000008) (0.683594,0.000008) (0.685547,0.000008) (0.687500,0.000008) (0.689453,0.000008) (0.691406,0.000008) (0.693359,0.000008) (0.695312,0.000008) (0.697266,0.000008) (0.699219,0.000007) (0.701172,0.000007) (0.703125,0.000007) (0.705078,0.000007) (0.707031,0.000007) (0.708984,0.000007) (0.710938,0.000007) (0.712891,0.000007) (0.714844,0.000006) (0.716797,0.000006) (0.718750,0.000006) (0.720703,0.000006) (0.722656,0.000006) (0.724609,0.000006) (0.726562,0.000006) (0.728516,0.000006) (0.730469,0.000006) (0.732422,0.000005) (0.734375,0.000005) (0.736328,0.000005) (0.738281,0.000005) (0.740234,0.000005) (0.742188,0.000005) (0.744141,0.000005) (0.746094,0.000005) (0.748047,0.000005) (0.750000,0.000005) (0.751953,0.000005) (0.753906,0.000005) (0.755859,0.000004) (0.757812,0.000004) (0.759766,0.000004) (0.761719,0.000004) (0.763672,0.000004) (0.765625,0.000004) (0.767578,0.000004) (0.769531,0.000004) (0.771484,0.000004) (0.773438,0.000004) (0.775391,0.000004) (0.777344,0.000004) (0.779297,0.000004) (0.781250,0.000004) (0.783203,0.000004) (0.785156,0.000004) (0.787109,0.000004) (0.789062,0.000004) (0.791016,0.000004) (0.792969,0.000004) (0.794922,0.000004) (0.796875,0.000004) (0.798828,0.000004) (0.800781,0.000004) (0.802734,0.000003) (0.804688,0.000003) (0.806641,0.000003) (0.808594,0.000003) (0.810547,0.000003) (0.812500,0.000003) (0.814453,0.000003) (0.816406,0.000003) (0.818359,0.000003) (0.820312,0.000003) (0.822266,0.000003) (0.824219,0.000003) (0.826172,0.000003) (0.828125,0.000003) (0.830078,0.000003) (0.832031,0.000003) (0.833984,0.000003) (0.835938,0.000003) (0.837891,0.000003) (0.839844,0.000003) (0.841797,0.000003) (0.843750,0.000003) (0.845703,0.000003) (0.847656,0.000003) (0.849609,0.000003) (0.851562,0.000003) (0.853516,0.000002) (0.855469,0.000002) (0.857422,0.000002) (0.859375,0.000002) (0.861328,0.000002) (0.863281,0.000002) (0.865234,0.000002) (0.867188,0.000002) (0.869141,0.000002) (0.871094,0.000002) (0.873047,0.000002) (0.875000,0.000002) (0.876953,0.000002) (0.878906,0.000002) (0.880859,0.000002) (0.882812,0.000002) (0.884766,0.000002) (0.886719,0.000002) (0.888672,0.000002) (0.890625,0.000002) (0.892578,0.000002) (0.894531,0.000002) (0.896484,0.000002) (0.898438,0.000002) (0.900391,0.000001) (0.902344,0.000001) (0.904297,0.000001) (0.906250,0.000001) (0.908203,0.000001) (0.910156,0.000001) (0.912109,0.000001) (0.914062,0.000001) (0.916016,0.000001) (0.917969,0.000001) (0.919922,0.000001) (0.921875,0.000001) (0.923828,0.000001) (0.925781,0.000001) (0.927734,0.000001) (0.929688,0.000001) (0.931641,0.000001) (0.933594,0.000001) (0.935547,0.000001) (0.937500,0.000001) (0.939453,0.000001) (0.941406,0.000001) (0.943359,0.000001) (0.945312,0.000001) (0.947266,0.000001) (0.949219,0.000001) (0.951172,0.000001) (0.953125,0.000001) (0.955078,0.000001) (0.957031,0.000001) (0.958984,0.000001) (0.960938,0.000000) (0.962891,0.000000) (0.964844,0.000000) (0.966797,0.000000) (0.968750,0.000000) (0.970703,0.000000) (0.972656,0.000000) (0.974609,0.000000) (0.976562,0.000000) (0.978516,0.000000) (0.980469,0.000000) (0.982422,0.000000) (0.984375,0.000000) (0.986328,0.000000) (0.988281,0.000000) (0.990234,0.000000) (0.992188,0.000000) (0.994141,0.000000) (0.996094,0.000000) (0.998047,0.000000) (1.000000,0.000000) }; -\addplot[gray,only marks,mark=*] coordinates {(0.034483,0.386091) (0.396552,0.006830) (0.517241,0.000962)}; +\addplot[black,only marks,mark=*] coordinates {(0.001953,0.247783) (0.214844,0.000248) (0.519531,0.000021)}; \addplot[gray,mark=none] coordinates { (0.000000,1.000000) (0.017241,0.487558) (0.034483,0.386091) (0.051724,0.126229) (0.068966,0.108863) (0.086207,0.100941) (0.103448,0.097250) (0.120690,0.060934) (0.137931,0.054349) (0.155172,0.025283) (0.172414,0.025270) (0.189655,0.025262) (0.206897,0.025238) (0.224138,0.025208) (0.241379,0.022267) (0.258621,0.016262) (0.275862,0.016261) (0.293103,0.012610) (0.310345,0.009401) (0.327586,0.008822) (0.344828,0.008804) (0.362069,0.008801) (0.379310,0.007326) (0.396552,0.006830) (0.413793,0.003673) (0.431034,0.003672) (0.448276,0.003642) (0.465517,0.001939) (0.482759,0.001709) (0.500000,0.000965) (0.517241,0.000962) (0.534483,0.000277) (0.551724,0.000119) (0.568966,0.000093) (0.586207,0.000088) (0.603448,0.000050) (0.620690,0.000048) (0.637931,0.000043) (0.655172,0.000042) (0.672414,0.000025) (0.689655,0.000021) (0.706897,0.000011) (0.724138,0.000011) (0.741379,0.000011) (0.758621,0.000011) (0.775862,0.000011) (0.793103,0.000010) (0.810345,0.000009) (0.827586,0.000008) (0.844828,0.000006) (0.862069,0.000005) (0.879310,0.000004) (0.896552,0.000003) (0.913793,0.000002) (0.931034,0.000002) (0.948276,0.000001) (0.965517,0.000001) (0.982759,0.000001) (1.000000,0.000000) }; -\addplot[darkgray,only marks,mark=*] coordinates {(0.071429,0.409043) (0.285714,0.001856) (0.285714,0.001856)}; +\addplot[gray,only marks,mark=*] coordinates {(0.034483,0.386091) (0.396552,0.006830) (0.517241,0.000962)}; \addplot[darkgray,mark=none] coordinates { (0.000000,1.000000) (0.035714,0.909090) (0.071429,0.409043) (0.107143,0.409043) (0.142857,0.045445) (0.178571,0.045445) (0.214286,0.045437) (0.250000,0.045437) (0.285714,0.001856) (0.321429,0.000157) (0.357143,0.000150) (0.392857,0.000148) (0.428571,0.000138) (0.464286,0.000116) (0.500000,0.000070) (0.535714,0.000048) (0.571429,0.000032) (0.607143,0.000032) (0.642857,0.000032) (0.678571,0.000016) (0.714286,0.000009) (0.750000,0.000008) (0.785714,0.000008) (0.821429,0.000008) (0.857143,0.000006) (0.892857,0.000005) (0.928571,0.000002) (0.964286,0.000001) (1.000000,0.000001) }; -\addplot[lightgray,only marks,mark=*] coordinates {(0.038627,0.153140) (0.197425,0.002447) (0.433476,0.000174)}; +\addplot[darkgray,only marks,mark=*] coordinates {(0.071429,0.409043) (0.285714,0.001856) (0.285714,0.001856)}; \addplot[lightgray,mark=none] coordinates { (0.000000,1.000000) (0.004292,0.333547) (0.008584,0.333312) (0.012876,0.166857) (0.017167,0.166758) (0.021459,0.166551) (0.025751,0.166414) (0.030043,0.166294) (0.034335,0.165678) (0.038627,0.153140) (0.042918,0.084910) (0.047210,0.084877) (0.051502,0.083928) (0.055794,0.083394) (0.060086,0.083329) (0.064378,0.083328) (0.068670,0.083313) (0.072961,0.083313) (0.077253,0.083302) (0.081545,0.083301) (0.085837,0.083292) (0.090129,0.083239) (0.094421,0.083209) (0.098712,0.083176) (0.103004,0.083169) (0.107296,0.083125) (0.111588,0.083071) (0.115880,0.083067) (0.120172,0.083054) (0.124464,0.082872) (0.128755,0.082758) (0.133047,0.082151) (0.137339,0.081810) (0.141631,0.081809) (0.145923,0.081721) (0.150215,0.081378) (0.154506,0.081001) (0.158798,0.063929) (0.163090,0.041639) (0.167382,0.017348) (0.171674,0.012510) (0.175966,0.011755) (0.180258,0.004971) (0.184549,0.004140) (0.188841,0.003972) (0.193133,0.002505) (0.197425,0.002447) (0.201717,0.002335) (0.206009,0.002075) (0.210300,0.001713) (0.214592,0.001685) (0.218884,0.001622) (0.223176,0.001588) (0.227468,0.001512) (0.231760,0.001506) (0.236052,0.001486) (0.240343,0.001475) (0.244635,0.001291) (0.248927,0.001284) (0.253219,0.001203) (0.257511,0.001158) (0.261803,0.001088) (0.266094,0.001087) (0.270386,0.001028) (0.274678,0.001019) (0.278970,0.001010) (0.283262,0.000943) (0.287554,0.000860) (0.291845,0.000808) (0.296137,0.000797) (0.300429,0.000788) (0.304721,0.000773) (0.309013,0.000769) (0.313305,0.000686) (0.317597,0.000640) (0.321888,0.000621) (0.326180,0.000604) (0.330472,0.000548) (0.334764,0.000478) (0.339056,0.000468) (0.343348,0.000444) (0.347639,0.000424) (0.351931,0.000419) (0.356223,0.000404) (0.360515,0.000388) (0.364807,0.000384) (0.369099,0.000381) (0.373391,0.000333) (0.377682,0.000327) (0.381974,0.000318) (0.386266,0.000301) (0.390558,0.000271) (0.394850,0.000262) (0.399142,0.000255) (0.403433,0.000243) (0.407725,0.000238) (0.412017,0.000237) (0.416309,0.000235) (0.420601,0.000230) (0.424893,0.000209) (0.429185,0.000189) (0.433476,0.000174) (0.437768,0.000165) (0.442060,0.000164) (0.446352,0.000153) (0.450644,0.000151) (0.454936,0.000150) (0.459227,0.000140) (0.463519,0.000136) (0.467811,0.000136) (0.472103,0.000118) (0.476395,0.000117) (0.480687,0.000112) (0.484979,0.000111) (0.489270,0.000106) (0.493562,0.000106) (0.497854,0.000106) (0.502146,0.000106) (0.506438,0.000106) (0.510730,0.000102) (0.515021,0.000092) (0.519313,0.000087) (0.523605,0.000082) (0.527897,0.000079) (0.532189,0.000077) (0.536481,0.000076) (0.540773,0.000075) (0.545064,0.000074) (0.549356,0.000073) (0.553648,0.000068) (0.557940,0.000068) (0.562232,0.000066) (0.566524,0.000063) (0.570815,0.000063) (0.575107,0.000062) (0.579399,0.000061) (0.583691,0.000061) (0.587983,0.000060) (0.592275,0.000059) (0.596567,0.000053) (0.600858,0.000050) (0.605150,0.000047) (0.609442,0.000046) (0.613734,0.000042) (0.618026,0.000042) (0.622318,0.000041) (0.626609,0.000040) (0.630901,0.000035) (0.635193,0.000035) (0.639485,0.000033) (0.643777,0.000033) (0.648069,0.000032) (0.652361,0.000032) (0.656652,0.000031) (0.660944,0.000031) (0.665236,0.000031) (0.669528,0.000031) (0.673820,0.000030) (0.678112,0.000029) (0.682403,0.000028) (0.686695,0.000027) (0.690987,0.000026) (0.695279,0.000025) (0.699571,0.000023) (0.703863,0.000022) (0.708155,0.000022) (0.712446,0.000021) (0.716738,0.000019) (0.721030,0.000018) (0.725322,0.000017) (0.729614,0.000016) (0.733906,0.000013) (0.738197,0.000012) (0.742489,0.000011) (0.746781,0.000011) (0.751073,0.000011) (0.755365,0.000011) (0.759657,0.000011) (0.763948,0.000011) (0.768240,0.000011) (0.772532,0.000011) (0.776824,0.000011) (0.781116,0.000011) (0.785408,0.000010) (0.789700,0.000010) (0.793991,0.000009) (0.798283,0.000009) (0.802575,0.000009) (0.806867,0.000009) (0.811159,0.000008) (0.815451,0.000007) (0.819742,0.000005) (0.824034,0.000005) (0.828326,0.000005) (0.832618,0.000005) (0.836910,0.000005) (0.841202,0.000004) (0.845494,0.000004) (0.849785,0.000004) (0.854077,0.000004) (0.858369,0.000004) (0.862661,0.000004) (0.866953,0.000004) (0.871245,0.000003) (0.875536,0.000003) (0.879828,0.000003) (0.884120,0.000003) (0.888412,0.000003) (0.892704,0.000002) (0.896996,0.000002) (0.901288,0.000002) (0.905579,0.000002) (0.909871,0.000002) (0.914163,0.000002) (0.918455,0.000001) (0.922747,0.000001) (0.927039,0.000001) (0.931330,0.000001) (0.935622,0.000001) (0.939914,0.000001) (0.944206,0.000001) (0.948498,0.000001) (0.952790,0.000001) (0.957082,0.000001) (0.961373,0.000001) (0.965665,0.000001) (0.969957,0.000001) (0.974249,0.000001) (0.978541,0.000001) (0.982833,0.000001) (0.987124,0.000001) (0.991416,0.000001) (0.995708,0.000001) (1.000000,0.000001) }; +\addplot[lightgray,only marks,mark=*] coordinates {(0.038627,0.153140) (0.197425,0.002447) (0.433476,0.000174)}; \addplot[brown,mark=none] coordinates { (0.000000,1.000000) (0.000834,0.872400) (0.001668,0.683224) (0.002502,0.608314) (0.003336,0.542330) (0.004170,0.519721) (0.005004,0.447508) (0.005838,0.440065) (0.006672,0.420670) (0.007506,0.418862) (0.008340,0.418009) (0.009174,0.379519) (0.010008,0.357223) (0.010842,0.353534) (0.011676,0.333568) (0.012510,0.319704) (0.013344,0.268160) (0.014178,0.251065) (0.015013,0.226789) (0.015847,0.220089) (0.016681,0.215066) (0.017515,0.213903) (0.018349,0.213091) (0.019183,0.197153) (0.020017,0.187389) (0.020851,0.177430) (0.021685,0.173396) (0.022519,0.170787) (0.023353,0.160834) (0.024187,0.160045) (0.025021,0.157071) (0.025855,0.146612) (0.026689,0.144178) (0.027523,0.137699) (0.028357,0.136683) (0.029191,0.124833) (0.030025,0.121453) (0.030859,0.119189) (0.031693,0.115002) (0.032527,0.114249) (0.033361,0.107546) (0.034195,0.107268) (0.035029,0.104187) (0.035863,0.096624) (0.036697,0.089912) (0.037531,0.089585) (0.038365,0.087446) (0.039199,0.087298) (0.040033,0.084823) (0.040867,0.083414) (0.041701,0.083212) (0.042535,0.082227) (0.043369,0.079913) (0.044204,0.075734) (0.045038,0.073337) (0.045872,0.073039) (0.046706,0.072381) (0.047540,0.069693) (0.048374,0.067325) (0.049208,0.065996) (0.050042,0.057532) (0.050876,0.055707) (0.051710,0.055669) (0.052544,0.049083) (0.053378,0.048652) (0.054212,0.048015) (0.055046,0.045918) (0.055880,0.045234) (0.056714,0.042272) (0.057548,0.041798) (0.058382,0.040969) (0.059216,0.040163) (0.060050,0.040016) (0.060884,0.038778) (0.061718,0.038686) (0.062552,0.038456) (0.063386,0.033439) (0.064220,0.032381) (0.065054,0.031115) (0.065888,0.030103) (0.066722,0.029385) (0.067556,0.026654) (0.068390,0.025877) (0.069224,0.024467) (0.070058,0.024427) (0.070892,0.024134) (0.071726,0.024036) (0.072560,0.021379) (0.073394,0.020813) (0.074229,0.020166) (0.075063,0.020056) (0.075897,0.019981) (0.076731,0.019791) (0.077565,0.019672) (0.078399,0.019356) (0.079233,0.019269) (0.080067,0.019134) (0.080901,0.018119) (0.081735,0.017905) (0.082569,0.017878) (0.083403,0.017865) (0.084237,0.017769) (0.085071,0.017758) (0.085905,0.017065) (0.086739,0.016959) (0.087573,0.016686) (0.088407,0.015666) (0.089241,0.014908) (0.090075,0.014542) (0.090909,0.014518) (0.091743,0.014200) (0.092577,0.013865) (0.093411,0.013736) (0.094245,0.013273) (0.095079,0.013197) (0.095913,0.012997) (0.096747,0.012759) (0.097581,0.012642) (0.098415,0.012344) (0.099249,0.012031) (0.100083,0.011973) (0.100917,0.011805) (0.101751,0.011594) (0.102585,0.011387) (0.103420,0.011332) (0.104254,0.011246) (0.105088,0.010925) (0.105922,0.010566) (0.106756,0.010269) (0.107590,0.010235) (0.108424,0.010220) (0.109258,0.010135) (0.110092,0.010071) (0.110926,0.010048) (0.111760,0.010002) (0.112594,0.009762) (0.113428,0.009756) (0.114262,0.009751) (0.115096,0.009730) (0.115930,0.009551) (0.116764,0.009536) (0.117598,0.009404) (0.118432,0.009399) (0.119266,0.009298) (0.120100,0.009263) (0.120934,0.009245) (0.121768,0.009137) (0.122602,0.009120) (0.123436,0.009097) (0.124270,0.008816) (0.125104,0.008646) (0.125938,0.008484) (0.126772,0.008405) (0.127606,0.008149) (0.128440,0.008032) (0.129274,0.007872) (0.130108,0.007866) (0.130942,0.007823) (0.131776,0.007801) (0.132611,0.007718) (0.133445,0.007481) (0.134279,0.007373) (0.135113,0.007345) (0.135947,0.007296) (0.136781,0.007269) (0.137615,0.007233) (0.138449,0.006991) (0.139283,0.006905) (0.140117,0.006795) (0.140951,0.006738) (0.141785,0.006708) (0.142619,0.006551) (0.143453,0.006510) (0.144287,0.006435) (0.145121,0.006361) (0.145955,0.006238) (0.146789,0.006134) (0.147623,0.006027) (0.148457,0.005991) (0.149291,0.005921) (0.150125,0.005852) (0.150959,0.005852) (0.151793,0.005823) (0.152627,0.005794) (0.153461,0.005787) (0.154295,0.005746) (0.155129,0.005672) (0.155963,0.005619) (0.156797,0.005612) (0.157631,0.005557) (0.158465,0.005495) (0.159299,0.005495) (0.160133,0.005422) (0.160967,0.005324) (0.161802,0.005217) (0.162636,0.005196) (0.163470,0.005167) (0.164304,0.005107) (0.165138,0.005012) (0.165972,0.004999) (0.166806,0.004985) (0.167640,0.004981) (0.168474,0.004936) (0.169308,0.004912) (0.170142,0.004836) (0.170976,0.004822) (0.171810,0.004755) (0.172644,0.004692) (0.173478,0.004687) (0.174312,0.004667) (0.175146,0.004605) (0.175980,0.004546) (0.176814,0.004523) (0.177648,0.004518) (0.178482,0.004512) (0.179316,0.004447) (0.180150,0.004427) (0.180984,0.004408) (0.181818,0.004401) (0.182652,0.004336) (0.183486,0.004326) (0.184320,0.004255) (0.185154,0.004163) (0.185988,0.004152) (0.186822,0.004150) (0.187656,0.004132) (0.188490,0.004125) (0.189324,0.003972) (0.190158,0.003971) (0.190992,0.003942) (0.191827,0.003842) (0.192661,0.003797) (0.193495,0.003710) (0.194329,0.003703) (0.195163,0.003684) (0.195997,0.003626) (0.196831,0.003620) (0.197665,0.003576) (0.198499,0.003526) (0.199333,0.003451) (0.200167,0.003447) (0.201001,0.003402) (0.201835,0.003390) (0.202669,0.003364) (0.203503,0.003361) (0.204337,0.003356) (0.205171,0.003350) (0.206005,0.003341) (0.206839,0.003321) (0.207673,0.003278) (0.208507,0.003246) (0.209341,0.003239) (0.210175,0.003219) (0.211009,0.003208) (0.211843,0.003129) (0.212677,0.003123) (0.213511,0.003073) (0.214345,0.003063) (0.215179,0.003053) (0.216013,0.003053) (0.216847,0.003026) (0.217681,0.003007) (0.218515,0.002989) (0.219349,0.002929) (0.220183,0.002915) (0.221018,0.002913) (0.221852,0.002890) (0.222686,0.002861) (0.223520,0.002845) (0.224354,0.002804) (0.225188,0.002783) (0.226022,0.002781) (0.226856,0.002694) (0.227690,0.002669) (0.228524,0.002631) (0.229358,0.002579) (0.230192,0.002578) (0.231026,0.002573) (0.231860,0.002566) (0.232694,0.002507) (0.233528,0.002487) (0.234362,0.002486) (0.235196,0.002416) (0.236030,0.002367) (0.236864,0.002347) (0.237698,0.002344) (0.238532,0.002338) (0.239366,0.002330) (0.240200,0.002318) (0.241034,0.002315) (0.241868,0.002308) (0.242702,0.002308) (0.243536,0.002292) (0.244370,0.002287) (0.245204,0.002283) (0.246038,0.002264) (0.246872,0.002236) (0.247706,0.002227) (0.248540,0.002185) (0.249374,0.002173) (0.250209,0.002169) (0.251043,0.002135) (0.251877,0.002109) (0.252711,0.002039) (0.253545,0.002031) (0.254379,0.001987) (0.255213,0.001970) (0.256047,0.001966) (0.256881,0.001936) (0.257715,0.001908) (0.258549,0.001908) (0.259383,0.001893) (0.260217,0.001886) (0.261051,0.001882) (0.261885,0.001827) (0.262719,0.001827) (0.263553,0.001817) (0.264387,0.001797) (0.265221,0.001749) (0.266055,0.001742) (0.266889,0.001739) (0.267723,0.001727) (0.268557,0.001704) (0.269391,0.001700) (0.270225,0.001691) (0.271059,0.001690) (0.271893,0.001653) (0.272727,0.001600) (0.273561,0.001595) (0.274395,0.001555) (0.275229,0.001547) (0.276063,0.001546) (0.276897,0.001519) (0.277731,0.001513) (0.278565,0.001510) (0.279399,0.001505) (0.280234,0.001474) (0.281068,0.001468) (0.281902,0.001459) (0.282736,0.001458) (0.283570,0.001432) (0.284404,0.001410) (0.285238,0.001407) (0.286072,0.001401) (0.286906,0.001396) (0.287740,0.001391) (0.288574,0.001376) (0.289408,0.001372) (0.290242,0.001369) (0.291076,0.001345) (0.291910,0.001344) (0.292744,0.001318) (0.293578,0.001299) (0.294412,0.001295) (0.295246,0.001287) (0.296080,0.001285) (0.296914,0.001284) (0.297748,0.001270) (0.298582,0.001265) (0.299416,0.001253) (0.300250,0.001235) (0.301084,0.001233) (0.301918,0.001224) (0.302752,0.001222) (0.303586,0.001219) (0.304420,0.001209) (0.305254,0.001202) (0.306088,0.001191) (0.306922,0.001180) (0.307756,0.001173) (0.308590,0.001170) (0.309425,0.001167) (0.310259,0.001154) (0.311093,0.001147) (0.311927,0.001143) (0.312761,0.001130) (0.313595,0.001126) (0.314429,0.001124) (0.315263,0.001116) (0.316097,0.001115) (0.316931,0.001099) (0.317765,0.001088) (0.318599,0.001088) (0.319433,0.001082) (0.320267,0.001074) (0.321101,0.001071) (0.321935,0.001070) (0.322769,0.001066) (0.323603,0.001062) (0.324437,0.001047) (0.325271,0.001043) (0.326105,0.001041) (0.326939,0.001040) (0.327773,0.001038) (0.328607,0.001027) (0.329441,0.001025) (0.330275,0.001016) (0.331109,0.001016) (0.331943,0.000996) (0.332777,0.000992) (0.333611,0.000985) (0.334445,0.000979) (0.335279,0.000978) (0.336113,0.000978) (0.336947,0.000957) (0.337781,0.000953) (0.338616,0.000951) (0.339450,0.000947) (0.340284,0.000944) (0.341118,0.000939) (0.341952,0.000932) (0.342786,0.000930) (0.343620,0.000930) (0.344454,0.000928) (0.345288,0.000915) (0.346122,0.000914) (0.346956,0.000914) (0.347790,0.000911) (0.348624,0.000910) (0.349458,0.000908) (0.350292,0.000904) (0.351126,0.000895) (0.351960,0.000890) (0.352794,0.000887) (0.353628,0.000884) (0.354462,0.000879) (0.355296,0.000861) (0.356130,0.000861) (0.356964,0.000826) (0.357798,0.000814) (0.358632,0.000808) (0.359466,0.000800) (0.360300,0.000797) (0.361134,0.000796) (0.361968,0.000782) (0.362802,0.000779) (0.363636,0.000778) (0.364470,0.000777) (0.365304,0.000777) (0.366138,0.000775) (0.366972,0.000767) (0.367807,0.000764) (0.368641,0.000761) (0.369475,0.000758) (0.370309,0.000753) (0.371143,0.000753) (0.371977,0.000751) (0.372811,0.000738) (0.373645,0.000718) (0.374479,0.000718) (0.375313,0.000710) (0.376147,0.000709) (0.376981,0.000707) (0.377815,0.000701) (0.378649,0.000699) (0.379483,0.000694) (0.380317,0.000694) (0.381151,0.000688) (0.381985,0.000686) (0.382819,0.000683) (0.383653,0.000681) (0.384487,0.000665) (0.385321,0.000664) (0.386155,0.000660) (0.386989,0.000659) (0.387823,0.000657) (0.388657,0.000657) (0.389491,0.000655) (0.390325,0.000654) (0.391159,0.000647) (0.391993,0.000645) (0.392827,0.000644) (0.393661,0.000643) (0.394495,0.000642) (0.395329,0.000640) (0.396163,0.000639) (0.396997,0.000637) (0.397832,0.000634) (0.398666,0.000630) (0.399500,0.000614) (0.400334,0.000613) (0.401168,0.000607) (0.402002,0.000604) (0.402836,0.000603) (0.403670,0.000602) (0.404504,0.000602) (0.405338,0.000598) (0.406172,0.000597) (0.407006,0.000592) (0.407840,0.000588) (0.408674,0.000576) (0.409508,0.000572) (0.410342,0.000570) (0.411176,0.000570) (0.412010,0.000567) (0.412844,0.000567) (0.413678,0.000566) (0.414512,0.000564) (0.415346,0.000563) (0.416180,0.000554) (0.417014,0.000550) (0.417848,0.000548) (0.418682,0.000547) (0.419516,0.000547) (0.420350,0.000546) (0.421184,0.000542) (0.422018,0.000542) (0.422852,0.000535) (0.423686,0.000529) (0.424520,0.000518) (0.425354,0.000516) (0.426188,0.000515) (0.427023,0.000513) (0.427857,0.000512) (0.428691,0.000511) (0.429525,0.000503) (0.430359,0.000503) (0.431193,0.000503) (0.432027,0.000499) (0.432861,0.000497) (0.433695,0.000497) (0.434529,0.000495) (0.435363,0.000495) (0.436197,0.000494) (0.437031,0.000494) (0.437865,0.000492) (0.438699,0.000491) (0.439533,0.000490) (0.440367,0.000489) (0.441201,0.000488) (0.442035,0.000486) (0.442869,0.000484) (0.443703,0.000480) (0.444537,0.000479) (0.445371,0.000478) (0.446205,0.000471) (0.447039,0.000467) (0.447873,0.000466) (0.448707,0.000464) (0.449541,0.000460) (0.450375,0.000458) (0.451209,0.000456) (0.452043,0.000452) (0.452877,0.000451) (0.453711,0.000448) (0.454545,0.000446) (0.455379,0.000445) (0.456214,0.000444) (0.457048,0.000437) (0.457882,0.000436) (0.458716,0.000435) (0.459550,0.000431) (0.460384,0.000431) (0.461218,0.000430) (0.462052,0.000428) (0.462886,0.000428) (0.463720,0.000428) (0.464554,0.000427) (0.465388,0.000427) (0.466222,0.000422) (0.467056,0.000420) (0.467890,0.000415) (0.468724,0.000409) (0.469558,0.000408) (0.470392,0.000408) (0.471226,0.000406) (0.472060,0.000405) (0.472894,0.000404) (0.473728,0.000404) (0.474562,0.000402) (0.475396,0.000402) (0.476230,0.000402) (0.477064,0.000402) (0.477898,0.000399) (0.478732,0.000399) (0.479566,0.000398) (0.480400,0.000395) (0.481234,0.000395) (0.482068,0.000394) (0.482902,0.000390) (0.483736,0.000389) (0.484570,0.000387) (0.485405,0.000385) (0.486239,0.000383) (0.487073,0.000382) (0.487907,0.000381) (0.488741,0.000380) (0.489575,0.000380) (0.490409,0.000377) (0.491243,0.000375) (0.492077,0.000374) (0.492911,0.000373) (0.493745,0.000371) (0.494579,0.000370) (0.495413,0.000369) (0.496247,0.000368) (0.497081,0.000366) (0.497915,0.000364) (0.498749,0.000362) (0.499583,0.000362) (0.500417,0.000358) (0.501251,0.000354) (0.502085,0.000346) (0.502919,0.000345) (0.503753,0.000344) (0.504587,0.000343) (0.505421,0.000341) (0.506255,0.000340) (0.507089,0.000337) (0.507923,0.000337) (0.508757,0.000331) (0.509591,0.000328) (0.510425,0.000325) (0.511259,0.000323) (0.512093,0.000319) (0.512927,0.000319) (0.513761,0.000317) (0.514595,0.000315) (0.515430,0.000314) (0.516264,0.000313) (0.517098,0.000313) (0.517932,0.000312) (0.518766,0.000312) (0.519600,0.000311) (0.520434,0.000302) (0.521268,0.000300) (0.522102,0.000300) (0.522936,0.000295) (0.523770,0.000295) (0.524604,0.000295) (0.525438,0.000292) (0.526272,0.000290) (0.527106,0.000290) (0.527940,0.000288) (0.528774,0.000287) (0.529608,0.000285) (0.530442,0.000280) (0.531276,0.000278) (0.532110,0.000278) (0.532944,0.000278) (0.533778,0.000277) (0.534612,0.000276) (0.535446,0.000274) (0.536280,0.000273) (0.537114,0.000271) (0.537948,0.000271) (0.538782,0.000270) (0.539616,0.000266) (0.540450,0.000263) (0.541284,0.000260) (0.542118,0.000260) (0.542952,0.000258) (0.543786,0.000258) (0.544621,0.000256) (0.545455,0.000253) (0.546289,0.000252) (0.547123,0.000251) (0.547957,0.000249) (0.548791,0.000248) (0.549625,0.000248) (0.550459,0.000248) (0.551293,0.000246) (0.552127,0.000246) (0.552961,0.000244) (0.553795,0.000244) (0.554629,0.000242) (0.555463,0.000241) (0.556297,0.000240) (0.557131,0.000240) (0.557965,0.000239) (0.558799,0.000236) (0.559633,0.000236) (0.560467,0.000235) (0.561301,0.000234) (0.562135,0.000234) (0.562969,0.000234) (0.563803,0.000233) (0.564637,0.000233) (0.565471,0.000225) (0.566305,0.000223) (0.567139,0.000223) (0.567973,0.000220) (0.568807,0.000219) (0.569641,0.000218) (0.570475,0.000218) (0.571309,0.000217) (0.572143,0.000216) (0.572977,0.000213) (0.573812,0.000211) (0.574646,0.000207) (0.575480,0.000206) (0.576314,0.000206) (0.577148,0.000205) (0.577982,0.000205) (0.578816,0.000203) (0.579650,0.000203) (0.580484,0.000203) (0.581318,0.000203) (0.582152,0.000203) (0.582986,0.000201) (0.583820,0.000200) (0.584654,0.000200) (0.585488,0.000199) (0.586322,0.000199) (0.587156,0.000197) (0.587990,0.000194) (0.588824,0.000193) (0.589658,0.000191) (0.590492,0.000190) (0.591326,0.000190) (0.592160,0.000186) (0.592994,0.000186) (0.593828,0.000181) (0.594662,0.000178) (0.595496,0.000175) (0.596330,0.000174) (0.597164,0.000173) (0.597998,0.000173) (0.598832,0.000172) (0.599666,0.000171) (0.600500,0.000171) (0.601334,0.000170) (0.602168,0.000170) (0.603003,0.000169) (0.603837,0.000166) (0.604671,0.000165) (0.605505,0.000165) (0.606339,0.000165) (0.607173,0.000164) (0.608007,0.000163) (0.608841,0.000162) (0.609675,0.000162) (0.610509,0.000162) (0.611343,0.000162) (0.612177,0.000161) (0.613011,0.000161) (0.613845,0.000159) (0.614679,0.000158) (0.615513,0.000158) (0.616347,0.000157) (0.617181,0.000156) (0.618015,0.000155) (0.618849,0.000155) (0.619683,0.000152) (0.620517,0.000152) (0.621351,0.000151) (0.622185,0.000151) (0.623019,0.000149) (0.623853,0.000149) (0.624687,0.000148) (0.625521,0.000147) (0.626355,0.000147) (0.627189,0.000146) (0.628023,0.000146) (0.628857,0.000146) (0.629691,0.000146) (0.630525,0.000145) (0.631359,0.000145) (0.632193,0.000144) (0.633028,0.000144) (0.633862,0.000144) (0.634696,0.000144) (0.635530,0.000143) (0.636364,0.000142) (0.637198,0.000142) (0.638032,0.000142) (0.638866,0.000142) (0.639700,0.000141) (0.640534,0.000140) (0.641368,0.000139) (0.642202,0.000137) (0.643036,0.000137) (0.643870,0.000133) (0.644704,0.000131) (0.645538,0.000131) (0.646372,0.000129) (0.647206,0.000129) (0.648040,0.000129) (0.648874,0.000128) (0.649708,0.000128) (0.650542,0.000127) (0.651376,0.000124) (0.652210,0.000123) (0.653044,0.000119) (0.653878,0.000117) (0.654712,0.000117) (0.655546,0.000117) (0.656380,0.000115) (0.657214,0.000114) (0.658048,0.000114) (0.658882,0.000114) (0.659716,0.000113) (0.660550,0.000112) (0.661384,0.000111) (0.662219,0.000111) (0.663053,0.000111) (0.663887,0.000111) (0.664721,0.000110) (0.665555,0.000110) (0.666389,0.000109) (0.667223,0.000108) (0.668057,0.000108) (0.668891,0.000107) (0.669725,0.000105) (0.670559,0.000105) (0.671393,0.000105) (0.672227,0.000105) (0.673061,0.000105) (0.673895,0.000105) (0.674729,0.000105) (0.675563,0.000104) (0.676397,0.000104) (0.677231,0.000103) (0.678065,0.000102) (0.678899,0.000101) (0.679733,0.000101) (0.680567,0.000100) (0.681401,0.000100) (0.682235,0.000100) (0.683069,0.000099) (0.683903,0.000099) (0.684737,0.000098) (0.685571,0.000098) (0.686405,0.000098) (0.687239,0.000097) (0.688073,0.000094) (0.688907,0.000094) (0.689741,0.000092) (0.690575,0.000092) (0.691410,0.000091) (0.692244,0.000089) (0.693078,0.000089) (0.693912,0.000087) (0.694746,0.000087) (0.695580,0.000087) (0.696414,0.000086) (0.697248,0.000086) (0.698082,0.000086) (0.698916,0.000085) (0.699750,0.000085) (0.700584,0.000085) (0.701418,0.000085) (0.702252,0.000084) (0.703086,0.000084) (0.703920,0.000083) (0.704754,0.000083) (0.705588,0.000082) (0.706422,0.000081) (0.707256,0.000080) (0.708090,0.000080) (0.708924,0.000080) (0.709758,0.000079) (0.710592,0.000079) (0.711426,0.000078) (0.712260,0.000078) (0.713094,0.000077) (0.713928,0.000076) (0.714762,0.000076) (0.715596,0.000076) (0.716430,0.000075) (0.717264,0.000075) (0.718098,0.000072) (0.718932,0.000071) (0.719766,0.000071) (0.720601,0.000070) (0.721435,0.000070) (0.722269,0.000070) (0.723103,0.000070) (0.723937,0.000070) (0.724771,0.000070) (0.725605,0.000069) (0.726439,0.000068) (0.727273,0.000068) (0.728107,0.000068) (0.728941,0.000067) (0.729775,0.000067) (0.730609,0.000067) (0.731443,0.000067) (0.732277,0.000066) (0.733111,0.000066) (0.733945,0.000065) (0.734779,0.000065) (0.735613,0.000065) (0.736447,0.000065) (0.737281,0.000064) (0.738115,0.000064) (0.738949,0.000063) (0.739783,0.000063) (0.740617,0.000063) (0.741451,0.000062) (0.742285,0.000062) (0.743119,0.000060) (0.743953,0.000060) (0.744787,0.000059) (0.745621,0.000059) (0.746455,0.000059) (0.747289,0.000059) (0.748123,0.000058) (0.748957,0.000058) (0.749791,0.000057) (0.750626,0.000057) (0.751460,0.000057) (0.752294,0.000057) (0.753128,0.000057) (0.753962,0.000057) (0.754796,0.000057) (0.755630,0.000057) (0.756464,0.000057) (0.757298,0.000057) (0.758132,0.000057) (0.758966,0.000057) (0.759800,0.000057) (0.760634,0.000057) (0.761468,0.000057) (0.762302,0.000057) (0.763136,0.000056) (0.763970,0.000056) (0.764804,0.000055) (0.765638,0.000055) (0.766472,0.000055) (0.767306,0.000055) (0.768140,0.000055) (0.768974,0.000055) (0.769808,0.000054) (0.770642,0.000054) (0.771476,0.000054) (0.772310,0.000054) (0.773144,0.000054) (0.773978,0.000053) (0.774812,0.000053) (0.775646,0.000053) (0.776480,0.000053) (0.777314,0.000053) (0.778148,0.000053) (0.778982,0.000053) (0.779817,0.000052) (0.780651,0.000052) (0.781485,0.000052) (0.782319,0.000052) (0.783153,0.000052) (0.783987,0.000052) (0.784821,0.000052) (0.785655,0.000051) (0.786489,0.000051) (0.787323,0.000051) (0.788157,0.000051) (0.788991,0.000050) (0.789825,0.000050) (0.790659,0.000050) (0.791493,0.000049) (0.792327,0.000049) (0.793161,0.000049) (0.793995,0.000049) (0.794829,0.000049) (0.795663,0.000049) (0.796497,0.000049) (0.797331,0.000047) (0.798165,0.000047) (0.798999,0.000047) (0.799833,0.000047) (0.800667,0.000046) (0.801501,0.000046) (0.802335,0.000046) (0.803169,0.000046) (0.804003,0.000045) (0.804837,0.000045) (0.805671,0.000044) (0.806505,0.000044) (0.807339,0.000043) (0.808173,0.000043) (0.809008,0.000043) (0.809842,0.000043) (0.810676,0.000042) (0.811510,0.000042) (0.812344,0.000041) (0.813178,0.000041) (0.814012,0.000041) (0.814846,0.000041) (0.815680,0.000040) (0.816514,0.000040) (0.817348,0.000038) (0.818182,0.000038) (0.819016,0.000038) (0.819850,0.000037) (0.820684,0.000037) (0.821518,0.000037) (0.822352,0.000037) (0.823186,0.000037) (0.824020,0.000036) (0.824854,0.000036) (0.825688,0.000035) (0.826522,0.000035) (0.827356,0.000035) (0.828190,0.000035) (0.829024,0.000034) (0.829858,0.000034) (0.830692,0.000033) (0.831526,0.000033) (0.832360,0.000033) (0.833194,0.000033) (0.834028,0.000032) (0.834862,0.000032) (0.835696,0.000031) (0.836530,0.000031) (0.837364,0.000030) (0.838198,0.000030) (0.839033,0.000030) (0.839867,0.000030) (0.840701,0.000029) (0.841535,0.000029) (0.842369,0.000029) (0.843203,0.000029) (0.844037,0.000029) (0.844871,0.000028) (0.845705,0.000028) (0.846539,0.000028) (0.847373,0.000028) (0.848207,0.000028) (0.849041,0.000028) (0.849875,0.000028) (0.850709,0.000028) (0.851543,0.000028) (0.852377,0.000028) (0.853211,0.000028) (0.854045,0.000028) (0.854879,0.000028) (0.855713,0.000028) (0.856547,0.000028) (0.857381,0.000028) (0.858215,0.000028) (0.859049,0.000027) (0.859883,0.000027) (0.860717,0.000027) (0.861551,0.000027) (0.862385,0.000027) (0.863219,0.000027) (0.864053,0.000027) (0.864887,0.000027) (0.865721,0.000027) (0.866555,0.000027) (0.867389,0.000027) (0.868224,0.000027) (0.869058,0.000027) (0.869892,0.000026) (0.870726,0.000026) (0.871560,0.000026) (0.872394,0.000025) (0.873228,0.000025) (0.874062,0.000025) (0.874896,0.000025) (0.875730,0.000025) (0.876564,0.000025) (0.877398,0.000025) (0.878232,0.000025) (0.879066,0.000025) (0.879900,0.000025) (0.880734,0.000024) (0.881568,0.000024) (0.882402,0.000024) (0.883236,0.000024) (0.884070,0.000024) (0.884904,0.000024) (0.885738,0.000023) (0.886572,0.000023) (0.887406,0.000023) (0.888240,0.000023) (0.889074,0.000023) (0.889908,0.000023) (0.890742,0.000022) (0.891576,0.000022) (0.892410,0.000022) (0.893244,0.000022) (0.894078,0.000022) (0.894912,0.000022) (0.895746,0.000022) (0.896580,0.000022) (0.897415,0.000021) (0.898249,0.000021) (0.899083,0.000021) (0.899917,0.000021) (0.900751,0.000021) (0.901585,0.000021) (0.902419,0.000021) (0.903253,0.000021) (0.904087,0.000021) (0.904921,0.000021) (0.905755,0.000021) (0.906589,0.000021) (0.907423,0.000021) (0.908257,0.000020) (0.909091,0.000020) (0.909925,0.000020) (0.910759,0.000020) (0.911593,0.000020) (0.912427,0.000020) (0.913261,0.000020) (0.914095,0.000019) (0.914929,0.000019) (0.915763,0.000019) (0.916597,0.000018) (0.917431,0.000018) (0.918265,0.000018) (0.919099,0.000017) (0.919933,0.000017) (0.920767,0.000017) (0.921601,0.000017) (0.922435,0.000017) (0.923269,0.000016) (0.924103,0.000016) (0.924937,0.000016) (0.925771,0.000016) (0.926606,0.000016) (0.927440,0.000016) (0.928274,0.000015) (0.929108,0.000015) (0.929942,0.000015) (0.930776,0.000015) (0.931610,0.000015) (0.932444,0.000015) (0.933278,0.000015) (0.934112,0.000015) (0.934946,0.000014) (0.935780,0.000014) (0.936614,0.000014) (0.937448,0.000014) (0.938282,0.000013) (0.939116,0.000013) (0.939950,0.000012) (0.940784,0.000012) (0.941618,0.000012) (0.942452,0.000012) (0.943286,0.000012) (0.944120,0.000012) (0.944954,0.000012) (0.945788,0.000012) (0.946622,0.000011) (0.947456,0.000011) (0.948290,0.000011) (0.949124,0.000011) (0.949958,0.000011) (0.950792,0.000011) (0.951626,0.000010) (0.952460,0.000010) (0.953294,0.000010) (0.954128,0.000010) (0.954962,0.000009) (0.955796,0.000009) (0.956631,0.000009) (0.957465,0.000009) (0.958299,0.000008) (0.959133,0.000008) (0.959967,0.000008) (0.960801,0.000008) (0.961635,0.000008) (0.962469,0.000008) (0.963303,0.000008) (0.964137,0.000008) (0.964971,0.000007) (0.965805,0.000007) (0.966639,0.000007) (0.967473,0.000007) (0.968307,0.000007) (0.969141,0.000007) (0.969975,0.000006) (0.970809,0.000006) (0.971643,0.000006) (0.972477,0.000005) (0.973311,0.000005) (0.974145,0.000004) (0.974979,0.000004) (0.975813,0.000004) (0.976647,0.000004) (0.977481,0.000004) (0.978315,0.000003) (0.979149,0.000003) (0.979983,0.000003) (0.980817,0.000003) (0.981651,0.000002) (0.982485,0.000002) (0.983319,0.000002) (0.984153,0.000002) (0.984987,0.000002) (0.985822,0.000002) (0.986656,0.000001) (0.987490,0.000001) (0.988324,0.000001) (0.989158,0.000001) (0.989992,0.000001) (0.990826,0.000001) (0.991660,0.000001) (0.992494,0.000001) (0.993328,0.000001) (0.994162,0.000001) (0.994996,0.000001) (0.995830,0.000001) (0.996664,0.000001) (0.997498,0.000001) (0.998332,0.000001) (0.999166,0.000001) (1.000000,0.000001) diff --git a/talk/vmil2012/presentation/figures/framechain1.pdf b/talk/vmil2012/presentation/figures/framechain1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..739545a0285cb335bd79f0276e06c6ae24708fc5 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/framechain2.pdf b/talk/vmil2012/presentation/figures/framechain2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2b173bd9e139a811bd6530ace8387d958e43d570 GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/go_data.tex b/talk/vmil2012/presentation/figures/go_data.tex --- a/talk/vmil2012/presentation/figures/go_data.tex +++ b/talk/vmil2012/presentation/figures/go_data.tex @@ -1,6 +1,6 @@ -\addplot[green,mark=none] coordinates { +\addplot[brown,mark=none] coordinates { (0.000000,1.000000) (0.000834,0.872400) (0.001668,0.683224) (0.002502,0.608314) (0.003336,0.542330) (0.004170,0.519721) (0.005004,0.447508) (0.005838,0.440065) (0.006672,0.420670) (0.007506,0.418862) (0.008340,0.418009) (0.009174,0.379519) (0.010008,0.357223) (0.010842,0.353534) (0.011676,0.333568) (0.012510,0.319704) (0.013344,0.268160) (0.014178,0.251065) (0.015013,0.226789) (0.015847,0.220089) (0.016681,0.215066) (0.017515,0.213903) (0.018349,0.213091) (0.019183,0.197153) (0.020017,0.187389) (0.020851,0.177430) (0.021685,0.173396) (0.022519,0.170787) (0.023353,0.160834) (0.024187,0.160045) (0.025021,0.157071) (0.025855,0.146612) (0.026689,0.144178) (0.027523,0.137699) (0.028357,0.136683) (0.029191,0.124833) (0.030025,0.121453) (0.030859,0.119189) (0.031693,0.115002) (0.032527,0.114249) (0.033361,0.107546) (0.034195,0.107268) (0.035029,0.104187) (0.035863,0.096624) (0.036697,0.089912) (0.037531,0.089585) (0.038365,0.087446) (0.039199,0.087298) (0.040033,0.084823) (0.040867,0.083414) (0.041701,0.083212) (0.042535,0.082227) (0.043369,0.079913) (0.044204,0.075734) (0.045038,0.073337) (0.045872,0.073039) (0.046706,0.072381) (0.047540,0.069693) (0.048374,0.067325) (0.049208,0.065996) (0.050042,0.057532) (0.050876,0.055707) (0.051710,0.055669) (0.052544,0.049083) (0.053378,0.048652) (0.054212,0.048015) (0.055046,0.045918) (0.055880,0.045234) (0.056714,0.042272) (0.057548,0.041798) (0.058382,0.040969) (0.059216,0.040163) (0.060050,0.040016) (0.060884,0.038778) (0.061718,0.038686) (0.062552,0.038456) (0.063386,0.033439) (0.064220,0.032381) (0.065054,0.031115) (0.065888,0.030103) (0.066722,0.029385) (0.067556,0.026654) (0.068390,0.025877) (0.069224,0.024467) (0.070058,0.024427) (0.070892,0.024134) (0.071726,0.024036) (0.072560,0.021379) (0.073394,0.020813) (0.074229,0.020166) (0.075063,0.020056) (0.075897,0.019981) (0.076731,0.019791) (0.077565,0.019672) (0.078399,0.019356) (0.079233,0.019269) (0.080067,0.019134) (0.080901,0.018119) (0.081735,0.017905) (0.082569,0.017878) (0.083403,0.017865) (0.084237,0.017769) (0.085071,0.017758) (0.085905,0.017065) (0.086739,0.016959) (0.087573,0.016686) (0.088407,0.015666) (0.089241,0.014908) (0.090075,0.014542) (0.090909,0.014518) (0.091743,0.014200) (0.092577,0.013865) (0.093411,0.013736) (0.094245,0.013273) (0.095079,0.013197) (0.095913,0.012997) (0.096747,0.012759) (0.097581,0.012642) (0.098415,0.012344) (0.099249,0.012031) (0.100083,0.011973) (0.100917,0.011805) (0.101751,0.011594) (0.102585,0.011387) (0.103420,0.011332) (0.104254,0.011246) (0.105088,0.010925) (0.105922,0.010566) (0.106756,0.010269) (0.107590,0.010235) (0.108424,0.010220) (0.109258,0.010135) (0.110092,0.010071) (0.110926,0.010048) (0.111760,0.010002) (0.112594,0.009762) (0.113428,0.009756) (0.114262,0.009751) (0.115096,0.009730) (0.115930,0.009551) (0.116764,0.009536) (0.117598,0.009404) (0.118432,0.009399) (0.119266,0.009298) (0.120100,0.009263) (0.120934,0.009245) (0.121768,0.009137) (0.122602,0.009120) (0.123436,0.009097) (0.124270,0.008816) (0.125104,0.008646) (0.125938,0.008484) (0.126772,0.008405) (0.127606,0.008149) (0.128440,0.008032) (0.129274,0.007872) (0.130108,0.007866) (0.130942,0.007823) (0.131776,0.007801) (0.132611,0.007718) (0.133445,0.007481) (0.134279,0.007373) (0.135113,0.007345) (0.135947,0.007296) (0.136781,0.007269) (0.137615,0.007233) (0.138449,0.006991) (0.139283,0.006905) (0.140117,0.006795) (0.140951,0.006738) (0.141785,0.006708) (0.142619,0.006551) (0.143453,0.006510) (0.144287,0.006435) (0.145121,0.006361) (0.145955,0.006238) (0.146789,0.006134) (0.147623,0.006027) (0.148457,0.005991) (0.149291,0.005921) (0.150125,0.005852) (0.150959,0.005852) (0.151793,0.005823) (0.152627,0.005794) (0.153461,0.005787) (0.154295,0.005746) (0.155129,0.005672) (0.155963,0.005619) (0.156797,0.005612) (0.157631,0.005557) (0.158465,0.005495) (0.159299,0.005495) (0.160133,0.005422) (0.160967,0.005324) (0.161802,0.005217) (0.162636,0.005196) (0.163470,0.005167) (0.164304,0.005107) (0.165138,0.005012) (0.165972,0.004999) (0.166806,0.004985) (0.167640,0.004981) (0.168474,0.004936) (0.169308,0.004912) (0.170142,0.004836) (0.170976,0.004822) (0.171810,0.004755) (0.172644,0.004692) (0.173478,0.004687) (0.174312,0.004667) (0.175146,0.004605) (0.175980,0.004546) (0.176814,0.004523) (0.177648,0.004518) (0.178482,0.004512) (0.179316,0.004447) (0.180150,0.004427) (0.180984,0.004408) (0.181818,0.004401) (0.182652,0.004336) (0.183486,0.004326) (0.184320,0.004255) (0.185154,0.004163) (0.185988,0.004152) (0.186822,0.004150) (0.187656,0.004132) (0.188490,0.004125) (0.189324,0.003972) (0.190158,0.003971) (0.190992,0.003942) (0.191827,0.003842) (0.192661,0.003797) (0.193495,0.003710) (0.194329,0.003703) (0.195163,0.003684) (0.195997,0.003626) (0.196831,0.003620) (0.197665,0.003576) (0.198499,0.003526) (0.199333,0.003451) (0.200167,0.003447) (0.201001,0.003402) (0.201835,0.003390) (0.202669,0.003364) (0.203503,0.003361) (0.204337,0.003356) (0.205171,0.003350) (0.206005,0.003341) (0.206839,0.003321) (0.207673,0.003278) (0.208507,0.003246) (0.209341,0.003239) (0.210175,0.003219) (0.211009,0.003208) (0.211843,0.003129) (0.212677,0.003123) (0.213511,0.003073) (0.214345,0.003063) (0.215179,0.003053) (0.216013,0.003053) (0.216847,0.003026) (0.217681,0.003007) (0.218515,0.002989) (0.219349,0.002929) (0.220183,0.002915) (0.221018,0.002913) (0.221852,0.002890) (0.222686,0.002861) (0.223520,0.002845) (0.224354,0.002804) (0.225188,0.002783) (0.226022,0.002781) (0.226856,0.002694) (0.227690,0.002669) (0.228524,0.002631) (0.229358,0.002579) (0.230192,0.002578) (0.231026,0.002573) (0.231860,0.002566) (0.232694,0.002507) (0.233528,0.002487) (0.234362,0.002486) (0.235196,0.002416) (0.236030,0.002367) (0.236864,0.002347) (0.237698,0.002344) (0.238532,0.002338) (0.239366,0.002330) (0.240200,0.002318) (0.241034,0.002315) (0.241868,0.002308) (0.242702,0.002308) (0.243536,0.002292) (0.244370,0.002287) (0.245204,0.002283) (0.246038,0.002264) (0.246872,0.002236) (0.247706,0.002227) (0.248540,0.002185) (0.249374,0.002173) (0.250209,0.002169) (0.251043,0.002135) (0.251877,0.002109) (0.252711,0.002039) (0.253545,0.002031) (0.254379,0.001987) (0.255213,0.001970) (0.256047,0.001966) (0.256881,0.001936) (0.257715,0.001908) (0.258549,0.001908) (0.259383,0.001893) (0.260217,0.001886) (0.261051,0.001882) (0.261885,0.001827) (0.262719,0.001827) (0.263553,0.001817) (0.264387,0.001797) (0.265221,0.001749) (0.266055,0.001742) (0.266889,0.001739) (0.267723,0.001727) (0.268557,0.001704) (0.269391,0.001700) (0.270225,0.001691) (0.271059,0.001690) (0.271893,0.001653) (0.272727,0.001600) (0.273561,0.001595) (0.274395,0.001555) (0.275229,0.001547) (0.276063,0.001546) (0.276897,0.001519) (0.277731,0.001513) (0.278565,0.001510) (0.279399,0.001505) (0.280234,0.001474) (0.281068,0.001468) (0.281902,0.001459) (0.282736,0.001458) (0.283570,0.001432) (0.284404,0.001410) (0.285238,0.001407) (0.286072,0.001401) (0.286906,0.001396) (0.287740,0.001391) (0.288574,0.001376) (0.289408,0.001372) (0.290242,0.001369) (0.291076,0.001345) (0.291910,0.001344) (0.292744,0.001318) (0.293578,0.001299) (0.294412,0.001295) (0.295246,0.001287) (0.296080,0.001285) (0.296914,0.001284) (0.297748,0.001270) (0.298582,0.001265) (0.299416,0.001253) (0.300250,0.001235) (0.301084,0.001233) (0.301918,0.001224) (0.302752,0.001222) (0.303586,0.001219) (0.304420,0.001209) (0.305254,0.001202) (0.306088,0.001191) (0.306922,0.001180) (0.307756,0.001173) (0.308590,0.001170) (0.309425,0.001167) (0.310259,0.001154) (0.311093,0.001147) (0.311927,0.001143) (0.312761,0.001130) (0.313595,0.001126) (0.314429,0.001124) (0.315263,0.001116) (0.316097,0.001115) (0.316931,0.001099) (0.317765,0.001088) (0.318599,0.001088) (0.319433,0.001082) (0.320267,0.001074) (0.321101,0.001071) (0.321935,0.001070) (0.322769,0.001066) (0.323603,0.001062) (0.324437,0.001047) (0.325271,0.001043) (0.326105,0.001041) (0.326939,0.001040) (0.327773,0.001038) (0.328607,0.001027) (0.329441,0.001025) (0.330275,0.001016) (0.331109,0.001016) (0.331943,0.000996) (0.332777,0.000992) (0.333611,0.000985) (0.334445,0.000979) (0.335279,0.000978) (0.336113,0.000978) (0.336947,0.000957) (0.337781,0.000953) (0.338616,0.000951) (0.339450,0.000947) (0.340284,0.000944) (0.341118,0.000939) (0.341952,0.000932) (0.342786,0.000930) (0.343620,0.000930) (0.344454,0.000928) (0.345288,0.000915) (0.346122,0.000914) (0.346956,0.000914) (0.347790,0.000911) (0.348624,0.000910) (0.349458,0.000908) (0.350292,0.000904) (0.351126,0.000895) (0.351960,0.000890) (0.352794,0.000887) (0.353628,0.000884) (0.354462,0.000879) (0.355296,0.000861) (0.356130,0.000861) (0.356964,0.000826) (0.357798,0.000814) (0.358632,0.000808) (0.359466,0.000800) (0.360300,0.000797) (0.361134,0.000796) (0.361968,0.000782) (0.362802,0.000779) (0.363636,0.000778) (0.364470,0.000777) (0.365304,0.000777) (0.366138,0.000775) (0.366972,0.000767) (0.367807,0.000764) (0.368641,0.000761) (0.369475,0.000758) (0.370309,0.000753) (0.371143,0.000753) (0.371977,0.000751) (0.372811,0.000738) (0.373645,0.000718) (0.374479,0.000718) (0.375313,0.000710) (0.376147,0.000709) (0.376981,0.000707) (0.377815,0.000701) (0.378649,0.000699) (0.379483,0.000694) (0.380317,0.000694) (0.381151,0.000688) (0.381985,0.000686) (0.382819,0.000683) (0.383653,0.000681) (0.384487,0.000665) (0.385321,0.000664) (0.386155,0.000660) (0.386989,0.000659) (0.387823,0.000657) (0.388657,0.000657) (0.389491,0.000655) (0.390325,0.000654) (0.391159,0.000647) (0.391993,0.000645) (0.392827,0.000644) (0.393661,0.000643) (0.394495,0.000642) (0.395329,0.000640) (0.396163,0.000639) (0.396997,0.000637) (0.397832,0.000634) (0.398666,0.000630) (0.399500,0.000614) (0.400334,0.000613) (0.401168,0.000607) (0.402002,0.000604) (0.402836,0.000603) (0.403670,0.000602) (0.404504,0.000602) (0.405338,0.000598) (0.406172,0.000597) (0.407006,0.000592) (0.407840,0.000588) (0.408674,0.000576) (0.409508,0.000572) (0.410342,0.000570) (0.411176,0.000570) (0.412010,0.000567) (0.412844,0.000567) (0.413678,0.000566) (0.414512,0.000564) (0.415346,0.000563) (0.416180,0.000554) (0.417014,0.000550) (0.417848,0.000548) (0.418682,0.000547) (0.419516,0.000547) (0.420350,0.000546) (0.421184,0.000542) (0.422018,0.000542) (0.422852,0.000535) (0.423686,0.000529) (0.424520,0.000518) (0.425354,0.000516) (0.426188,0.000515) (0.427023,0.000513) (0.427857,0.000512) (0.428691,0.000511) (0.429525,0.000503) (0.430359,0.000503) (0.431193,0.000503) (0.432027,0.000499) (0.432861,0.000497) (0.433695,0.000497) (0.434529,0.000495) (0.435363,0.000495) (0.436197,0.000494) (0.437031,0.000494) (0.437865,0.000492) (0.438699,0.000491) (0.439533,0.000490) (0.440367,0.000489) (0.441201,0.000488) (0.442035,0.000486) (0.442869,0.000484) (0.443703,0.000480) (0.444537,0.000479) (0.445371,0.000478) (0.446205,0.000471) (0.447039,0.000467) (0.447873,0.000466) (0.448707,0.000464) (0.449541,0.000460) (0.450375,0.000458) (0.451209,0.000456) (0.452043,0.000452) (0.452877,0.000451) (0.453711,0.000448) (0.454545,0.000446) (0.455379,0.000445) (0.456214,0.000444) (0.457048,0.000437) (0.457882,0.000436) (0.458716,0.000435) (0.459550,0.000431) (0.460384,0.000431) (0.461218,0.000430) (0.462052,0.000428) (0.462886,0.000428) (0.463720,0.000428) (0.464554,0.000427) (0.465388,0.000427) (0.466222,0.000422) (0.467056,0.000420) (0.467890,0.000415) (0.468724,0.000409) (0.469558,0.000408) (0.470392,0.000408) (0.471226,0.000406) (0.472060,0.000405) (0.472894,0.000404) (0.473728,0.000404) (0.474562,0.000402) (0.475396,0.000402) (0.476230,0.000402) (0.477064,0.000402) (0.477898,0.000399) (0.478732,0.000399) (0.479566,0.000398) (0.480400,0.000395) (0.481234,0.000395) (0.482068,0.000394) (0.482902,0.000390) (0.483736,0.000389) (0.484570,0.000387) (0.485405,0.000385) (0.486239,0.000383) (0.487073,0.000382) (0.487907,0.000381) (0.488741,0.000380) (0.489575,0.000380) (0.490409,0.000377) (0.491243,0.000375) (0.492077,0.000374) (0.492911,0.000373) (0.493745,0.000371) (0.494579,0.000370) (0.495413,0.000369) (0.496247,0.000368) (0.497081,0.000366) (0.497915,0.000364) (0.498749,0.000362) (0.499583,0.000362) (0.500417,0.000358) (0.501251,0.000354) (0.502085,0.000346) (0.502919,0.000345) (0.503753,0.000344) (0.504587,0.000343) (0.505421,0.000341) (0.506255,0.000340) (0.507089,0.000337) (0.507923,0.000337) (0.508757,0.000331) (0.509591,0.000328) (0.510425,0.000325) (0.511259,0.000323) (0.512093,0.000319) (0.512927,0.000319) (0.513761,0.000317) (0.514595,0.000315) (0.515430,0.000314) (0.516264,0.000313) (0.517098,0.000313) (0.517932,0.000312) (0.518766,0.000312) (0.519600,0.000311) (0.520434,0.000302) (0.521268,0.000300) (0.522102,0.000300) (0.522936,0.000295) (0.523770,0.000295) (0.524604,0.000295) (0.525438,0.000292) (0.526272,0.000290) (0.527106,0.000290) (0.527940,0.000288) (0.528774,0.000287) (0.529608,0.000285) (0.530442,0.000280) (0.531276,0.000278) (0.532110,0.000278) (0.532944,0.000278) (0.533778,0.000277) (0.534612,0.000276) (0.535446,0.000274) (0.536280,0.000273) (0.537114,0.000271) (0.537948,0.000271) (0.538782,0.000270) (0.539616,0.000266) (0.540450,0.000263) (0.541284,0.000260) (0.542118,0.000260) (0.542952,0.000258) (0.543786,0.000258) (0.544621,0.000256) (0.545455,0.000253) (0.546289,0.000252) (0.547123,0.000251) (0.547957,0.000249) (0.548791,0.000248) (0.549625,0.000248) (0.550459,0.000248) (0.551293,0.000246) (0.552127,0.000246) (0.552961,0.000244) (0.553795,0.000244) (0.554629,0.000242) (0.555463,0.000241) (0.556297,0.000240) (0.557131,0.000240) (0.557965,0.000239) (0.558799,0.000236) (0.559633,0.000236) (0.560467,0.000235) (0.561301,0.000234) (0.562135,0.000234) (0.562969,0.000234) (0.563803,0.000233) (0.564637,0.000233) (0.565471,0.000225) (0.566305,0.000223) (0.567139,0.000223) (0.567973,0.000220) (0.568807,0.000219) (0.569641,0.000218) (0.570475,0.000218) (0.571309,0.000217) (0.572143,0.000216) (0.572977,0.000213) (0.573812,0.000211) (0.574646,0.000207) (0.575480,0.000206) (0.576314,0.000206) (0.577148,0.000205) (0.577982,0.000205) (0.578816,0.000203) (0.579650,0.000203) (0.580484,0.000203) (0.581318,0.000203) (0.582152,0.000203) (0.582986,0.000201) (0.583820,0.000200) (0.584654,0.000200) (0.585488,0.000199) (0.586322,0.000199) (0.587156,0.000197) (0.587990,0.000194) (0.588824,0.000193) (0.589658,0.000191) (0.590492,0.000190) (0.591326,0.000190) (0.592160,0.000186) (0.592994,0.000186) (0.593828,0.000181) (0.594662,0.000178) (0.595496,0.000175) (0.596330,0.000174) (0.597164,0.000173) (0.597998,0.000173) (0.598832,0.000172) (0.599666,0.000171) (0.600500,0.000171) (0.601334,0.000170) (0.602168,0.000170) (0.603003,0.000169) (0.603837,0.000166) (0.604671,0.000165) (0.605505,0.000165) (0.606339,0.000165) (0.607173,0.000164) (0.608007,0.000163) (0.608841,0.000162) (0.609675,0.000162) (0.610509,0.000162) (0.611343,0.000162) (0.612177,0.000161) (0.613011,0.000161) (0.613845,0.000159) (0.614679,0.000158) (0.615513,0.000158) (0.616347,0.000157) (0.617181,0.000156) (0.618015,0.000155) (0.618849,0.000155) (0.619683,0.000152) (0.620517,0.000152) (0.621351,0.000151) (0.622185,0.000151) (0.623019,0.000149) (0.623853,0.000149) (0.624687,0.000148) (0.625521,0.000147) (0.626355,0.000147) (0.627189,0.000146) (0.628023,0.000146) (0.628857,0.000146) (0.629691,0.000146) (0.630525,0.000145) (0.631359,0.000145) (0.632193,0.000144) (0.633028,0.000144) (0.633862,0.000144) (0.634696,0.000144) (0.635530,0.000143) (0.636364,0.000142) (0.637198,0.000142) (0.638032,0.000142) (0.638866,0.000142) (0.639700,0.000141) (0.640534,0.000140) (0.641368,0.000139) (0.642202,0.000137) (0.643036,0.000137) (0.643870,0.000133) (0.644704,0.000131) (0.645538,0.000131) (0.646372,0.000129) (0.647206,0.000129) (0.648040,0.000129) (0.648874,0.000128) (0.649708,0.000128) (0.650542,0.000127) (0.651376,0.000124) (0.652210,0.000123) (0.653044,0.000119) (0.653878,0.000117) (0.654712,0.000117) (0.655546,0.000117) (0.656380,0.000115) (0.657214,0.000114) (0.658048,0.000114) (0.658882,0.000114) (0.659716,0.000113) (0.660550,0.000112) (0.661384,0.000111) (0.662219,0.000111) (0.663053,0.000111) (0.663887,0.000111) (0.664721,0.000110) (0.665555,0.000110) (0.666389,0.000109) (0.667223,0.000108) (0.668057,0.000108) (0.668891,0.000107) (0.669725,0.000105) (0.670559,0.000105) (0.671393,0.000105) (0.672227,0.000105) (0.673061,0.000105) (0.673895,0.000105) (0.674729,0.000105) (0.675563,0.000104) (0.676397,0.000104) (0.677231,0.000103) (0.678065,0.000102) (0.678899,0.000101) (0.679733,0.000101) (0.680567,0.000100) (0.681401,0.000100) (0.682235,0.000100) (0.683069,0.000099) (0.683903,0.000099) (0.684737,0.000098) (0.685571,0.000098) (0.686405,0.000098) (0.687239,0.000097) (0.688073,0.000094) (0.688907,0.000094) (0.689741,0.000092) (0.690575,0.000092) (0.691410,0.000091) (0.692244,0.000089) (0.693078,0.000089) (0.693912,0.000087) (0.694746,0.000087) (0.695580,0.000087) (0.696414,0.000086) (0.697248,0.000086) (0.698082,0.000086) (0.698916,0.000085) (0.699750,0.000085) (0.700584,0.000085) (0.701418,0.000085) (0.702252,0.000084) (0.703086,0.000084) (0.703920,0.000083) (0.704754,0.000083) (0.705588,0.000082) (0.706422,0.000081) (0.707256,0.000080) (0.708090,0.000080) (0.708924,0.000080) (0.709758,0.000079) (0.710592,0.000079) (0.711426,0.000078) (0.712260,0.000078) (0.713094,0.000077) (0.713928,0.000076) (0.714762,0.000076) (0.715596,0.000076) (0.716430,0.000075) (0.717264,0.000075) (0.718098,0.000072) (0.718932,0.000071) (0.719766,0.000071) (0.720601,0.000070) (0.721435,0.000070) (0.722269,0.000070) (0.723103,0.000070) (0.723937,0.000070) (0.724771,0.000070) (0.725605,0.000069) (0.726439,0.000068) (0.727273,0.000068) (0.728107,0.000068) (0.728941,0.000067) (0.729775,0.000067) (0.730609,0.000067) (0.731443,0.000067) (0.732277,0.000066) (0.733111,0.000066) (0.733945,0.000065) (0.734779,0.000065) (0.735613,0.000065) (0.736447,0.000065) (0.737281,0.000064) (0.738115,0.000064) (0.738949,0.000063) (0.739783,0.000063) (0.740617,0.000063) (0.741451,0.000062) (0.742285,0.000062) (0.743119,0.000060) (0.743953,0.000060) (0.744787,0.000059) (0.745621,0.000059) (0.746455,0.000059) (0.747289,0.000059) (0.748123,0.000058) (0.748957,0.000058) (0.749791,0.000057) (0.750626,0.000057) (0.751460,0.000057) (0.752294,0.000057) (0.753128,0.000057) (0.753962,0.000057) (0.754796,0.000057) (0.755630,0.000057) (0.756464,0.000057) (0.757298,0.000057) (0.758132,0.000057) (0.758966,0.000057) (0.759800,0.000057) (0.760634,0.000057) (0.761468,0.000057) (0.762302,0.000057) (0.763136,0.000056) (0.763970,0.000056) (0.764804,0.000055) (0.765638,0.000055) (0.766472,0.000055) (0.767306,0.000055) (0.768140,0.000055) (0.768974,0.000055) (0.769808,0.000054) (0.770642,0.000054) (0.771476,0.000054) (0.772310,0.000054) (0.773144,0.000054) (0.773978,0.000053) (0.774812,0.000053) (0.775646,0.000053) (0.776480,0.000053) (0.777314,0.000053) (0.778148,0.000053) (0.778982,0.000053) (0.779817,0.000052) (0.780651,0.000052) (0.781485,0.000052) (0.782319,0.000052) (0.783153,0.000052) (0.783987,0.000052) (0.784821,0.000052) (0.785655,0.000051) (0.786489,0.000051) (0.787323,0.000051) (0.788157,0.000051) (0.788991,0.000050) (0.789825,0.000050) (0.790659,0.000050) (0.791493,0.000049) (0.792327,0.000049) (0.793161,0.000049) (0.793995,0.000049) (0.794829,0.000049) (0.795663,0.000049) (0.796497,0.000049) (0.797331,0.000047) (0.798165,0.000047) (0.798999,0.000047) (0.799833,0.000047) (0.800667,0.000046) (0.801501,0.000046) (0.802335,0.000046) (0.803169,0.000046) (0.804003,0.000045) (0.804837,0.000045) (0.805671,0.000044) (0.806505,0.000044) (0.807339,0.000043) (0.808173,0.000043) (0.809008,0.000043) (0.809842,0.000043) (0.810676,0.000042) (0.811510,0.000042) (0.812344,0.000041) (0.813178,0.000041) (0.814012,0.000041) (0.814846,0.000041) (0.815680,0.000040) (0.816514,0.000040) (0.817348,0.000038) (0.818182,0.000038) (0.819016,0.000038) (0.819850,0.000037) (0.820684,0.000037) (0.821518,0.000037) (0.822352,0.000037) (0.823186,0.000037) (0.824020,0.000036) (0.824854,0.000036) (0.825688,0.000035) (0.826522,0.000035) (0.827356,0.000035) (0.828190,0.000035) (0.829024,0.000034) (0.829858,0.000034) (0.830692,0.000033) (0.831526,0.000033) (0.832360,0.000033) (0.833194,0.000033) (0.834028,0.000032) (0.834862,0.000032) (0.835696,0.000031) (0.836530,0.000031) (0.837364,0.000030) (0.838198,0.000030) (0.839033,0.000030) (0.839867,0.000030) (0.840701,0.000029) (0.841535,0.000029) (0.842369,0.000029) (0.843203,0.000029) (0.844037,0.000029) (0.844871,0.000028) (0.845705,0.000028) (0.846539,0.000028) (0.847373,0.000028) (0.848207,0.000028) (0.849041,0.000028) (0.849875,0.000028) (0.850709,0.000028) (0.851543,0.000028) (0.852377,0.000028) (0.853211,0.000028) (0.854045,0.000028) (0.854879,0.000028) (0.855713,0.000028) (0.856547,0.000028) (0.857381,0.000028) (0.858215,0.000028) (0.859049,0.000027) (0.859883,0.000027) (0.860717,0.000027) (0.861551,0.000027) (0.862385,0.000027) (0.863219,0.000027) (0.864053,0.000027) (0.864887,0.000027) (0.865721,0.000027) (0.866555,0.000027) (0.867389,0.000027) (0.868224,0.000027) (0.869058,0.000027) (0.869892,0.000026) (0.870726,0.000026) (0.871560,0.000026) (0.872394,0.000025) (0.873228,0.000025) (0.874062,0.000025) (0.874896,0.000025) (0.875730,0.000025) (0.876564,0.000025) (0.877398,0.000025) (0.878232,0.000025) (0.879066,0.000025) (0.879900,0.000025) (0.880734,0.000024) (0.881568,0.000024) (0.882402,0.000024) (0.883236,0.000024) (0.884070,0.000024) (0.884904,0.000024) (0.885738,0.000023) (0.886572,0.000023) (0.887406,0.000023) (0.888240,0.000023) (0.889074,0.000023) (0.889908,0.000023) (0.890742,0.000022) (0.891576,0.000022) (0.892410,0.000022) (0.893244,0.000022) (0.894078,0.000022) (0.894912,0.000022) (0.895746,0.000022) (0.896580,0.000022) (0.897415,0.000021) (0.898249,0.000021) (0.899083,0.000021) (0.899917,0.000021) (0.900751,0.000021) (0.901585,0.000021) (0.902419,0.000021) (0.903253,0.000021) (0.904087,0.000021) (0.904921,0.000021) (0.905755,0.000021) (0.906589,0.000021) (0.907423,0.000021) (0.908257,0.000020) (0.909091,0.000020) (0.909925,0.000020) (0.910759,0.000020) (0.911593,0.000020) (0.912427,0.000020) (0.913261,0.000020) (0.914095,0.000019) (0.914929,0.000019) (0.915763,0.000019) (0.916597,0.000018) (0.917431,0.000018) (0.918265,0.000018) (0.919099,0.000017) (0.919933,0.000017) (0.920767,0.000017) (0.921601,0.000017) (0.922435,0.000017) (0.923269,0.000016) (0.924103,0.000016) (0.924937,0.000016) (0.925771,0.000016) (0.926606,0.000016) (0.927440,0.000016) (0.928274,0.000015) (0.929108,0.000015) (0.929942,0.000015) (0.930776,0.000015) (0.931610,0.000015) (0.932444,0.000015) (0.933278,0.000015) (0.934112,0.000015) (0.934946,0.000014) (0.935780,0.000014) (0.936614,0.000014) (0.937448,0.000014) (0.938282,0.000013) (0.939116,0.000013) (0.939950,0.000012) (0.940784,0.000012) (0.941618,0.000012) (0.942452,0.000012) (0.943286,0.000012) (0.944120,0.000012) (0.944954,0.000012) (0.945788,0.000012) (0.946622,0.000011) (0.947456,0.000011) (0.948290,0.000011) (0.949124,0.000011) (0.949958,0.000011) (0.950792,0.000011) (0.951626,0.000010) (0.952460,0.000010) (0.953294,0.000010) (0.954128,0.000010) (0.954962,0.000009) (0.955796,0.000009) (0.956631,0.000009) (0.957465,0.000009) (0.958299,0.000008) (0.959133,0.000008) (0.959967,0.000008) (0.960801,0.000008) (0.961635,0.000008) (0.962469,0.000008) (0.963303,0.000008) (0.964137,0.000008) (0.964971,0.000007) (0.965805,0.000007) (0.966639,0.000007) (0.967473,0.000007) (0.968307,0.000007) (0.969141,0.000007) (0.969975,0.000006) (0.970809,0.000006) (0.971643,0.000006) (0.972477,0.000005) (0.973311,0.000005) (0.974145,0.000004) (0.974979,0.000004) (0.975813,0.000004) (0.976647,0.000004) (0.977481,0.000004) (0.978315,0.000003) (0.979149,0.000003) (0.979983,0.000003) (0.980817,0.000003) (0.981651,0.000002) (0.982485,0.000002) (0.983319,0.000002) (0.984153,0.000002) (0.984987,0.000002) (0.985822,0.000002) (0.986656,0.000001) (0.987490,0.000001) (0.988324,0.000001) (0.989158,0.000001) (0.989992,0.000001) (0.990826,0.000001) (0.991660,0.000001) (0.992494,0.000001) (0.993328,0.000001) (0.994162,0.000001) (0.994996,0.000001) (0.995830,0.000001) (0.996664,0.000001) (0.997498,0.000001) (0.998332,0.000001) (0.999166,0.000001) (1.000000,0.000001) }; -\addplot[green,only marks,mark=*] coordinates {(0.015013,0.226789) (0.341952,0.000932) (0.663053,0.000111)}; +\addplot[brown,only marks,mark=*] coordinates {(0.015013,0.226789) (0.341952,0.000932) (0.663053,0.000111)}; \ No newline at end of file diff --git a/talk/vmil2012/presentation/figures/jit_memory.pdf b/talk/vmil2012/presentation/figures/jit_memory.pdf new file mode 100644 index 0000000000000000000000000000000000000000..760a992c738602fe4decea13cbc78eeac3db15eb GIT binary patch [cut] diff --git a/talk/vmil2012/presentation/figures/loop.graffle b/talk/vmil2012/presentation/figures/loop.graffle --- a/talk/vmil2012/presentation/figures/loop.graffle +++ b/talk/vmil2012/presentation/figures/loop.graffle @@ -14,7 +14,7 @@ BackgroundGraphic Bounds - {{0, 0}, {559, 783}} + {{0, 0}, {1118, 783}} Class SolidGraphic ID @@ -132,15 +132,13 @@ Bounds - {{353.00001525878906, 92.5}, {166.99998474121094, 93.5}} + {{232.00001379686913, 294.74999999999989}, {150.99998620313085, 93.5}} Class ShapedGraphic ID 59 Magnets - {0, 1} - {0, -1} {1, 0} {-1, 0} @@ -163,7 +161,7 @@ Bounds - {{353, 59}, {167, 33.5}} + {{232, 261.25}, {151, 33.5}} Class ShapedGraphic ID @@ -189,13 +187,6 @@ ID 58 - Magnets - - {0, 1} - {0, -1} - {1, 0} - {-1, 0} - Class @@ -209,9 +200,9 @@ 54 Points - {186, 334.75} - {232, 285.49998514226786} - {242.89735689328157, 270.5} + {82.536736108577472, 339.10023442863826} + {52, 351.5} + {34.428503435249759, 361.50264298468693} Style @@ -233,6 +224,8 @@ ID 42 + Info + 2 @@ -247,9 +240,9 @@ 53 Points - {186, 301.25} - {211, 234} - {242.89735689328157, 147} + {83, 301.25} + {60, 286} + {33.993974985969523, 268.75} Style @@ -271,8 +264,6 @@ ID 37 - Info - 1 @@ -287,9 +278,9 @@ 48 Points - {186, 334.75} - {327, 318} - {436.50000762939453, 186} + {134.5, 351.5} + {186, 384} + {232.0000137968691, 341.49999999999989} Style @@ -324,8 +315,8 @@ Points {186, 301.25} - {260, 220} - {353.00001525878906, 139.25} + {211, 307} + {232.0000137968691, 341.49999999999989} Style @@ -392,6 +383,8 @@ 42 Magnets + {0, 1} + {0, -1} {1, 0} {-1, 0} @@ -410,7 +403,7 @@ Bounds - {{237, 247}, {85, 47}} + {{-46, 338.25}, {85, 47}} Class ShapedGraphic ID @@ -437,7 +430,7 @@ Bounds - {{237, 123.5}, {85, 47}} + {{-46, 245.25}, {85, 47}} Class ShapedGraphic ID @@ -713,6 +706,997 @@ Shape From noreply at buildbot.pypy.org Tue Oct 23 16:56:54 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Tue, 23 Oct 2012 16:56:54 +0200 (CEST) Subject: [pypy-commit] pypy default: added a missing import Message-ID: <20121023145654.E25571C0C32@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r58379:440e7fa6494e Date: 2012-10-23 07:56 -0700 http://bitbucket.org/pypy/pypy/changeset/440e7fa6494e/ Log: added a missing import diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -323,10 +323,12 @@ def robjmodel_hlinvoke(s_repr, s_llcallable, *args_s): from pypy.rpython import rmodel - assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr),"hlinvoke expects a constant repr as first argument" - r_func, nimplicitarg = s_repr.const.get_r_implfunc() + from pypy.rpython.error import TyperError - nbargs = len(args_s) + nimplicitarg + assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr), "hlinvoke expects a constant repr as first argument" + r_func, nimplicitarg = s_repr.const.get_r_implfunc() + + nbargs = len(args_s) + nimplicitarg s_sigs = r_func.get_s_signatures((nbargs, (), False, False)) if len(s_sigs) != 1: raise TyperError("cannot hlinvoke callable %r with not uniform" @@ -337,6 +339,7 @@ return lltype_to_annotation(rresult.lowleveltype) + def robjmodel_keepalive_until_here(*args_s): return immutablevalue(None) From noreply at buildbot.pypy.org Tue Oct 23 18:38:49 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Tue, 23 Oct 2012 18:38:49 +0200 (CEST) Subject: [pypy-commit] pypy default: bah, bug-to-bug compatibility to cpython about when it is allowed to return a Message-ID: <20121023163849.872D31C1C8C@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r58380:6272fd9c2531 Date: 2012-10-23 18:38 +0200 http://bitbucket.org/pypy/pypy/changeset/6272fd9c2531/ Log: bah, bug-to-bug compatibility to cpython about when it is allowed to return a non complex from __complex__. This in part reverts 6d1ad31ec914, so it in part reintroduce the behaviour of f1c048beb436. See test___complex___returning_non_complex for details. diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py --- a/pypy/objspace/std/complextype.py +++ b/pypy/objspace/std/complextype.py @@ -149,12 +149,12 @@ else: # non-string arguments - realval, imagval = unpackcomplex(space, w_real) + realval, imagval = unpackcomplex(space, w_real, strict_typing=False) # now take w_imag into account if not noarg2: # complex(x, y) == x+y*j, even if 'y' is already a complex. - realval2, imagval2 = unpackcomplex(space, w_imag) + realval2, imagval2 = unpackcomplex(space, w_imag, strict_typing=False) # try to preserve the signs of zeroes of realval and realval2 if imagval2 != 0.0: @@ -170,7 +170,13 @@ return w_obj -def unpackcomplex(space, w_complex): +def unpackcomplex(space, w_complex, strict_typing=True): + """ + convert w_complex into a complex and return the unwrapped (real, imag) + tuple. If strict_typing==True, we also typecheck the value returned by + __complex__ to actually be a complex (and not e.g. a float). + See test___complex___returning_non_complex. + """ from pypy.objspace.std.complexobject import W_ComplexObject if type(w_complex) is W_ComplexObject: return (w_complex.realval, w_complex.imagval) @@ -194,15 +200,15 @@ if w_z is not None: # __complex__() must return a complex or (float,int,long) object # (XXX should not use isinstance here) - if (space.isinstance_w(w_z, space.w_int) or - space.isinstance_w(w_z, space.w_long) or - space.isinstance_w(w_z, space.w_float)): + if not strict_typing and (space.isinstance_w(w_z, space.w_int) or + space.isinstance_w(w_z, space.w_long) or + space.isinstance_w(w_z, space.w_float)): return (space.float_w(w_z), 0.0) elif isinstance(w_z, W_ComplexObject): return (w_z.realval, w_z.imagval) raise OperationError(space.w_TypeError, space.wrap("__complex__() must return" - " a number")) + " a complex number")) # # no '__complex__' method, so we assume it is a float, diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -250,13 +250,6 @@ assert complex(OS(1+10j), 5j) == -4+10j assert complex(NS(1+10j), 5j) == -4+10j - assert complex(OS(2.0)) == 2+0j - assert complex(NS(2.0)) == 2+0j - assert complex(OS(2)) == 2+0j - assert complex(NS(2)) == 2+0j - assert complex(OS(2L)) == 2+0j - assert complex(NS(2L)) == 2+0j - raises(TypeError, complex, OS(None)) raises(TypeError, complex, NS(None)) @@ -363,6 +356,25 @@ assert self.almost_equal(complex(real=float2(17.), imag=float2(23.)), 17+23j) raises(TypeError, complex, float2(None)) + def test___complex___returning_non_complex(self): + import cmath + class Obj(object): + def __init__(self, value): + self.value = value + def __complex__(self): + return self.value + + # "bug-to-bug" compatibility to CPython: complex() is more relaxed in + # what __complex__ can return. cmath functions really wants a complex + # number to be returned by __complex__. + assert complex(Obj(2.0)) == 2+0j + assert complex(Obj(2)) == 2+0j + assert complex(Obj(2L)) == 2+0j + # + assert cmath.polar(1) == (1.0, 0.0) + raises(TypeError, "cmath.polar(Obj(1))") + + def test_hash(self): for x in xrange(-30, 30): assert hash(x) == hash(complex(x, 0)) From noreply at buildbot.pypy.org Tue Oct 23 21:08:04 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Tue, 23 Oct 2012 21:08:04 +0200 (CEST) Subject: [pypy-commit] pypy jit-usable_retrace_3: hg merge default Message-ID: <20121023190804.091821C1C8F@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: jit-usable_retrace_3 Changeset: r58381:1b058bdcfbcb Date: 2012-10-20 13:04 +0200 http://bitbucket.org/pypy/pypy/changeset/1b058bdcfbcb/ Log: hg merge default diff too long, truncating to 2000 out of 90315 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,5 +1,6 @@ syntax: glob *.py[co] +*.sw[po] *~ .*.swp .idea diff --git a/lib-python/2.7/BaseHTTPServer.py b/lib-python/2.7/BaseHTTPServer.py --- a/lib-python/2.7/BaseHTTPServer.py +++ b/lib-python/2.7/BaseHTTPServer.py @@ -244,14 +244,11 @@ self.request_version = version = self.default_request_version self.close_connection = 1 requestline = self.raw_requestline - if requestline[-2:] == '\r\n': - requestline = requestline[:-2] - elif requestline[-1:] == '\n': - requestline = requestline[:-1] + requestline = requestline.rstrip('\r\n') self.requestline = requestline words = requestline.split() if len(words) == 3: - [command, path, version] = words + command, path, version = words if version[:5] != 'HTTP/': self.send_error(400, "Bad request version (%r)" % version) return False @@ -277,7 +274,7 @@ "Invalid HTTP Version (%s)" % base_version_number) return False elif len(words) == 2: - [command, path] = words + command, path = words self.close_connection = 1 if command != 'GET': self.send_error(400, diff --git a/lib-python/2.7/ConfigParser.py b/lib-python/2.7/ConfigParser.py --- a/lib-python/2.7/ConfigParser.py +++ b/lib-python/2.7/ConfigParser.py @@ -142,6 +142,7 @@ def __init__(self, section): Error.__init__(self, 'No section: %r' % (section,)) self.section = section + self.args = (section, ) class DuplicateSectionError(Error): """Raised when a section is multiply-created.""" @@ -149,6 +150,7 @@ def __init__(self, section): Error.__init__(self, "Section %r already exists" % section) self.section = section + self.args = (section, ) class NoOptionError(Error): """A requested option was not found.""" @@ -158,6 +160,7 @@ (option, section)) self.option = option self.section = section + self.args = (option, section) class InterpolationError(Error): """Base class for interpolation-related exceptions.""" @@ -166,6 +169,7 @@ Error.__init__(self, msg) self.option = option self.section = section + self.args = (option, section, msg) class InterpolationMissingOptionError(InterpolationError): """A string substitution required a setting which was not available.""" @@ -179,6 +183,7 @@ % (section, option, reference, rawval)) InterpolationError.__init__(self, option, section, msg) self.reference = reference + self.args = (option, section, rawval, reference) class InterpolationSyntaxError(InterpolationError): """Raised when the source text into which substitutions are made @@ -194,6 +199,7 @@ "\trawval : %s\n" % (section, option, rawval)) InterpolationError.__init__(self, option, section, msg) + self.args = (option, section, rawval) class ParsingError(Error): """Raised when a configuration file does not follow legal syntax.""" @@ -202,6 +208,7 @@ Error.__init__(self, 'File contains parsing errors: %s' % filename) self.filename = filename self.errors = [] + self.args = (filename, ) def append(self, lineno, line): self.errors.append((lineno, line)) @@ -218,6 +225,7 @@ self.filename = filename self.lineno = lineno self.line = line + self.args = (filename, lineno, line) class RawConfigParser: @@ -570,7 +578,7 @@ def keys(self): result = [] seen = set() - for mapping in self_maps: + for mapping in self._maps: for key in mapping: if key not in seen: result.append(key) diff --git a/lib-python/2.7/HTMLParser.py b/lib-python/2.7/HTMLParser.py --- a/lib-python/2.7/HTMLParser.py +++ b/lib-python/2.7/HTMLParser.py @@ -14,7 +14,6 @@ # Regular expressions used for parsing interesting_normal = re.compile('[&<]') -interesting_cdata = re.compile(r'<(/|\Z)') incomplete = re.compile('&[a-zA-Z#]') entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') @@ -24,25 +23,31 @@ piclose = re.compile('>') commentclose = re.compile(r'--\s*>') tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*') +# see http://www.w3.org/TR/html5/tokenization.html#tag-open-state +# and http://www.w3.org/TR/html5/tokenization.html#tag-name-state +tagfind_tolerant = re.compile('[a-zA-Z][^\t\n\r\f />\x00]*') + attrfind = re.compile( - r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' - r'(\'[^\']*\'|"[^"]*"|[^\s"\'=<>`]*))?') + r'[\s/]*((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' + r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*') locatestarttagend = re.compile(r""" <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name - (?:\s+ # whitespace before attribute name - (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name - (?:\s*=\s* # value indicator + (?:[\s/]* # optional whitespace before attribute name + (?:(?<=['"\s/])[^\s/>][^\s/=>]* # attribute name + (?:\s*=+\s* # value indicator (?:'[^']*' # LITA-enclosed value - |\"[^\"]*\" # LIT-enclosed value - |[^'\">\s]+ # bare value + |"[^"]*" # LIT-enclosed value + |(?!['"])[^>\s]* # bare value ) - )? - ) - )* + )?(?:\s|/(?!>))* + )* + )? \s* # trailing whitespace """, re.VERBOSE) endendtag = re.compile('>') +# the HTML 5 spec, section 8.1.2.2, doesn't allow spaces between +# ') @@ -96,6 +101,7 @@ self.rawdata = '' self.lasttag = '???' self.interesting = interesting_normal + self.cdata_elem = None markupbase.ParserBase.reset(self) def feed(self, data): @@ -120,11 +126,13 @@ """Return full source of start tag: '<...>'.""" return self.__starttag_text - def set_cdata_mode(self): - self.interesting = interesting_cdata + def set_cdata_mode(self, elem): + self.cdata_elem = elem.lower() + self.interesting = re.compile(r'' % self.cdata_elem, re.I) def clear_cdata_mode(self): self.interesting = interesting_normal + self.cdata_elem = None # Internal -- handle data as far as reasonable. May leave state # and data to be processed by a subsequent call. If 'end' is @@ -138,6 +146,8 @@ if match: j = match.start() else: + if self.cdata_elem: + break j = n if i < j: self.handle_data(rawdata[i:j]) i = self.updatepos(i, j) @@ -153,16 +163,23 @@ elif startswith("', i + 1) + if k < 0: + k = rawdata.find('<', i + 1) + if k < 0: + k = i + 1 + else: + k += 1 + self.handle_data(rawdata[i:k]) i = self.updatepos(i, k) elif startswith("&#", i): match = charref.match(rawdata, i) @@ -206,11 +223,46 @@ else: assert 0, "interesting.search() lied" # end while - if end and i < n: + if end and i < n and not self.cdata_elem: self.handle_data(rawdata[i:n]) i = self.updatepos(i, n) self.rawdata = rawdata[i:] + # Internal -- parse html declarations, return length or -1 if not terminated + # See w3.org/TR/html5/tokenization.html#markup-declaration-open-state + # See also parse_declaration in _markupbase + def parse_html_declaration(self, i): + rawdata = self.rawdata + if rawdata[i:i+2] != ' + gtpos = rawdata.find('>', i+9) + if gtpos == -1: + return -1 + self.handle_decl(rawdata[i+2:gtpos]) + return gtpos+1 + else: + return self.parse_bogus_comment(i) + + # Internal -- parse bogus comment, return length or -1 if not terminated + # see http://www.w3.org/TR/html5/tokenization.html#bogus-comment-state + def parse_bogus_comment(self, i, report=1): + rawdata = self.rawdata + if rawdata[i:i+2] not in ('', i+2) + if pos == -1: + return -1 + if report: + self.handle_comment(rawdata[i+2:pos]) + return pos + 1 + # Internal -- parse processing instr, return end or -1 if not terminated def parse_pi(self, i): rawdata = self.rawdata @@ -249,6 +301,7 @@ elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ attrvalue[:1] == '"' == attrvalue[-1:]: attrvalue = attrvalue[1:-1] + if attrvalue: attrvalue = self.unescape(attrvalue) attrs.append((attrname.lower(), attrvalue)) k = m.end() @@ -262,15 +315,15 @@ - self.__starttag_text.rfind("\n") else: offset = offset + len(self.__starttag_text) - self.error("junk characters in start tag: %r" - % (rawdata[k:endpos][:20],)) + self.handle_data(rawdata[i:endpos]) + return endpos if end.endswith('/>'): # XHTML-style empty tag: self.handle_startendtag(tag, attrs) else: self.handle_starttag(tag, attrs) if tag in self.CDATA_CONTENT_ELEMENTS: - self.set_cdata_mode() + self.set_cdata_mode(tag) return endpos # Internal -- check to see if we have a complete starttag; return end @@ -300,8 +353,10 @@ # end of input in or before attribute value, or we have the # '/' from a '/>' ending return -1 - self.updatepos(i, j) - self.error("malformed start tag") + if j > i: + return j + else: + return i + 1 raise AssertionError("we should not get here!") # Internal -- parse endtag, return end or -1 if incomplete @@ -311,14 +366,38 @@ match = endendtag.search(rawdata, i+1) # > if not match: return -1 - j = match.end() + gtpos = match.end() match = endtagfind.match(rawdata, i) # if not match: - self.error("bad end tag: %r" % (rawdata[i:j],)) - tag = match.group(1) - self.handle_endtag(tag.lower()) + if self.cdata_elem is not None: + self.handle_data(rawdata[i:gtpos]) + return gtpos + # find the name: w3.org/TR/html5/tokenization.html#tag-name-state + namematch = tagfind_tolerant.match(rawdata, i+2) + if not namematch: + # w3.org/TR/html5/tokenization.html#end-tag-open-state + if rawdata[i:i+3] == '': + return i+3 + else: + return self.parse_bogus_comment(i) + tagname = namematch.group().lower() + # consume and ignore other stuff between the name and the > + # Note: this is not 100% correct, since we might have things like + # , but looking for > after tha name should cover + # most of the cases and is much simpler + gtpos = rawdata.find('>', namematch.end()) + self.handle_endtag(tagname) + return gtpos+1 + + elem = match.group(1).lower() # script or style + if self.cdata_elem is not None: + if elem != self.cdata_elem: + self.handle_data(rawdata[i:gtpos]) + return gtpos + + self.handle_endtag(elem) self.clear_cdata_mode() - return j + return gtpos # Overridable -- finish processing of start+end tag: def handle_startendtag(self, tag, attrs): @@ -358,7 +437,7 @@ pass def unknown_decl(self, data): - self.error("unknown declaration: %r" % (data,)) + pass # Internal -- helper to remove special character quoting entitydefs = None diff --git a/lib-python/2.7/SocketServer.py b/lib-python/2.7/SocketServer.py --- a/lib-python/2.7/SocketServer.py +++ b/lib-python/2.7/SocketServer.py @@ -82,7 +82,7 @@ data is stored externally (e.g. in the file system), a synchronous class will essentially render the service "deaf" while one request is being handled -- which may be for a very long time if a client is slow -to reqd all the data it has requested. Here a threading or forking +to read all the data it has requested. Here a threading or forking server is appropriate. In some cases, it may be appropriate to process part of a request @@ -589,8 +589,7 @@ """Start a new thread to process the request.""" t = threading.Thread(target = self.process_request_thread, args = (request, client_address)) - if self.daemon_threads: - t.setDaemon (1) + t.daemon = self.daemon_threads t.start() diff --git a/lib-python/2.7/_pyio.py b/lib-python/2.7/_pyio.py --- a/lib-python/2.7/_pyio.py +++ b/lib-python/2.7/_pyio.py @@ -8,6 +8,7 @@ import abc import codecs import warnings +import errno # Import thread instead of threading to reduce startup cost try: from thread import allocate_lock as Lock @@ -720,8 +721,11 @@ def close(self): if self.raw is not None and not self.closed: - self.flush() - self.raw.close() + try: + # may raise BlockingIOError or BrokenPipeError etc + self.flush() + finally: + self.raw.close() def detach(self): if self.raw is None: @@ -1074,13 +1078,9 @@ # XXX we can implement some more tricks to try and avoid # partial writes if len(self._write_buf) > self.buffer_size: - # We're full, so let's pre-flush the buffer - try: - self._flush_unlocked() - except BlockingIOError as e: - # We can't accept anything else. - # XXX Why not just let the exception pass through? - raise BlockingIOError(e.errno, e.strerror, 0) + # We're full, so let's pre-flush the buffer. (This may + # raise BlockingIOError with characters_written == 0.) + self._flush_unlocked() before = len(self._write_buf) self._write_buf.extend(b) written = len(self._write_buf) - before @@ -1111,24 +1111,23 @@ def _flush_unlocked(self): if self.closed: raise ValueError("flush of closed file") - written = 0 - try: - while self._write_buf: - try: - n = self.raw.write(self._write_buf) - except IOError as e: - if e.errno != EINTR: - raise - continue - if n > len(self._write_buf) or n < 0: - raise IOError("write() returned incorrect number of bytes") - del self._write_buf[:n] - written += n - except BlockingIOError as e: - n = e.characters_written + while self._write_buf: + try: + n = self.raw.write(self._write_buf) + except BlockingIOError: + raise RuntimeError("self.raw should implement RawIOBase: it " + "should not raise BlockingIOError") + except IOError as e: + if e.errno != EINTR: + raise + continue + if n is None: + raise BlockingIOError( + errno.EAGAIN, + "write could not complete without blocking", 0) + if n > len(self._write_buf) or n < 0: + raise IOError("write() returned incorrect number of bytes") del self._write_buf[:n] - written += n - raise BlockingIOError(e.errno, e.strerror, written) def tell(self): return _BufferedIOMixin.tell(self) + len(self._write_buf) diff --git a/lib-python/2.7/aifc.py b/lib-python/2.7/aifc.py --- a/lib-python/2.7/aifc.py +++ b/lib-python/2.7/aifc.py @@ -162,6 +162,12 @@ except struct.error: raise EOFError +def _read_ushort(file): + try: + return struct.unpack('>H', file.read(2))[0] + except struct.error: + raise EOFError + def _read_string(file): length = ord(file.read(1)) if length == 0: @@ -194,13 +200,19 @@ def _write_short(f, x): f.write(struct.pack('>h', x)) +def _write_ushort(f, x): + f.write(struct.pack('>H', x)) + def _write_long(f, x): + f.write(struct.pack('>l', x)) + +def _write_ulong(f, x): f.write(struct.pack('>L', x)) def _write_string(f, s): if len(s) > 255: raise ValueError("string exceeds maximum pstring length") - f.write(chr(len(s))) + f.write(struct.pack('B', len(s))) f.write(s) if len(s) & 1 == 0: f.write(chr(0)) @@ -218,7 +230,7 @@ lomant = 0 else: fmant, expon = math.frexp(x) - if expon > 16384 or fmant >= 1: # Infinity or NaN + if expon > 16384 or fmant >= 1 or fmant != fmant: # Infinity or NaN expon = sign|0x7FFF himant = 0 lomant = 0 @@ -234,9 +246,9 @@ fmant = math.ldexp(fmant - fsmant, 32) fsmant = math.floor(fmant) lomant = long(fsmant) - _write_short(f, expon) - _write_long(f, himant) - _write_long(f, lomant) + _write_ushort(f, expon) + _write_ulong(f, himant) + _write_ulong(f, lomant) from chunk import Chunk @@ -840,15 +852,15 @@ if self._aifc: self._file.write('AIFC') self._file.write('FVER') - _write_long(self._file, 4) - _write_long(self._file, self._version) + _write_ulong(self._file, 4) + _write_ulong(self._file, self._version) else: self._file.write('AIFF') self._file.write('COMM') - _write_long(self._file, commlength) + _write_ulong(self._file, commlength) _write_short(self._file, self._nchannels) self._nframes_pos = self._file.tell() - _write_long(self._file, self._nframes) + _write_ulong(self._file, self._nframes) _write_short(self._file, self._sampwidth * 8) _write_float(self._file, self._framerate) if self._aifc: @@ -856,9 +868,9 @@ _write_string(self._file, self._compname) self._file.write('SSND') self._ssnd_length_pos = self._file.tell() - _write_long(self._file, self._datalength + 8) - _write_long(self._file, 0) - _write_long(self._file, 0) + _write_ulong(self._file, self._datalength + 8) + _write_ulong(self._file, 0) + _write_ulong(self._file, 0) def _write_form_length(self, datalength): if self._aifc: @@ -869,8 +881,8 @@ else: commlength = 18 verslength = 0 - _write_long(self._file, 4 + verslength + self._marklength + \ - 8 + commlength + 16 + datalength) + _write_ulong(self._file, 4 + verslength + self._marklength + \ + 8 + commlength + 16 + datalength) return commlength def _patchheader(self): @@ -888,9 +900,9 @@ self._file.seek(self._form_length_pos, 0) dummy = self._write_form_length(datalength) self._file.seek(self._nframes_pos, 0) - _write_long(self._file, self._nframeswritten) + _write_ulong(self._file, self._nframeswritten) self._file.seek(self._ssnd_length_pos, 0) - _write_long(self._file, datalength + 8) + _write_ulong(self._file, datalength + 8) self._file.seek(curpos, 0) self._nframes = self._nframeswritten self._datalength = datalength @@ -905,13 +917,13 @@ length = length + len(name) + 1 + 6 if len(name) & 1 == 0: length = length + 1 - _write_long(self._file, length) + _write_ulong(self._file, length) self._marklength = length + 8 _write_short(self._file, len(self._markers)) for marker in self._markers: id, pos, name = marker _write_short(self._file, id) - _write_long(self._file, pos) + _write_ulong(self._file, pos) _write_string(self._file, name) def open(f, mode=None): diff --git a/lib-python/2.7/asyncore.py b/lib-python/2.7/asyncore.py --- a/lib-python/2.7/asyncore.py +++ b/lib-python/2.7/asyncore.py @@ -132,7 +132,8 @@ is_w = obj.writable() if is_r: r.append(fd) - if is_w: + # accepting sockets should not be writable + if is_w and not obj.accepting: w.append(fd) if is_r or is_w: e.append(fd) @@ -179,7 +180,8 @@ flags = 0 if obj.readable(): flags |= select.POLLIN | select.POLLPRI - if obj.writable(): + # accepting sockets should not be writable + if obj.writable() and not obj.accepting: flags |= select.POLLOUT if flags: # Only check for exceptions if object was either readable diff --git a/lib-python/2.7/cgi.py b/lib-python/2.7/cgi.py --- a/lib-python/2.7/cgi.py +++ b/lib-python/2.7/cgi.py @@ -293,7 +293,7 @@ while s[:1] == ';': s = s[1:] end = s.find(';') - while end > 0 and s.count('"', 0, end) % 2: + while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: end = s.find(';', end + 1) if end < 0: end = len(s) diff --git a/lib-python/2.7/cmd.py b/lib-python/2.7/cmd.py --- a/lib-python/2.7/cmd.py +++ b/lib-python/2.7/cmd.py @@ -209,6 +209,8 @@ if cmd is None: return self.default(line) self.lastcmd = line + if line == 'EOF' : + self.lastcmd = '' if cmd == '': return self.default(line) else: diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -312,6 +312,7 @@ def _asdict(self): 'Return a new OrderedDict which maps field names to their values' return OrderedDict(zip(self._fields, self)) \n + __dict__ = property(_asdict) \n def _replace(_self, **kwds): 'Return a new %(typename)s object replacing specified fields with new values' result = _self._make(map(kwds.pop, %(field_names)r, _self)) diff --git a/lib-python/2.7/compileall.py b/lib-python/2.7/compileall.py --- a/lib-python/2.7/compileall.py +++ b/lib-python/2.7/compileall.py @@ -1,4 +1,4 @@ -"""Module/script to "compile" all .py files to .pyc (or .pyo) file. +"""Module/script to byte-compile all .py files to .pyc (or .pyo) files. When called as a script with arguments, this compiles the directories given as arguments recursively; the -l option prevents it from @@ -26,8 +26,8 @@ dir: the directory to byte-compile maxlevels: maximum recursion level (default 10) - ddir: if given, purported directory name (this is the - directory name that will show up in error messages) + ddir: the directory that will be prepended to the path to the + file as it is compiled into each byte-code file. force: if 1, force compilation, even if timestamps are up-to-date quiet: if 1, be quiet during compilation """ @@ -64,8 +64,8 @@ Arguments (only fullname is required): fullname: the file to byte-compile - ddir: if given, purported directory name (this is the - directory name that will show up in error messages) + ddir: if given, the directory name compiled in to the + byte-code file. force: if 1, force compilation, even if timestamps are up-to-date quiet: if 1, be quiet during compilation """ @@ -157,14 +157,27 @@ print msg print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \ "[-x regexp] [-i list] [directory|file ...]" - print "-l: don't recurse down" + print + print "arguments: zero or more file and directory names to compile; " \ + "if no arguments given, " + print " defaults to the equivalent of -l sys.path" + print + print "options:" + print "-l: don't recurse into subdirectories" print "-f: force rebuild even if timestamps are up-to-date" - print "-q: quiet operation" - print "-d destdir: purported directory name for error messages" - print " if no directory arguments, -l sys.path is assumed" - print "-x regexp: skip files matching the regular expression regexp" - print " the regexp is searched for in the full path of the file" - print "-i list: expand list with its content (file and directory names)" + print "-q: output only error messages" + print "-d destdir: directory to prepend to file paths for use in " \ + "compile-time tracebacks and in" + print " runtime tracebacks in cases where the source " \ + "file is unavailable" + print "-x regexp: skip files matching the regular expression regexp; " \ + "the regexp is searched for" + print " in the full path of each file considered for " \ + "compilation" + print "-i file: add all the files and directories listed in file to " \ + "the list considered for" + print ' compilation; if "-", names are read from stdin' + sys.exit(2) maxlevels = 10 ddir = None @@ -205,7 +218,7 @@ else: success = compile_path() except KeyboardInterrupt: - print "\n[interrupt]" + print "\n[interrupted]" success = 0 return success diff --git a/lib-python/2.7/cookielib.py b/lib-python/2.7/cookielib.py --- a/lib-python/2.7/cookielib.py +++ b/lib-python/2.7/cookielib.py @@ -1014,7 +1014,7 @@ (not erhn.startswith(".") and not ("."+erhn).endswith(domain))): _debug(" effective request-host %s (even with added " - "initial dot) does not end end with %s", + "initial dot) does not end with %s", erhn, domain) return False if (cookie.version > 0 or diff --git a/lib-python/2.7/ctypes/__init__.py b/lib-python/2.7/ctypes/__init__.py --- a/lib-python/2.7/ctypes/__init__.py +++ b/lib-python/2.7/ctypes/__init__.py @@ -263,6 +263,22 @@ from _ctypes import POINTER, pointer, _pointer_type_cache +def _reset_cache(): + _pointer_type_cache.clear() + _c_functype_cache.clear() + if _os.name in ("nt", "ce"): + _win_functype_cache.clear() + # _SimpleCData.c_wchar_p_from_param + POINTER(c_wchar).from_param = c_wchar_p.from_param + # _SimpleCData.c_char_p_from_param + POINTER(c_char).from_param = c_char_p.from_param + _pointer_type_cache[None] = c_void_p + # XXX for whatever reasons, creating the first instance of a callback + # function is needed for the unittests on Win64 to succeed. This MAY + # be a compiler bug, since the problem occurs only when _ctypes is + # compiled with the MS SDK compiler. Or an uninitialized variable? + CFUNCTYPE(c_int)(lambda: None) + try: from _ctypes import set_conversion_mode except ImportError: @@ -279,8 +295,6 @@ class c_wchar(_SimpleCData): _type_ = "u" - POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param - def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array @@ -299,8 +313,6 @@ return buf raise TypeError(init) -POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param - # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: @@ -463,8 +475,6 @@ descr = FormatError(code).strip() return WindowsError(code, descr) -_pointer_type_cache[None] = c_void_p - if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int @@ -550,8 +560,4 @@ elif sizeof(kind) == 8: c_uint64 = kind del(kind) -# XXX for whatever reasons, creating the first instance of a callback -# function is needed for the unittests on Win64 to succeed. This MAY -# be a compiler bug, since the problem occurs only when _ctypes is -# compiled with the MS SDK compiler. Or an uninitialized variable? -CFUNCTYPE(c_int)(lambda: None) +_reset_cache() diff --git a/lib-python/2.7/ctypes/_endian.py b/lib-python/2.7/ctypes/_endian.py --- a/lib-python/2.7/ctypes/_endian.py +++ b/lib-python/2.7/ctypes/_endian.py @@ -4,20 +4,24 @@ import sys from ctypes import * -_array_type = type(c_int * 3) +_array_type = type(Array) def _other_endian(typ): """Return the type with the 'other' byte order. Simple types like c_int and so on already have __ctype_be__ and __ctype_le__ attributes which contain the types, for more complicated types - only arrays are supported. + arrays and structures are supported. """ - try: + # check _OTHER_ENDIAN attribute (present if typ is primitive type) + if hasattr(typ, _OTHER_ENDIAN): return getattr(typ, _OTHER_ENDIAN) - except AttributeError: - if type(typ) == _array_type: - return _other_endian(typ._type_) * typ._length_ - raise TypeError("This type does not support other endian: %s" % typ) + # if typ is array + if isinstance(typ, _array_type): + return _other_endian(typ._type_) * typ._length_ + # if typ is structure + if issubclass(typ, Structure): + return typ + raise TypeError("This type does not support other endian: %s" % typ) class _swapped_meta(type(Structure)): def __setattr__(self, attrname, value): diff --git a/lib-python/2.7/ctypes/test/test_as_parameter.py b/lib-python/2.7/ctypes/test/test_as_parameter.py --- a/lib-python/2.7/ctypes/test/test_as_parameter.py +++ b/lib-python/2.7/ctypes/test/test_as_parameter.py @@ -74,6 +74,7 @@ def test_callbacks(self): f = dll._testfunc_callback_i_if f.restype = c_int + f.argtypes = None MyCallback = CFUNCTYPE(c_int, c_int) diff --git a/lib-python/2.7/ctypes/test/test_buffers.py b/lib-python/2.7/ctypes/test/test_buffers.py --- a/lib-python/2.7/ctypes/test/test_buffers.py +++ b/lib-python/2.7/ctypes/test/test_buffers.py @@ -20,6 +20,10 @@ self.assertEqual(b[::2], "ac") self.assertEqual(b[::5], "a") + def test_buffer_interface(self): + self.assertEqual(len(bytearray(create_string_buffer(0))), 0) + self.assertEqual(len(bytearray(create_string_buffer(1))), 1) + def test_string_conversion(self): b = create_string_buffer(u"abc") self.assertEqual(len(b), 4) # trailing nul char diff --git a/lib-python/2.7/ctypes/test/test_byteswap.py b/lib-python/2.7/ctypes/test/test_byteswap.py --- a/lib-python/2.7/ctypes/test/test_byteswap.py +++ b/lib-python/2.7/ctypes/test/test_byteswap.py @@ -1,4 +1,4 @@ -import sys, unittest, struct, math +import sys, unittest, struct, math, ctypes from binascii import hexlify from ctypes import * @@ -191,19 +191,34 @@ pass self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)]) + @xfail def test_struct_struct(self): - # Nested structures with different byte order not (yet) supported - if sys.byteorder == "little": - base = BigEndianStructure - else: - base = LittleEndianStructure + # nested structures with different byteorders - class T(Structure): - _fields_ = [("a", c_int), - ("b", c_int)] - class S(base): - pass - self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)]) + # create nested structures with given byteorders and set memory to data + + for nested, data in ( + (BigEndianStructure, b'\0\0\0\1\0\0\0\2'), + (LittleEndianStructure, b'\1\0\0\0\2\0\0\0'), + ): + for parent in ( + BigEndianStructure, + LittleEndianStructure, + Structure, + ): + class NestedStructure(nested): + _fields_ = [("x", c_uint32), + ("y", c_uint32)] + + class TestStructure(parent): + _fields_ = [("point", NestedStructure)] + + self.assertEqual(len(data), sizeof(TestStructure)) + ptr = POINTER(TestStructure) + s = cast(data, ptr)[0] + del ctypes._pointer_type_cache[TestStructure] + self.assertEqual(s.point.x, 1) + self.assertEqual(s.point.y, 2) @xfail def test_struct_fields_2(self): diff --git a/lib-python/2.7/ctypes/test/test_callbacks.py b/lib-python/2.7/ctypes/test/test_callbacks.py --- a/lib-python/2.7/ctypes/test/test_callbacks.py +++ b/lib-python/2.7/ctypes/test/test_callbacks.py @@ -142,6 +142,14 @@ if isinstance(x, X)] self.assertEqual(len(live), 0) + def test_issue12483(self): + import gc + class Nasty: + def __del__(self): + gc.collect() + CFUNCTYPE(None)(lambda x=Nasty(): None) + + try: WINFUNCTYPE except NameError: diff --git a/lib-python/2.7/ctypes/test/test_functions.py b/lib-python/2.7/ctypes/test/test_functions.py --- a/lib-python/2.7/ctypes/test/test_functions.py +++ b/lib-python/2.7/ctypes/test/test_functions.py @@ -253,6 +253,7 @@ def test_callbacks(self): f = dll._testfunc_callback_i_if f.restype = c_int + f.argtypes = None MyCallback = CFUNCTYPE(c_int, c_int) diff --git a/lib-python/2.7/ctypes/test/test_structures.py b/lib-python/2.7/ctypes/test/test_structures.py --- a/lib-python/2.7/ctypes/test/test_structures.py +++ b/lib-python/2.7/ctypes/test/test_structures.py @@ -239,6 +239,14 @@ pass self.assertRaises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)]) + def test_invalid_name(self): + # field name must be string + def declare_with_name(name): + class S(Structure): + _fields_ = [(name, c_int)] + + self.assertRaises(TypeError, declare_with_name, u"x\xe9") + def test_intarray_fields(self): class SomeInts(Structure): _fields_ = [("a", c_int * 4)] @@ -324,6 +332,18 @@ else: self.assertEqual(msg, "(Phone) exceptions.TypeError: too many initializers") + def test_huge_field_name(self): + # issue12881: segfault with large structure field names + def create_class(length): + class S(Structure): + _fields_ = [('x' * length, c_int)] + + for length in [10 ** i for i in range(0, 8)]: + try: + create_class(length) + except MemoryError: + # MemoryErrors are OK, we just don't want to segfault + pass def get_except(self, func, *args): try: diff --git a/lib-python/2.7/ctypes/util.py b/lib-python/2.7/ctypes/util.py --- a/lib-python/2.7/ctypes/util.py +++ b/lib-python/2.7/ctypes/util.py @@ -182,28 +182,6 @@ else: - def _findLib_ldconfig(name): - # XXX assuming GLIBC's ldconfig (with option -p) - expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) - f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null') - try: - data = f.read() - finally: - f.close() - res = re.search(expr, data) - if not res: - # Hm, this works only for libs needed by the python executable. - cmd = 'ldd %s 2>/dev/null' % sys.executable - f = os.popen(cmd) - try: - data = f.read() - finally: - f.close() - res = re.search(expr, data) - if not res: - return None - return res.group(0) - def _findSoname_ldconfig(name): import struct if struct.calcsize('l') == 4: @@ -220,8 +198,7 @@ abi_type = mach_map.get(machine, 'libc6') # XXX assuming GLIBC's ldconfig (with option -p) - expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \ - % (abi_type, re.escape(name)) + expr = r'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type) f = os.popen('/sbin/ldconfig -p 2>/dev/null') try: data = f.read() diff --git a/lib-python/2.7/decimal.py b/lib-python/2.7/decimal.py --- a/lib-python/2.7/decimal.py +++ b/lib-python/2.7/decimal.py @@ -21,7 +21,7 @@ This is a Py2.3 implementation of decimal floating point arithmetic based on the General Decimal Arithmetic Specification: - www2.hursley.ibm.com/decimal/decarith.html + http://speleotrove.com/decimal/decarith.html and IEEE standard 854-1987: @@ -1942,9 +1942,9 @@ nonzero. For efficiency, other._exp should not be too large, so that 10**abs(other._exp) is a feasible calculation.""" - # In the comments below, we write x for the value of self and - # y for the value of other. Write x = xc*10**xe and y = - # yc*10**ye. + # In the comments below, we write x for the value of self and y for the + # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc + # and yc positive integers not divisible by 10. # The main purpose of this method is to identify the *failure* # of x**y to be exactly representable with as little effort as @@ -1952,13 +1952,12 @@ # eliminate the possibility of x**y being exact. Only if all # these tests are passed do we go on to actually compute x**y. - # Here's the main idea. First normalize both x and y. We - # express y as a rational m/n, with m and n relatively prime - # and n>0. Then for x**y to be exactly representable (at - # *any* precision), xc must be the nth power of a positive - # integer and xe must be divisible by n. If m is negative - # then additionally xc must be a power of either 2 or 5, hence - # a power of 2**n or 5**n. + # Here's the main idea. Express y as a rational number m/n, with m and + # n relatively prime and n>0. Then for x**y to be exactly + # representable (at *any* precision), xc must be the nth power of a + # positive integer and xe must be divisible by n. If y is negative + # then additionally xc must be a power of either 2 or 5, hence a power + # of 2**n or 5**n. # # There's a limit to how small |y| can be: if y=m/n as above # then: @@ -2030,21 +2029,43 @@ return None # now xc is a power of 2; e is its exponent e = _nbits(xc)-1 - # find e*y and xe*y; both must be integers - if ye >= 0: - y_as_int = yc*10**ye - e = e*y_as_int - xe = xe*y_as_int - else: - ten_pow = 10**-ye - e, remainder = divmod(e*yc, ten_pow) - if remainder: - return None - xe, remainder = divmod(xe*yc, ten_pow) - if remainder: - return None - - if e*65 >= p*93: # 93/65 > log(10)/log(5) + + # We now have: + # + # x = 2**e * 10**xe, e > 0, and y < 0. + # + # The exact result is: + # + # x**y = 5**(-e*y) * 10**(e*y + xe*y) + # + # provided that both e*y and xe*y are integers. Note that if + # 5**(-e*y) >= 10**p, then the result can't be expressed + # exactly with p digits of precision. + # + # Using the above, we can guard against large values of ye. + # 93/65 is an upper bound for log(10)/log(5), so if + # + # ye >= len(str(93*p//65)) + # + # then + # + # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), + # + # so 5**(-e*y) >= 10**p, and the coefficient of the result + # can't be expressed in p digits. + + # emax >= largest e such that 5**e < 10**p. + emax = p*93//65 + if ye >= len(str(emax)): + return None + + # Find -e*y and -xe*y; both must be integers + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: return None xc = 5**e @@ -2058,19 +2079,20 @@ while xc % 5 == 0: xc //= 5 e -= 1 - if ye >= 0: - y_as_integer = yc*10**ye - e = e*y_as_integer - xe = xe*y_as_integer - else: - ten_pow = 10**-ye - e, remainder = divmod(e*yc, ten_pow) - if remainder: - return None - xe, remainder = divmod(xe*yc, ten_pow) - if remainder: - return None - if e*3 >= p*10: # 10/3 > log(10)/log(2) + + # Guard against large values of ye, using the same logic as in + # the 'xc is a power of 2' branch. 10/3 is an upper bound for + # log(10)/log(2). + emax = p*10//3 + if ye >= len(str(emax)): + return None + + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: return None xc = 2**e else: @@ -5463,6 +5485,27 @@ hex_n = "%x" % n return 4*len(hex_n) - correction[hex_n[0]] +def _decimal_lshift_exact(n, e): + """ Given integers n and e, return n * 10**e if it's an integer, else None. + + The computation is designed to avoid computing large powers of 10 + unnecessarily. + + >>> _decimal_lshift_exact(3, 4) + 30000 + >>> _decimal_lshift_exact(300, -999999999) # returns None + + """ + if n == 0: + return 0 + elif e >= 0: + return n * 10**e + else: + # val_n = largest power of 10 dividing n. + str_n = str(abs(n)) + val_n = len(str_n) - len(str_n.rstrip('0')) + return None if val_n < -e else n // 10**-e + def _sqrt_nearest(n, a): """Closest integer to the square root of the positive integer n. a is an initial approximation to the square root. Any positive integer diff --git a/lib-python/2.7/distutils/__init__.py b/lib-python/2.7/distutils/__init__.py --- a/lib-python/2.7/distutils/__init__.py +++ b/lib-python/2.7/distutils/__init__.py @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "2.7.2" +__version__ = "2.7.3" #--end constants-- diff --git a/lib-python/2.7/distutils/ccompiler.py b/lib-python/2.7/distutils/ccompiler.py --- a/lib-python/2.7/distutils/ccompiler.py +++ b/lib-python/2.7/distutils/ccompiler.py @@ -18,58 +18,6 @@ from distutils.util import split_quoted, execute from distutils import log -_sysconfig = __import__('sysconfig') - -def customize_compiler(compiler): - """Do any platform-specific customization of a CCompiler instance. - - Mainly needed on Unix, so we can plug in the information that - varies across Unices and is stored in Python's Makefile. - """ - if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ - _sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO', 'AR', - 'ARFLAGS') - - if 'CC' in os.environ: - cc = os.environ['CC'] - if 'CXX' in os.environ: - cxx = os.environ['CXX'] - if 'LDSHARED' in os.environ: - ldshared = os.environ['LDSHARED'] - if 'CPP' in os.environ: - cpp = os.environ['CPP'] - else: - cpp = cc + " -E" # not always - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: - cflags = opt + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] - cflags = cflags + ' ' + os.environ['CPPFLAGS'] - ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - if 'AR' in os.environ: - ar = os.environ['AR'] - if 'ARFLAGS' in os.environ: - archiver = ar + ' ' + os.environ['ARFLAGS'] - else: - archiver = ar + ' ' + ar_flags - - cc_cmd = cc + ' ' + cflags - compiler.set_executables( - preprocessor=cpp, - compiler=cc_cmd, - compiler_so=cc_cmd + ' ' + ccshared, - compiler_cxx=cxx, - linker_so=ldshared, - linker_exe=cc, - archiver=archiver) - - compiler.shared_lib_extension = so_ext - class CCompiler: """Abstract base class to define the interface that must be implemented by real compiler classes. Also has some utility methods used by diff --git a/lib-python/2.7/distutils/command/bdist_dumb.py b/lib-python/2.7/distutils/command/bdist_dumb.py --- a/lib-python/2.7/distutils/command/bdist_dumb.py +++ b/lib-python/2.7/distutils/command/bdist_dumb.py @@ -58,7 +58,7 @@ self.format = None self.keep_temp = 0 self.dist_dir = None - self.skip_build = 0 + self.skip_build = None self.relative = 0 self.owner = None self.group = None @@ -78,7 +78,8 @@ self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'), - ('plat_name', 'plat_name')) + ('plat_name', 'plat_name'), + ('skip_build', 'skip_build')) def run(self): if not self.skip_build: diff --git a/lib-python/2.7/distutils/command/bdist_msi.py b/lib-python/2.7/distutils/command/bdist_msi.py --- a/lib-python/2.7/distutils/command/bdist_msi.py +++ b/lib-python/2.7/distutils/command/bdist_msi.py @@ -131,18 +131,22 @@ self.no_target_optimize = 0 self.target_version = None self.dist_dir = None - self.skip_build = 0 + self.skip_build = None self.install_script = None self.pre_install_script = None self.versions = None def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'msi') + short_version = get_python_version() if (not self.target_version) and self.distribution.has_ext_modules(): self.target_version = short_version + if self.target_version: self.versions = [self.target_version] if not self.skip_build and self.distribution.has_ext_modules()\ diff --git a/lib-python/2.7/distutils/command/bdist_wininst.py b/lib-python/2.7/distutils/command/bdist_wininst.py --- a/lib-python/2.7/distutils/command/bdist_wininst.py +++ b/lib-python/2.7/distutils/command/bdist_wininst.py @@ -71,7 +71,7 @@ self.dist_dir = None self.bitmap = None self.title = None - self.skip_build = 0 + self.skip_build = None self.install_script = None self.pre_install_script = None self.user_access_control = None @@ -80,6 +80,8 @@ def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + if self.bdist_dir is None: if self.skip_build and self.plat_name: # If build is skipped and plat_name is overridden, bdist will @@ -89,8 +91,10 @@ # next the command will be initialized using that name bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'wininst') + if not self.target_version: self.target_version = "" + if not self.skip_build and self.distribution.has_ext_modules(): short_version = get_python_version() if self.target_version and self.target_version != short_version: diff --git a/lib-python/2.7/distutils/command/build_clib.py b/lib-python/2.7/distutils/command/build_clib.py --- a/lib-python/2.7/distutils/command/build_clib.py +++ b/lib-python/2.7/distutils/command/build_clib.py @@ -19,7 +19,7 @@ import os from distutils.core import Command from distutils.errors import DistutilsSetupError -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler from distutils import log def show_compilers(): diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py --- a/lib-python/2.7/distutils/command/build_ext.py +++ b/lib-python/2.7/distutils/command/build_ext.py @@ -160,8 +160,7 @@ if plat_py_include != py_include: self.include_dirs.append(plat_py_include) - if isinstance(self.libraries, str): - self.libraries = [self.libraries] + self.ensure_string_list('libraries') # Life is easier if we're not forever checking for None, so # simplify these options to empty lists if unset diff --git a/lib-python/2.7/distutils/command/check.py b/lib-python/2.7/distutils/command/check.py --- a/lib-python/2.7/distutils/command/check.py +++ b/lib-python/2.7/distutils/command/check.py @@ -5,6 +5,7 @@ __revision__ = "$Id$" from distutils.core import Command +from distutils.dist import PKG_INFO_ENCODING from distutils.errors import DistutilsSetupError try: @@ -108,6 +109,8 @@ def check_restructuredtext(self): """Checks if the long string fields are reST-compliant.""" data = self.distribution.get_long_description() + if not isinstance(data, unicode): + data = data.decode(PKG_INFO_ENCODING) for warning in self._check_rst_data(data): line = warning[-1].get('line') if line is None: diff --git a/lib-python/2.7/distutils/command/config.py b/lib-python/2.7/distutils/command/config.py --- a/lib-python/2.7/distutils/command/config.py +++ b/lib-python/2.7/distutils/command/config.py @@ -16,7 +16,7 @@ from distutils.core import Command from distutils.errors import DistutilsExecError -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler from distutils import log LANG_EXT = {'c': '.c', 'c++': '.cxx'} diff --git a/lib-python/2.7/distutils/command/register.py b/lib-python/2.7/distutils/command/register.py --- a/lib-python/2.7/distutils/command/register.py +++ b/lib-python/2.7/distutils/command/register.py @@ -10,7 +10,6 @@ import urllib2 import getpass import urlparse -import StringIO from warnings import warn from distutils.core import PyPIRCCommand @@ -260,21 +259,30 @@ boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = '\n--' + boundary end_boundary = sep_boundary + '--' - body = StringIO.StringIO() + chunks = [] for key, value in data.items(): # handle multiple entries for the same name if type(value) not in (type([]), type( () )): value = [value] for value in value: - body.write(sep_boundary) - body.write('\nContent-Disposition: form-data; name="%s"'%key) - body.write("\n\n") - body.write(value) + chunks.append(sep_boundary) + chunks.append('\nContent-Disposition: form-data; name="%s"'%key) + chunks.append("\n\n") + chunks.append(value) if value and value[-1] == '\r': - body.write('\n') # write an extra newline (lurve Macs) - body.write(end_boundary) - body.write("\n") - body = body.getvalue() + chunks.append('\n') # write an extra newline (lurve Macs) + chunks.append(end_boundary) + chunks.append("\n") + + # chunks may be bytes (str) or unicode objects that we need to encode + body = [] + for chunk in chunks: + if isinstance(chunk, unicode): + body.append(chunk.encode('utf-8')) + else: + body.append(chunk) + + body = ''.join(body) # build the Request headers = { diff --git a/lib-python/2.7/distutils/command/sdist.py b/lib-python/2.7/distutils/command/sdist.py --- a/lib-python/2.7/distutils/command/sdist.py +++ b/lib-python/2.7/distutils/command/sdist.py @@ -182,14 +182,20 @@ reading the manifest, or just using the default file set -- it all depends on the user's options. """ - # new behavior: + # new behavior when using a template: # the file list is recalculated everytime because # even if MANIFEST.in or setup.py are not changed # the user might have added some files in the tree that # need to be included. # - # This makes --force the default and only behavior. + # This makes --force the default and only behavior with templates. template_exists = os.path.isfile(self.template) + if not template_exists and self._manifest_is_not_generated(): + self.read_manifest() + self.filelist.sort() + self.filelist.remove_duplicates() + return + if not template_exists: self.warn(("manifest template '%s' does not exist " + "(using default file list)") % @@ -314,7 +320,10 @@ try: self.filelist.process_template_line(line) - except DistutilsTemplateError, msg: + # the call above can raise a DistutilsTemplateError for + # malformed lines, or a ValueError from the lower-level + # convert_path function + except (DistutilsTemplateError, ValueError) as msg: self.warn("%s, line %d: %s" % (template.filename, template.current_line, msg)) @@ -352,23 +361,28 @@ by 'add_defaults()' and 'read_template()') to the manifest file named by 'self.manifest'. """ - if os.path.isfile(self.manifest): - fp = open(self.manifest) - try: - first_line = fp.readline() - finally: - fp.close() - - if first_line != '# file GENERATED by distutils, do NOT edit\n': - log.info("not writing to manually maintained " - "manifest file '%s'" % self.manifest) - return + if self._manifest_is_not_generated(): + log.info("not writing to manually maintained " + "manifest file '%s'" % self.manifest) + return content = self.filelist.files[:] content.insert(0, '# file GENERATED by distutils, do NOT edit') self.execute(file_util.write_file, (self.manifest, content), "writing manifest file '%s'" % self.manifest) + def _manifest_is_not_generated(self): + # check for special comment used in 2.7.1 and higher + if not os.path.isfile(self.manifest): + return False + + fp = open(self.manifest, 'rU') + try: + first_line = fp.readline() + finally: + fp.close() + return first_line != '# file GENERATED by distutils, do NOT edit\n' + def read_manifest(self): """Read the manifest file (named by 'self.manifest') and use it to fill in 'self.filelist', the list of files to include in the source @@ -376,12 +390,11 @@ """ log.info("reading manifest file '%s'", self.manifest) manifest = open(self.manifest) - while 1: - line = manifest.readline() - if line == '': # end of file - break - if line[-1] == '\n': - line = line[0:-1] + for line in manifest: + # ignore comments and blank lines + line = line.strip() + if line.startswith('#') or not line: + continue self.filelist.append(line) manifest.close() diff --git a/lib-python/2.7/distutils/dep_util.py b/lib-python/2.7/distutils/dep_util.py --- a/lib-python/2.7/distutils/dep_util.py +++ b/lib-python/2.7/distutils/dep_util.py @@ -7,6 +7,7 @@ __revision__ = "$Id$" import os +from stat import ST_MTIME from distutils.errors import DistutilsFileError def newer(source, target): @@ -27,7 +28,7 @@ if not os.path.exists(target): return True - return os.stat(source).st_mtime > os.stat(target).st_mtime + return os.stat(source)[ST_MTIME] > os.stat(target)[ST_MTIME] def newer_pairwise(sources, targets): """Walk two filename lists in parallel, testing if each source is newer @@ -71,7 +72,7 @@ # is more recent than 'target', then 'target' is out-of-date and # we can immediately return true. If we fall through to the end # of the loop, then 'target' is up-to-date and we return false. - target_mtime = os.stat(target).st_mtime + target_mtime = os.stat(target)[ST_MTIME] for source in sources: if not os.path.exists(source): @@ -82,7 +83,7 @@ elif missing == 'newer': # missing source means target is return True # out-of-date - if os.stat(source).st_mtime > target_mtime: + if os.stat(source)[ST_MTIME] > target_mtime: return True return False diff --git a/lib-python/2.7/distutils/dist.py b/lib-python/2.7/distutils/dist.py --- a/lib-python/2.7/distutils/dist.py +++ b/lib-python/2.7/distutils/dist.py @@ -1111,7 +1111,8 @@ """Write the PKG-INFO format data to a file object. """ version = '1.0' - if self.provides or self.requires or self.obsoletes: + if (self.provides or self.requires or self.obsoletes or + self.classifiers or self.download_url): version = '1.1' self._write_field(file, 'Metadata-Version', version) diff --git a/lib-python/2.7/distutils/filelist.py b/lib-python/2.7/distutils/filelist.py --- a/lib-python/2.7/distutils/filelist.py +++ b/lib-python/2.7/distutils/filelist.py @@ -210,6 +210,7 @@ Return 1 if files are found. """ + # XXX docstring lying about what the special chars are? files_found = 0 pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) self.debug_print("include_pattern: applying regex r'%s'" % @@ -297,11 +298,14 @@ # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, # and by extension they shouldn't match such "special characters" under # any OS. So change all non-escaped dots in the RE to match any - # character except the special characters. - # XXX currently the "special characters" are just slash -- i.e. this is - # Unix-only. - pattern_re = re.sub(r'((?\s*" manifest_buf = re.sub(pattern, "", manifest_buf) + # Now see if any other assemblies are referenced - if not, we + # don't want a manifest embedded. + pattern = re.compile( + r"""|)""", re.DOTALL) + if re.search(pattern, manifest_buf) is None: + return None + manifest_f = open(manifest_file, 'w') try: manifest_f.write(manifest_buf) + return manifest_file finally: manifest_f.close() except IOError: diff --git a/lib-python/2.7/distutils/spawn.py b/lib-python/2.7/distutils/spawn.py --- a/lib-python/2.7/distutils/spawn.py +++ b/lib-python/2.7/distutils/spawn.py @@ -96,17 +96,43 @@ raise DistutilsExecError, \ "command '%s' failed with exit status %d" % (cmd[0], rc) +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return exec_fn = search_path and os.execvp or os.execv + exec_args = [cmd[0], cmd] + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(cmd[0], cmd) + exec_fn(*exec_args) except OSError, e: sys.stderr.write("unable to execute %s: %s\n" % (cmd[0], e.strerror)) diff --git a/lib-python/2.7/distutils/sysconfig.py b/lib-python/2.7/distutils/sysconfig.py --- a/lib-python/2.7/distutils/sysconfig.py +++ b/lib-python/2.7/distutils/sysconfig.py @@ -26,4 +26,5 @@ from distutils.sysconfig_cpython import _config_vars # needed by setuptools from distutils.sysconfig_cpython import _variable_rx # read_setup_file() +_USE_CLANG = None diff --git a/lib-python/2.7/distutils/sysconfig_cpython.py b/lib-python/2.7/distutils/sysconfig_cpython.py --- a/lib-python/2.7/distutils/sysconfig_cpython.py +++ b/lib-python/2.7/distutils/sysconfig_cpython.py @@ -149,12 +149,43 @@ varies across Unices and is stored in Python's Makefile. """ if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \ + (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO') + 'CCSHARED', 'LDSHARED', 'SO', 'AR', + 'ARFLAGS') + newcc = None if 'CC' in os.environ: - cc = os.environ['CC'] + newcc = os.environ['CC'] + elif sys.platform == 'darwin' and cc == 'gcc-4.2': + # Issue #13590: + # Since Apple removed gcc-4.2 in Xcode 4.2, we can no + # longer assume it is available for extension module builds. + # If Python was built with gcc-4.2, check first to see if + # it is available on this system; if not, try to use clang + # instead unless the caller explicitly set CC. + global _USE_CLANG + if _USE_CLANG is None: + from distutils import log + from subprocess import Popen, PIPE + p = Popen("! type gcc-4.2 && type clang && exit 2", + shell=True, stdout=PIPE, stderr=PIPE) + p.wait() + if p.returncode == 2: + _USE_CLANG = True + log.warn("gcc-4.2 not found, using clang instead") + else: + _USE_CLANG = False + if _USE_CLANG: + newcc = 'clang' + if newcc: + # On OS X, if CC is overridden, use that as the default + # command for LDSHARED as well + if (sys.platform == 'darwin' + and 'LDSHARED' not in os.environ + and ldshared.startswith(cc)): + ldshared = newcc + ldshared[len(cc):] + cc = newcc if 'CXX' in os.environ: cxx = os.environ['CXX'] if 'LDSHARED' in os.environ: @@ -172,6 +203,12 @@ cpp = cpp + ' ' + os.environ['CPPFLAGS'] cflags = cflags + ' ' + os.environ['CPPFLAGS'] ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] + if 'AR' in os.environ: + ar = os.environ['AR'] + if 'ARFLAGS' in os.environ: + archiver = ar + ' ' + os.environ['ARFLAGS'] + else: + archiver = ar + ' ' + ar_flags cc_cmd = cc + ' ' + cflags compiler.set_executables( @@ -180,7 +217,8 @@ compiler_so=cc_cmd + ' ' + ccshared, compiler_cxx=cxx, linker_so=ldshared, - linker_exe=cc) + linker_exe=cc, + archiver=archiver) compiler.shared_lib_extension = so_ext @@ -380,21 +418,6 @@ raise DistutilsPlatformError(my_msg) - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target - elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')): - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. diff --git a/lib-python/2.7/distutils/tests/Setup.sample b/lib-python/2.7/distutils/tests/Setup.sample old mode 100755 new mode 100644 diff --git a/lib-python/2.7/distutils/tests/support.py b/lib-python/2.7/distutils/tests/support.py --- a/lib-python/2.7/distutils/tests/support.py +++ b/lib-python/2.7/distutils/tests/support.py @@ -1,7 +1,10 @@ """Support code for distutils test cases.""" import os +import sys import shutil import tempfile +import unittest +import sysconfig from copy import deepcopy import warnings @@ -9,6 +12,7 @@ from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL from distutils.core import Distribution + def capture_warnings(func): def _capture_warnings(*args, **kw): with warnings.catch_warnings(): @@ -16,6 +20,7 @@ return func(*args, **kw) return _capture_warnings + class LoggingSilencer(object): def setUp(self): @@ -49,6 +54,7 @@ def clear_logs(self): self.logs = [] + class TempdirManager(object): """Mix-in class that handles temporary directories for test cases. @@ -57,9 +63,13 @@ def setUp(self): super(TempdirManager, self).setUp() + self.old_cwd = os.getcwd() self.tempdirs = [] def tearDown(self): + # Restore working dir, for Solaris and derivatives, where rmdir() + # on the current directory fails. + os.chdir(self.old_cwd) super(TempdirManager, self).tearDown() while self.tempdirs: d = self.tempdirs.pop() @@ -105,6 +115,7 @@ return pkg_dir, dist + class DummyCommand: """Class to store options for retrieval via set_undefined_options().""" @@ -115,6 +126,7 @@ def ensure_finalized(self): pass + class EnvironGuard(object): def setUp(self): @@ -131,3 +143,79 @@ del os.environ[key] super(EnvironGuard, self).tearDown() + + +def copy_xxmodule_c(directory): From noreply at buildbot.pypy.org Tue Oct 23 21:08:05 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Tue, 23 Oct 2012 21:08:05 +0200 (CEST) Subject: [pypy-commit] pypy jit-usable_retrace_3: only clone Const's Message-ID: <20121023190805.417E81C1C8F@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: jit-usable_retrace_3 Changeset: r58382:d57bced28c45 Date: 2012-10-23 14:46 +0200 http://bitbucket.org/pypy/pypy/changeset/d57bced28c45/ Log: only clone Const's diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py b/pypy/jit/metainterp/optimizeopt/virtualstate.py --- a/pypy/jit/metainterp/optimizeopt/virtualstate.py +++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py @@ -382,14 +382,11 @@ return # It is enough if we can generate guards to make states compatibe, FIXME: rename method except InvalidLoop: pass - if value.is_constant(): - op = ResOperation(rop.SAME_AS, [box], box.clonebox()) - #optimizer._newoperations.append(op) FIXME - return optimizer.getvalue(op.result) - else: - v = OptValue(box) - optimizer.make_equal_to(box, v, True) - return v + if isinstance(box, Const): + box = box.clonebox() + v = OptValue(box) + optimizer.make_equal_to(box, v, True) + return v def _generate_guards(self, other, box, cpu, extra_guards): if not isinstance(other, NotVirtualStateInfo): From noreply at buildbot.pypy.org Tue Oct 23 21:08:06 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Tue, 23 Oct 2012 21:08:06 +0200 (CEST) Subject: [pypy-commit] pypy jit-usable_retrace_3: unboxed case Message-ID: <20121023190806.6E9C21C1C8F@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: jit-usable_retrace_3 Changeset: r58383:3f77e097f483 Date: 2012-10-23 15:32 +0200 http://bitbucket.org/pypy/pypy/changeset/3f77e097f483/ Log: unboxed case diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -458,6 +458,7 @@ def make_equal_to(self, box, value, replace=False): assert isinstance(value, OptValue) assert replace or box not in self.values + assert not isinstance(box, Const) self.values[box] = value def make_constant(self, box, constbox): diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -207,7 +207,7 @@ exported_values[box] = self.optimizer.getvalue(box) target_token.exported_state = ExportedState(short_boxes, inputarg_setup_ops, - exported_values, jump_args, resume_at_jump_descr) + exported_values, original_jump_args, resume_at_jump_descr) def import_state(self, targetop): if not targetop: # Trace did not start with a label @@ -299,7 +299,6 @@ short_inputargs = virtual_state.make_inputargs(values, self.optimizer, keyboxes=True) self.short[0] = ResOperation(rop.LABEL, short_inputargs, None) - def close_bridge(self, start_label): inputargs = self.inputargs short_jumpargs = inputargs[:] diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py --- a/pypy/jit/metainterp/test/test_ajit.py +++ b/pypy/jit/metainterp/test/test_ajit.py @@ -3052,7 +3052,52 @@ res = self.meta_interp(f, [32]) assert res == f(32) - def test_nested_loops(self): + def test_nested_loops_unboxed(self): + class A: + pass + + bytecode = "iajb+JI" + def get_printable_location(i): + return "%d: %s" % (i, bytecode[i]) + myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'sa', 'c', 'i', 'j', 'obj'], + get_printable_location=get_printable_location) + def f(n): + pc = sa = 0 + i = j = 0 + c = n + 1 + obj = A() + while pc < len(bytecode): + myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j, c=c, obj=obj) + op = bytecode[pc] + if op == 'i': + i = 0 + elif op == 'j': + j = 0 + elif op == '+': + sa += 3 * i + j + 5 * c + elif op == 'a': + i = i + 1 + obj = A() + elif op == 'b': + j = j + 1 + elif op == 'J': + if j < n: + pc -= 2 + myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, c=c, obj=obj) + continue + elif op == 'I': + if i < n: + pc -= 5 + myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, c=c, obj=obj) + continue + pc += 1 + return sa + res = self.meta_interp(f, [10]) + assert res == f(10) + self.check_resops(new_with_vtable=0) + self.check_retraced_simple_loop(2, int_mul=0) + + def test_nested_loops_boxed(self): class Int(object): def __init__(self, val): self.val = val @@ -3093,7 +3138,7 @@ res = self.meta_interp(f, [10]) assert res == f(10) self.check_resops(new_with_vtable=0) - self.check_retraced_simple_loop(2, getfield_gc=0) + self.check_retraced_simple_loop(2, getfield_gc=0, int_mul=0) def test_retrace_failure_fallback(self): myjitdriver = JitDriver(greens = [], reds = ['n', 'a', 'sa']) From noreply at buildbot.pypy.org Tue Oct 23 21:08:07 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Tue, 23 Oct 2012 21:08:07 +0200 (CEST) Subject: [pypy-commit] pypy jit-usable_retrace_3: rename Message-ID: <20121023190807.A13851C1C8F@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: jit-usable_retrace_3 Changeset: r58384:7f959049e8ee Date: 2012-10-23 15:44 +0200 http://bitbucket.org/pypy/pypy/changeset/7f959049e8ee/ Log: rename diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -286,7 +286,7 @@ virtual_state = self.initial_virtual_state values = [self.getvalue(arg) for arg in exported_state.jump_args] - virtual_state = virtual_state.make_generalization_of(exported_state.generalize_virtual_state, + virtual_state = virtual_state.make_guarded_generalization_of(exported_state.generalize_virtual_state, exported_state.jump_args, self.optimizer) values = [self.getvalue(arg) for arg in exported_state.jump_args] diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py b/pypy/jit/metainterp/optimizeopt/virtualstate.py --- a/pypy/jit/metainterp/optimizeopt/virtualstate.py +++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py @@ -23,7 +23,7 @@ def generalization_of(self, other, renum, bad): raise NotImplementedError - def make_generalization_of(self, other, value, optimizer): + def make_guarded_generalization_of(self, other, value, optimizer): pass def generate_guards(self, other, box, cpu, extra_guards, renum): @@ -109,7 +109,7 @@ return True - def make_generalization_of(self, other, value, optimizer): + def make_guarded_generalization_of(self, other, value, optimizer): if not self._generalization_of(other): raise InvalidLoop assert isinstance(other, AbstractVirtualStructStateInfo) @@ -121,7 +121,7 @@ for i in range(len(self.fielddescrs)): if other.fielddescrs[i] is not self.fielddescrs[i]: raise InvalidLoop - new_field_value = self.fieldstate[i].make_generalization_of(other.fieldstate[i], + new_field_value = self.fieldstate[i].make_guarded_generalization_of(other.fieldstate[i], value.getfield(self.fielddescrs[i], None), optimizer) if new_field_value: @@ -374,12 +374,12 @@ return False return True - def make_generalization_of(self, other, value, optimizer): + def make_guarded_generalization_of(self, other, value, optimizer): if not self.generalization_of(other, {}, {}): box = value.get_key_box() try: self._generate_guards(other, box, optimizer.cpu, []) - return # It is enough if we can generate guards to make states compatibe, FIXME: rename method + return except InvalidLoop: pass if isinstance(box, Const): @@ -515,11 +515,11 @@ return False return True - def make_generalization_of(self, other, jumpargs, optimizer): + def make_guarded_generalization_of(self, other, jumpargs, optimizer): assert len(self.state) == len(other.state) == len(jumpargs) values = [optimizer.getvalue(arg) for arg in jumpargs] for i in range(len(self.state)): - new_value = self.state[i].make_generalization_of(other.state[i], values[i], optimizer) + new_value = self.state[i].make_guarded_generalization_of(other.state[i], values[i], optimizer) if new_value: optimizer.make_equal_to(jumpargs[i], new_value, True) From noreply at buildbot.pypy.org Tue Oct 23 21:08:08 2012 From: noreply at buildbot.pypy.org (hakanardo) Date: Tue, 23 Oct 2012 21:08:08 +0200 (CEST) Subject: [pypy-commit] pypy jit-usable_retrace_3: started on new testframework for VirtualState tests Message-ID: <20121023190808.CED731C1C8F@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: jit-usable_retrace_3 Changeset: r58385:2f7abcc2de9d Date: 2012-10-23 16:45 +0200 http://bitbucket.org/pypy/pypy/changeset/2f7abcc2de9d/ Log: started on new testframework for VirtualState tests diff --git a/pypy/jit/metainterp/test/test_virtualstate.py b/pypy/jit/metainterp/test/test_virtualstate.py --- a/pypy/jit/metainterp/test/test_virtualstate.py +++ b/pypy/jit/metainterp/test/test_virtualstate.py @@ -2,9 +2,9 @@ import py from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.virtualstate import VirtualStateInfo, VStructStateInfo, \ - VArrayStateInfo, NotVirtualStateInfo, VirtualState, ShortBoxes + VArrayStateInfo, NotVirtualStateInfo, VirtualState, ShortBoxes, VirtualStateAdder from pypy.jit.metainterp.optimizeopt.optimizer import OptValue -from pypy.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr, ConstInt, ConstPtr +from pypy.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr, ConstInt, ConstPtr, AbstractValue from pypy.rpython.lltypesystem import lltype, llmemory from pypy.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin, BaseTest, \ equaloplists, FakeDescrWithSnapshot @@ -12,6 +12,7 @@ from pypy.jit.metainterp.history import TreeLoop, JitCellToken from pypy.jit.metainterp.optimizeopt.test.test_optimizeopt import FakeMetaInterpStaticData from pypy.jit.metainterp.resoperation import ResOperation, rop +from pypy.jit.metainterp.optimizeopt.optimizer import LEVEL_UNKNOWN class TestBasic: someptr1 = LLtypeMixin.myptr @@ -1163,3 +1164,51 @@ if op and op.result == int_neg.getarg(0)] assert len(getfield) == 1 assert getfield[0].getarg(0) == self.p1 + +class FakeCPU(object): + pass + +class FakeOptimizer(object): + unknown_ptr1, unknown_ptr2 = BoxPtr(), BoxPtr() + unknown_int1, unknown_int2 = BoxInt(1), BoxInt(2) + const_int0, const_int1 = ConstInt(0), ConstInt(1) + + def __init__(self): + self.values = {} + for n in dir(self): + box = getattr(self, n) + if isinstance(box, AbstractValue): + self.values[box] = OptValue(box) + + def getvalue(self, box): + return self.values[box] + + def force_at_end_of_preamble(self): + pass + + optearlyforce = None + opaque_pointers = {} + cpu = FakeCPU() + +class CompareUnknown(object): + def __eq__(self, other): + return isinstance(other, NotVirtualStateInfo) and other.level == LEVEL_UNKNOWN +Unknown = CompareUnknown() + +class TestGuardedGenerlaization: + optimizer = FakeOptimizer() + + def combine(self, inputargs, jumpargs, expected): + modifier = VirtualStateAdder(self.optimizer) + vstate1 = modifier.get_virtual_state(inputargs) + vstate2 = modifier.get_virtual_state(jumpargs) + vstate = vstate1.make_guarded_generalization_of(vstate2, jumpargs, self.optimizer) + assert vstate.state == expected + + def test_unknown(self): + o = self.optimizer + self.combine([o.unknown_ptr1, o.unknown_int1], + [o.unknown_ptr2, o.unknown_int2], + [Unknown, Unknown]) + + From noreply at buildbot.pypy.org Tue Oct 23 22:06:20 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 23 Oct 2012 22:06:20 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fill in the optional _string module's docs Message-ID: <20121023200620.861BB1C01F9@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58386:96c9e6df0361 Date: 2012-10-23 11:53 -0700 http://bitbucket.org/pypy/pypy/changeset/96c9e6df0361/ Log: fill in the optional _string module's docs diff --git a/pypy/doc/config/objspace.usemodules._string.txt b/pypy/doc/config/objspace.usemodules._string.txt new file mode 100644 --- /dev/null +++ b/pypy/doc/config/objspace.usemodules._string.txt @@ -0,0 +1,2 @@ +Use the '_string' module, which provides the utility functions for the +``string.Formatter`` class. From noreply at buildbot.pypy.org Tue Oct 23 22:06:22 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 23 Oct 2012 22:06:22 +0200 (CEST) Subject: [pypy-commit] pypy py3k: fix tests for CO_FUTURE_BARRY_AS_BDFL Message-ID: <20121023200622.6949F1C01F9@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58387:93a6ba5f2e0a Date: 2012-10-23 13:07 -0700 http://bitbucket.org/pypy/pypy/changeset/93a6ba5f2e0a/ Log: fix tests for CO_FUTURE_BARRY_AS_BDFL diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -15,15 +15,18 @@ def setup_class(cls): cls.parser = pyparse.PythonParser(cls.space) - def get_ast(self, source, p_mode="exec"): - info = pyparse.CompileInfo("", p_mode, - consts.CO_FUTURE_WITH_STATEMENT) + def get_ast(self, source, p_mode=None, flags=None): + if p_mode is None: + p_mode = "exec" + if flags is None: + flags = consts.CO_FUTURE_WITH_STATEMENT + info = pyparse.CompileInfo("", p_mode, flags) tree = self.parser.parse_source(source, info) ast_node = ast_from_node(self.space, tree, info) return ast_node - def get_first_expr(self, source): - mod = self.get_ast(source) + def get_first_expr(self, source, p_mode=None, flags=None): + mod = self.get_ast(source, p_mode, flags) assert len(mod.body) == 1 expr = mod.body[0] assert isinstance(expr, ast.Expr) @@ -853,7 +856,6 @@ ("<=", ast.LtE), ("==", ast.Eq), ("!=", ast.NotEq), - ("<>", ast.NotEq), ("in", ast.In), ("is", ast.Is), ("is not", ast.IsNot), @@ -881,6 +883,20 @@ names = comp.left.id + "".join(n.id for n in comp.comparators) assert names == vars + def test_flufl(self): + source = "x <> y" + raises(SyntaxError, self.get_ast, source) + comp = self.get_first_expr(source, + flags=consts.CO_FUTURE_BARRY_AS_BDFL) + assert isinstance(comp, ast.Compare) + assert isinstance(comp.left, ast.Name) + assert comp.left.ctx == ast.Load + assert len(comp.ops) == 1 + assert comp.ops[0] == ast.NotEq + assert len(comp.comparators) == 1 + assert isinstance(comp.comparators[0], ast.Name) + assert comp.comparators[0].ctx == ast.Load + def test_binop(self): binops = ( ("|", ast.BitOr), From noreply at buildbot.pypy.org Tue Oct 23 22:11:57 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 23 Oct 2012 22:11:57 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix translation Message-ID: <20121023201157.0791F1C01F9@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58388:21c70617155a Date: 2012-10-23 22:09 +0200 http://bitbucket.org/pypy/pypy/changeset/21c70617155a/ Log: Fix translation diff --git a/pypy/objspace/std/stringtype.py b/pypy/objspace/std/stringtype.py --- a/pypy/objspace/std/stringtype.py +++ b/pypy/objspace/std/stringtype.py @@ -313,8 +313,7 @@ w_bytes_method = space.lookup(w_source, "__bytes__") if w_bytes_method: w_bytes = space.call_function(w_bytes_method, w_source) - # XXX a bit inefficient - return space.bytes_w(w_bytes) + w_source = w_bytes # sequence of bytes data = [] From noreply at buildbot.pypy.org Wed Oct 24 00:56:10 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 00:56:10 +0200 (CEST) Subject: [pypy-commit] pypy py3k: remove _socket.makefile: it's now implemented in socket.py. Message-ID: <20121023225610.B9BBD1C02AD@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58389:9f64095856e5 Date: 2012-10-23 22:44 +0200 http://bitbucket.org/pypy/pypy/changeset/9f64095856e5/ Log: remove _socket.makefile: it's now implemented in socket.py. diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -179,16 +179,6 @@ except SocketError, e: raise converted_error(space, e) - @unwrap_spec(w_mode = WrappedDefault("r"), - w_buffsize = WrappedDefault(-1)) - def makefile_w(self, space, w_mode=None, w_buffsize=None): - """makefile([mode[, buffersize]]) -> file object - - Return a regular file object corresponding to the socket. - The mode and buffersize arguments are as for the built-in open() function. - """ - return app_makefile(space, self, w_mode, w_buffsize) - @unwrap_spec(buffersize='nonnegint', flags=int) def recv_w(self, space, buffersize, flags=0): """recv(buffersize[, flags]) -> data @@ -422,17 +412,6 @@ return self.close_w(space) -app_makefile = gateway.applevel(r''' -def makefile(self, mode="r", buffersize=-1): - """makefile([mode[, buffersize]]) -> file object - - Return a regular file object corresponding to the socket. - The mode and buffersize arguments are as for the built-in open() function. - """ - import os - newfd = os.dup(self.fileno()) - return os.fdopen(newfd, mode, buffersize) -''', filename =__file__).interphook('makefile') # ____________________________________________________________ # Error handling @@ -474,7 +453,7 @@ socketmethodnames = """ _accept bind close connect connect_ex dup fileno detach -getpeername getsockname getsockopt gettimeout listen makefile +getpeername getsockname getsockopt gettimeout listen recv recvfrom send sendall sendto setblocking setsockopt settimeout shutdown _reuse _drop recv_into recvfrom_into """.split() @@ -516,7 +495,6 @@ getsockopt(level, optname[, buflen]) -- get socket options gettimeout() -- return timeout or None listen(n) -- start listening for incoming connections -makefile([mode, [bufsize]]) -- return a file object for the socket [*] recv(buflen[, flags]) -- receive data recvfrom(buflen[, flags]) -- receive data and sender's address sendall(data[, flags]) -- send all data From noreply at buildbot.pypy.org Wed Oct 24 00:56:12 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 00:56:12 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Remove socket.fromfd(), and dup() is now a module-level function. Message-ID: <20121023225612.882F61C02AD@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58390:a6bc13df8ea2 Date: 2012-10-23 23:30 +0200 http://bitbucket.org/pypy/pypy/changeset/a6bc13df8ea2/ Log: Remove socket.fromfd(), and dup() is now a module-level function. diff --git a/pypy/module/_socket/__init__.py b/pypy/module/_socket/__init__.py --- a/pypy/module/_socket/__init__.py +++ b/pypy/module/_socket/__init__.py @@ -25,14 +25,13 @@ for name in """ gethostbyname gethostbyname_ex gethostbyaddr gethostname getservbyname getservbyport getprotobyname - fromfd socketpair + dup socketpair ntohs ntohl htons htonl inet_aton inet_ntoa inet_pton inet_ntop getaddrinfo getnameinfo getdefaulttimeout setdefaulttimeout """.split(): - if name in ('inet_pton', 'inet_ntop', - 'fromfd', 'socketpair', + if name in ('inet_pton', 'inet_ntop', 'socketpair', ) and not hasattr(rsocket, name): continue diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -126,18 +126,10 @@ raise converted_error(space, e) return space.newtuple([space.wrap(host), space.wrap(servport)]) - at unwrap_spec(fd=int, family=int, type=int, proto=int) -def fromfd(space, fd, family, type, proto=0): - """fromfd(fd, family, type[, proto]) -> socket object - - Create a socket object from the given file descriptor. - The remaining arguments are the same as for socket(). - """ - try: - sock = rsocket.fromfd(fd, family, type, proto, W_RSocket) - except SocketError, e: - raise converted_error(space, e) - return space.wrap(sock) + at unwrap_spec(fd=int) +def dup(space, fd): + newfd = rsocket.dup(fd) + return space.wrap(newfd) @unwrap_spec(family=int, type=int, proto=int) def socketpair(space, family=rsocket.socketpair_default_family, diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -93,12 +93,6 @@ error = self.connect_ex(addr) return space.wrap(error) - def dup_w(self, space): - try: - return self.dup(W_RSocket) - except SocketError, e: - raise converted_error(space, e) - def fileno_w(self, space): """fileno() -> integer @@ -452,15 +446,11 @@ # ____________________________________________________________ socketmethodnames = """ -_accept bind close connect connect_ex dup fileno detach +_accept bind close connect connect_ex fileno detach getpeername getsockname getsockopt gettimeout listen recv recvfrom send sendall sendto setblocking setsockopt settimeout shutdown _reuse _drop recv_into recvfrom_into """.split() -# Remove non-implemented methods -for name in ('dup',): - if not hasattr(RSocket, name): - socketmethodnames.remove(name) if hasattr(rsocket._c, 'WSAIoctl'): socketmethodnames.append('ioctl') @@ -488,7 +478,6 @@ close() -- close the socket connect(addr) -- connect the socket to a remote address connect_ex(addr) -- connect, return an error code instead of an exception -dup() -- return a new socket object identical to the current one [*] fileno() -- return underlying file descriptor getpeername() -- return remote address [*] getsockname() -- return local address diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -91,25 +91,6 @@ "(_socket, name): return _socket.getprotobyname(name)") assert space.unwrap(w_n) == socket.IPPROTO_TCP -def test_fromfd(): - # XXX review - if not hasattr(socket, 'fromfd'): - py.test.skip("No socket.fromfd on this platform") - orig_fd = path.open() - fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()), - space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM), - space.wrap(0)], - """(_socket, fd, family, type, proto): - return _socket.fromfd(fd, family, type, proto)""") - - assert space.unwrap(space.call_method(fd, 'fileno')) - fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()), - space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM)], - """(_socket, fd, family, type): - return _socket.fromfd(fd, family, type)""") - - assert space.unwrap(space.call_method(fd, 'fileno')) - def test_ntohs(): w_n = space.appexec([w_socket, space.wrap(125)], "(_socket, x): return _socket.ntohs(x)") @@ -503,13 +484,10 @@ def test_dup(self): import _socket as socket - if not hasattr(socket.socket, 'dup'): - skip('No dup() on this platform') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('localhost', 0)) - s2 = s.dup() - assert s.fileno() != s2.fileno() - assert s.getsockname() == s2.getsockname() + fd = socket.dup(s.fileno()) + assert s.fileno() != fd def test_buffer(self): # Test that send/sendall/sendto accept a buffer as arg diff --git a/pypy/rlib/_rsocket_rffi.py b/pypy/rlib/_rsocket_rffi.py --- a/pypy/rlib/_rsocket_rffi.py +++ b/pypy/rlib/_rsocket_rffi.py @@ -343,6 +343,12 @@ ('iErrorCode', rffi.CFixedArray(rffi.INT, 10)), #FD_MAX_EVENTS ]) + CConfig.WSAPROTOCOL_INFO = platform.Struct( + 'struct WSAPROTOCOL_INFO', + []) # Struct is just passed between functions + CConfig.FROM_PROTOCOL_INFO = platform.DefinedConstantInteger( + 'FROM_PROTOCOL_INFO') + CConfig.timeval = platform.Struct('struct timeval', [('tv_sec', rffi.LONG), ('tv_usec', rffi.LONG)]) @@ -602,6 +608,18 @@ rffi.INT) tcp_keepalive = cConfig.tcp_keepalive + WSAPROTOCOL_INFO = cConfig.WSAPROTOCOL_INFO + FROM_PROTOCOL_INFO = cConfig.FROM_PROTOCOL_INFO + WSADuplicateSocket = external('WSADuplicateSocket', + [socketfd_type, rwin32.DWORD, + lltype.Ptr(WSAPROTOCOL_INFO)], + rffi.INT) + WSASocket = external('WSASocket', + [rffi.INT, rffi.INT, rffi.INT, + lltype.Ptr(WSAPROTOCOL_INFO), + rffi.DWORD, rffi.DWORD], + socketfd_type) + if WIN32: WSAData = cConfig.WSAData WSAStartup = external('WSAStartup', [rffi.INT, lltype.Ptr(WSAData)], diff --git a/pypy/rlib/rsocket.py b/pypy/rlib/rsocket.py --- a/pypy/rlib/rsocket.py +++ b/pypy/rlib/rsocket.py @@ -1187,13 +1187,20 @@ return (make_socket(fd0, family, type, proto, SocketClass), make_socket(fd1, family, type, proto, SocketClass)) -if hasattr(_c, 'dup'): - def fromfd(fd, family, type, proto=0, SocketClass=RSocket): - # Dup the fd so it and the socket can be closed independently - fd = _c.dup(fd) - if fd < 0: - raise last_error() - return make_socket(fd, family, type, proto, SocketClass) +if _c.WIN32: + def dup(fd): + with lltype.scoped_alloc(_c.WSAData, zero=True) as info: + if _c.WSADuplicateSocket(fd, rwin32.GetCurrentProcessId(), info): + raise last_error() + result = _c.WSASocket( + _c.FROM_PROTOCOL_INFO, _c.FROM_PROTOCOL_INFO, + _c.FROM_PROTOCOL_INFO, info, 0, 0) + if result == INVALID_SOCKET: + raise last_error() + return result +else: + def dup(fd): + return _c.dup(fd) def getdefaulttimeout(): return defaults.timeout From noreply at buildbot.pypy.org Wed Oct 24 00:56:13 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 00:56:13 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix tests in _multiprocessing Message-ID: <20121023225613.E69B61C02AD@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58391:533ae279f477 Date: 2012-10-23 23:48 +0200 http://bitbucket.org/pypy/pypy/changeset/533ae279f477/ Log: Fix tests in _multiprocessing diff --git a/pypy/module/_multiprocessing/interp_connection.py b/pypy/module/_multiprocessing/interp_connection.py --- a/pypy/module/_multiprocessing/interp_connection.py +++ b/pypy/module/_multiprocessing/interp_connection.py @@ -102,9 +102,9 @@ space, self.BUFFER_SIZE, maxlength) try: if newbuf: - return space.wrap(rffi.charpsize2str(newbuf, res)) + return space.wrapbytes(rffi.charpsize2str(newbuf, res)) else: - return space.wrap(rffi.charpsize2str(self.buffer, res)) + return space.wrapbytes(rffi.charpsize2str(self.buffer, res)) finally: if newbuf: rffi.free_charp(newbuf) @@ -118,14 +118,14 @@ space, length - offset, PY_SSIZE_T_MAX) try: if newbuf: - raise BufferTooShort(space, space.wrap( + raise BufferTooShort(space, space.wrapbytes( rffi.charpsize2str(newbuf, res))) rwbuffer.setslice(offset, rffi.charpsize2str(self.buffer, res)) finally: if newbuf: rffi.free_charp(newbuf) - return space.wrap(res) + return space.wrapbytes(res) def send(self, space, w_obj): self._check_writable(space) @@ -148,9 +148,9 @@ space, self.BUFFER_SIZE, PY_SSIZE_T_MAX) try: if newbuf: - w_received = space.wrap(rffi.charpsize2str(newbuf, res)) + w_received = space.wrapbytes(rffi.charpsize2str(newbuf, res)) else: - w_received = space.wrap(rffi.charpsize2str(self.buffer, res)) + w_received = space.wrapbytes(rffi.charpsize2str(self.buffer, res)) finally: if newbuf: rffi.free_charp(newbuf) diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -35,11 +35,10 @@ class BaseConnectionTest(object): def test_connection(self): - py3k_skip('fixme later') rhandle, whandle = self.make_pair() - whandle.send_bytes("abc") - assert rhandle.recv_bytes(100) == "abc" + whandle.send_bytes(b"abc") + assert rhandle.recv_bytes(100) == b"abc" obj = [1, 2.0, "hello"] whandle.send(obj) @@ -47,7 +46,6 @@ assert obj == obj2 def test_poll(self): - py3k_skip('fixme later') rhandle, whandle = self.make_pair() assert rhandle.poll() == False @@ -61,7 +59,6 @@ raises(IOError, whandle.poll) def test_read_into(self): - py3k_skip('fixme later') import array, multiprocessing rhandle, whandle = self.make_pair() @@ -96,7 +93,7 @@ class AppTestSocketConnection(BaseConnectionTest): def setup_class(cls): space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal', - 'struct', 'array')) + 'struct', 'array', '_socket')) cls.space = space cls.w_connections = space.newlist([]) @@ -160,7 +157,6 @@ raises(IOError, _multiprocessing.Connection, -15) def test_byte_order(self): - py3k_skip('fixme later') import socket if not 'fromfd' in dir(socket): skip('No fromfd in socket') From noreply at buildbot.pypy.org Wed Oct 24 00:56:15 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 00:56:15 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Like CPython, avoid too large factorials. Message-ID: <20121023225615.4D35E1C02AD@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58392:53ce3af8e70b Date: 2012-10-24 00:49 +0200 http://bitbucket.org/pypy/pypy/changeset/53ce3af8e70b/ Log: Like CPython, avoid too large factorials. diff --git a/pypy/module/math/app_math.py b/pypy/module/math/app_math.py --- a/pypy/module/math/app_math.py +++ b/pypy/module/math/app_math.py @@ -1,3 +1,5 @@ +import sys + def factorial(x): """Find x!.""" if isinstance(x, float): @@ -5,6 +7,8 @@ if fl != x: raise ValueError("float arguments must be integral") x = fl + if x > sys.maxsize: + raise OverflowError("Too large for a factorial") if x < 0: raise ValueError("x must be >= 0") res = 1 diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -89,7 +89,7 @@ assert actual == expected def test_factorial(self): - import math + import math, sys assert math.factorial(0) == 1 assert math.factorial(1) == 1 assert math.factorial(2) == 2 @@ -98,6 +98,8 @@ raises(ValueError, math.factorial, -1) raises(ValueError, math.factorial, -1.) raises(ValueError, math.factorial, 1.1) + raises(OverflowError, math.factorial, sys.maxsize+1) + raises(OverflowError, math.factorial, 10e100) def test_log1p(self): import math From noreply at buildbot.pypy.org Wed Oct 24 00:56:16 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 00:56:16 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix syntax error when importing hashlib, or random, or tempfile. Message-ID: <20121023225616.A916F1C02AD@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58393:a4733acc6b11 Date: 2012-10-24 00:55 +0200 http://bitbucket.org/pypy/pypy/changeset/a4733acc6b11/ Log: Fix syntax error when importing hashlib, or random, or tempfile. diff --git a/lib_pypy/_sha1.py b/lib_pypy/_sha1.py --- a/lib_pypy/_sha1.py +++ b/lib_pypy/_sha1.py @@ -43,7 +43,7 @@ # Strip off leading zeros. for i in range(len(s)): - if s[i] <> '\000': + if s[i] != '\000': break else: # Only happens when n == 0. diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py --- a/pypy/interpreter/astcompiler/astbuilder.py +++ b/pypy/interpreter/astcompiler/astbuilder.py @@ -855,9 +855,9 @@ elif comp_type == tokens.NOTEQUAL: flufl = self.compile_info.flags & consts.CO_FUTURE_BARRY_AS_BDFL if flufl and comp_node.value == '!=': - self.error('message', comp_node) + self.error('invalid comparison', comp_node) elif not flufl and comp_node.value == '<>': - self.error('message', comp_node) + self.error('invalid comparison', comp_node) return ast.NotEq elif comp_type == tokens.NAME: if comp_node.value == "is": From noreply at buildbot.pypy.org Wed Oct 24 01:54:06 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 24 Oct 2012 01:54:06 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: final version of slides Message-ID: <20121023235406.D18FB1C01F9@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4895:04c3e5b2e7b0 Date: 2012-10-23 16:52 -0700 http://bitbucket.org/pypy/extradoc/changeset/04c3e5b2e7b0/ Log: final version of slides diff --git a/talk/dls2012/presentation/talk.tex b/talk/dls2012/presentation/talk.tex --- a/talk/dls2012/presentation/talk.tex +++ b/talk/dls2012/presentation/talk.tex @@ -113,11 +113,6 @@ \end{frame} \begin{frame} - \frametitle{How fast is PyPy?} - \includegraphics[scale=0.3]{figures/all_numbers.png} -\end{frame} - -\begin{frame} \frametitle{Tracing JITs Compile by Observing an Interpreter} \begin{itemize} \item VM contains both an interpreter and the tracing JIT compiler @@ -144,6 +139,7 @@ \item A trace is an extended basic block \item (it has one entry and several exits) \item traces are easy to optime due to lack of control flow merges + \pause \item most optimizations are one forward pass \item optimizers are often like symbolic executors \item can do optimizations that are expensive or even untractable with full control flow @@ -152,6 +148,27 @@ \begin{frame} \frametitle{Example} + \includegraphics[width=\columnwidth]{figures/optimization1} +\end{frame} + +\begin{frame} + \frametitle{Example} + \includegraphics[width=\columnwidth]{figures/optimization2} +\end{frame} + +\begin{frame} + \frametitle{Example} + \includegraphics[width=\columnwidth]{figures/optimization3} +\end{frame} + +\begin{frame} + \frametitle{Example} + \includegraphics[width=\columnwidth]{figures/optimization4} +\end{frame} + +\begin{frame} + \frametitle{Example} + \includegraphics[width=\columnwidth]{figures/optimization5} \end{frame} @@ -160,7 +177,7 @@ \begin{itemize} \item most traces actually are loops \item naive foward passes ignore this bit of control flow optimization available - \item how to fix that without sacrifing simplicity? + \item how to fix that without sacrifing simplicity of optimizations? \end{itemize} \end{frame} @@ -309,6 +326,17 @@ \end{columns} \end{frame} +\begin{frame} + \frametitle{Optimizations helped by loop peeling} + \begin{itemize} + \item redundant guard removal + \item common subexpression elimination + \item heap optimizations + \item allocation removal + \end{itemize} +\end{frame} + + \begin{frame}[fragile] \frametitle{Larger example} \begin{columns} @@ -401,7 +429,7 @@ \frametitle{Conclusion} \begin{itemize} \item a simple preprocessing step on traces enables loop-aware optimizations for tracing JITs - \item no changes to the existing optimizations necessary + \item only minimal changes to the existing optimizations necessary \end{itemize} \end{frame} From noreply at buildbot.pypy.org Wed Oct 24 01:54:08 2012 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 24 Oct 2012 01:54:08 +0200 (CEST) Subject: [pypy-commit] extradoc extradoc: talk as given Message-ID: <20121023235408.34ED21C01F9@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: extradoc Changeset: r4896:eab637f57363 Date: 2012-10-23 16:53 -0700 http://bitbucket.org/pypy/extradoc/changeset/eab637f57363/ Log: talk as given diff --git a/talk/dls2012/presentation/bolz-dls-loop-talk.pdf b/talk/dls2012/presentation/bolz-dls-loop-talk.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0b8c2b80124177569f6d65556b855efb34728cda GIT binary patch [cut] From noreply at buildbot.pypy.org Wed Oct 24 08:24:13 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 08:24:13 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Fix translation Message-ID: <20121024062413.8BC521C003E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58394:3de7391aaa89 Date: 2012-10-24 08:23 +0200 http://bitbucket.org/pypy/pypy/changeset/3de7391aaa89/ Log: Fix translation diff --git a/pypy/module/_multiprocessing/interp_connection.py b/pypy/module/_multiprocessing/interp_connection.py --- a/pypy/module/_multiprocessing/interp_connection.py +++ b/pypy/module/_multiprocessing/interp_connection.py @@ -125,7 +125,7 @@ if newbuf: rffi.free_charp(newbuf) - return space.wrapbytes(res) + return space.wrap(res) def send(self, space, w_obj): self._check_writable(space) From noreply at buildbot.pypy.org Wed Oct 24 12:40:45 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 24 Oct 2012 12:40:45 +0200 (CEST) Subject: [pypy-commit] pypy py3k: in-progress: make list comprehensions in their own function; I just check this is to push it on my notebook :-) Message-ID: <20121024104045.632091C0B5C@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58395:97e1b1af67ce Date: 2012-10-22 09:55 +0200 http://bitbucket.org/pypy/pypy/changeset/97e1b1af67ce/ Log: in-progress: make list comprehensions in their own function; I just check this is to push it on my notebook :-) 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 @@ -118,6 +118,19 @@ codegen.emit_op(ops.POP_TOP) +class __extend__(ast.ListComp): + + def build_container(self, codegen): + codegen.emit_op_arg(ops.BUILD_LIST, 0) + + def get_generators(self): + return self.generators + + def accept_comp_iteration(self, codegen, index): + self.elt.walkabout(codegen) + codegen.emit_op_arg(ops.LIST_APPEND, index + 1) + + class __extend__(ast.SetComp): def build_container(self, codegen): @@ -1080,13 +1093,17 @@ self.use_next_block(anchor) def visit_ListComp(self, lc): - self.update_position(lc.lineno) - if len(lc.generators) != 1 or lc.generators[0].ifs: - single = False - self.emit_op_arg(ops.BUILD_LIST, 0) - else: - single = True - self._listcomp_generator(lc.generators, 0, lc.elt, single=single) + self._compile_comprehension(lc, "", + ComprehensionCodeGenerator) + + ## def visit_ListComp(self, lc): + ## self.update_position(lc.lineno) + ## if len(lc.generators) != 1 or lc.generators[0].ifs: + ## single = False + ## self.emit_op_arg(ops.BUILD_LIST, 0) + ## else: + ## single = True + ## self._listcomp_generator(lc.generators, 0, lc.elt, single=single) def _comp_generator(self, node, generators, gen_index): start = self.new_block() diff --git a/pypy/interpreter/astcompiler/symtable.py b/pypy/interpreter/astcompiler/symtable.py --- a/pypy/interpreter/astcompiler/symtable.py +++ b/pypy/interpreter/astcompiler/symtable.py @@ -473,6 +473,9 @@ item.walkabout(self) self.pop_scope() + def visit_ListComp(self, listcomp): + self._visit_comprehension(listcomp, listcomp.generators, listcomp.elt) + def visit_GeneratorExp(self, genexp): self._visit_comprehension(genexp, genexp.generators, genexp.elt) diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -877,6 +877,7 @@ class TestOptimizations: def count_instructions(self, source): code, blocks = generate_function_code(source, self.space) + import pdb;pdb.set_trace() instrs = [] for block in blocks: instrs.extend(block.instructions) diff --git a/pypy/interpreter/astcompiler/test/test_symtable.py b/pypy/interpreter/astcompiler/test/test_symtable.py --- a/pypy/interpreter/astcompiler/test/test_symtable.py +++ b/pypy/interpreter/astcompiler/test/test_symtable.py @@ -106,6 +106,9 @@ def test_genexp(self): self.check_comprehension("(%s)") + def test_listcomp(self): + self.check_comprehension("[%s]") + def test_setcomp(self): self.check_comprehension("{%s}") From noreply at buildbot.pypy.org Wed Oct 24 12:40:46 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 24 Oct 2012 12:40:46 +0200 (CEST) Subject: [pypy-commit] pypy py3k: finish the work started in 97e1b1af67ce: run list comprehensions in their own scope, as we do for genexp, setcomp and dictcomp Message-ID: <20121024104046.D08CB1C0B5C@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58396:06ea8add5a80 Date: 2012-10-24 12:18 +0200 http://bitbucket.org/pypy/pypy/changeset/06ea8add5a80/ Log: finish the work started in 97e1b1af67ce: run list comprehensions in their own scope, as we do for genexp, setcomp and dictcomp diff --git a/TODO b/TODO --- a/TODO +++ b/TODO @@ -18,4 +18,7 @@ unskip numpypy tests in module/test_lib_pypy/numpypy/ optimize W_UnicodeObject, right now it stores both an unicode and an utf8 -version of the same string \ No newline at end of file +version of the same string + +re-enable BUILD_LIST_FROM_ARG: see the comment in astcompiler/codegen.py in +ast.ListComp.build_container \ No newline at end of file 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 @@ -121,6 +121,10 @@ class __extend__(ast.ListComp): def build_container(self, codegen): + # XXX: this is suboptimal: if we use BUILD_LIST_FROM_ARG it's faster + # because it preallocates the list; however, we cannot use it because + # at this point we only have the iterator, not the original iterable + # object codegen.emit_op_arg(ops.BUILD_LIST, 0) def get_generators(self): @@ -1059,52 +1063,10 @@ self.emit_op_arg(ops.CALL_METHOD, (kwarg_count << 8) | arg_count) return True - def _listcomp_generator(self, gens, gen_index, elt, single=False): - start = self.new_block() - skip = self.new_block() - if_cleanup = self.new_block() - anchor = self.new_block() - gen = gens[gen_index] - assert isinstance(gen, ast.comprehension) - gen.iter.walkabout(self) - if single: - self.emit_op_arg(ops.BUILD_LIST_FROM_ARG, 0) - self.emit_op(ops.GET_ITER) - self.use_next_block(start) - self.emit_jump(ops.FOR_ITER, anchor) - self.use_next_block() - gen.target.walkabout(self) - if gen.ifs: - if_count = len(gen.ifs) - for if_ in gen.ifs: - if_.accept_jump_if(self, False, if_cleanup) - self.use_next_block() - else: - if_count = 0 - gen_index += 1 - if gen_index < len(gens): - self._listcomp_generator(gens, gen_index, elt) - else: - elt.walkabout(self) - self.emit_op_arg(ops.LIST_APPEND, gen_index + 1) - self.use_next_block(skip) - self.use_next_block(if_cleanup) - self.emit_jump(ops.JUMP_ABSOLUTE, start, True) - self.use_next_block(anchor) - def visit_ListComp(self, lc): self._compile_comprehension(lc, "", ComprehensionCodeGenerator) - ## def visit_ListComp(self, lc): - ## self.update_position(lc.lineno) - ## if len(lc.generators) != 1 or lc.generators[0].ifs: - ## single = False - ## self.emit_op_arg(ops.BUILD_LIST, 0) - ## else: - ## single = True - ## self._listcomp_generator(lc.generators, 0, lc.elt, single=single) - def _comp_generator(self, node, generators, gen_index): start = self.new_block() skip = self.new_block() diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -877,7 +877,6 @@ class TestOptimizations: def count_instructions(self, source): code, blocks = generate_function_code(source, self.space) - import pdb;pdb.set_trace() instrs = [] for block in blocks: instrs.extend(block.instructions) @@ -988,17 +987,4 @@ return d['f'](5) """) assert 'generator' in space.str_w(space.repr(w_generator)) - - def test_list_comprehension(self): - source = "def f(): [i for i in l]" - source2 = "def f(): [i for i in l for j in l]" - source3 = "def f(): [i for i in l if i]" - counts = self.count_instructions(source) - assert ops.BUILD_LIST not in counts - assert counts[ops.BUILD_LIST_FROM_ARG] == 1 - counts = self.count_instructions(source2) - assert counts[ops.BUILD_LIST] == 1 - assert ops.BUILD_LIST_FROM_ARG not in counts - counts = self.count_instructions(source3) - assert counts[ops.BUILD_LIST] == 1 - assert ops.BUILD_LIST_FROM_ARG not in counts + diff --git a/pypy/interpreter/test/test_generator.py b/pypy/interpreter/test/test_generator.py --- a/pypy/interpreter/test/test_generator.py +++ b/pypy/interpreter/test/test_generator.py @@ -254,11 +254,11 @@ exec(""" def f(): total = sum(i for i in [x for x in z]) - return total, x + return total z = [1, 2, 7] res = f() """, d, d) - assert d['res'] == (10, 7) + assert d['res'] == 10 def test_repr(self): def myFunc(): From noreply at buildbot.pypy.org Wed Oct 24 12:40:49 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 24 Oct 2012 12:40:49 +0200 (CEST) Subject: [pypy-commit] pypy py3k: merge heads Message-ID: <20121024104049.1DA761C0B5C@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58397:cc7ea41e3eab Date: 2012-10-24 12:40 +0200 http://bitbucket.org/pypy/pypy/changeset/cc7ea41e3eab/ Log: merge heads diff too long, truncating to 2000 out of 2970 lines diff --git a/lib-python/3.2/inspect.py b/lib-python/3.2/inspect.py --- a/lib-python/3.2/inspect.py +++ b/lib-python/3.2/inspect.py @@ -767,7 +767,13 @@ and 'varkw' are the names of the * and ** arguments or None.""" if not iscode(co): - raise TypeError('{!r} is not a code object'.format(co)) + if hasattr(len, 'func_code') and type(co) is type(len.func_code): + # PyPy extension: built-in function objects have a func_code too. + # There is no co_code on it, but co_argcount and co_varnames and + # co_flags are present. + pass + else: + raise TypeError('{!r} is not a code object'.format(co)) nargs = co.co_argcount names = co.co_varnames diff --git a/lib-python/3.2/test/test_module.py b/lib-python/3.2/test/test_module.py --- a/lib-python/3.2/test/test_module.py +++ b/lib-python/3.2/test/test_module.py @@ -1,6 +1,6 @@ # Test the module type import unittest -from test.support import run_unittest, gc_collect +from test.support import run_unittest, gc_collect, check_impl_detail import sys ModuleType = type(sys) @@ -10,8 +10,10 @@ # An uninitialized module has no __dict__ or __name__, # and __doc__ is None foo = ModuleType.__new__(ModuleType) - self.assertTrue(foo.__dict__ is None) - self.assertRaises(SystemError, dir, foo) + self.assertFalse(foo.__dict__) + if check_impl_detail(): + self.assertTrue(foo.__dict__ is None) + self.assertRaises(SystemError, dir, foo) try: s = foo.__name__ self.fail("__name__ = %s" % repr(s)) diff --git a/lib-python/3.2/test/test_weakref.py b/lib-python/3.2/test/test_weakref.py --- a/lib-python/3.2/test/test_weakref.py +++ b/lib-python/3.2/test/test_weakref.py @@ -8,6 +8,7 @@ import copy from test import support +from test.support import gc_collect # Used in ReferencesTestCase.test_ref_created_during_del() . ref_from_del = None @@ -67,6 +68,7 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del o + gc_collect() self.assertTrue(ref1() is None, "expected reference to be invalidated") self.assertTrue(ref2() is None, @@ -98,13 +100,16 @@ ref1 = weakref.proxy(o, self.callback) ref2 = weakref.proxy(o, self.callback) del o + gc_collect() def check(proxy): proxy.bar self.assertRaises(ReferenceError, check, ref1) self.assertRaises(ReferenceError, check, ref2) - self.assertRaises(ReferenceError, bool, weakref.proxy(C())) + ref3 = weakref.proxy(C()) + gc_collect() + self.assertRaises(ReferenceError, bool, ref3) self.assertEqual(self.cbcalled, 2) def check_basic_ref(self, factory): @@ -121,6 +126,7 @@ o = factory() ref = weakref.ref(o, self.callback) del o + gc_collect() self.assertTrue(self.cbcalled == 1, "callback did not properly set 'cbcalled'") self.assertTrue(ref() is None, @@ -145,6 +151,7 @@ self.assertTrue(weakref.getweakrefcount(o) == 2, "wrong weak ref count for object") del proxy + gc_collect() self.assertTrue(weakref.getweakrefcount(o) == 1, "wrong weak ref count for object after deleting proxy") @@ -320,6 +327,7 @@ "got wrong number of weak reference objects") del ref1, ref2, proxy1, proxy2 + gc_collect() self.assertTrue(weakref.getweakrefcount(o) == 0, "weak reference objects not unlinked from" " referent when discarded.") @@ -333,6 +341,7 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del ref1 + gc_collect() self.assertTrue(weakref.getweakrefs(o) == [ref2], "list of refs does not match") @@ -340,10 +349,12 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del ref2 + gc_collect() self.assertTrue(weakref.getweakrefs(o) == [ref1], "list of refs does not match") del ref1 + gc_collect() self.assertTrue(weakref.getweakrefs(o) == [], "list of refs not cleared") @@ -629,9 +640,11 @@ gc.collect() self.assertEqual(alist, []) + @support.impl_detail(pypy=False) def test_gc_during_ref_creation(self): self.check_gc_during_creation(weakref.ref) + @support.impl_detail(pypy=False) def test_gc_during_proxy_creation(self): self.check_gc_during_creation(weakref.proxy) @@ -709,6 +722,7 @@ self.assertTrue(mr.called) self.assertEqual(mr.value, 24) del o + gc_collect() self.assertTrue(mr() is None) self.assertTrue(mr.called) @@ -835,15 +849,18 @@ del items1, items2 self.assertEqual(len(dict), self.COUNT) del objects[0] + gc_collect() self.assertEqual(len(dict), self.COUNT - 1, "deleting object did not cause dictionary update") del objects, o + gc_collect() self.assertEqual(len(dict), 0, "deleting the values did not clear the dictionary") # regression on SF bug #447152: dict = weakref.WeakValueDictionary() self.assertRaises(KeyError, dict.__getitem__, 1) dict[2] = C() + gc_collect() self.assertRaises(KeyError, dict.__getitem__, 2) def test_weak_keys(self): @@ -864,9 +881,11 @@ del items1, items2 self.assertEqual(len(dict), self.COUNT) del objects[0] + gc_collect() self.assertTrue(len(dict) == (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o + gc_collect() self.assertTrue(len(dict) == 0, "deleting the keys did not clear the dictionary") o = Object(42) @@ -1225,6 +1244,7 @@ for o in objs: count += 1 del d[o] + gc_collect() self.assertEqual(len(d), 0) self.assertEqual(count, 2) @@ -1317,6 +1337,7 @@ >>> id2obj(a_id) is a True >>> del a +>>> gc_collect() >>> try: ... id2obj(a_id) ... except KeyError: diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py --- a/lib_pypy/_ctypes/structure.py +++ b/lib_pypy/_ctypes/structure.py @@ -69,7 +69,8 @@ resnames.append(name) names = resnames self._names = names - self.__dict__.update(fields) + for name, field in fields.items(): + setattr(self, name, field) class Field(object): def __init__(self, name, offset, size, ctype, num, is_bitfield): diff --git a/lib_pypy/_sha1.py b/lib_pypy/_sha1.py --- a/lib_pypy/_sha1.py +++ b/lib_pypy/_sha1.py @@ -43,7 +43,7 @@ # Strip off leading zeros. for i in range(len(s)): - if s[i] <> '\000': + if s[i] != '\000': break else: # Only happens when n == 0. diff --git a/lib_pypy/_sha512.py b/lib_pypy/_sha512.py --- a/lib_pypy/_sha512.py +++ b/lib_pypy/_sha512.py @@ -32,10 +32,10 @@ W = [] d = sha_info['data'] - for i in xrange(0,16): + for i in range(0,16): W.append( (d[8*i]<<56) + (d[8*i+1]<<48) + (d[8*i+2]<<40) + (d[8*i+3]<<32) + (d[8*i+4]<<24) + (d[8*i+5]<<16) + (d[8*i+6]<<8) + d[8*i+7]) - for i in xrange(16,80): + for i in range(16,80): W.append( (Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]) & 0xffffffffffffffff ) ss = sha_info['digest'][:] @@ -152,14 +152,6 @@ sha_info['digestsize'] = 48 return sha_info -def getbuf(s): - if isinstance(s, str): - return s - elif isinstance(s, unicode): - return str(s) - else: - return buffer(s) - def sha_update(sha_info, buffer): count = len(buffer) buffer_idx = 0 @@ -199,7 +191,7 @@ # copy buffer pos = sha_info['local'] - sha_info['data'][pos:pos+count] = [struct.unpack('B',c)[0] for c in buffer[buffer_idx:buffer_idx + count]] + sha_info['data'][pos:pos+count] = buffer[buffer_idx:buffer_idx + count] sha_info['local'] = count def sha_final(sha_info): @@ -240,7 +232,7 @@ dig = [] for i in sha_info['digest']: dig.extend([ ((i>>56) & 0xff), ((i>>48) & 0xff), ((i>>40) & 0xff), ((i>>32) & 0xff), ((i>>24) & 0xff), ((i>>16) & 0xff), ((i>>8) & 0xff), (i & 0xff) ]) - return ''.join([chr(i) for i in dig]) + return bytes(dig) class sha512(object): digest_size = digestsize = SHA_DIGESTSIZE @@ -249,10 +241,10 @@ def __init__(self, s=None): self._sha = sha_init() if s: - sha_update(self._sha, getbuf(s)) + sha_update(self._sha, s) def update(self, s): - sha_update(self._sha, getbuf(s)) + sha_update(self._sha, s) def digest(self): return sha_final(self._sha.copy())[:self._sha['digestsize']] @@ -271,7 +263,7 @@ def __init__(self, s=None): self._sha = sha384_init() if s: - sha_update(self._sha, getbuf(s)) + sha_update(self._sha, s) def copy(self): new = sha384.__new__(sha384) diff --git a/lib_pypy/pypy_test/test_ctypes_support.py b/lib_pypy/pypy_test/test_ctypes_support.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_ctypes_support.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import absolute_import - -import py -from ctypes import * -try: - from ctypes_support import standard_c_lib, get_errno, set_errno -except ImportError: # on top of cpython - from lib_pypy.ctypes_support import standard_c_lib, get_errno, set_errno - - -def test_stdlib_and_errno(): - py.test.skip("this is expected on top of pypy, we need to fix ctypes in a way that is now in 2.6 in order to make this reliable") - write = standard_c_lib.write - write.argtypes = [c_int, c_char_p, c_size_t] - write.restype = c_size_t - # clear errno first - set_errno(0) - assert get_errno() == 0 - write(-345, "abc", 3) - assert get_errno() != 0 - set_errno(0) - assert get_errno() == 0 - -def test_argument_conversion_and_checks(): - strlen = standard_c_lib.strlen - strlen.argtypes = [c_char_p] - strlen.restype = c_size_t - assert strlen("eggs") == 4 - - # Should raise ArgumentError, not segfault - py.test.raises(ArgumentError, strlen, False) - diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -158,9 +158,7 @@ body = body.lstrip() assert body.startswith('(') src = py.code.Source("def anonymous" + body) - d = {} - exec src.compile() in d - return d['anonymous'](*args) + return (src, args) def wrap(self, obj): return obj @@ -208,7 +206,7 @@ if option.runappdirect: py.test.skip("translation test, skipped for appdirect") -def run_with_python(python, target): +def run_with_python(python, target, **definitions): if python is None: py.test.skip("Cannot find the default python3 interpreter to run with -A") # we assume that the source of target is in utf-8. Unfortunately, we don't @@ -239,10 +237,20 @@ return res else: raise AssertionError("DID NOT RAISE") + class Test: + pass + self = Test() """ + defs = [] + for symbol, value in definitions.items(): + if isinstance(value, tuple) and isinstance(value[0], py.code.Source): + code, args = value + defs.append(str(code)) + args = ','.join(repr(arg) for arg in args) + defs.append("self.%s = anonymous(%s)\n" % (symbol, args)) source = py.code.Source(target)[1:].deindent() pyfile = udir.join('src.py') - source = helpers + str(source) + source = helpers + '\n'.join(defs) + str(source) with pyfile.open('w') as f: f.write(source) res, stdout, stderr = runsubprocess.run_subprocess( @@ -504,9 +512,11 @@ def runtest(self): target = self.obj src = extract_docstring_if_empty_function(target.im_func) + space = target.im_self.space if self.config.option.runappdirect: - return run_with_python(self.config.option.python, src) - space = target.im_self.space + appexec_definitions = self.parent.obj.__dict__ + return run_with_python(self.config.option.python, src, + **appexec_definitions) filename = self._getdynfilename(target) func = app2interp_temp(src, filename=filename) w_instance = self.parent.w_instance diff --git a/pypy/doc/config/objspace.usemodules._string.txt b/pypy/doc/config/objspace.usemodules._string.txt new file mode 100644 --- /dev/null +++ b/pypy/doc/config/objspace.usemodules._string.txt @@ -0,0 +1,2 @@ +Use the '_string' module, which provides the utility functions for the +``string.Formatter`` class. diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py --- a/pypy/interpreter/astcompiler/astbuilder.py +++ b/pypy/interpreter/astcompiler/astbuilder.py @@ -853,6 +853,11 @@ elif comp_type == tokens.GREATEREQUAL: return ast.GtE elif comp_type == tokens.NOTEQUAL: + flufl = self.compile_info.flags & consts.CO_FUTURE_BARRY_AS_BDFL + if flufl and comp_node.value == '!=': + self.error('invalid comparison', comp_node) + elif not flufl and comp_node.value == '<>': + self.error('invalid comparison', comp_node) return ast.NotEq elif comp_type == tokens.NAME: if comp_node.value == "is": @@ -1118,7 +1123,6 @@ elif first_child_type == tokens.STRING: space = self.space encoding = self.compile_info.encoding - flags = self.compile_info.flags try: sub_strings_w = [parsestring.parsestr(space, encoding, s.value) for s in atom_node.children] diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py --- a/pypy/interpreter/astcompiler/consts.py +++ b/pypy/interpreter/astcompiler/consts.py @@ -15,6 +15,7 @@ CO_FUTURE_WITH_STATEMENT = 0x8000 CO_FUTURE_PRINT_FUNCTION = 0x10000 CO_FUTURE_UNICODE_LITERALS = 0x20000 +CO_FUTURE_BARRY_AS_BDFL = 0x40000 CO_CONTAINSGLOBALS = 0x80000 # pypy-specific: need to check that it's not used # by any other flag diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -15,15 +15,18 @@ def setup_class(cls): cls.parser = pyparse.PythonParser(cls.space) - def get_ast(self, source, p_mode="exec"): - info = pyparse.CompileInfo("", p_mode, - consts.CO_FUTURE_WITH_STATEMENT) + def get_ast(self, source, p_mode=None, flags=None): + if p_mode is None: + p_mode = "exec" + if flags is None: + flags = consts.CO_FUTURE_WITH_STATEMENT + info = pyparse.CompileInfo("", p_mode, flags) tree = self.parser.parse_source(source, info) ast_node = ast_from_node(self.space, tree, info) return ast_node - def get_first_expr(self, source): - mod = self.get_ast(source) + def get_first_expr(self, source, p_mode=None, flags=None): + mod = self.get_ast(source, p_mode, flags) assert len(mod.body) == 1 expr = mod.body[0] assert isinstance(expr, ast.Expr) @@ -853,7 +856,6 @@ ("<=", ast.LtE), ("==", ast.Eq), ("!=", ast.NotEq), - ("<>", ast.NotEq), ("in", ast.In), ("is", ast.Is), ("is not", ast.IsNot), @@ -881,6 +883,20 @@ names = comp.left.id + "".join(n.id for n in comp.comparators) assert names == vars + def test_flufl(self): + source = "x <> y" + raises(SyntaxError, self.get_ast, source) + comp = self.get_first_expr(source, + flags=consts.CO_FUTURE_BARRY_AS_BDFL) + assert isinstance(comp, ast.Compare) + assert isinstance(comp.left, ast.Name) + assert comp.left.ctx == ast.Load + assert len(comp.ops) == 1 + assert comp.ops[0] == ast.NotEq + assert len(comp.comparators) == 1 + assert isinstance(comp.comparators[0], ast.Name) + assert comp.comparators[0].ctx == ast.Load + def test_binop(self): binops = ( ("|", ast.BitOr), diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -817,7 +817,17 @@ def f(): try: raise TypeError() from ValueError() - except TypeError: + except TypeError as e: + assert isinstance(e.__cause__, ValueError) + return 42 + """ + yield self.st, test, "f()", 42 + test = """if 1: + def f(): + try: + raise TypeError from ValueError + except TypeError as e: + assert isinstance(e.__cause__, ValueError) return 42 """ yield self.st, test, "f()", 42 diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -434,6 +434,7 @@ raise operationerrfmt(space.w_ValueError, "%s() requires a code object with %d free vars, not %d", self.name, closure_len, len(code.co_freevars)) + self.fget_func_doc(space) # see test_issue1293 self.code = code def fget_func_closure(self, space): diff --git a/pypy/interpreter/pycompiler.py b/pypy/interpreter/pycompiler.py --- a/pypy/interpreter/pycompiler.py +++ b/pypy/interpreter/pycompiler.py @@ -101,7 +101,7 @@ """ def __init__(self, space, override_version=None): PyCodeCompiler.__init__(self, space) - self.future_flags = future.futureFlags_2_7 + self.future_flags = future.futureFlags_3_2 self.parser = pyparse.PythonParser(space, self.future_flags) self.additional_rules = {} self.compiler_flags = self.future_flags.allowed_flags diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -484,6 +484,8 @@ w_value = w_cause = space.w_None if nbargs == 2: w_cause = self.popvalue() + if space.exception_is_valid_obj_as_class_w(w_cause): + w_cause = space.call_function(w_cause) w_value = self.popvalue() if space.exception_is_valid_obj_as_class_w(w_value): w_type = w_value diff --git a/pypy/interpreter/pyparser/future.py b/pypy/interpreter/pyparser/future.py --- a/pypy/interpreter/pyparser/future.py +++ b/pypy/interpreter/pyparser/future.py @@ -24,8 +24,9 @@ the "in" comparisons with explicit numeric comparisons. """ -from pypy.interpreter.astcompiler.consts import CO_GENERATOR_ALLOWED, \ - CO_FUTURE_DIVISION, CO_FUTURE_WITH_STATEMENT, CO_FUTURE_ABSOLUTE_IMPORT +from pypy.interpreter.astcompiler.consts import ( + CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION, CO_FUTURE_WITH_STATEMENT, + CO_FUTURE_ABSOLUTE_IMPORT, CO_FUTURE_BARRY_AS_BDFL) def get_futures(future_flags, source): futures = FutureAutomaton(future_flags, source) 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 @@ -778,6 +778,22 @@ for case in cases: raises(SyntaxError, compile, case, "", "exec") + def test_barry_as_bdfl(self): + # from test_flufl.py :-) + import __future__ + code = "from __future__ import barry_as_FLUFL; 2 {0} 3" + compile(code.format('<>'), '', 'exec', + __future__.CO_FUTURE_BARRY_AS_BDFL) + raises(SyntaxError, compile, code.format('!='), + '', 'exec', + __future__.CO_FUTURE_BARRY_AS_BDFL) + + def test_guido_as_bdfl(self): + # from test_flufl.py :-) + code = '2 {0} 3' + compile(code.format('!='), '', 'exec') + raises(SyntaxError, compile, code.format('<>'), + '', 'exec') class AppTestOptimizer: diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py --- a/pypy/interpreter/test/test_function.py +++ b/pypy/interpreter/test/test_function.py @@ -322,6 +322,12 @@ assert f.__doc__ == "hi" assert type(f.__doc__) is str + def test_issue1293(self): + def f1(): "doc f1" + def f2(): "doc f2" + f1.__code__ = f2.__code__ + assert f1.__doc__ == "doc f1" + def test_subclassing(self): # cannot subclass 'function' or 'builtin_function' def f(): diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -3,11 +3,9 @@ """ from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.rlib.runicode import UNICHR -from pypy.rlib.rfloat import isnan, isinf, round_double -from pypy.rlib import rfloat import __builtin__ def abs(space, w_val): @@ -21,11 +19,8 @@ object, but escape the non-ASCII characters in the string returned by repr() using \\x, \\u or \\U escapes. This generates a string similar to that returned by repr() in Python 2.""" - from pypy.objspace.std.unicodetype import decode_object, encode_object - # repr is guaranteed to be unicode - w_repr = space.repr(w_obj) - w_encoded = encode_object(space, w_repr, 'ascii', 'backslashreplace') - return decode_object(space, w_encoded, 'ascii', None) + from pypy.objspace.std.unicodetype import ascii_from_object + return ascii_from_object(space, w_obj) @unwrap_spec(code=int) def chr(space, code): @@ -102,40 +97,22 @@ # ____________________________________________________________ -# Here 0.30103 is an upper bound for log10(2) -NDIGITS_MAX = int((rfloat.DBL_MANT_DIG - rfloat.DBL_MIN_EXP) * 0.30103) -NDIGITS_MIN = -int((rfloat.DBL_MAX_EXP + 1) * 0.30103) - - at unwrap_spec(number=float, w_ndigits = WrappedDefault(0)) -def round(space, number, w_ndigits): - """round(number[, ndigits]) -> floating point number + at unwrap_spec(w_ndigits=WrappedDefault(None)) +def round(space, w_number, w_ndigits=None): + """round(number[, ndigits]) -> number Round a number to a given precision in decimal digits (default 0 digits). -This always returns a floating point number. Precision may be negative.""" - # Algorithm copied directly from CPython - - # interpret 2nd argument as a Py_ssize_t; clip on overflow - ndigits = space.getindex_w(w_ndigits, None) - - # nans, infinities and zeros round to themselves - if number == 0 or isinf(number) or isnan(number): - return space.wrap(number) - - # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x - # always rounds to itself. For ndigits < NDIGITS_MIN, x always - # rounds to +-0.0. - if ndigits > NDIGITS_MAX: - return space.wrap(number) - elif ndigits < NDIGITS_MIN: - # return 0.0, but with sign of x - return space.wrap(0.0 * number) - - # finite x, and ndigits is not unreasonably large - z = round_double(number, ndigits) - if isinf(z): - raise OperationError(space.w_OverflowError, - space.wrap("rounded value too large to represent")) - return space.wrap(z) +This returns an int when called with one argument, otherwise the +same type as the number. ndigits may be negative.""" + round = space.lookup(w_number, '__round__') + if round is None: + raise operationerrfmt(space.w_TypeError, + "type %s doesn't define __round__ method", + space.type(w_number).getname(space)) + if space.is_none(w_ndigits): + return space.get_and_call_function(round, w_number) + else: + return space.get_and_call_function(round, w_number, w_ndigits) # ____________________________________________________________ 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 @@ -642,6 +642,77 @@ assert round(562949953421312.5, 1) == 562949953421312.5 assert round(56294995342131.5, 3) == 56294995342131.5 + assert round(0.0) == 0.0 + assert type(round(0.0)) == int + assert round(1.0) == 1.0 + assert round(10.0) == 10.0 + assert round(1000000000.0) == 1000000000.0 + assert round(1e20) == 1e20 + + assert round(-1.0) == -1.0 + assert round(-10.0) == -10.0 + assert round(-1000000000.0) == -1000000000.0 + assert round(-1e20) == -1e20 + + assert round(0.1) == 0.0 + assert round(1.1) == 1.0 + assert round(10.1) == 10.0 + assert round(1000000000.1) == 1000000000.0 + + assert round(-1.1) == -1.0 + assert round(-10.1) == -10.0 + assert round(-1000000000.1) == -1000000000.0 + + assert round(0.9) == 1.0 + assert round(9.9) == 10.0 + assert round(999999999.9) == 1000000000.0 + + assert round(-0.9) == -1.0 + assert round(-9.9) == -10.0 + assert round(-999999999.9) == -1000000000.0 + + assert round(-8.0, -1) == -10.0 + assert type(round(-8.0, -1)) == float + + assert type(round(-8.0, 0)) == float + assert type(round(-8.0, 1)) == float + + # Check even / odd rounding behaviour + assert round(5.5) == 6 + assert round(6.5) == 6 + assert round(-5.5) == -6 + assert round(-6.5) == -6 + + # Check behavior on ints + assert round(0) == 0 + assert round(8) == 8 + assert round(-8) == -8 + assert type(round(0)) == int + assert type(round(-8, -1)) == int + assert type(round(-8, 0)) == int + assert type(round(-8, 1)) == int + + assert round(number=-8.0, ndigits=-1) == -10.0 + raises(TypeError, round) + + # test generic rounding delegation for reals + class TestRound: + def __round__(self): + return 23 + + class TestNoRound: + pass + + assert round(TestRound()) == 23 + + raises(TypeError, round, 1, 2, 3) + raises(TypeError, round, TestNoRound()) + + t = TestNoRound() + t.__round__ = lambda *args: args + raises(TypeError, round, t) + raises(TypeError, round, t, 0) + def test_vars_obscure_case(self): class C_get_vars(object): def getDict(self): diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,8 +4,9 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi +from pypy.rlib import jit, clibffi, jit_libffi, rposix from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -147,9 +148,13 @@ argtype = self.fargs[i] if isinstance(argtype, W_CTypePointer): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) - if get_mustfree_flag(data): + flag = get_mustfree_flag(data) + if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') + elif flag == 2: + file = rffi.cast(rffi.CCHARPP, data)[0] + rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -164,6 +169,27 @@ assert isinstance(abi, int) return space.wrap(abi) +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +def prepare_file_call_argument(fileobj): + import os + space = fileobj.space + fileobj.direct_flush() + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fd2 = os.dup(fd) + f = rffi_fdopen(fd2, fileobj.mode) + if not f: + os.close(fd2) + raise OSError(rposix.get_errno(), "fdopen failed") + except OSError, e: + raise wrap_oserror(space, e) + return f + # ____________________________________________________________ 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 @@ -157,7 +157,7 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - raise self._convert_error("compatible pointer", w_ob) + raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): from pypy.module._cffi_backend import ctypearray @@ -177,7 +177,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = [] + _attrs_ = ['is_file'] + _immutable_fields_ = ['is_file'] def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -186,6 +187,7 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" + self.is_file = (ctitem.name == "struct _IO_FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -234,7 +236,7 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) - def _prepare_pointer_call_argument(self, w_init): + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): @@ -243,10 +245,19 @@ space.isinstance_w(w_init, space.w_bytes)): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 + elif self.is_file: + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = space.interpclass_w(w_init) + if isinstance(ob, W_File): + result = ctypefunc.prepare_file_call_argument(ob) + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 2 + return 0 else: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 if self.ctitem.size <= 0: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 try: datasize = ovfcheck(length * self.ctitem.size) except OverflowError: @@ -259,25 +270,19 @@ except Exception: lltype.free(result, flavor='raw') raise - return result + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 1 def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag space = self.space ob = space.interpclass_w(w_ob) - if isinstance(ob, cdataobj.W_CData): - buffer = lltype.nullptr(rffi.CCHARP.TO) - else: - buffer = self._prepare_pointer_call_argument(w_ob) - # - if buffer: - rffi.cast(rffi.CCHARPP, cdata)[0] = buffer - set_mustfree_flag(cdata, True) - return True - else: - set_mustfree_flag(cdata, False) + result = (not isinstance(ob, cdataobj.W_CData) and + self._prepare_pointer_call_argument(w_ob, cdata)) + if result == 0: self.convert_from_object(cdata, w_ob) - return False + set_mustfree_flag(cdata, result) + return result def getcfield(self, attr): return self.ctitem.getcfield(attr) 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 @@ -2211,3 +2211,56 @@ buffer(p)[:] = bytearray(b"foo\x00") assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] + +def test_FILE(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fscanf = ll.load_function(BFunc2, "fscanf") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r', 256) + fw1 = posix.fdopen(fdw, 'w', 256) + # + fw1.write(b"X") + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.close() + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"Xhello" + fr1.close() + +def test_FILE_only_for_FILE_arg(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + B_NOT_FILE = new_struct_type("NOT_FILE") + B_NOT_FILEP = new_pointer_type(B_NOT_FILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not file") diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -454,7 +454,7 @@ make_decoder_wrapper('mbcs_decode') # utf-8 functions are not regular, because we have to pass -# "allow_surrogates=True" +# "allow_surrogates=False" @unwrap_spec(uni=unicode, errors='str_or_None') def utf_8_encode(space, uni, errors="strict"): if errors is None: @@ -462,7 +462,7 @@ state = space.fromcache(CodecState) result = runicode.unicode_encode_utf_8( uni, len(uni), errors, state.encode_error_handler, - allow_surrogates=True) + allow_surrogates=False) return space.newtuple([space.wrapbytes(result), space.wrap(len(uni))]) @unwrap_spec(string='bufferstr', errors='str_or_None', @@ -475,7 +475,7 @@ result, consumed = runicode.str_decode_utf_8( string, len(string), errors, final, state.decode_error_handler, - allow_surrogates=True) + allow_surrogates=False) return space.newtuple([space.wrap(result), space.wrap(consumed)]) @unwrap_spec(data="bufferstr", errors='str_or_None', byteorder=int, diff --git a/pypy/module/_csv/interp_reader.py b/pypy/module/_csv/interp_reader.py --- a/pypy/module/_csv/interp_reader.py +++ b/pypy/module/_csv/interp_reader.py @@ -40,6 +40,7 @@ def save_field(self, field_builder): field = field_builder.build() + print "AFA SAVE FIELD", field if self.numeric_field: from pypy.objspace.std.strutil import ParseStringError from pypy.objspace.std.strutil import string_to_float @@ -71,11 +72,7 @@ state != START_RECORD and state != EAT_CRNL and (len(field_builder.build()) > 0 or state == IN_QUOTED_FIELD)): - if dialect.strict: - raise self.error(u"newline inside string") - else: - self.save_field(field_builder) - break + raise self.error(u"newline inside string") raise self.line_num += 1 line = space.unicode_w(w_line) diff --git a/pypy/module/_csv/test/test_reader.py b/pypy/module/_csv/test/test_reader.py --- a/pypy/module/_csv/test/test_reader.py +++ b/pypy/module/_csv/test/test_reader.py @@ -28,7 +28,7 @@ def test_cannot_read_bytes(self): import _csv reader = _csv.reader([b'foo']) - raises(TypeError, "next(reader)") + raises((TypeError, _csv.Error), next, reader) def test_read_oddinputs(self): self._read_test([], []) @@ -107,9 +107,9 @@ self._read_test(['12,12,1",'], [['12', '12', '1"', '']]) def test_read_eof(self): - self._read_test(['a,"'], [['a', '']]) - self._read_test(['"a'], [['a']]) - self._read_test(['^'], [['\n']], escapechar='^') - self._read_test(['a,"'], 'Error', strict=True) + self._read_test(['a,"'], []) + self._read_test(['"a'], 'Error') + self._read_test(['^'], 'Error', escapechar='^') + self._read_test(['a,"'], [], strict=True) self._read_test(['"a'], 'Error', strict=True) self._read_test(['^'], 'Error', escapechar='^', strict=True) diff --git a/pypy/module/_multiprocessing/interp_connection.py b/pypy/module/_multiprocessing/interp_connection.py --- a/pypy/module/_multiprocessing/interp_connection.py +++ b/pypy/module/_multiprocessing/interp_connection.py @@ -102,9 +102,9 @@ space, self.BUFFER_SIZE, maxlength) try: if newbuf: - return space.wrap(rffi.charpsize2str(newbuf, res)) + return space.wrapbytes(rffi.charpsize2str(newbuf, res)) else: - return space.wrap(rffi.charpsize2str(self.buffer, res)) + return space.wrapbytes(rffi.charpsize2str(self.buffer, res)) finally: if newbuf: rffi.free_charp(newbuf) @@ -118,7 +118,7 @@ space, length - offset, PY_SSIZE_T_MAX) try: if newbuf: - raise BufferTooShort(space, space.wrap( + raise BufferTooShort(space, space.wrapbytes( rffi.charpsize2str(newbuf, res))) rwbuffer.setslice(offset, rffi.charpsize2str(self.buffer, res)) finally: @@ -148,9 +148,9 @@ space, self.BUFFER_SIZE, PY_SSIZE_T_MAX) try: if newbuf: - w_received = space.wrap(rffi.charpsize2str(newbuf, res)) + w_received = space.wrapbytes(rffi.charpsize2str(newbuf, res)) else: - w_received = space.wrap(rffi.charpsize2str(self.buffer, res)) + w_received = space.wrapbytes(rffi.charpsize2str(self.buffer, res)) finally: if newbuf: rffi.free_charp(newbuf) diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -35,11 +35,10 @@ class BaseConnectionTest(object): def test_connection(self): - py3k_skip('fixme later') rhandle, whandle = self.make_pair() - whandle.send_bytes("abc") - assert rhandle.recv_bytes(100) == "abc" + whandle.send_bytes(b"abc") + assert rhandle.recv_bytes(100) == b"abc" obj = [1, 2.0, "hello"] whandle.send(obj) @@ -47,7 +46,6 @@ assert obj == obj2 def test_poll(self): - py3k_skip('fixme later') rhandle, whandle = self.make_pair() assert rhandle.poll() == False @@ -61,7 +59,6 @@ raises(IOError, whandle.poll) def test_read_into(self): - py3k_skip('fixme later') import array, multiprocessing rhandle, whandle = self.make_pair() @@ -96,7 +93,7 @@ class AppTestSocketConnection(BaseConnectionTest): def setup_class(cls): space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal', - 'struct', 'array')) + 'struct', 'array', '_socket')) cls.space = space cls.w_connections = space.newlist([]) @@ -160,7 +157,6 @@ raises(IOError, _multiprocessing.Connection, -15) def test_byte_order(self): - py3k_skip('fixme later') import socket if not 'fromfd' in dir(socket): skip('No fromfd in socket') diff --git a/pypy/module/_socket/__init__.py b/pypy/module/_socket/__init__.py --- a/pypy/module/_socket/__init__.py +++ b/pypy/module/_socket/__init__.py @@ -25,14 +25,13 @@ for name in """ gethostbyname gethostbyname_ex gethostbyaddr gethostname getservbyname getservbyport getprotobyname - fromfd socketpair + dup socketpair ntohs ntohl htons htonl inet_aton inet_ntoa inet_pton inet_ntop getaddrinfo getnameinfo getdefaulttimeout setdefaulttimeout """.split(): - if name in ('inet_pton', 'inet_ntop', - 'fromfd', 'socketpair', + if name in ('inet_pton', 'inet_ntop', 'socketpair', ) and not hasattr(rsocket, name): continue diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -126,18 +126,10 @@ raise converted_error(space, e) return space.newtuple([space.wrap(host), space.wrap(servport)]) - at unwrap_spec(fd=int, family=int, type=int, proto=int) -def fromfd(space, fd, family, type, proto=0): - """fromfd(fd, family, type[, proto]) -> socket object - - Create a socket object from the given file descriptor. - The remaining arguments are the same as for socket(). - """ - try: - sock = rsocket.fromfd(fd, family, type, proto, W_RSocket) - except SocketError, e: - raise converted_error(space, e) - return space.wrap(sock) + at unwrap_spec(fd=int) +def dup(space, fd): + newfd = rsocket.dup(fd) + return space.wrap(newfd) @unwrap_spec(family=int, type=int, proto=int) def socketpair(space, family=rsocket.socketpair_default_family, diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -93,12 +93,6 @@ error = self.connect_ex(addr) return space.wrap(error) - def dup_w(self, space): - try: - return self.dup(W_RSocket) - except SocketError, e: - raise converted_error(space, e) - def fileno_w(self, space): """fileno() -> integer @@ -179,16 +173,6 @@ except SocketError, e: raise converted_error(space, e) - @unwrap_spec(w_mode = WrappedDefault("r"), - w_buffsize = WrappedDefault(-1)) - def makefile_w(self, space, w_mode=None, w_buffsize=None): - """makefile([mode[, buffersize]]) -> file object - - Return a regular file object corresponding to the socket. - The mode and buffersize arguments are as for the built-in open() function. - """ - return app_makefile(space, self, w_mode, w_buffsize) - @unwrap_spec(buffersize='nonnegint', flags=int) def recv_w(self, space, buffersize, flags=0): """recv(buffersize[, flags]) -> data @@ -422,17 +406,6 @@ return self.close_w(space) -app_makefile = gateway.applevel(r''' -def makefile(self, mode="r", buffersize=-1): - """makefile([mode[, buffersize]]) -> file object - - Return a regular file object corresponding to the socket. - The mode and buffersize arguments are as for the built-in open() function. - """ - import os - newfd = os.dup(self.fileno()) - return os.fdopen(newfd, mode, buffersize) -''', filename =__file__).interphook('makefile') # ____________________________________________________________ # Error handling @@ -473,15 +446,11 @@ # ____________________________________________________________ socketmethodnames = """ -_accept bind close connect connect_ex dup fileno detach -getpeername getsockname getsockopt gettimeout listen makefile +_accept bind close connect connect_ex fileno detach +getpeername getsockname getsockopt gettimeout listen recv recvfrom send sendall sendto setblocking setsockopt settimeout shutdown _reuse _drop recv_into recvfrom_into """.split() -# Remove non-implemented methods -for name in ('dup',): - if not hasattr(RSocket, name): - socketmethodnames.remove(name) if hasattr(rsocket._c, 'WSAIoctl'): socketmethodnames.append('ioctl') @@ -509,14 +478,12 @@ close() -- close the socket connect(addr) -- connect the socket to a remote address connect_ex(addr) -- connect, return an error code instead of an exception -dup() -- return a new socket object identical to the current one [*] fileno() -- return underlying file descriptor getpeername() -- return remote address [*] getsockname() -- return local address getsockopt(level, optname[, buflen]) -- get socket options gettimeout() -- return timeout or None listen(n) -- start listening for incoming connections -makefile([mode, [bufsize]]) -- return a file object for the socket [*] recv(buflen[, flags]) -- receive data recvfrom(buflen[, flags]) -- receive data and sender's address sendall(data[, flags]) -- send all data diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -91,25 +91,6 @@ "(_socket, name): return _socket.getprotobyname(name)") assert space.unwrap(w_n) == socket.IPPROTO_TCP -def test_fromfd(): - # XXX review - if not hasattr(socket, 'fromfd'): - py.test.skip("No socket.fromfd on this platform") - orig_fd = path.open() - fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()), - space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM), - space.wrap(0)], - """(_socket, fd, family, type, proto): - return _socket.fromfd(fd, family, type, proto)""") - - assert space.unwrap(space.call_method(fd, 'fileno')) - fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()), - space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM)], - """(_socket, fd, family, type): - return _socket.fromfd(fd, family, type)""") - - assert space.unwrap(space.call_method(fd, 'fileno')) - def test_ntohs(): w_n = space.appexec([w_socket, space.wrap(125)], "(_socket, x): return _socket.ntohs(x)") @@ -503,13 +484,10 @@ def test_dup(self): import _socket as socket - if not hasattr(socket.socket, 'dup'): - skip('No dup() on this platform') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('localhost', 0)) - s2 = s.dup() - assert s.fileno() != s2.fileno() - assert s.getsockname() == s2.getsockname() + fd = socket.dup(s.fileno()) + assert s.fileno() != fd def test_buffer(self): # Test that send/sendall/sendto accept a buffer as arg diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py --- a/pypy/module/_sre/interp_sre.py +++ b/pypy/module/_sre/interp_sre.py @@ -113,12 +113,18 @@ if endpos < pos: endpos = pos if space.is_true(space.isinstance(w_string, space.w_unicode)): unicodestr = space.unicode_w(w_string) + if not space.isinstance_w(self.w_pattern, space.w_unicode): + raise OperationError(space.w_TypeError, space.wrap( + "can't use a string pattern on a bytes-like object")) if pos > len(unicodestr): pos = len(unicodestr) if endpos > len(unicodestr): endpos = len(unicodestr) return rsre_core.UnicodeMatchContext(self.code, unicodestr, pos, endpos, self.flags) else: str = space.bufferstr_w(w_string) + if space.isinstance_w(self.w_pattern, space.w_unicode): + raise OperationError(space.w_TypeError, space.wrap( + "can't use a bytes pattern on a string-like object")) if pos > len(str): pos = len(str) if endpos > len(str): endpos = len(str) return rsre_core.StrMatchContext(self.code, str, diff --git a/pypy/module/_sre/test/test_app_sre.py b/pypy/module/_sre/test/test_app_sre.py --- a/pypy/module/_sre/test/test_app_sre.py +++ b/pypy/module/_sre/test/test_app_sre.py @@ -5,17 +5,20 @@ from pypy.interpreter.gateway import app2interp_temp from pypy.conftest import gettestobjspace, option -def init_globals_hack(space): - space.appexec([space.wrap(autopath.this_dir)], """(this_dir): - import builtins as b - import sys, os.path - # Uh-oh, ugly hack - sys.path.insert(0, this_dir) - import support_test_app_sre - b.s = support_test_app_sre - sys.path.pop(0) +def init_app_test(cls, space): + cls.w_s = space.appexec([space.wrap(autopath.this_dir)], + """(this_dir): + import sys + # Uh-oh, ugly hack + sys.path.insert(0, this_dir) + try: + import support_test_app_sre + return support_test_app_sre + finally: + sys.path.pop(0) """) + class AppTestSrePy: def test_magic(self): @@ -194,8 +197,8 @@ # which (if interpreted literally, as CPython does) gives the # following strangeish rules: assert isinstance(re.sub("a", "b", "diwoiioamoi"), str) - assert isinstance(re.sub("a", "b", b"diwoiiobmoi"), bytes) - assert isinstance(re.sub('x', b'y', b'x'), bytes) + raises(TypeError, re.sub, "a", "b", b"diwoiiobmoi") + raises(TypeError, re.sub, 'x', b'y', b'x') def test_sub_callable(self): import re @@ -315,7 +318,7 @@ def test_scanner_zero_width_match(self): import re, sys if sys.version_info[:2] == (2, 3): - return + skip("2.3 is different here") p = re.compile(".*").scanner("bla") assert ("bla", "") == (p.search().group(0), p.search().group(0)) assert None == p.search() @@ -329,7 +332,7 @@ cls.space = gettestobjspace(usemodules=('_locale',)) except py.test.skip.Exception: cls.space = gettestobjspace(usemodules=('_rawffi',)) - init_globals_hack(cls.space) + init_app_test(cls, cls.space) def setup_method(self, method): import locale @@ -340,11 +343,13 @@ locale.setlocale(locale.LC_ALL, (None, None)) def test_getlower_no_flags(self): + s = self.s UPPER_AE = "\xc4" s.assert_lower_equal([("a", "a"), ("A", "a"), (UPPER_AE, UPPER_AE), ("\u00c4", "\u00c4"), ("\u4444", "\u4444")], 0) def test_getlower_locale(self): + s = self.s import locale, sre_constants UPPER_AE = "\xc4" LOWER_AE = "\xe4" @@ -359,6 +364,7 @@ skip("unsupported locale de_DE") def test_getlower_unicode(self): + s = self.s import sre_constants UPPER_AE = "\xc4" LOWER_AE = "\xe4" @@ -587,34 +593,41 @@ class AppTestOpcodes: def setup_class(cls): + if option.runappdirect: + py.test.skip("can only be run on py.py: _sre opcodes don't match") try: cls.space = gettestobjspace(usemodules=('_locale',)) except py.test.skip.Exception: cls.space = gettestobjspace(usemodules=('_rawffi',)) # This imports support_test_sre as the global "s" - init_globals_hack(cls.space) + init_app_test(cls, cls.space) def test_length_optimization(self): + s = self.s pattern = "bla" opcodes = [s.OPCODES["info"], 3, 3, len(pattern)] \ + s.encode_literal(pattern) + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["b", "bl", "ab"]) def test_literal(self): + s = self.s opcodes = s.encode_literal("bla") + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["bl", "blu"]) s.assert_match(opcodes, ["bla", "blab", "cbla", "bbla"]) def test_not_literal(self): + s = self.s opcodes = s.encode_literal("b") \ + [s.OPCODES["not_literal"], ord("a"), s.OPCODES["success"]] s.assert_match(opcodes, ["bx", "ababy"]) s.assert_no_match(opcodes, ["ba", "jabadu"]) def test_unknown(self): + s = self.s raises(RuntimeError, s.search, [55555], "b") def test_at_beginning(self): + s = self.s for atname in ["at_beginning", "at_beginning_string"]: opcodes = [s.OPCODES["at"], s.ATCODES[atname]] \ + s.encode_literal("bla") + [s.OPCODES["success"]] @@ -622,30 +635,35 @@ s.assert_no_match(opcodes, "abla") def test_at_beginning_line(self): + s = self.s opcodes = [s.OPCODES["at"], s.ATCODES["at_beginning_line"]] \ + s.encode_literal("bla") + [s.OPCODES["success"]] s.assert_match(opcodes, ["bla", "x\nbla"]) s.assert_no_match(opcodes, ["abla", "abla\nubla"]) def test_at_end(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end"], s.OPCODES["success"]] s.assert_match(opcodes, ["bla", "bla\n"]) s.assert_no_match(opcodes, ["blau", "abla\nblau"]) def test_at_end_line(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end_line"], s.OPCODES["success"]] s.assert_match(opcodes, ["bla\n", "bla\nx", "bla"]) s.assert_no_match(opcodes, ["blau"]) def test_at_end_string(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end_string"], s.OPCODES["success"]] s.assert_match(opcodes, "bla") s.assert_no_match(opcodes, ["blau", "bla\n"]) def test_at_boundary(self): + s = self.s for atname in "at_boundary", "at_loc_boundary", "at_uni_boundary": opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES[atname], s.OPCODES["success"]] @@ -657,6 +675,7 @@ s.assert_no_match(opcodes, "") def test_at_non_boundary(self): + s = self.s for atname in "at_non_boundary", "at_loc_non_boundary", "at_uni_non_boundary": opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES[atname], s.OPCODES["success"]] @@ -664,6 +683,7 @@ s.assert_no_match(opcodes, ["bla ja", "bla"]) def test_at_loc_boundary(self): + s = self.s import locale try: s.void_locale() @@ -683,6 +703,7 @@ skip("locale error") def test_at_uni_boundary(self): + s = self.s UPPER_PI = "\u03a0" LOWER_PI = "\u03c0" opcodes = s.encode_literal("bl") + [s.OPCODES["any"], s.OPCODES["at"], @@ -694,6 +715,7 @@ s.assert_match(opcodes, ["blaha", "bl%sja" % UPPER_PI]) def test_category_loc_word(self): + s = self.s import locale try: s.void_locale() @@ -714,23 +736,27 @@ skip("locale error") def test_any(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["any"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_match(opcodes, ["b a", "bla", "bboas"]) s.assert_no_match(opcodes, ["b\na", "oba", "b"]) def test_any_all(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["any_all"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_match(opcodes, ["b a", "bla", "bboas", "b\na"]) s.assert_no_match(opcodes, ["oba", "b"]) def test_in_failure(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 2, s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["ba", "bla"]) def test_in_literal(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 7] \ + s.encode_literal("la") + [s.OPCODES["failure"], s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -738,6 +764,7 @@ s.assert_no_match(opcodes, ["ba", "bja", "blla"]) def test_in_category(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 6, s.OPCODES["category"], s.CHCODES["category_digit"], s.OPCODES["category"], s.CHCODES["category_space"], s.OPCODES["failure"]] + s.encode_literal("a") + [s.OPCODES["success"]] @@ -748,6 +775,7 @@ import _sre if _sre.CODESIZE != 2: return + s = self.s # charset bitmap for characters "l" and "h" bitmap = 6 * [0] + [4352] + 9 * [0] opcodes = s.encode_literal("b") + [s.OPCODES["in"], 19, s.OPCODES["charset"]] \ @@ -759,6 +787,7 @@ # disabled because this actually only works on big-endian machines if _sre.CODESIZE != 2: return + s = self.s # constructing bigcharset for lowercase pi (\u03c0) UPPER_PI = u"\u03a0" LOWER_PI = u"\u03c0" @@ -774,6 +803,7 @@ # XXX bigcharset test for ucs4 missing here def test_in_range(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 5, s.OPCODES["range"], ord("1"), ord("9"), s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -781,6 +811,7 @@ s.assert_no_match(opcodes, ["baa", "b5"]) def test_in_negate(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 7, s.OPCODES["negate"]] \ + s.encode_literal("la") + [s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -788,12 +819,14 @@ s.assert_no_match(opcodes, ["bla", "baa", "blbla"]) def test_literal_ignore(self): + s = self.s opcodes = s.encode_literal("b") \ + [s.OPCODES["literal_ignore"], ord("a"), s.OPCODES["success"]] s.assert_match(opcodes, ["ba", "bA"]) s.assert_no_match(opcodes, ["bb", "bu"]) def test_not_literal_ignore(self): + s = self.s UPPER_PI = "\u03a0" opcodes = s.encode_literal("b") \ + [s.OPCODES["not_literal_ignore"], ord("a"), s.OPCODES["success"]] @@ -801,6 +834,7 @@ s.assert_no_match(opcodes, ["ba", "bA"]) def test_in_ignore(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in_ignore"], 8] \ + s.encode_literal("abc") + [s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] @@ -808,6 +842,7 @@ s.assert_no_match(opcodes, ["ba", "bja", "blla"]) def test_in_jump_info(self): + s = self.s for opname in "jump", "info": opcodes = s.encode_literal("b") \ + [s.OPCODES[opname], 3, s.OPCODES["failure"], s.OPCODES["failure"]] \ @@ -815,6 +850,7 @@ s.assert_match(opcodes, "ba") def _test_mark(self): + s = self.s # XXX need to rewrite this implementation-independent opcodes = s.encode_literal("a") + [s.OPCODES["mark"], 0] \ + s.encode_literal("b") + [s.OPCODES["mark"], 1, s.OPCODES["success"]] @@ -826,6 +862,7 @@ assert [1, 2] == state.marks def test_branch(self): + s = self.s opcodes = [s.OPCODES["branch"], 7] + s.encode_literal("ab") \ + [s.OPCODES["jump"], 9, 7] + s.encode_literal("cd") \ + [s.OPCODES["jump"], 2, s.OPCODES["failure"], s.OPCODES["success"]] @@ -833,18 +870,21 @@ s.assert_no_match(opcodes, ["aacas", "ac", "bla"]) def test_repeat_one(self): + s = self.s opcodes = [s.OPCODES["repeat_one"], 6, 1, 65535] + s.encode_literal("a") \ + [s.OPCODES["success"]] + s.encode_literal("ab") + [s.OPCODES["success"]] s.assert_match(opcodes, ["aab", "aaaab"]) s.assert_no_match(opcodes, ["ab", "a"]) def test_min_repeat_one(self): + s = self.s opcodes = [s.OPCODES["min_repeat_one"], 5, 1, 65535, s.OPCODES["any"]] \ + [s.OPCODES["success"]] + s.encode_literal("b") + [s.OPCODES["success"]] s.assert_match(opcodes, ["aab", "ardb", "bb"]) s.assert_no_match(opcodes, ["b"]) def test_repeat_maximizing(self): + s = self.s opcodes = [s.OPCODES["repeat"], 5, 1, 65535] + s.encode_literal("a") \ + [s.OPCODES["max_until"]] + s.encode_literal("b") + [s.OPCODES["success"]] s.assert_match(opcodes, ["ab", "aaaab", "baabb"]) @@ -856,6 +896,7 @@ # CPython 2.3 fails with a recursion limit exceeded error here. import sys if not sys.version_info[:2] == (2, 3): + s = self.s opcodes = [s.OPCODES["repeat"], 10, 1, 65535, s.OPCODES["repeat_one"], 6, 0, 65535] + s.encode_literal("a") + [s.OPCODES["success"], s.OPCODES["max_until"], s.OPCODES["success"]] @@ -863,6 +904,7 @@ assert "" == s.search(opcodes, "bb").group(0) def test_repeat_minimizing(self): + s = self.s opcodes = [s.OPCODES["repeat"], 4, 1, 65535, s.OPCODES["any"], s.OPCODES["min_until"]] + s.encode_literal("b") + [s.OPCODES["success"]] s.assert_match(opcodes, ["ab", "aaaab", "baabb"]) @@ -870,24 +912,28 @@ assert "aab" == s.search(opcodes, "aabb").group(0) def test_groupref(self): + s = self.s opcodes = [s.OPCODES["mark"], 0, s.OPCODES["any"], s.OPCODES["mark"], 1] \ + s.encode_literal("a") + [s.OPCODES["groupref"], 0, s.OPCODES["success"]] s.assert_match(opcodes, ["bab", "aaa", "dad"]) s.assert_no_match(opcodes, ["ba", "bad", "baad"]) def test_groupref_ignore(self): + s = self.s opcodes = [s.OPCODES["mark"], 0, s.OPCODES["any"], s.OPCODES["mark"], 1] \ + s.encode_literal("a") + [s.OPCODES["groupref_ignore"], 0, s.OPCODES["success"]] s.assert_match(opcodes, ["bab", "baB", "Dad"]) s.assert_no_match(opcodes, ["ba", "bad", "baad"]) def test_assert(self): + s = self.s opcodes = s.encode_literal("a") + [s.OPCODES["assert"], 4, 0] \ + s.encode_literal("b") + [s.OPCODES["success"], s.OPCODES["success"]] assert "a" == s.search(opcodes, "ab").group(0) s.assert_no_match(opcodes, ["a", "aa"]) def test_assert_not(self): + s = self.s opcodes = s.encode_literal("a") + [s.OPCODES["assert_not"], 4, 0] \ + s.encode_literal("b") + [s.OPCODES["success"], s.OPCODES["success"]] assert "a" == s.search(opcodes, "ac").group(0) 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 @@ -376,12 +376,12 @@ proxy_typedef_dict[special_method] = interp2app(func) callable_proxy_typedef_dict[special_method] = interp2app(func) -# __unicode__ is not yet a space operation +# __bytes__ is not yet a space operation def proxy_unicode(space, w_obj): w_obj = force(space, w_obj) - return space.call_method(w_obj, '__unicode__') -proxy_typedef_dict['__unicode__'] = interp2app(proxy_unicode) -callable_proxy_typedef_dict['__unicode__'] = interp2app(proxy_unicode) + return space.call_method(w_obj, '__bytes__') +proxy_typedef_dict['__bytes__'] = interp2app(proxy_unicode) +callable_proxy_typedef_dict['__bytes__'] = interp2app(proxy_unicode) W_Proxy.typedef = TypeDef("weakproxy", diff --git a/pypy/module/_weakref/test/test_weakref.py b/pypy/module/_weakref/test/test_weakref.py --- a/pypy/module/_weakref/test/test_weakref.py +++ b/pypy/module/_weakref/test/test_weakref.py @@ -419,14 +419,14 @@ print(s) assert "dead" in s - def test_unicode(self): + def test_bytes(self): import _weakref class C(object): - def __str__(self): - return "string" + def __bytes__(self): + return b"string" instance = C() - assert "__str__" in dir(_weakref.proxy(instance)) - assert str(_weakref.proxy(instance)) == "string" + assert "__bytes__" in dir(_weakref.proxy(instance)) + assert bytes(_weakref.proxy(instance)) == b"string" def test_eq(self): import _weakref 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 @@ -255,6 +255,9 @@ else: intarg = rffi.cast(rffi.INT, intarg) # C long => C int rv = ioctl_int(fd, op, intarg) + if rv < 0: + raise _get_error(space, "ioctl") + return space.wrap(rv) try: arg = space.bufferstr_w(w_arg) diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -13,7 +13,7 @@ class AppTestFcntl: def setup_class(cls): - space = gettestobjspace(usemodules=('fcntl', 'array', 'struct')) + space = gettestobjspace(usemodules=('fcntl', 'array', 'struct', 'termios')) cls.space = space tmpprefix = str(udir.ensure('test_fcntl', dir=1).join('tmp_')) cls.w_tmp = space.wrap(tmpprefix) @@ -136,11 +136,10 @@ import array import sys, os - if "linux" in sys.platform: - TIOCGPGRP = 0x540f - elif "darwin" in sys.platform or "freebsd" in sys.platform: - TIOCGPGRP = 0x40047477 - else: + try: + from termios import TIOCGPGRP + import pty + except ImportError: skip("don't know how to test ioctl() on this platform") raises(TypeError, fcntl.ioctl, "foo") @@ -148,28 +147,49 @@ #raises(TypeError, fcntl.ioctl, 0, TIOCGPGRP, float(0)) raises(TypeError, fcntl.ioctl, 0, TIOCGPGRP, 1, "foo") - if not os.isatty(0): - skip("stdin is not a tty") + child_pid, mfd = pty.fork() + if child_pid == 0: + # We're the child + return + try: + buf = array.array('h', [0]) + res = fcntl.ioctl(mfd, TIOCGPGRP, buf, True) + assert res == 0 + assert buf[0] != 0 + expected = buf.tostring() - buf = array.array('h', [0]) - res = fcntl.ioctl(0, TIOCGPGRP, buf, True) - assert res == 0 - assert buf[0] != 0 - expected = buf.tostring() + if '__pypy__' in sys.builtin_module_names or sys.version_info >= (2,5): + buf = array.array('h', [0]) + res = fcntl.ioctl(mfd, TIOCGPGRP, buf) + assert res == 0 + assert buf.tostring() == expected - if '__pypy__' in sys.builtin_module_names or sys.version_info >= (2,5): - buf = array.array('h', [0]) - res = fcntl.ioctl(0, TIOCGPGRP, buf) - assert res == 0 - assert buf.tostring() == expected + res = fcntl.ioctl(mfd, TIOCGPGRP, buf, False) + assert res == expected - res = fcntl.ioctl(0, TIOCGPGRP, buf, False) - assert res == expected + raises(TypeError, fcntl.ioctl, mfd, TIOCGPGRP, "\x00\x00", True) - raises(TypeError, fcntl.ioctl, 0, TIOCGPGRP, "\x00\x00", True) + res = fcntl.ioctl(mfd, TIOCGPGRP, "\x00\x00") + assert res == expected + finally: + os.close(mfd) - res = fcntl.ioctl(0, TIOCGPGRP, "\x00\x00") - assert res == expected + def test_ioctl_int(self): + import os + import fcntl + + try: + from termios import TCFLSH, TCIOFLUSH + import pty + except ImportError: + skip("don't know how to test ioctl() on this platform") + + mfd, sfd = pty.openpty() + try: + assert fcntl.ioctl(mfd, TCFLSH, TCIOFLUSH) == 0 + finally: + os.close(mfd) + os.close(sfd) def test_lockf_with_ex(self): import fcntl diff --git a/pypy/module/math/app_math.py b/pypy/module/math/app_math.py --- a/pypy/module/math/app_math.py +++ b/pypy/module/math/app_math.py @@ -1,3 +1,5 @@ +import sys + def factorial(x): """Find x!.""" if isinstance(x, float): @@ -5,6 +7,8 @@ if fl != x: raise ValueError("float arguments must be integral") x = fl + if x > sys.maxsize: + raise OverflowError("Too large for a factorial") if x < 0: raise ValueError("x must be >= 0") res = 1 diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -89,7 +89,7 @@ assert actual == expected def test_factorial(self): - import math + import math, sys assert math.factorial(0) == 1 assert math.factorial(1) == 1 assert math.factorial(2) == 2 @@ -98,6 +98,8 @@ raises(ValueError, math.factorial, -1) raises(ValueError, math.factorial, -1.) raises(ValueError, math.factorial, 1.1) + raises(OverflowError, math.factorial, sys.maxsize+1) + raises(OverflowError, math.factorial, 10e100) def test_log1p(self): import math diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -1,6 +1,6 @@ from pypy.interpreter.error import OperationError, wrap_oserror from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.rlib import rmmap, rarithmetic from pypy.rlib.rmmap import RValueError, RTypeError @@ -132,6 +132,13 @@ def __len__(self): return self.space.wrap(self.mmap.size) + def closed_get(self, space): + try: + self.mmap.check_valid() + except RValueError: + return space.w_True + return space.w_False + def check_valid(self): try: self.mmap.check_valid() @@ -199,6 +206,14 @@ space = self.space return space.wrap(StringLikeBuffer(space, space.wrap(self))) + def descr_enter(self, space): + self.check_valid() + return space.wrap(self) + + def descr_exit(self, space, __args__): + self.close() + + if rmmap._POSIX: @unwrap_spec(fileno=int, length=int, flags=int, @@ -260,6 +275,10 @@ __getitem__ = interp2app(W_MMap.descr_getitem), __setitem__ = interp2app(W_MMap.descr_setitem), __buffer__ = interp2app(W_MMap.descr_buffer), + __enter__ = interp2app(W_MMap.descr_enter), + __exit__ = interp2app(W_MMap.descr_exit), + + closed = GetSetProperty(W_MMap.closed_get), ) constants = rmmap.constants diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -622,6 +622,12 @@ finally: m.close() + def test_context_manager(self): + import mmap + with mmap.mmap(-1, 10) as m: + assert not m.closed + assert m.closed + def test_all(self): # this is a global test, ported from test_mmap.py import mmap diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -39,9 +39,16 @@ def fsencode_w(space, w_obj): if space.isinstance_w(w_obj, space.w_unicode): w_obj = space.call_method(w_obj, 'encode', - getfilesystemencoding(space)) + getfilesystemencoding(space), + space.wrap('surrogateescape')) return space.bytes0_w(w_obj) +def fsdecode(space, w_obj): + w_unicode = space.call_method(w_obj, 'decode', + getfilesystemencoding(space), + space.wrap('surrogateescape')) + return w_unicode + class FileEncoder(object): def __init__(self, space, w_obj): self.space = space @@ -63,8 +70,7 @@ def as_unicode(self): space = self.space - w_unicode = space.call_method(self.w_obj, 'decode', - getfilesystemencoding(space)) + w_unicode = fsdecode(space, self.w_obj) return space.unicode0_w(w_unicode) @specialize.memo() @@ -544,17 +550,11 @@ From noreply at buildbot.pypy.org Wed Oct 24 18:31:03 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 24 Oct 2012 18:31:03 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: Start attacking the optimizer chain Message-ID: <20121024163103.F2A291C0DED@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58398:e286cf78805e Date: 2012-10-24 18:30 +0200 http://bitbucket.org/pypy/pypy/changeset/e286cf78805e/ Log: Start attacking the optimizer chain diff --git a/pypy/jit/metainterp/optimizeopt/earlyforce.py b/pypy/jit/metainterp/optimizeopt/earlyforce.py --- a/pypy/jit/metainterp/optimizeopt/earlyforce.py +++ b/pypy/jit/metainterp/optimizeopt/earlyforce.py @@ -8,6 +8,8 @@ class OptEarlyForce(Optimization): def propagate_forward(self, op): + self.emit_operation(op) + return opnum = op.getopnum() if (opnum != rop.SETFIELD_GC and opnum != rop.SETARRAYITEM_GC and diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py --- a/pypy/jit/metainterp/optimizeopt/heap.py +++ b/pypy/jit/metainterp/optimizeopt/heap.py @@ -229,17 +229,17 @@ cf = submap[index] = CachedField() return cf - def emit_operation(self, op): - self.emitting_operation(op) - if self.posponedop: - posponedop = self.posponedop - self.posponedop = None - self.next_optimization.propagate_forward(posponedop) - if (op.is_comparison() or op.getopnum() in opgroups.CALL_MAY_FORCE - or op.is_ovf()): - self.posponedop = op - else: - Optimization.emit_operation(self, op) + #def emit_operation(self, op): + # self.emitting_operation(op) + # if self.posponedop: + # posponedop = self.posponedop + # self.posponedop = None + # self.next_optimization.propagate_forward(posponedop) + # if (op.is_comparison() or op.getopnum() in opgroups.CALL_MAY_FORCE + # or op.is_ovf()): + # self.posponedop = op + # else: + # Optimization.emit_operation(self, op) def emitting_operation(self, op): if op.has_no_side_effect(): @@ -540,6 +540,6 @@ self.emit_operation(op) -dispatch_opt = make_dispatcher_method(OptHeap, 'optimize_', - default=OptHeap.emit_operation) -OptHeap.propagate_forward = dispatch_opt +#dispatch_opt = make_dispatcher_method(OptHeap, 'optimize_', +# default=OptHeap.emit_operation) +#OptHeap.propagate_forward = dispatch_opt diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -15,12 +15,12 @@ def new(self): return OptIntBounds() - def propagate_forward(self, op): - dispatch_opt(self, op) + #def propagate_forward(self, op): + # dispatch_opt(self, op) - def opt_default(self, op): - assert not op.is_ovf() - self.emit_operation(op) + #def opt_default(self, op): + # assert not op.is_ovf() + # self.emit_operation(op) def propagate_bounds_backward(self, box): @@ -471,6 +471,6 @@ propagate_bounds_INT_MUL_OVF = propagate_bounds_INT_MUL -dispatch_opt = make_dispatcher_method(OptIntBounds, 'optimize_', - default=OptIntBounds.opt_default) -dispatch_bounds_ops = make_dispatcher_method(OptIntBounds, 'propagate_bounds_') +#dispatch_opt = make_dispatcher_method(OptIntBounds, 'optimize_', +# default=OptIntBounds.opt_default) +#dispatch_bounds_ops = make_dispatcher_method(OptIntBounds, 'propagate_bounds_') diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -2,13 +2,12 @@ """ This file implements the entry point to optimizations - the Optimizer. optimizations are dispatched in order they're passed and for each operation optimize_XYZ where XYZ is the name of resop is called. The method can choose -to return None (optimized away) or call self.emit_operation which means +to return None (optimized away) or return the operation to emit. it'll be passed onto the next one. -Each resop can have an extra attribute optimize_replace, which points to -a new version of the same resop. Also each one can have optimize_value, -which is valid when optimize_replace is not set. There is 1-1 mapping, which -means that two resops cannot share the optimize_value extra attribute +Each resop can have an extra attribute _forwarded, which points to +a new version of the same resop. It can be a mutable resop (from optmodel) +or a constant. """ from pypy.jit.metainterp import jitprof, resume, compile @@ -19,10 +18,9 @@ IntLowerBound, MININT, MAXINT from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method from pypy.jit.metainterp.resoperation import rop, AbstractResOp, opgroups,\ - Const, ConstInt, ConstFloat, AbstractValue + Const, ConstInt, opname from pypy.jit.metainterp.typesystem import llhelper -from pypy.jit.codewriter import longlong -from pypy.rlib.objectmodel import specialize, we_are_translated +from pypy.rlib.objectmodel import specialize from pypy.tool.pairtype import extendabletype LEVEL_UNKNOWN = '\x00' @@ -43,11 +41,6 @@ def clone(self): return LenBound(self.mode, self.descr, self.bound.clone()) -class exploder(object): - def __getattribute__(self, attr): - import pdb - pdb.set_trace() - class OptValue(object): _attrs_ = ('known_class', 'last_guard', 'level', 'intbound', 'lenbound', 'is_bool_box') @@ -58,17 +51,6 @@ known_class = None intbound = ImmutableIntUnbounded() lenbound = None - is_bool_box = False - - def getbox(self): - import pdb - pdb.set_trace() - - def setbox(self, x): - import pdb - pdb.set_trace() - - box = property(getbox, setbox) def __init__(self, op, level=None, known_class=None, intbound=None): self.op = op @@ -196,6 +178,7 @@ self.intbound = IntUnbounded() def get_constant_class(self, cpu): + xxx level = self.level if level == LEVEL_KNOWNCLASS: return self.known_class @@ -291,21 +274,32 @@ class Optimization(object): - next_optimization = None + optimize_default = None def __init__(self): pass # make rpython happy - def propagate_forward(self, op): - raise NotImplementedError + #def propagate_forward(self, op): + # raise NotImplementedError - def emit_operation(self, op): - self.last_emitted_operation = op - self.next_optimization.propagate_forward(op) + #def emit_operation(self, op): + # self.last_emitted_operation = op + # self.next_optimization.propagate_forward(op) + + def optimize_operation(self, op): + name = 'optimize_' + opname[op.getopnum()] + next_func = getattr(self, name, self.optimize_default) + if next_func is not None: + op = next_func(op) + if op is None: + return + else: + self.last_emitted_operation = op + return op # FIXME: Move some of these here? - def getvalue(self, box, create=True): - return self.optimizer.getvalue(box, create=create) + def getforwarded(self, op): + return self.optimizer.getforwarded(op) def setvalue(self, box, value): self.optimizer.setvalue(box, value) @@ -319,8 +313,8 @@ def replace(self, box, value): return self.optimizer.replace(box, value) - def get_constant_box(self, box): - return self.optimizer.get_constant_box(box) + def get_constant_op(self, op): + return self.optimizer.get_constant_op(op) def new_box(self, fieldofs): return self.optimizer.new_box(fieldofs) @@ -392,25 +386,11 @@ if loop is not None: self.call_pure_results = loop.call_pure_results - self.set_optimizations(optimizations) + self.optimizations = optimizations + for opt in optimizations: + opt.optimizer = self self.setup() - def set_optimizations(self, optimizations): - if optimizations: - self.first_optimization = optimizations[0] - for i in range(1, len(optimizations)): - optimizations[i - 1].next_optimization = optimizations[i] - optimizations[-1].next_optimization = self - for o in optimizations: - o.optimizer = self - o.last_emitted_operation = None - o.setup() - else: - optimizations = [] - self.first_optimization = self - - self.optimizations = optimizations - def force_at_end_of_preamble(self): for o in self.optimizations: o.force_at_end_of_preamble() @@ -441,20 +421,29 @@ self.metainterp_sd.profiler.count(jitprof.Counters.OPT_FORCINGS) self.resumedata_memo.forget_numberings(virtualbox) - def getvalue(self, box): - if box.is_constant(): - if box.type == REF: - if not box.getref_base(): + def getforwarded(self, op): + if op.is_constant(): + if op.type == REF: + if not op.getref_base(): return CONST_NULL try: - return self.interned_refs[box.getref_base()] + return self.interned_refs[op.getref_base()] except KeyError: - self.interned_refs[box.getref_base()] = box - return box - return box - value = box._forwarded + self.interned_refs[op.getref_base()] = op + return op + return op + value = op._forwarded if value is None: - value = box.make_forwarded_copy() + value = op.make_forwarded_copy() + else: + if value._forwarded: + while value._forwarded: + value = value._forwarded + to_patch = op + while to_patch._forwarded: + next = to_patch._forwarded + to_patch._forwarded = value + to_patch = next #self.ensure_imported(value) return value @@ -465,13 +454,15 @@ box.set_extra("optimize_value", value) def copy_op_if_modified_by_optimization(self, op): + xxxx new_op = op.copy_if_modified_by_optimization(self) if new_op is not op: self.replace(op, new_op) return new_op # XXX some RPython magic needed - def copy_and_change(self, op, *args, **kwds): + def copy_and_change(self, op, *args, **kwds): + xxx new_op = op.copy_and_change(*args, **kwds) if new_op is not op: self.replace(op, new_op) @@ -481,19 +472,10 @@ pass @specialize.argtype(0) - def get_constant_box(self, box): - if isinstance(box, Const): - return box - try: - value = self.getvalue(box) - self.ensure_imported(value) - except KeyError: - return None - if value.is_constant(): - constbox = value.op - assert isinstance(constbox, Const) - return constbox - return None + def get_constant_op(self, op): + op = self.getforwarded(op) + if isinstance(op, Const): + return op def get_newoperations(self): self.flush() @@ -502,20 +484,6 @@ def clear_newoperations(self): self._newoperations = [] - def replace(self, what, with_): - assert isinstance(what, AbstractValue) - assert isinstance(with_, AbstractValue) - assert not what.has_extra("optimize_replace") - assert not what.is_constant() - if what.has_extra("optimize_value"): - v = what.get_extra("optimize_value") - v.op = with_ - with_.set_extra("optimize_value", v) - #if not we_are_translated(): - # if what.has_extra("optimize_value"): - # what.get_extra("optimize_value").__class__ = exploder - what.set_extra("optimize_replace", with_) - def make_constant(self, box, constbox): self.getvalue(box).make_constant(constbox) @@ -560,14 +528,16 @@ def propagate_all_forward(self, clear=True): if clear: self.clear_newoperations() - for op in self.loop.operations: - self.first_optimization.propagate_forward(op) - for arg in self.loop.inputargs: - arg.del_extra("optimize_value") - arg.del_extra("optimize_replace") - for op in self.loop.operations: - op.del_extra("optimize_value") - op.del_extra("optimize_replace") + i = 0 + while i < len(self.loop.operations): + op = self.loop.operations[i] + for opt in self.optimizations: + op = opt.optimize_operation(op) + if op is None: + break + else: + self.emit_operation(op) + i += 1 self.loop.operations = self.get_newoperations() self.loop.quasi_immutable_deps = self.quasi_immutable_deps # accumulate counters @@ -584,22 +554,10 @@ self.getvalue(op).is_bool_box = True self._emit_operation(op) - def get_value_replacement(self, box): - try: - value = self.getvalue(box) - except KeyError: - return None - else: - self.ensure_imported(value) - forced_box = value.force_box(self) - if forced_box is box: - return None - return forced_box - @specialize.argtype(0) def _emit_operation(self, op): assert op.getopnum() not in opgroups.CALL_PURE - op = self.copy_op_if_modified_by_optimization(op) + assert not op._forwarded if isinstance(op, Const): return self.metainterp_sd.profiler.count(jitprof.Counters.OPT_OPS) @@ -613,6 +571,7 @@ self._newoperations.append(op) def store_final_boxes_in_guard(self, op): + return # XXX we disable it for tests assert op.getdescr() is None descr = op.invent_descr(self.jitdriver_sd, self.metainterp_sd) op.setdescr(descr) diff --git a/pypy/jit/metainterp/optimizeopt/pure.py b/pypy/jit/metainterp/optimizeopt/pure.py --- a/pypy/jit/metainterp/optimizeopt/pure.py +++ b/pypy/jit/metainterp/optimizeopt/pure.py @@ -11,9 +11,6 @@ self.pure_operations = ArgsDict() self.emitted_pure_operations = [] - def propagate_forward(self, op): - dispatch_opt(self, op) - def optimize_default(self, op): canfold = op.is_always_pure() if op.is_ovf(): @@ -27,9 +24,10 @@ else: nextop = None + newop = self.getforwarded(op) if canfold: for i in range(op.numargs()): - if self.get_constant_box(op.getarg(i)) is None: + if self.get_constant_op(op.getarg(i)) is None: break else: # all constant arguments: constant-fold away @@ -40,21 +38,20 @@ return # did we do the exact same operation already? - key_op = op.get_key_op(self.optimizer) - oldop = self.pure_operations.get(key_op) + oldop = self.pure_operations.get(newop) if oldop is not None: self.replace(op, oldop) return else: - self.pure_operations.set(key_op, op) + self.pure_operations.set(newop, op) self.remember_emitting_pure(op) # otherwise, the operation remains - self.emit_operation(op) if op.returns_bool_result(): - self.getvalue(op).is_bool_box = True + newop.is_bool_box = True if nextop: self.emit_operation(nextop) + return newop def _new_optimize_call_pure(opnum): def optimize_CALL_PURE(self, op): @@ -131,5 +128,5 @@ continue sb.add_potential(op) -dispatch_opt = make_dispatcher_method(OptPure, 'optimize_', - default=OptPure.optimize_default) +#dispatch_opt = make_dispatcher_method(OptPure, 'optimize_', +# default=OptPure.optimize_default) diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -524,6 +524,6 @@ optimize_SAME_AS_r = optimize_SAME_AS_i optimize_SAME_AS_f = optimize_SAME_AS_i -dispatch_opt = make_dispatcher_method(OptRewrite, 'optimize_', - default=OptRewrite.emit_operation) -optimize_guards = _findall(OptRewrite, 'optimize_', 'GUARD') +#dispatch_opt = make_dispatcher_method(OptRewrite, 'optimize_', +# default=OptRewrite.emit_operation) +#optimize_guards = _findall(OptRewrite, 'optimize_', 'GUARD') diff --git a/pypy/jit/metainterp/optimizeopt/simplify.py b/pypy/jit/metainterp/optimizeopt/simplify.py --- a/pypy/jit/metainterp/optimizeopt/simplify.py +++ b/pypy/jit/metainterp/optimizeopt/simplify.py @@ -64,6 +64,6 @@ descr=newdescr) self.emit_operation(op) -dispatch_opt = make_dispatcher_method(OptSimplify, 'optimize_', - default=OptSimplify.emit_operation) -OptSimplify.propagate_forward = dispatch_opt +#dispatch_opt = make_dispatcher_method(OptSimplify, 'optimize_', +# default=OptSimplify.emit_operation) +#OptSimplify.propagate_forward = dispatch_opt diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -134,13 +134,13 @@ ops = """ [i] i0 = int_sub(i, 1) - guard_value(i0, 0) [i0] + guard_value(i0, 0) jump(i) """ expected = """ [i] i0 = int_sub(i, 1) - guard_value(i0, 0) [i0] + guard_value(i0, 0) jump(1) """ self.optimize_loop(ops, expected) diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -28,6 +28,7 @@ imp.import_value(value) def emit_operation(self, op): + xxx if op.returns_bool_result(): self.bool_boxes[self.getvalue(op)] = None if self.emitting_dissabled: diff --git a/pypy/jit/metainterp/optimizeopt/util.py b/pypy/jit/metainterp/optimizeopt/util.py --- a/pypy/jit/metainterp/optimizeopt/util.py +++ b/pypy/jit/metainterp/optimizeopt/util.py @@ -172,8 +172,8 @@ text_right = text_right or 'expected' print '%s| %s' % ('optimized'.center(width), text_right.center(width)) for op1, op2 in zip(oplist1, oplist2): - txt1 = str(op1) - txt2 = str(op2) + txt1 = repr(op1) + txt2 = repr(op2) while txt1 or txt2: print '%s| %s' % (txt1[:width].ljust(width), txt2[:width]) txt1 = txt1[width:] diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py --- a/pypy/jit/metainterp/optimizeopt/virtualize.py +++ b/pypy/jit/metainterp/optimizeopt/virtualize.py @@ -558,7 +558,7 @@ self.emit_operation(op) -dispatch_opt = make_dispatcher_method(OptVirtualize, 'optimize_', - default=OptVirtualize.emit_operation) +#dispatch_opt = make_dispatcher_method(OptVirtualize, 'optimize_', +# default=OptVirtualize.emit_operation) -OptVirtualize.propagate_forward = dispatch_opt +#OptVirtualize.propagate_forward = dispatch_opt diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -728,8 +728,8 @@ def propagate_forward(self, op): dispatch_opt(self, op) -dispatch_opt = make_dispatcher_method(OptString, 'optimize_', - default=OptString.emit_operation) +#dispatch_opt = make_dispatcher_method(OptString, 'optimize_', +# default=OptString.emit_operation) def _findall_call_oopspec(): prefix = 'opt_call_stroruni_' diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -474,7 +474,7 @@ # XXX this is a hack kill me import sys co_fname = sys._getframe(1).f_code.co_filename - if co_fname.endswith('resume.py') or co_fname.endswith('optimizeopt/util.py') or 'backend/llgraph' in co_fname or 'backend/test' in co_fname: + if co_fname.endswith('resume.py') or co_fname.endswith('optimizeopt/util.py') or 'backend/llgraph' in co_fname or 'backend/test' in co_fname or 'test/test_util' in co_fname: return object.__hash__(self) raise Exception("Should not hash resops, use get/set extra instead") @@ -650,6 +650,13 @@ return False # for tests return opboolresult[opnum] + # some debugging help + + def __setattr__(self, attr, val): + if attr not in ['_hash', '_str']: + assert self._forwarded is None + object.__setattr__(self, attr, val) + # =========== # type mixins # =========== diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py --- a/pypy/jit/metainterp/resume.py +++ b/pypy/jit/metainterp/resume.py @@ -198,9 +198,8 @@ length = len(boxes) numb = lltype.malloc(NUMBERING, length) for i in range(length): - box = boxes[i] - value = optimizer.getvalue(box) - box = value.get_key_box() + op = boxes[i] + optimized_op = optimizer.get_optimized_op(op) if isinstance(box, Const): tagged = self.getconst(box) From noreply at buildbot.pypy.org Wed Oct 24 19:02:49 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 24 Oct 2012 19:02:49 +0200 (CEST) Subject: [pypy-commit] pypy py3k: we must ignore the encoding cookie even if we are compiling bytes Message-ID: <20121024170249.B91391C0F47@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58399:f8df108f0a8a Date: 2012-10-24 19:02 +0200 http://bitbucket.org/pypy/pypy/changeset/f8df108f0a8a/ Log: we must ignore the encoding cookie even if we are compiling bytes diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -40,6 +40,7 @@ ast_node.sync_app_attrs(space) elif space.isinstance_w(w_source, space.w_bytes): source_str = space.bytes0_w(w_source) + flags |= consts.PyCF_IGNORE_COOKIE else: source_str = space.str0_w(w_source) flags |= consts.PyCF_IGNORE_COOKIE From noreply at buildbot.pypy.org Wed Oct 24 19:18:56 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 24 Oct 2012 19:18:56 +0200 (CEST) Subject: [pypy-commit] pypy py3k: catch the correct exception type for both pypy and cpython Message-ID: <20121024171856.951AE1C1C5C@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58400:0278546b4427 Date: 2012-10-24 19:18 +0200 http://bitbucket.org/pypy/pypy/changeset/0278546b4427/ Log: catch the correct exception type for both pypy and cpython diff --git a/pypy/module/__builtin__/test/test_descriptor.py b/pypy/module/__builtin__/test/test_descriptor.py --- a/pypy/module/__builtin__/test/test_descriptor.py +++ b/pypy/module/__builtin__/test/test_descriptor.py @@ -323,7 +323,9 @@ for attr in "__doc__", "fget", "fset", "fdel": try: setattr(raw, attr, 42) - except AttributeError as msg: + # it raises TypeError on pypy, AttributeError on CPython: we catch + # both so that it runs also with -A + except (TypeError, AttributeError) as msg: if str(msg).find('readonly') < 0: raise Exception("when setting readonly attr %r on a " "property, got unexpected TypeError " From noreply at buildbot.pypy.org Wed Oct 24 22:56:17 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 24 Oct 2012 22:56:17 +0200 (CEST) Subject: [pypy-commit] pypy py3k: partly revert b59013f9587e, this part is needed for the recently fixed Message-ID: <20121024205617.B7B1A1C0DBF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58401:db79e2d1c28e Date: 2012-10-24 13:51 -0700 http://bitbucket.org/pypy/pypy/changeset/db79e2d1c28e/ Log: partly revert b59013f9587e, this part is needed for the recently fixed http://bugs.python.org/issue16013 diff --git a/pypy/module/_csv/interp_reader.py b/pypy/module/_csv/interp_reader.py --- a/pypy/module/_csv/interp_reader.py +++ b/pypy/module/_csv/interp_reader.py @@ -40,7 +40,6 @@ def save_field(self, field_builder): field = field_builder.build() - print "AFA SAVE FIELD", field if self.numeric_field: from pypy.objspace.std.strutil import ParseStringError from pypy.objspace.std.strutil import string_to_float @@ -72,7 +71,11 @@ state != START_RECORD and state != EAT_CRNL and (len(field_builder.build()) > 0 or state == IN_QUOTED_FIELD)): - raise self.error(u"newline inside string") + if dialect.strict: + raise self.error(u"newline inside string") + else: + self.save_field(field_builder) + break raise self.line_num += 1 line = space.unicode_w(w_line) diff --git a/pypy/module/_csv/test/test_reader.py b/pypy/module/_csv/test/test_reader.py --- a/pypy/module/_csv/test/test_reader.py +++ b/pypy/module/_csv/test/test_reader.py @@ -107,9 +107,9 @@ self._read_test(['12,12,1",'], [['12', '12', '1"', '']]) def test_read_eof(self): - self._read_test(['a,"'], []) - self._read_test(['"a'], 'Error') - self._read_test(['^'], 'Error', escapechar='^') - self._read_test(['a,"'], [], strict=True) + self._read_test(['a,"'], [['a', '']]) + self._read_test(['"a'], [['a']]) + self._read_test(['^'], [['\n']], escapechar='^') + self._read_test(['a,"'], 'Error', strict=True) self._read_test(['"a'], 'Error', strict=True) self._read_test(['^'], 'Error', escapechar='^', strict=True) From noreply at buildbot.pypy.org Wed Oct 24 22:56:19 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 24 Oct 2012 22:56:19 +0200 (CEST) Subject: [pypy-commit] pypy py3k: update error message Message-ID: <20121024205619.702621C0DBF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58402:4d32af236868 Date: 2012-10-24 13:54 -0700 http://bitbucket.org/pypy/pypy/changeset/4d32af236868/ Log: update error message diff --git a/pypy/module/_csv/interp_reader.py b/pypy/module/_csv/interp_reader.py --- a/pypy/module/_csv/interp_reader.py +++ b/pypy/module/_csv/interp_reader.py @@ -72,7 +72,7 @@ (len(field_builder.build()) > 0 or state == IN_QUOTED_FIELD)): if dialect.strict: - raise self.error(u"newline inside string") + raise self.error(u"unexpected end of data") else: self.save_field(field_builder) break From noreply at buildbot.pypy.org Wed Oct 24 22:56:20 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 24 Oct 2012 22:56:20 +0200 (CEST) Subject: [pypy-commit] pypy py3k: 2to3 most of lib_pypy except _ctypes/numpypy/pyrepl Message-ID: <20121024205620.B2B941C0DBF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58403:c1aa74c06e86 Date: 2012-10-24 13:55 -0700 http://bitbucket.org/pypy/pypy/changeset/c1aa74c06e86/ Log: 2to3 most of lib_pypy except _ctypes/numpypy/pyrepl diff --git a/lib_pypy/__init__.py b/lib_pypy/__init__.py --- a/lib_pypy/__init__.py +++ b/lib_pypy/__init__.py @@ -1,4 +1,4 @@ # This __init__.py shows up in PyPy's app-level standard library. # Let's try to prevent that confusion... if __name__ != 'lib_pypy': - raise ImportError, '__init__' + raise ImportError('__init__') diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -7,7 +7,7 @@ import operator try: - from thread import get_ident as _thread_ident + from _thread import get_ident as _thread_ident except ImportError: def _thread_ident(): return -1 @@ -369,7 +369,7 @@ self._gen = itergen(deq.state, giveup) def __next__(self): - res = self._gen.next() + res = next(self._gen) self.counter -= 1 return res @@ -423,5 +423,5 @@ This API is used by pickle.py and copy.py. """ - return (type(self), (self.default_factory,), None, None, self.iteritems()) + return (type(self), (self.default_factory,), None, None, iter(self.items())) diff --git a/lib_pypy/_csv.py b/lib_pypy/_csv.py --- a/lib_pypy/_csv.py +++ b/lib_pypy/_csv.py @@ -82,12 +82,12 @@ (name,)) if dialect is not None: - if isinstance(dialect, basestring): + if isinstance(dialect, str): dialect = get_dialect(dialect) # Can we reuse this instance? if (isinstance(dialect, Dialect) - and all(value is None for value in kwargs.itervalues())): + and all(value is None for value in kwargs.values())): return dialect self = object.__new__(cls) @@ -167,7 +167,7 @@ def register_dialect(name, dialect=None, **kwargs): """Create a mapping from a string name to a dialect class. dialect = csv.register_dialect(name, dialect)""" - if not isinstance(name, basestring): + if not isinstance(name, str): raise TypeError("dialect name must be a string or unicode") dialect = _call_dialect(dialect, kwargs) @@ -221,11 +221,11 @@ def __iter__(self): return self - def next(self): + def __next__(self): self._parse_reset() while True: try: - line = self.input_iter.next() + line = next(self.input_iter) except StopIteration: # End of input OR exception if len(self.field) > 0: @@ -565,7 +565,7 @@ old_limit = _field_limit if limit is not undefined: - if not isinstance(limit, (int, long)): + if not isinstance(limit, int): raise TypeError("int expected, got %s" % (limit.__class__.__name__,)) _field_limit = limit diff --git a/lib_pypy/_marshal.py b/lib_pypy/_marshal.py --- a/lib_pypy/_marshal.py +++ b/lib_pypy/_marshal.py @@ -5,6 +5,7 @@ import types from _codecs import utf_8_decode, utf_8_encode +import sys try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f @@ -49,7 +50,7 @@ if func: break else: - raise ValueError, "unmarshallable object" + raise ValueError("unmarshallable object") func(self, x) def w_long64(self, x): @@ -72,7 +73,7 @@ def dump_none(self, x): self._write(TYPE_NONE) - dispatch[types.NoneType] = dump_none + dispatch[type(None)] = dump_none def dump_bool(self, x): if x: @@ -83,7 +84,7 @@ def dump_stopiter(self, x): if x is not StopIteration: - raise ValueError, "unmarshallable object" + raise ValueError("unmarshallable object") self._write(TYPE_STOPITER) dispatch[type(StopIteration)] = dump_stopiter @@ -91,7 +92,7 @@ self._write(TYPE_ELLIPSIS) try: - dispatch[types.EllipsisType] = dump_ellipsis + dispatch[type(Ellipsis)] = dump_ellipsis except NameError: pass @@ -103,7 +104,7 @@ else: self._write(TYPE_INT) self.w_long(x) - dispatch[types.IntType] = dump_int + dispatch[int] = dump_int def dump_long(self, x): self._write(TYPE_LONG) @@ -118,27 +119,27 @@ self.w_long(len(digits) * sign) for d in digits: self.w_short(d) - dispatch[types.LongType] = dump_long + dispatch[int] = dump_long def dump_float(self, x): write = self._write write(TYPE_FLOAT) - s = `x` + s = repr(x) write(chr(len(s))) write(s) - dispatch[types.FloatType] = dump_float + dispatch[float] = dump_float def dump_complex(self, x): write = self._write write(TYPE_COMPLEX) - s = `x.real` + s = repr(x.real) write(chr(len(s))) write(s) - s = `x.imag` + s = repr(x.imag) write(chr(len(s))) write(s) try: - dispatch[types.ComplexType] = dump_complex + dispatch[complex] = dump_complex except NameError: pass @@ -148,7 +149,7 @@ self._write(TYPE_STRING) self.w_long(len(x)) self._write(x) - dispatch[types.StringType] = dump_string + dispatch[bytes] = dump_string def dump_unicode(self, x): self._write(TYPE_UNICODE) @@ -156,21 +157,21 @@ s, len_s = utf_8_encode(x) self.w_long(len_s) self._write(s) - dispatch[types.UnicodeType] = dump_unicode + dispatch[str] = dump_unicode def dump_tuple(self, x): self._write(TYPE_TUPLE) self.w_long(len(x)) for item in x: self.dump(item) - dispatch[types.TupleType] = dump_tuple + dispatch[tuple] = dump_tuple def dump_list(self, x): self._write(TYPE_LIST) self.w_long(len(x)) for item in x: self.dump(item) - dispatch[types.ListType] = dump_list + dispatch[list] = dump_list def dump_dict(self, x): self._write(TYPE_DICT) @@ -178,7 +179,7 @@ self.dump(key) self.dump(value) self._write(TYPE_NULL) - dispatch[types.DictionaryType] = dump_dict + dispatch[dict] = dump_dict def dump_code(self, x): self._write(TYPE_CODE) @@ -252,7 +253,7 @@ try: return self.dispatch[c](self) except KeyError: - raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c)) + raise ValueError("bad marshal code: %c (%d)" % (c, ord(c))) def r_short(self): lo = ord(self._read(1)) @@ -270,7 +271,7 @@ d = ord(s[3]) x = a | (b<<8) | (c<<16) | (d<<24) if d & 0x80 and x > 0: - x = -((1L<<32) - x) + x = -((1<<32) - x) return int(x) else: return x @@ -280,14 +281,14 @@ b = ord(self._read(1)) c = ord(self._read(1)) d = ord(self._read(1)) - e = long(ord(self._read(1))) - f = long(ord(self._read(1))) - g = long(ord(self._read(1))) - h = long(ord(self._read(1))) + e = int(ord(self._read(1))) + f = int(ord(self._read(1))) + g = int(ord(self._read(1))) + h = int(ord(self._read(1))) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: - x = -((1L<<64) - x) + x = -((1<<64) - x) return x def load_null(self): @@ -324,10 +325,10 @@ if size < 0: sign = -1 size = -size - x = 0L + x = 0 for i in range(size): d = self.r_short() - x = x | (d<<(i*15L)) + x = x | (d<<(i*15)) return x * sign dispatch[TYPE_LONG] = load_long @@ -354,7 +355,7 @@ def load_interned(self): n = self.r_long() - ret = intern(self._read(n)) + ret = sys.intern(self._read(n)) self._stringtable.append(ret) return ret dispatch[TYPE_INTERNED] = load_interned @@ -459,7 +460,7 @@ self.bufpos += 4 x = a | (b<<8) | (c<<16) | (d<<24) if d & 0x80 and x > 0: - x = -((1L<<32) - x) + x = -((1<<32) - x) return int(x) else: return x @@ -469,14 +470,14 @@ b = ord(_read1(self)) c = ord(_read1(self)) d = ord(_read1(self)) - e = long(ord(_read1(self))) - f = long(ord(_read1(self))) - g = long(ord(_read1(self))) - h = long(ord(_read1(self))) + e = int(ord(_read1(self))) + f = int(ord(_read1(self))) + g = int(ord(_read1(self))) + h = int(ord(_read1(self))) x = a | (b<<8) | (c<<16) | (d<<24) x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56) if h & 0x80 and x > 0: - x = -((1L<<64) - x) + x = -((1<<64) - x) return x _load_dispatch = {} @@ -498,7 +499,7 @@ self.bufpos += 1 return _load_dispatch[c](self) except KeyError: - raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c)) + raise ValueError("bad marshal code: %c (%d)" % (c, ord(c))) except IndexError: raise EOFError @@ -540,10 +541,10 @@ if size < 0: sign = -1 size = -size - x = 0L + x = 0 for i in range(size): d = _r_short(self) - x = x | (d<<(i*15L)) + x = x | (d<<(i*15)) return x * sign dispatch[TYPE_LONG] = load_long @@ -570,7 +571,7 @@ def load_interned(self): n = _r_long(self) - ret = intern(_read(self, n)) + ret = sys.intern(_read(self, n)) self._stringtable.append(ret) return ret dispatch[TYPE_INTERNED] = load_interned diff --git a/lib_pypy/_md5.py b/lib_pypy/_md5.py --- a/lib_pypy/_md5.py +++ b/lib_pypy/_md5.py @@ -270,7 +270,7 @@ the hashed string. """ - leninBuf = long(len(inBuf)) + leninBuf = int(len(inBuf)) # Compute number of bytes mod 64. index = (self.count[0] >> 3) & 0x3F diff --git a/lib_pypy/_pypy_interact.py b/lib_pypy/_pypy_interact.py --- a/lib_pypy/_pypy_interact.py +++ b/lib_pypy/_pypy_interact.py @@ -74,5 +74,5 @@ if __name__ == '__main__': # for testing import os if os.getenv('PYTHONSTARTUP'): - execfile(os.getenv('PYTHONSTARTUP')) + exec(compile(open(os.getenv('PYTHONSTARTUP')).read(), os.getenv('PYTHONSTARTUP'), 'exec')) interactive_console() diff --git a/lib_pypy/_pypy_wait.py b/lib_pypy/_pypy_wait.py --- a/lib_pypy/_pypy_wait.py +++ b/lib_pypy/_pypy_wait.py @@ -1,6 +1,6 @@ +from resource import _struct_rusage, struct_rusage from ctypes import CDLL, c_int, POINTER, byref from ctypes.util import find_library -from resource import _struct_rusage, struct_rusage __all__ = ["wait3", "wait4"] diff --git a/lib_pypy/_scproxy.py b/lib_pypy/_scproxy.py --- a/lib_pypy/_scproxy.py +++ b/lib_pypy/_scproxy.py @@ -67,7 +67,7 @@ length = (ffi.CFStringGetLength(value) * 4) + 1 buff = create_string_buffer(length) ffi.CFStringGetCString(value, buff, length * 4, kCFStringEncodingUTF8) - return unicode(buff.value, 'utf8') + return str(buff.value, 'utf8') def cfnum_to_int32(num): result_ptr = pointer(c_int32(0)) @@ -121,9 +121,9 @@ if host: if cfportnum: port = cfnum_to_int32(cfportnum) - v = u'http://%s:%d' % (host, port) + v = 'http://%s:%d' % (host, port) else: - v = u'http://%s' % (host,) + v = 'http://%s' % (host,) result[proto.lower()] = v return result finally: diff --git a/lib_pypy/_sha256.py b/lib_pypy/_sha256.py --- a/lib_pypy/_sha256.py +++ b/lib_pypy/_sha256.py @@ -28,10 +28,10 @@ W = [] d = sha_info['data'] - for i in xrange(0,16): + for i in range(0,16): W.append( (d[4*i]<<24) + (d[4*i+1]<<16) + (d[4*i+2]<<8) + d[4*i+3]) - for i in xrange(16,64): + for i in range(16,64): W.append( (Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]) & 0xffffffff ) ss = sha_info['digest'][:] @@ -134,7 +134,7 @@ def getbuf(s): if isinstance(s, str): return s - elif isinstance(s, unicode): + elif isinstance(s, str): return str(s) else: return buffer(s) diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -244,10 +244,10 @@ # SQLite version information sqlite_version = sqlite.sqlite3_libversion() -class Error(StandardError): +class Error(Exception): pass -class Warning(StandardError): +class Warning(Exception): pass class InterfaceError(Error): @@ -279,7 +279,7 @@ return factory(database, **kwargs) def unicode_text_factory(x): - return unicode(x, 'utf-8') + return str(x, 'utf-8') class StatementCache(object): @@ -426,7 +426,7 @@ def __call__(self, sql): self._check_closed() - if not isinstance(sql, (str, unicode)): + if not isinstance(sql, str): raise Warning("SQL is of wrong type. Must be string or unicode.") statement = self.statement_cache.get(sql, self.row_factory) return statement @@ -436,7 +436,7 @@ def _set_isolation_level(self, val): if val is None: self.commit() - if isinstance(val, unicode): + if isinstance(val, str): val = str(val) self._isolation_level = val isolation_level = property(_get_isolation_level, _set_isolation_level) @@ -761,7 +761,7 @@ return CursorLock(self) def execute(self, sql, params=None): - if type(sql) is unicode: + if type(sql) is str: sql = sql.encode("utf-8") with self._check_and_lock(): @@ -801,7 +801,7 @@ return self def executemany(self, sql, many_params): - if type(sql) is unicode: + if type(sql) is str: sql = sql.encode("utf-8") with self._check_and_lock(): @@ -828,7 +828,7 @@ def executescript(self, sql): self._description = None self.reset = False - if type(sql) is unicode: + if type(sql) is str: sql = sql.encode("utf-8") self._check_closed() statement = c_void_p() @@ -975,7 +975,7 @@ def _build_row_cast_map(self): self.row_cast_map = [] - for i in xrange(sqlite.sqlite3_column_count(self.statement)): + for i in range(sqlite.sqlite3_column_count(self.statement)): converter = None if self.con.detect_types & PARSE_COLNAMES: @@ -1001,7 +1001,7 @@ self.row_cast_map.append(converter) def _check_decodable(self, param): - if self.con.text_factory in (unicode, OptimizedUnicode, unicode_text_factory): + if self.con.text_factory in (str, OptimizedUnicode, unicode_text_factory): for c in param: if ord(c) & 0x80 != 0: raise self.con.ProgrammingError( @@ -1020,7 +1020,7 @@ if param is None: sqlite.sqlite3_bind_null(self.statement, idx) - elif type(param) in (bool, int, long): + elif type(param) in (bool, int, int): if -2147483648 <= param <= 2147483647: sqlite.sqlite3_bind_int(self.statement, idx, param) else: @@ -1030,7 +1030,7 @@ elif isinstance(param, str): self._check_decodable(param) sqlite.sqlite3_bind_text(self.statement, idx, param, len(param), SQLITE_TRANSIENT) - elif isinstance(param, unicode): + elif isinstance(param, str): param = param.encode("utf-8") sqlite.sqlite3_bind_text(self.statement, idx, param, len(param), SQLITE_TRANSIENT) elif type(param) is buffer: @@ -1096,14 +1096,14 @@ def _readahead(self, cursor): self.column_count = sqlite.sqlite3_column_count(self.statement) row = [] - for i in xrange(self.column_count): + for i in range(self.column_count): typ = sqlite.sqlite3_column_type(self.statement, i) converter = self.row_cast_map[i] if converter is None: if typ == SQLITE_INTEGER: val = sqlite.sqlite3_column_int64(self.statement, i) - if -sys.maxint-1 <= val <= sys.maxint: + if -sys.maxsize-1 <= val <= sys.maxsize: val = int(val) elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_column_double(self.statement, i) @@ -1156,7 +1156,7 @@ if self.kind == DML: return None desc = [] - for i in xrange(sqlite.sqlite3_column_count(self.statement)): + for i in range(sqlite.sqlite3_column_count(self.statement)): name = sqlite.sqlite3_column_name(self.statement, i).split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc @@ -1242,7 +1242,7 @@ typ = sqlite.sqlite3_value_type(params[i]) if typ == SQLITE_INTEGER: val = sqlite.sqlite3_value_int64(params[i]) - if -sys.maxint-1 <= val <= sys.maxint: + if -sys.maxsize-1 <= val <= sys.maxsize: val = int(val) elif typ == SQLITE_FLOAT: val = sqlite.sqlite3_value_double(params[i]) @@ -1255,7 +1255,7 @@ elif typ == SQLITE_TEXT: val = sqlite.sqlite3_value_text(params[i]) # XXX changed from con.text_factory - val = unicode(val, 'utf-8') + val = str(val, 'utf-8') else: raise NotImplementedError _params.append(val) @@ -1264,12 +1264,12 @@ def _convert_result(con, val): if val is None: sqlite.sqlite3_result_null(con) - elif isinstance(val, (bool, int, long)): + elif isinstance(val, (bool, int)): sqlite.sqlite3_result_int64(con, int(val)) elif isinstance(val, str): # XXX ignoring unicode issue sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) - elif isinstance(val, unicode): + elif isinstance(val, str): val = val.encode('utf-8') sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) elif isinstance(val, float): @@ -1383,7 +1383,7 @@ def OptimizedUnicode(s): try: - val = unicode(s, "ascii").encode("ascii") + val = str(s, "ascii").encode("ascii") except UnicodeDecodeError: - val = unicode(s, "utf-8") + val = str(s, "utf-8") return val diff --git a/lib_pypy/_subprocess.py b/lib_pypy/_subprocess.py --- a/lib_pypy/_subprocess.py +++ b/lib_pypy/_subprocess.py @@ -155,7 +155,7 @@ if env is not None: envbuf = "" - for k, v in env.iteritems(): + for k, v in env.items(): envbuf += "%s=%s\0" % (k, v) envbuf += '\0' else: diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -2,12 +2,14 @@ # One-liner implementation of cPickle # +import marshal +import struct +import sys from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass from pickle import __doc__, __version__, format_version, compatible_formats from types import * -from copy_reg import dispatch_table -from copy_reg import _extension_registry, _inverted_registry, _extension_cache -import marshal, struct, sys +from copyreg import dispatch_table +from copyreg import _extension_registry, _inverted_registry, _extension_cache try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f @@ -186,7 +188,7 @@ def load_proto(self): proto = ord(self.read(1)) if not 0 <= proto <= 2: - raise ValueError, "unsupported pickle protocol: %d" % proto + raise ValueError("unsupported pickle protocol: %d" % proto) dispatch[PROTO] = load_proto def load_persid(self): @@ -221,7 +223,7 @@ try: val = int(data) except ValueError: - val = long(data) + val = int(data) self.append(val) dispatch[INT] = load_int @@ -238,7 +240,7 @@ dispatch[BININT2] = load_binint2 def load_long(self): - self.append(long(self.readline()[:-1], 0)) + self.append(int(self.readline()[:-1], 0)) dispatch[LONG] = load_long def load_long1(self): @@ -264,13 +266,13 @@ def load_string(self): rep = self.readline() if len(rep) < 3: - raise ValueError, "insecure string pickle" + raise ValueError("insecure string pickle") if rep[0] == "'" == rep[-2]: rep = rep[1:-2] elif rep[0] == '"' == rep[-2]: rep = rep[1:-2] else: - raise ValueError, "insecure string pickle" + raise ValueError("insecure string pickle") self.append(rep.decode("string-escape")) dispatch[STRING] = load_string @@ -280,12 +282,12 @@ dispatch[BINSTRING] = load_binstring def load_unicode(self): - self.append(unicode(self.readline()[:-1],'raw-unicode-escape')) + self.append(str(self.readline()[:-1],'raw-unicode-escape')) dispatch[UNICODE] = load_unicode def load_binunicode(self): L = mloads('i' + self.read(4)) - self.append(unicode(self.read(L),'utf-8')) + self.append(str(self.read(L),'utf-8')) dispatch[BINUNICODE] = load_binunicode def load_short_binstring(self): @@ -361,9 +363,9 @@ if not instantiated: try: value = klass(*args) - except TypeError, err: - raise TypeError, "in constructor for %s: %s" % ( - klass.__name__, str(err)), sys.exc_info()[2] + except TypeError as err: + raise TypeError("in constructor for %s: %s" % ( + klass.__name__, str(err))).with_traceback(sys.exc_info()[2]) self.append(value) def load_inst(self): @@ -523,8 +525,8 @@ try: d = inst.__dict__ try: - for k, v in state.iteritems(): - d[intern(k)] = v + for k, v in state.items(): + d[sys.intern(k)] = v # keys in state don't have to be strings # don't blow up, but don't go out of our way except TypeError: @@ -574,7 +576,7 @@ nbytes = len(data) if nbytes == 0: - return 0L + return 0 ind = nbytes - 1 while ind and ord(data[ind]) == 0: ind -= 1 @@ -585,7 +587,7 @@ if ord(data[ind]): n += ord(data[ind]) if ord(data[nbytes - 1]) >= 128: - n -= 1L << (nbytes << 3) + n -= 1 << (nbytes << 3) return n def load(f): diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -153,7 +153,7 @@ lib.DBM_INSERT = 0 lib.DBM_REPLACE = 1 -def open(filename, flag='r', mode=0666): +def open(filename, flag='r', mode=0o666): "open a DBM database" if not isinstance(filename, str): raise TypeError("expected string") diff --git a/lib_pypy/disassembler.py b/lib_pypy/disassembler.py --- a/lib_pypy/disassembler.py +++ b/lib_pypy/disassembler.py @@ -72,32 +72,30 @@ if type(x) is types.InstanceType: x = x.__class__ if hasattr(x, 'im_func'): - x = x.im_func + x = x.__func__ if hasattr(x, 'func_code'): - x = x.func_code + x = x.__code__ if hasattr(x, '__dict__'): xxx - items = x.__dict__.items() - items.sort() + sorted(x.__dict__.items()) for name, x1 in items: if type(x1) in (types.MethodType, types.FunctionType, types.CodeType, - types.ClassType): - print "Disassembly of %s:" % name + type): + print("Disassembly of %s:" % name) try: dis(x1) except TypeError as msg: - print "Sorry:", msg - print + print("Sorry:", msg) + print() elif hasattr(x, 'co_code'): return disassemble(x) elif isinstance(x, str): return disassemble_string(x) else: - raise TypeError, \ - "don't know how to disassemble %s objects" % \ - type(x).__name__ + raise TypeError("don't know how to disassemble %s objects" % \ + type(x).__name__) def distb(tb=None): """Disassemble a traceback (default: last traceback).""" @@ -105,7 +103,7 @@ try: tb = sys.last_traceback except AttributeError: - raise RuntimeError, "no last traceback to disassemble" + raise RuntimeError("no last traceback to disassemble") while tb.tb_next: tb = tb.tb_next disassemble(tb.tb_frame.f_code, tb.tb_lasti) @@ -148,7 +146,7 @@ extended_arg = 0 i = i+2 if op == EXTENDED_ARG: - extended_arg = oparg*65536L + extended_arg = oparg*65536 if op in hasconst: opargstr = repr(co.co_consts[oparg]) elif op in hasname: @@ -180,54 +178,54 @@ op = ord(c) if i == lasti: xxx - print '-->', + print('-->', end=' ') else: xxx - print ' ', + print(' ', end=' ') if i in labels: xxx - print '>>', + print('>>', end=' ') else: xxx - print ' ', + print(' ', end=' ') xxxx - print repr(i).rjust(4), - print opname[op].ljust(15), + print(repr(i).rjust(4), end=' ') + print(opname[op].ljust(15), end=' ') i = i+1 if op >= HAVE_ARGUMENT: oparg = ord(code[i]) + ord(code[i+1])*256 i = i+2 xxx - print repr(oparg).rjust(5), + print(repr(oparg).rjust(5), end=' ') if op in hasconst: if constants: xxx - print '(' + repr(constants[oparg]) + ')', + print('(' + repr(constants[oparg]) + ')', end=' ') else: xxx - print '(%d)'%oparg, + print('(%d)'%oparg, end=' ') elif op in hasname: if names is not None: xxx - print '(' + names[oparg] + ')', + print('(' + names[oparg] + ')', end=' ') else: xxx - print '(%d)'%oparg, + print('(%d)'%oparg, end=' ') elif op in hasjrel: xxx - print '(to ' + repr(i + oparg) + ')', + print('(to ' + repr(i + oparg) + ')', end=' ') elif op in haslocal: if varnames: xxx - print '(' + varnames[oparg] + ')', + print('(' + varnames[oparg] + ')', end=' ') else: xxx - print '(%d)' % oparg, + print('(%d)' % oparg, end=' ') elif op in hascompare: xxx - print '(' + cmp_op[oparg] + ')', + print('(' + cmp_op[oparg] + ')', end=' ') xxx - print + print() disco = disassemble # XXX For backwards compatibility diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -109,7 +109,7 @@ # Internal stuff try: - from thread import _local + from _thread import _local except ImportError: class _local(object): # assume no threads pass diff --git a/lib_pypy/identity_dict.py b/lib_pypy/identity_dict.py --- a/lib_pypy/identity_dict.py +++ b/lib_pypy/identity_dict.py @@ -32,7 +32,7 @@ def copy(self): d = type(self)() - d.update(self.iteritems()) + d.update(self.items()) assert len(d) == len(self) return d @@ -60,7 +60,7 @@ def copy(self): d = type(self)() - d.update(self.iteritems()) + d.update(self.items()) assert len(d) == len(self) return d diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py --- a/lib_pypy/itertools.py +++ b/lib_pypy/itertools.py @@ -204,7 +204,7 @@ key = lambda x: x self.keyfunc = key self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = xrange(0) + self.tgtkey = self.currkey = self.currvalue = range(0) def __iter__(self): return self @@ -458,7 +458,7 @@ def __init__(self, obj, times=None): self._obj = obj if times is not None: - xrange(times) # Raise a TypeError + range(times) # Raise a TypeError if times < 0: times = 0 self._times = times @@ -610,6 +610,6 @@ if isinstance(iterable, TeeObject): # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) return tuple([iterable] + - [TeeObject(tee_data=iterable.tee_data) for i in xrange(n-1)]) + [TeeObject(tee_data=iterable.tee_data) for i in range(n - 1)]) tee_data = TeeData(iter(iterable)) - return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)]) + return tuple([TeeObject(tee_data=tee_data) for i in range(n)]) diff --git a/lib_pypy/pwd.py b/lib_pypy/pwd.py --- a/lib_pypy/pwd.py +++ b/lib_pypy/pwd.py @@ -69,7 +69,7 @@ yield self.pw_dir yield self.pw_shell -class struct_passwd: +class struct_passwd(metaclass=structseqtype): """ pwd.struct_passwd: Results from getpw*() routines. @@ -77,7 +77,6 @@ (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell) or via the object attributes as named in the above tuple. """ - __metaclass__ = structseqtype name = "pwd.struct_passwd" pw_name = structseqfield(0) pw_passwd = structseqfield(1) @@ -167,9 +166,9 @@ from os import getuid uid = getuid() pw = getpwuid(uid) - print("uid %s: %s" % (pw.pw_uid, pw)) + print(("uid %s: %s" % (pw.pw_uid, pw))) name = pw.pw_name - print("name %r: %s" % (name, getpwnam(name))) + print(("name %r: %s" % (name, getpwnam(name)))) print("All:") for pw in getpwall(): print(pw) diff --git a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py b/lib_pypy/pypy_test/inprogress_test_binascii_extra.py --- a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py +++ b/lib_pypy/pypy_test/inprogress_test_binascii_extra.py @@ -1,4 +1,3 @@ -from __future__ import absolute_import from lib_pypy import binascii def test_uu(): diff --git a/lib_pypy/pypy_test/test_collections.py b/lib_pypy/pypy_test/test_collections.py --- a/lib_pypy/pypy_test/test_collections.py +++ b/lib_pypy/pypy_test/test_collections.py @@ -1,4 +1,3 @@ -from __future__ import absolute_import from lib_pypy import _collections as collections import py @@ -42,7 +41,7 @@ d = collections.deque(range(100)) d.reverse() - assert list(d) == range(99, -1, -1) + assert list(d) == list(range(99, -1, -1)) def test_subclass_with_kwargs(self): class SubclassWithKwargs(collections.deque): diff --git a/lib_pypy/pypy_test/test_coroutine.py b/lib_pypy/pypy_test/test_coroutine.py --- a/lib_pypy/pypy_test/test_coroutine.py +++ b/lib_pypy/pypy_test/test_coroutine.py @@ -1,9 +1,8 @@ -from __future__ import absolute_import from py.test import skip, raises try: from stackless import coroutine, CoroutineExit -except ImportError, e: +except ImportError as e: skip('cannot import stackless: %s' % (e,)) @@ -12,7 +11,7 @@ def test_is_zombie(self): co = coroutine() def f(): - print 'in coro' + print('in coro') assert not co.is_zombie co.bind(f) assert not co.is_zombie @@ -26,7 +25,7 @@ def __del__(self): res.append(self.is_zombie) def f(): - print 'in coro' + print('in coro') co = MyCoroutine() co.bind(f) co.switch() @@ -48,7 +47,7 @@ res.append(self.is_zombie) main = coroutine.getcurrent() def f(): - print 'in coro' + print('in coro') main.switch() co = MyCoroutine() co.bind(f) diff --git a/lib_pypy/pypy_test/test_datetime.py b/lib_pypy/pypy_test/test_datetime.py --- a/lib_pypy/pypy_test/test_datetime.py +++ b/lib_pypy/pypy_test/test_datetime.py @@ -1,10 +1,9 @@ -from __future__ import absolute_import import py from lib_pypy import datetime def test_repr(): - print datetime + print(datetime) expected = "datetime.datetime(1, 2, 3, 0, 0)" assert repr(datetime.datetime(1,2,3)) == expected diff --git a/lib_pypy/pypy_test/test_dbm_extra.py b/lib_pypy/pypy_test/test_dbm_extra.py --- a/lib_pypy/pypy_test/test_dbm_extra.py +++ b/lib_pypy/pypy_test/test_dbm_extra.py @@ -1,9 +1,8 @@ -from __future__ import absolute_import import py from pypy.tool.udir import udir try: from lib_pypy import dbm -except ImportError, e: +except ImportError as e: py.test.skip(e) def test_get(): diff --git a/lib_pypy/pypy_test/test_defaultdict.py b/lib_pypy/pypy_test/test_defaultdict.py --- a/lib_pypy/pypy_test/test_defaultdict.py +++ b/lib_pypy/pypy_test/test_defaultdict.py @@ -1,6 +1,5 @@ # defaultdict Tests # from CPython2.5 -from __future__ import absolute_import import py import sys if sys.version_info < (2, 5): diff --git a/lib_pypy/pypy_test/test_deque_extra.py b/lib_pypy/pypy_test/test_deque_extra.py --- a/lib_pypy/pypy_test/test_deque_extra.py +++ b/lib_pypy/pypy_test/test_deque_extra.py @@ -1,5 +1,4 @@ # Deque Tests -from __future__ import absolute_import import py @@ -23,17 +22,17 @@ def test_deque_iter(self): it = iter(self.d) py.test.raises(TypeError, len, it) - assert it.next() == 0 + assert next(it) == 0 self.d.pop() - py.test.raises(RuntimeError, it.next) + py.test.raises(RuntimeError, next, it) def test_deque_reversed(self): it = reversed(self.d) py.test.raises(TypeError, len, it) - assert it.next() == n-1 - assert it.next() == n-2 + assert next(it) == n-1 + assert next(it) == n-2 self.d.pop() - py.test.raises(RuntimeError, it.next) + py.test.raises(RuntimeError, next, it) def test_deque_remove(self): d = self.d diff --git a/lib_pypy/pypy_test/test_grp_extra.py b/lib_pypy/pypy_test/test_grp_extra.py --- a/lib_pypy/pypy_test/test_grp_extra.py +++ b/lib_pypy/pypy_test/test_grp_extra.py @@ -1,4 +1,3 @@ -from __future__ import absolute_import import py try: from lib_pypy import grp diff --git a/lib_pypy/pypy_test/test_itertools.py b/lib_pypy/pypy_test/test_itertools.py --- a/lib_pypy/pypy_test/test_itertools.py +++ b/lib_pypy/pypy_test/test_itertools.py @@ -10,7 +10,7 @@ def test_compress_diff_len(self): it = itertools.compress(['a'], []) - raises(StopIteration, it.next) + raises(StopIteration, next, it) def test_product(self): l = [1, 2] diff --git a/lib_pypy/pypy_test/test_marshal_extra.py b/lib_pypy/pypy_test/test_marshal_extra.py --- a/lib_pypy/pypy_test/test_marshal_extra.py +++ b/lib_pypy/pypy_test/test_marshal_extra.py @@ -1,4 +1,3 @@ -from __future__ import absolute_import import py import sys import marshal as cpy_marshal @@ -19,11 +18,11 @@ StopIteration, Ellipsis, 42, - sys.maxint, + sys.maxsize, -1.25, 2+5j, - 42L, - -1234567890123456789012345678901234567890L, + 42, + -1234567890123456789012345678901234567890, hello, # not interned "hello", (), @@ -32,9 +31,9 @@ [3, 4], {}, {5: 6, 7: 8}, - func.func_code, - scopefunc.func_code, - u'hello', + func.__code__, + scopefunc.__code__, + 'hello', ] try: @@ -64,13 +63,13 @@ yield dump_to_cpython, case def dumps_and_reload(case): - print 'dump_and_reload', `case` + print('dump_and_reload', repr(case)) s = marshal.dumps(case) obj = marshal.loads(s) assert obj == case def loads_from_cpython(case): - print 'load_from_cpython', `case` + print('load_from_cpython', repr(case)) try: s = cpy_marshal.dumps(case, *cpy_dump_version) except ValueError: @@ -79,7 +78,7 @@ assert obj == case def dumps_to_cpython(case): - print 'dump_to_cpython', `case` + print('dump_to_cpython', repr(case)) try: cpy_marshal.dumps(case, *cpy_dump_version) except ValueError: diff --git a/lib_pypy/pypy_test/test_md5_extra.py b/lib_pypy/pypy_test/test_md5_extra.py --- a/lib_pypy/pypy_test/test_md5_extra.py +++ b/lib_pypy/pypy_test/test_md5_extra.py @@ -4,7 +4,6 @@ 160 sec. per MB of data on a 233 MHz Intel Pentium CPU. """ -from __future__ import absolute_import import md5 # CPython's implementation in C. from lib_pypy import _md5 as pymd5 @@ -14,9 +13,9 @@ def formatHex(str): "Print a string's HEX code in groups of two digits." - d = map(None, str) + d = list(str) d = map(ord, d) - d = map(lambda x:"%02x" % x, d) + d = ["%02x" % x for x in d] return ' '.join(d) @@ -32,13 +31,13 @@ def printDiff(message, d1, d2, expectedResult=None): "Print different outputs for same message." - print "Message: '%s'" % message - print "Message length: %d" % len(message) + print("Message: '%s'" % message) + print("Message length: %d" % len(message)) if expectedResult: - print "%-48s (expected)" % format(expectedResult) - print "%-48s (Std. lib. MD5)" % formatHex(d1) - print "%-48s (Pure Python MD5)" % formatHex(d2) - print + print("%-48s (expected)" % format(expectedResult)) + print("%-48s (Std. lib. MD5)" % formatHex(d1)) + print("%-48s (Pure Python MD5)" % formatHex(d2)) + print() # The real comparison function. @@ -92,7 +91,7 @@ "57edf4a22be3c955ac49da2e2107b67a"), ) - for i in xrange(len(cases)): + for i in range(len(cases)): res = compareImp(cases[i][0]) if res is not None: d1, d2 = res @@ -129,7 +128,7 @@ "123456789 123456789 123456789 12345678", ) - for i in xrange(len(cases)): + for i in range(len(cases)): res = compareImp(cases[i][0]) if res is not None: d1, d2 = res @@ -147,7 +146,7 @@ ## (2**20*'a',), ## 1 MB, takes about 160 sec. on a 233 Mhz Pentium. ) - for i in xrange(len(cases)): + for i in range(len(cases)): res = compareImp(cases[i][0]) if res is not None: d1, d2 = res @@ -208,7 +207,7 @@ m2c = m2.copy() # Update and compare... - for i in xrange(len(cases)): + for i in range(len(cases)): message = cases[i][0] m1c.update(message) diff --git a/lib_pypy/pypy_test/test_os_wait.py b/lib_pypy/pypy_test/test_os_wait.py --- a/lib_pypy/pypy_test/test_os_wait.py +++ b/lib_pypy/pypy_test/test_os_wait.py @@ -1,5 +1,4 @@ # Generates the resource cache -from __future__ import absolute_import from lib_pypy.ctypes_config_cache import rebuild rebuild.rebuild_one('resource.ctc.py') diff --git a/lib_pypy/pypy_test/test_resource.py b/lib_pypy/pypy_test/test_resource.py --- a/lib_pypy/pypy_test/test_resource.py +++ b/lib_pypy/pypy_test/test_resource.py @@ -1,4 +1,3 @@ -from __future__ import absolute_import from lib_pypy.ctypes_config_cache import rebuild rebuild.rebuild_one('resource.ctc.py') @@ -27,5 +26,5 @@ if i < 2: expected_type = float else: - expected_type = (int, long) + expected_type = int assert isinstance(x[i], expected_type) diff --git a/lib_pypy/pypy_test/test_sha_extra.py b/lib_pypy/pypy_test/test_sha_extra.py --- a/lib_pypy/pypy_test/test_sha_extra.py +++ b/lib_pypy/pypy_test/test_sha_extra.py @@ -3,7 +3,6 @@ # use the three examples from Federal Information Processing Standards # Publication 180-1, Secure Hash Standard, 1995 April 17 # http://www.itl.nist.gov/div897/pubs/fip180-1.htm -from __future__ import absolute_import from lib_pypy import _sha as pysha class TestSHA: diff --git a/lib_pypy/pypy_test/test_stackless.py b/lib_pypy/pypy_test/test_stackless.py --- a/lib_pypy/pypy_test/test_stackless.py +++ b/lib_pypy/pypy_test/test_stackless.py @@ -4,21 +4,20 @@ 2. CPython (with the stackless_new module in the path 3. pypy-c """ -from __future__ import absolute_import from py.test import skip try: import stackless except ImportError: try: from lib_pypy import stackless - except ImportError, e: + except ImportError as e: skip('cannot import stackless: %s' % (e,)) SHOW_STRANGE = False def dprint(txt): if SHOW_STRANGE: - print txt + print(txt) class Test_Stackless: @@ -88,11 +87,11 @@ def test_send_counter(self): import random - numbers = range(20) + numbers = list(range(20)) random.shuffle(numbers) def counter(n, ch): - for i in xrange(n): + for i in range(n): stackless.schedule() ch.send(n) @@ -112,12 +111,12 @@ def test_receive_counter(self): import random - numbers = range(20) + numbers = list(range(20)) random.shuffle(numbers) rlist = [] def counter(n, ch): - for i in xrange(n): + for i in range(n): stackless.schedule() ch.receive() rlist.append(n) @@ -184,7 +183,7 @@ try: stackless.run() # cheating, can't test for ZeroDivisionError - except Exception, e: + except Exception as e: rlist.append('E') stackless.schedule() stackless.schedule() @@ -457,7 +456,7 @@ def exp_recv(chan): try: val = chan.receive() - except Exception, exp: + except Exception as exp: assert exp.__class__ is Exception assert str(exp) == 'test' diff --git a/lib_pypy/pypy_test/test_stackless_pickling.py b/lib_pypy/pypy_test/test_stackless_pickling.py --- a/lib_pypy/pypy_test/test_stackless_pickling.py +++ b/lib_pypy/pypy_test/test_stackless_pickling.py @@ -1,11 +1,10 @@ -from __future__ import absolute_import from py.test import skip try: import stackless except ImportError: try: from lib_pypy import stackless as stackless - except ImportError, e: + except ImportError as e: skip('cannot import stackless: %s' % (e,)) @@ -15,7 +14,7 @@ def test_pickle_main_coroutine(self): import stackless, pickle s = pickle.dumps(stackless.coroutine.getcurrent()) - print s + print(s) c = pickle.loads(s) assert c is stackless.coroutine.getcurrent() @@ -31,13 +30,13 @@ mod = new.module('mod') mod.output = output - exec """from stackless import schedule + exec("""from stackless import schedule def aCallable(name): output.append(('b', name)) schedule() output.append(('a', name)) -""" in mod.__dict__ +""", mod.__dict__) import sys sys.modules['mod'] = mod aCallable = mod.aCallable diff --git a/lib_pypy/pypy_test/test_structseq.py b/lib_pypy/pypy_test/test_structseq.py --- a/lib_pypy/pypy_test/test_structseq.py +++ b/lib_pypy/pypy_test/test_structseq.py @@ -1,11 +1,8 @@ -from __future__ import absolute_import import py from lib_pypy._structseq import structseqfield, structseqtype -class mydata: - __metaclass__ = structseqtype - +class mydata(metaclass=structseqtype): st_mode = structseqfield(0, "protection bits") st_ino = structseqfield(1) st_dev = structseqfield(2) @@ -31,7 +28,7 @@ assert mydata.n_unnamed_fields == 0 def test_mydata(): - x = mydata(range(100, 111)) + x = mydata(list(range(100, 111))) assert x.n_sequence_fields == type(x).n_sequence_fields == 10 assert x.n_fields == type(x).n_fields == 14 assert x.st_mode == 100 @@ -39,42 +36,42 @@ assert x.st_ctime == 109 # copied by the default=lambda... assert x.st_rdev == 110 assert len(x) == 10 - assert list(x) == range(100, 110) + assert list(x) == list(range(100, 110)) assert x + (5,) == tuple(range(100, 110)) + (5,) assert x[4:12:2] == (104, 106, 108) assert 104 in x assert 110 not in x def test_default_None(): - x = mydata(range(100, 110)) + x = mydata(list(range(100, 110))) assert x.st_rdev is None def test_constructor(): - x = mydata(range(100, 111), {'st_mtime': 12.25}) + x = mydata(list(range(100, 111)), {'st_mtime': 12.25}) assert x[8] == 108 assert x.st_mtime == 12.25 def test_compare_like_tuple(): - x = mydata(range(100, 111)) - y = mydata(range(100, 110) + [555]) + x = mydata(list(range(100, 111))) + y = mydata(list(range(100, 110)) + [555]) assert x == tuple(range(100, 110)) assert x == y # blame CPython assert hash(x) == hash(y) == hash(tuple(range(100, 110))) def test_pickle(): import pickle - x = mydata(range(100, 111)) + x = mydata(list(range(100, 111))) s = pickle.dumps(x) y = pickle.loads(s) assert x == y assert x.st_rdev == y.st_rdev == 110 def test_readonly(): - x = mydata(range(100, 113)) + x = mydata(list(range(100, 113))) py.test.raises((TypeError, AttributeError), "x.st_mode = 1") py.test.raises((TypeError, AttributeError), "x.st_mtime = 1") py.test.raises((TypeError, AttributeError), "x.st_rdev = 1") def test_no_extra_assignments(): - x = mydata(range(100, 113)) + x = mydata(list(range(100, 113))) py.test.raises((TypeError, AttributeError), "x.some_random_attribute = 1") diff --git a/lib_pypy/pypy_test/test_syslog.py b/lib_pypy/pypy_test/test_syslog.py --- a/lib_pypy/pypy_test/test_syslog.py +++ b/lib_pypy/pypy_test/test_syslog.py @@ -1,4 +1,3 @@ -from __future__ import absolute_import # XXX very minimal test from lib_pypy.ctypes_config_cache import rebuild diff --git a/lib_pypy/resource.py b/lib_pypy/resource.py --- a/lib_pypy/resource.py +++ b/lib_pypy/resource.py @@ -67,9 +67,7 @@ _getrusage.restype = c_int -class struct_rusage: - __metaclass__ = _structseq.structseqtype - +class struct_rusage(metaclass=_structseq.structseqtype): ru_utime = _structseq.structseqfield(0) ru_stime = _structseq.structseqfield(1) ru_maxrss = _structseq.structseqfield(2) diff --git a/lib_pypy/stackless.py b/lib_pypy/stackless.py --- a/lib_pypy/stackless.py +++ b/lib_pypy/stackless.py @@ -93,7 +93,7 @@ try: - from thread import _local + from _thread import _local except ImportError: class _local(object): # assume no threads pass @@ -168,7 +168,7 @@ self.traceback = exp_traceback def raise_(self): - raise self.type, self.value, self.traceback + raise self.type(self.value).with_traceback(self.traceback) # # @@ -433,16 +433,16 @@ def insert(self): if self.blocked: - raise RuntimeError, "You cannot run a blocked tasklet" + raise RuntimeError("You cannot run a blocked tasklet") if not self.alive: - raise RuntimeError, "You cannot run an unbound(dead) tasklet" + raise RuntimeError("You cannot run an unbound(dead) tasklet") _scheduler_append(self) def remove(self): if self.blocked: - raise RuntimeError, "You cannot remove a blocked tasklet." + raise RuntimeError("You cannot remove a blocked tasklet.") if self is getcurrent(): - raise RuntimeError, "The current tasklet cannot be removed." + raise RuntimeError("The current tasklet cannot be removed.") # not sure if I will revive this " Use t=tasklet().capture()" _scheduler_remove(self) @@ -535,7 +535,7 @@ _main_tasklet = coroutine.getcurrent() _main_tasklet.__class__ = tasklet # XXX HAAAAAAAAAAAAAAAAAAAAACK _last_task = _main_tasklet - tasklet._init.im_func(_main_tasklet, label='main') + tasklet._init.__func__(_main_tasklet, label='main') _squeue = deque() _scheduler_append(_main_tasklet) diff --git a/lib_pypy/tputil.py b/lib_pypy/tputil.py --- a/lib_pypy/tputil.py +++ b/lib_pypy/tputil.py @@ -53,8 +53,8 @@ res = objattr(*self.args, **self.kwargs) if self.opname == "__getattribute__": if (isinstance(res, MethodType) and - res.im_self is self.instance): - res = MethodType(res.im_func, self.proxyobj, res.im_class) + res.__self__ is self.instance): + res = MethodType(res.__func__, self.proxyobj, res.__self__.__class__) if res is self.obj: res = self.proxyobj return res From noreply at buildbot.pypy.org Wed Oct 24 22:56:21 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 24 Oct 2012 22:56:21 +0200 (CEST) Subject: [pypy-commit] pypy py3k: kill refs to the exceptions module Message-ID: <20121024205621.D8F101C0DBF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58404:1da7c415dfb4 Date: 2012-10-24 13:56 -0700 http://bitbucket.org/pypy/pypy/changeset/1da7c415dfb4/ Log: kill refs to the exceptions module diff --git a/lib_pypy/pypy_test/test_exception_extra.py b/lib_pypy/pypy_test/test_exception_extra.py --- a/lib_pypy/pypy_test/test_exception_extra.py +++ b/lib_pypy/pypy_test/test_exception_extra.py @@ -1,16 +1,11 @@ def app_test_environmenterror_repr(): - import exceptions as ex - e = ex.EnvironmentError("hello") + e = EnvironmentError("hello") assert str(e) == "hello" - e = ex.EnvironmentError(1, "hello") + e = EnvironmentError(1, "hello") assert str(e) == "[Errno 1] hello" - e = ex.EnvironmentError(1, "hello", "world") + e = EnvironmentError(1, "hello", "world") assert str(e) == "[Errno 1] hello: 'world'" -def app_test_import(): - import exceptions - assert exceptions.SyntaxError is SyntaxError - def app_test_baseexception(): assert issubclass(Exception, BaseException) From noreply at buildbot.pypy.org Wed Oct 24 23:25:01 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 23:25:01 +0200 (CEST) Subject: [pypy-commit] pyrepl py3k-readline: Typo. Now pyrepl works with pypy! Message-ID: <20121024212501.D6D891C0DBF@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k-readline Changeset: r200:1d5880d5ced3 Date: 2012-10-24 23:24 +0200 http://bitbucket.org/pypy/pyrepl/changeset/1d5880d5ced3/ Log: Typo. Now pyrepl works with pypy! diff --git a/pyrepl/curses.py b/pyrepl/curses.py --- a/pyrepl/curses.py +++ b/pyrepl/curses.py @@ -24,7 +24,7 @@ try: # Forces import of the builtin module. Seems necessary with PyPy. - _curses = imp.init_builtin('_minimal_curses2') + _curses = imp.init_builtin('_minimal_curses') if not _curses: raise ImportError setupterm = _curses.setupterm @@ -32,4 +32,5 @@ tparm = _curses.tparm error = _curses.error except ImportError: + raise from ._minimal_curses import setupterm, tigetstr, tparm, error From noreply at buildbot.pypy.org Wed Oct 24 23:35:16 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 23:35:16 +0200 (CEST) Subject: [pypy-commit] pypy py3k: test_itertools: skip some implementation details Message-ID: <20121024213516.B1FA51C0DBF@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58405:ef65b97b8e37 Date: 2012-10-24 08:37 +0200 http://bitbucket.org/pypy/pypy/changeset/ef65b97b8e37/ Log: test_itertools: skip some implementation details and accepts TypeError when the types don't match. diff --git a/lib-python/3.2/test/test_itertools.py b/lib-python/3.2/test/test_itertools.py --- a/lib-python/3.2/test/test_itertools.py +++ b/lib-python/3.2/test/test_itertools.py @@ -159,8 +159,9 @@ self.assertEqual(result, list(combinations3(values, r))) # matches second pure python version # Test implementation detail: tuple re-use - self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1) - self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1) + if support.check_impl_detail(pypy=False): + self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1) + self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1) def test_combinations_with_replacement(self): cwr = combinations_with_replacement @@ -229,8 +230,9 @@ self.assertEqual(result, list(cwr2(values, r))) # matches second pure python version # Test implementation detail: tuple re-use - self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1) - self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1) + if support.check_impl_detail(pypy=False): + self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1) + self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1) def test_permutations(self): self.assertRaises(TypeError, permutations) # too few arguments @@ -293,8 +295,9 @@ self.assertEqual(result, list(permutations(values))) # test default r # Test implementation detail: tuple re-use - self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1) - self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1) + if support.check_impl_detail(pypy=False): + self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1) + self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1) def test_combinatorics(self): # Test relationships between product(), permutations(), @@ -561,8 +564,9 @@ lzip('abc', 'def')) self.assertEqual([pair for pair in zip('abc', 'def')], lzip('abc', 'def')) - ids = list(map(id, zip('abc', 'def'))) - self.assertEqual(min(ids), max(ids)) + if support.check_impl_detail(pypy=False): + ids = list(map(id, zip('abc', 'def'))) + self.assertEqual(min(ids), max(ids)) ids = list(map(id, list(zip('abc', 'def')))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) @@ -608,8 +612,9 @@ list(zip('abc', 'def'))) self.assertEqual([pair for pair in zip_longest('abc', 'def')], list(zip('abc', 'def'))) - ids = list(map(id, zip_longest('abc', 'def'))) - self.assertEqual(min(ids), max(ids)) + if support.check_impl_detail(pypy=False): + ids = list(map(id, zip_longest('abc', 'def'))) + self.assertEqual(min(ids), max(ids)) ids = list(map(id, list(zip_longest('abc', 'def')))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) @@ -712,8 +717,9 @@ self.assertEqual(len(list(product(*args))), expected_len) # Test implementation detail: tuple re-use - self.assertEqual(len(set(map(id, product('abc', 'def')))), 1) - self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1) + if support.check_impl_detail(pypy=False): + self.assertEqual(len(set(map(id, product('abc', 'def')))), 1) + self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1) def test_repeat(self): self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a']) @@ -804,11 +810,11 @@ self.assertRaises(ValueError, islice, range(10), 1, -5, -1) self.assertRaises(ValueError, islice, range(10), 1, 10, -1) self.assertRaises(ValueError, islice, range(10), 1, 10, 0) - self.assertRaises(ValueError, islice, range(10), 'a') - self.assertRaises(ValueError, islice, range(10), 'a', 1) - self.assertRaises(ValueError, islice, range(10), 1, 'a') - self.assertRaises(ValueError, islice, range(10), 'a', 1, 1) - self.assertRaises(ValueError, islice, range(10), 1, 'a', 1) + self.assertRaises((TypeError, ValueError), islice, range(10), 'a') + self.assertRaises((TypeError, ValueError), islice, range(10), 'a', 1) + self.assertRaises((TypeError, ValueError), range(10), 1, 'a') + self.assertRaises((TypeError, ValueError), range(10), 'a', 1, 1) + self.assertRaises((TypeError, ValueError), range(10), 1, 'a', 1) self.assertEqual(len(list(islice(count(), 1, 10, maxsize))), 1) # Issue #10323: Less islice in a predictable state From noreply at buildbot.pypy.org Wed Oct 24 23:35:17 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 23:35:17 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Do the same changes as in the 2.7 test suite. Message-ID: <20121024213517.EEB841C0DBF@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58406:e50a9da4f6c2 Date: 2012-10-24 08:43 +0200 http://bitbucket.org/pypy/pypy/changeset/e50a9da4f6c2/ Log: Do the same changes as in the 2.7 test suite. diff --git a/lib-python/3.2/test/test_itertools.py b/lib-python/3.2/test/test_itertools.py --- a/lib-python/3.2/test/test_itertools.py +++ b/lib-python/3.2/test/test_itertools.py @@ -158,10 +158,11 @@ self.assertEqual(result, list(combinations2(values, r))) # matches second pure python version self.assertEqual(result, list(combinations3(values, r))) # matches second pure python version + @support.impl_detail("tuple reuse is specific to CPython") + def test_combinations_tuple_reuse(self): # Test implementation detail: tuple re-use - if support.check_impl_detail(pypy=False): - self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1) - self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1) + self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1) + self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1) def test_combinations_with_replacement(self): cwr = combinations_with_replacement @@ -229,10 +230,12 @@ self.assertEqual(result, list(cwr1(values, r))) # matches first pure python version self.assertEqual(result, list(cwr2(values, r))) # matches second pure python version + @support.impl_detail("tuple reuse is specific to CPython") + def test_combinations_with_replacement_tuple_reuse(self): # Test implementation detail: tuple re-use - if support.check_impl_detail(pypy=False): - self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1) - self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1) + cwr = combinations_with_replacement + self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1) + self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1) def test_permutations(self): self.assertRaises(TypeError, permutations) # too few arguments @@ -294,10 +297,11 @@ self.assertEqual(result, list(permutations(values, None))) # test r as None self.assertEqual(result, list(permutations(values))) # test default r + @support.impl_detail("tuple reuse is specific to CPython") + def test_permutations_tuple_reuse(self): # Test implementation detail: tuple re-use - if support.check_impl_detail(pypy=False): - self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1) - self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1) + self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1) + self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1) def test_combinatorics(self): # Test relationships between product(), permutations(), @@ -559,14 +563,16 @@ self.assertEqual(list(zip()), lzip()) self.assertRaises(TypeError, zip, 3) self.assertRaises(TypeError, zip, range(3), 3) - # Check tuple re-use (implementation detail) + self.assertEqual([tuple(list(pair)) for pair in zip('abc', 'def')], lzip('abc', 'def')) self.assertEqual([pair for pair in zip('abc', 'def')], lzip('abc', 'def')) - if support.check_impl_detail(pypy=False): - ids = list(map(id, zip('abc', 'def'))) - self.assertEqual(min(ids), max(ids)) + + @support.impl_detail("tuple reuse is specific to CPython") + def test_izip_tuple_reuse(self): + ids = list(map(id, zip('abc', 'def'))) + self.assertEqual(min(ids), max(ids)) ids = list(map(id, list(zip('abc', 'def')))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) @@ -607,14 +613,15 @@ else: self.fail('Did not raise Type in: ' + stmt) - # Check tuple re-use (implementation detail) self.assertEqual([tuple(list(pair)) for pair in zip_longest('abc', 'def')], list(zip('abc', 'def'))) self.assertEqual([pair for pair in zip_longest('abc', 'def')], list(zip('abc', 'def'))) - if support.check_impl_detail(pypy=False): - ids = list(map(id, zip_longest('abc', 'def'))) - self.assertEqual(min(ids), max(ids)) + + @support.impl_detail("tuple reuse is specific to CPython") + def test_izip_longest_tuple_reuse(self): + ids = list(map(id, zip_longest('abc', 'def'))) + self.assertEqual(min(ids), max(ids)) ids = list(map(id, list(zip_longest('abc', 'def')))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) @@ -716,10 +723,10 @@ args = map(iter, args) self.assertEqual(len(list(product(*args))), expected_len) - # Test implementation detail: tuple re-use - if support.check_impl_detail(pypy=False): - self.assertEqual(len(set(map(id, product('abc', 'def')))), 1) - self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1) + @support.impl_detail("tuple reuse is specific to CPython") + def test_product_tuple_reuse(self): + self.assertEqual(len(set(map(id, product('abc', 'def')))), 1) + self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1) def test_repeat(self): self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a']) From noreply at buildbot.pypy.org Wed Oct 24 23:35:19 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 23:35:19 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Also skip part of this test, like for 2.7 Message-ID: <20121024213519.323C61C0DBF@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58407:9235686f0e23 Date: 2012-10-24 08:46 +0200 http://bitbucket.org/pypy/pypy/changeset/9235686f0e23/ Log: Also skip part of this test, like for 2.7 diff --git a/lib-python/3.2/test/test_itertools.py b/lib-python/3.2/test/test_itertools.py --- a/lib-python/3.2/test/test_itertools.py +++ b/lib-python/3.2/test/test_itertools.py @@ -901,9 +901,17 @@ self.assertRaises(TypeError, tee, [1,2], 3, 'x') # tee object should be instantiable - a, b = tee('abc') - c = type(a)('def') - self.assertEqual(list(c), list('def')) + if support.check_impl_detail(): + # XXX I (arigo) would argue that 'type(a)(iterable)' has + # ill-defined semantics: it always return a fresh tee object, + # but depending on whether 'iterable' is itself a tee object + # or not, it is ok or not to continue using 'iterable' after + # the call. I cannot imagine why 'type(a)(non_tee_object)' + # would be useful, as 'iter(non_tee_obect)' is equivalent + # as far as I can see. + a, b = tee('abc') + c = type(a)('def') + self.assertEqual(list(c), list('def')) # test long-lagged and multi-way split a, b, c = tee(range(2000), 3) @@ -941,6 +949,7 @@ p = proxy(a) self.assertEqual(getattr(p, '__class__'), type(b)) del a + support.gc_collect() self.assertRaises(ReferenceError, getattr, p, '__class__') def test_StopIteration(self): From noreply at buildbot.pypy.org Wed Oct 24 23:35:20 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 23:35:20 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Skip an implementation detail, and cherry-pick change for CPython Issue #14177 Message-ID: <20121024213520.61AD31C0DBF@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58408:3b8a6e70f232 Date: 2012-10-24 22:02 +0200 http://bitbucket.org/pypy/pypy/changeset/3b8a6e70f232/ Log: Skip an implementation detail, and cherry-pick change for CPython Issue #14177 that is not yet released and that PyPy already implements (marshal.loads rejects unicode strings) diff --git a/lib-python/3.2/test/test_marshal.py b/lib-python/3.2/test/test_marshal.py --- a/lib-python/3.2/test/test_marshal.py +++ b/lib-python/3.2/test/test_marshal.py @@ -162,9 +162,10 @@ pass def test_loads_recursion(self): - s = 'c' + ('X' * 4*4) + '{' * 2**20 + s = b'c' + (b'X' * 4*4) + b'{' * 2**20 self.assertRaises(ValueError, marshal.loads, s) + @test_support.impl_detail('specific recursion check') def test_recursion_limit(self): # Create a deeply nested structure. head = last = [] @@ -235,6 +236,11 @@ finally: support.unlink(support.TESTFN) + def test_loads_reject_unicode_strings(self): + # Issue #14177: marshal.loads() should not accept unicode strings + unicode_string = 'T' + self.assertRaises(TypeError, marshal.loads, unicode_string) + def test_main(): support.run_unittest(IntTestCase, From noreply at buildbot.pypy.org Wed Oct 24 23:35:21 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 23:35:21 +0200 (CEST) Subject: [pypy-commit] pypy py3k: CPython issue 13343: Fix a crash when a lambda expression uses a global Message-ID: <20121024213521.DAC591C0DBF@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58409:9ccaaa9b4bac Date: 2012-10-24 23:04 +0200 http://bitbucket.org/pypy/pypy/changeset/9ccaaa9b4bac/ Log: CPython issue 13343: Fix a crash when a lambda expression uses a global variable in the default value of a keyword-only argument: (lambda *, arg=GLOBAL_NAME: None) diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py --- a/pypy/interpreter/astcompiler/ast.py +++ b/pypy/interpreter/astcompiler/ast.py @@ -2477,6 +2477,12 @@ for node in seq: node.walkabout(self) + def visit_kwonlydefaults(self, seq): + if seq is not None: + for node in seq: + if node: + node.walkabout(self) + def default_visitor(self, node): raise NodeVisitorNotImplemented diff --git a/pypy/interpreter/astcompiler/symtable.py b/pypy/interpreter/astcompiler/symtable.py --- a/pypy/interpreter/astcompiler/symtable.py +++ b/pypy/interpreter/astcompiler/symtable.py @@ -356,10 +356,7 @@ args = func.args assert isinstance(args, ast.arguments) self.visit_sequence(args.defaults) - if args.kw_defaults: - for arg in args.kw_defaults: - if arg: - arg.walkabout(self) + self.visit_kwonlydefaults(args.kw_defaults) self._visit_annotations(func) self.visit_sequence(func.decorator_list) new_scope = FunctionScope(func.name, func.lineno, func.col_offset) @@ -453,6 +450,7 @@ args = lamb.args assert isinstance(args, ast.arguments) self.visit_sequence(args.defaults) + self.visit_kwonlydefaults(args.kw_defaults) new_scope = FunctionScope("lambda", lamb.lineno, lamb.col_offset) self.push_scope(new_scope, lamb) lamb.args.walkabout(self) diff --git a/pypy/interpreter/astcompiler/test/test_symtable.py b/pypy/interpreter/astcompiler/test/test_symtable.py --- a/pypy/interpreter/astcompiler/test/test_symtable.py +++ b/pypy/interpreter/astcompiler/test/test_symtable.py @@ -376,3 +376,7 @@ scp = self.mod_scope("with x as y: pass") assert scp.lookup("_[1]") == symtable.SCOPE_LOCAL assert scp.lookup("_[2]") == symtable.SCOPE_LOCAL + + def test_issue13343(self): + scp = self.mod_scope("lambda *, k1=x, k2: None") + assert scp.lookup("x") == symtable.SCOPE_GLOBAL_IMPLICIT diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py --- a/pypy/interpreter/astcompiler/tools/asdl_py.py +++ b/pypy/interpreter/astcompiler/tools/asdl_py.py @@ -222,6 +222,12 @@ self.emit("for node in seq:", 3) self.emit("node.walkabout(self)", 4) self.emit("") + self.emit("def visit_kwonlydefaults(self, seq):", 1) + self.emit("if seq is not None:", 2) + self.emit("for node in seq:", 3) + self.emit("if node:", 4) + self.emit("node.walkabout(self)", 5) + self.emit("") self.emit("def default_visitor(self, node):", 1) self.emit("raise NodeVisitorNotImplemented", 2) self.emit("") From noreply at buildbot.pypy.org Wed Oct 24 23:35:23 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 23:35:23 +0200 (CEST) Subject: [pypy-commit] pypy py3k: io module: replace some ValueError by UnsupportedOperation. Message-ID: <20121024213523.0E7801C0DBF@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58410:7a0955158bb6 Date: 2012-10-24 23:08 +0200 http://bitbucket.org/pypy/pypy/changeset/7a0955158bb6/ Log: io module: replace some ValueError by UnsupportedOperation. diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -77,11 +77,6 @@ return False class W_BufferedIOBase(W_IOBase): - def _unsupportedoperation(self, space, message): - w_exc = space.getattr(space.getbuiltinmodule('_io'), - space.wrap('UnsupportedOperation')) - raise OperationError(w_exc, space.wrap(message)) - def _check_init(self, space): raise NotImplementedError diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -212,15 +212,11 @@ def _check_readable(self, space): if not self.readable: - raise OperationError( - space.w_ValueError, - space.wrap("file not open for reading")) + self._unsupportedoperation(space, "File not open for reading") def _check_writable(self, space): if not self.writable: - raise OperationError( - space.w_ValueError, - space.wrap("file not open for writing")) + self._unsupportedoperation(space, "File not open for writing") def _close(self, space): if self.fd < 0: diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -16,26 +16,25 @@ else: return space.int_w(w_size) +def unsupported(space, message): + w_exc = space.getattr(space.getbuiltinmodule('_io'), + space.wrap('UnsupportedOperation')) + return OperationError(w_exc, space.wrap(message)) + # May be called with any object def check_readable_w(space, w_obj): if not space.is_true(space.call_method(w_obj, 'readable')): - raise OperationError( - space.w_IOError, - space.wrap("file or stream is not readable")) + raise unsupported(space, "File or stream is not readable") # May be called with any object def check_writable_w(space, w_obj): if not space.is_true(space.call_method(w_obj, 'writable')): - raise OperationError( - space.w_IOError, - space.wrap("file or stream is not writable")) + raise unsupported(space, "File or stream is not writable") # May be called with any object def check_seekable_w(space, w_obj): if not space.is_true(space.call_method(w_obj, 'seekable')): - raise OperationError( - space.w_IOError, - space.wrap("file or stream is not seekable")) + raise unsupported(space, "File or stream is not seekable") class W_IOBase(Wrappable): def __init__(self, space): @@ -85,6 +84,9 @@ # attribute as returned by whatever subclass. return self.__IOBase_closed + def _unsupportedoperation(self, space, message): + raise unsupported(space, message) + def _check_closed(self, space, message=None): if message is None: message = "I/O operation on closed file" @@ -113,9 +115,18 @@ space.w_ValueError, space.wrap("I/O operation on closed file")) + def seek_w(self, space): + self._unsupportedoperation(space, "seek") + def tell_w(self, space): return space.call_method(self, "seek", space.wrap(0), space.wrap(1)) + def truncate_w(self, space): + self._unsupportedoperation(space, "truncate") + + def fileno_w(self, space): + self._unsupportedoperation(space, "fileno") + def enter_w(self, space): self._check_closed(space) return space.wrap(self) @@ -252,7 +263,10 @@ __next__ = interp2app(W_IOBase.next_w), close = interp2app(W_IOBase.close_w), flush = interp2app(W_IOBase.flush_w), + seek = interp2app(W_IOBase.seek_w), tell = interp2app(W_IOBase.tell_w), + truncate = interp2app(W_IOBase.truncate_w), + fileno = interp2app(W_IOBase.fileno_w), isatty = interp2app(W_IOBase.isatty_w), readable = interp2app(W_IOBase.readable_w), writable = interp2app(W_IOBase.writable_w), diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -196,11 +196,6 @@ def __init__(self, space): W_IOBase.__init__(self, space) - def _unsupportedoperation(self, space, message): - w_exc = space.getattr(space.getbuiltinmodule('_io'), - space.wrap('UnsupportedOperation')) - raise OperationError(w_exc, space.wrap(message)) - def read_w(self, space, w_size=None): self._unsupportedoperation(space, "read") @@ -544,7 +539,7 @@ remain buffered in the decoder, yet to be converted.""" if not self.w_decoder: - raise OperationError(space.w_IOError, space.wrap("not readable")) + self._unsupportedoperation(space, "not readable") if self.telling: # To prepare for tell(), we need to snapshot a point in the file @@ -590,7 +585,7 @@ def read_w(self, space, w_size=None): self._check_closed(space) if not self.w_decoder: - raise OperationError(space.w_IOError, space.wrap("not readable")) + self._unsupportedoperation(space, "not readable") size = convert_size(space, w_size) self._writeflush(space) From noreply at buildbot.pypy.org Wed Oct 24 23:35:24 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 24 Oct 2012 23:35:24 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Update pyrepl from upstream (py3k-readline branch) Message-ID: <20121024213524.411F81C0DBF@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58411:be161e2bc46a Date: 2012-10-24 23:34 +0200 http://bitbucket.org/pypy/pypy/changeset/be161e2bc46a/ Log: Update pyrepl from upstream (py3k-readline branch) diff --git a/lib_pypy/pyrepl/_minimal_curses.py b/lib_pypy/pyrepl/_minimal_curses.py new file mode 100644 --- /dev/null +++ b/lib_pypy/pyrepl/_minimal_curses.py @@ -0,0 +1,69 @@ +"""Minimal '_curses' module, the low-level interface for curses module +which is not meant to be used directly. + +Based on ctypes. It's too incomplete to be really called '_curses', so +to use it, you have to import it and stick it in sys.modules['_curses'] +manually. + +Note that there is also a built-in module _minimal_curses which will +hide this one if compiled in. +""" + +import ctypes, ctypes.util + +class error(Exception): + pass + + +def _find_clib(): + trylibs = ['ncurses', 'curses'] + + for lib in trylibs: + path = ctypes.util.find_library(lib) + if path: + return path + raise ImportError("curses library not found") + +_clibpath = _find_clib() +clib = ctypes.cdll.LoadLibrary(_clibpath) + +clib.setupterm.argtypes = [ctypes.c_char_p, ctypes.c_int, + ctypes.POINTER(ctypes.c_int)] +clib.setupterm.restype = ctypes.c_int + +clib.tigetstr.argtypes = [ctypes.c_char_p] +clib.tigetstr.restype = ctypes.POINTER(ctypes.c_char) + +clib.tparm.argtypes = [ctypes.c_char_p] + 9 * [ctypes.c_int] +clib.tparm.restype = ctypes.c_char_p + +OK = 0 +ERR = -1 + +# ____________________________________________________________ + +try: from __pypy__ import builtinify +except ImportError: builtinify = lambda f: f + + at builtinify +def setupterm(termstr, fd): + err = ctypes.c_int(0) + result = clib.setupterm(termstr, fd, ctypes.byref(err)) + if result == ERR: + raise error("setupterm() failed (err=%d)" % err.value) + + at builtinify +def tigetstr(cap): + if not isinstance(cap, bytes): + cap = cap.encode('ascii') + result = clib.tigetstr(cap) + if ctypes.cast(result, ctypes.c_void_p).value == ERR: + return None + return ctypes.cast(result, ctypes.c_char_p).value + + at builtinify +def tparm(str, i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0): + result = clib.tparm(str, i1, i2, i3, i4, i5, i6, i7, i8, i9) + if result is None: + raise error("tparm() returned NULL") + return result diff --git a/lib_pypy/pyrepl/cmdrepl.py b/lib_pypy/pyrepl/cmdrepl.py --- a/lib_pypy/pyrepl/cmdrepl.py +++ b/lib_pypy/pyrepl/cmdrepl.py @@ -33,7 +33,7 @@ which is in fact done by the `pythoni' script that comes with pyrepl.""" -from __future__ import nested_scopes +from __future__ import print_function from pyrepl import completing_reader as cr, reader, completer from pyrepl.completing_reader import CompletingReader as CR @@ -96,7 +96,7 @@ if intro is not None: self.intro = intro if self.intro: - print self.intro + print(self.intro) stop = None while not stop: if self.cmdqueue: diff --git a/lib_pypy/pyrepl/commands.py b/lib_pypy/pyrepl/commands.py --- a/lib_pypy/pyrepl/commands.py +++ b/lib_pypy/pyrepl/commands.py @@ -33,9 +33,12 @@ class Command(object): finish = 0 kills_digit_arg = 1 - def __init__(self, reader, cmd): + + def __init__(self, reader, event_name, event): self.reader = reader - self.event_name, self.event = cmd + self.event = event + self.event_name = event_name + def do(self): pass diff --git a/lib_pypy/pyrepl/completer.py b/lib_pypy/pyrepl/completer.py --- a/lib_pypy/pyrepl/completer.py +++ b/lib_pypy/pyrepl/completer.py @@ -17,7 +17,10 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import __builtin__ +try: + import __builtin__ as builtins +except ImportError: + import builtins class Completer: def __init__(self, ns): @@ -38,12 +41,11 @@ """ import keyword matches = [] - n = len(text) for list in [keyword.kwlist, - __builtin__.__dict__.keys(), + builtins.__dict__.keys(), self.ns.keys()]: for word in list: - if word[:n] == text and word != "__builtins__": + if word.startswith(text) and word != "__builtins__": matches.append(word) return matches diff --git a/lib_pypy/pyrepl/completing_reader.py b/lib_pypy/pyrepl/completing_reader.py --- a/lib_pypy/pyrepl/completing_reader.py +++ b/lib_pypy/pyrepl/completing_reader.py @@ -168,7 +168,7 @@ r.insert(completions[0][len(stem):]) else: p = prefix(completions, len(stem)) - if p <> '': + if p: r.insert(p) if r.last_command_is(self.__class__): if not r.cmpltn_menu_vis: @@ -259,7 +259,7 @@ p = self.pos - 1 while p >= 0 and st.get(b[p], SW) == SW: p -= 1 - return u''.join(b[p+1:self.pos]) + return ''.join(b[p+1:self.pos]) def get_completions(self, stem): return [] diff --git a/lib_pypy/pyrepl/console.py b/lib_pypy/pyrepl/console.py --- a/lib_pypy/pyrepl/console.py +++ b/lib_pypy/pyrepl/console.py @@ -17,8 +17,9 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -class Event: +class Event(object): """An Event. `evt' is 'key' or somesuch.""" + __slots__ = 'evt', 'data', 'raw' def __init__(self, evt, data, raw=''): self.evt = evt @@ -28,7 +29,7 @@ def __repr__(self): return 'Event(%r, %r)'%(self.evt, self.data) -class Console: +class Console(object): """Attributes: screen, diff --git a/lib_pypy/pyrepl/copy_code.py b/lib_pypy/pyrepl/copy_code.py --- a/lib_pypy/pyrepl/copy_code.py +++ b/lib_pypy/pyrepl/copy_code.py @@ -17,7 +17,7 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import new +from types import CodeType def copy_code_with_changes(codeobject, argcount=None, @@ -44,7 +44,7 @@ if name is None: name = codeobject.co_name if firstlineno is None: firstlineno = codeobject.co_firstlineno if lnotab is None: lnotab = codeobject.co_lnotab - return new.code(argcount, + return CodeType(argcount, nlocals, stacksize, flags, 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,21 +19,18 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# Some try-import logic for two purposes: avoiding to bring in the whole -# pure Python curses package if possible; and, in _curses is not actually -# present, falling back to _minimal_curses (which is either a ctypes-based -# pure Python module or a PyPy built-in module). + +import imp + try: - import _curses + # Forces import of the builtin module. Seems necessary with PyPy. + _curses = imp.init_builtin('_minimal_curses') + if not _curses: + raise ImportError + setupterm = _curses.setupterm + tigetstr = _curses.tigetstr + tparm = _curses.tparm + error = _curses.error except ImportError: - try: - import _minimal_curses as _curses - except ImportError: - # Who knows, maybe some environment has "curses" but not "_curses". - # If not, at least the following import gives a clean ImportError. - import _curses - -setupterm = _curses.setupterm -tigetstr = _curses.tigetstr -tparm = _curses.tparm -error = _curses.error + raise + from ._minimal_curses import setupterm, tigetstr, tparm, error diff --git a/lib_pypy/pyrepl/historical_reader.py b/lib_pypy/pyrepl/historical_reader.py --- a/lib_pypy/pyrepl/historical_reader.py +++ b/lib_pypy/pyrepl/historical_reader.py @@ -33,7 +33,8 @@ (r'\C-g', 'isearch-cancel'), (r'\', 'isearch-backspace')]) -del c +if 'c' in globals(): + del c ISEARCH_DIRECTION_NONE = '' ISEARCH_DIRECTION_BACKWARDS = 'r' @@ -230,7 +231,7 @@ self.dirty = 1 def get_item(self, i): - if i <> len(self.history): + if i != len(self.history): return self.transient_history.get(i, self.history[i]) else: return self.transient_history.get(i, self.get_unicode()) @@ -253,7 +254,7 @@ raise def get_prompt(self, lineno, cursor_on_line): - if cursor_on_line and self.isearch_direction <> ISEARCH_DIRECTION_NONE: + if cursor_on_line and self.isearch_direction != ISEARCH_DIRECTION_NONE: d = 'rf'[self.isearch_direction == ISEARCH_DIRECTION_FORWARDS] return "(%s-search `%s') "%(d, self.isearch_term) else: diff --git a/lib_pypy/pyrepl/input.py b/lib_pypy/pyrepl/input.py --- a/lib_pypy/pyrepl/input.py +++ b/lib_pypy/pyrepl/input.py @@ -32,8 +32,10 @@ # executive, temporary decision: [tab] and [C-i] are distinct, but # [meta-key] is identified with [esc key]. We demand that any console # class does quite a lot towards emulating a unix terminal. +from __future__ import print_function +import unicodedata +from collections import deque -from pyrepl import unicodedata_ class InputTranslator(object): def push(self, evt): @@ -43,7 +45,9 @@ def empty(self): pass + class KeymapTranslator(InputTranslator): + def __init__(self, keymap, verbose=0, invalid_cls=None, character_cls=None): self.verbose = verbose @@ -58,8 +62,9 @@ if self.verbose: print(d) self.k = self.ck = compile_keymap(d, ()) - self.results = [] + self.results = deque() self.stack = [] + def push(self, evt): if self.verbose: print("pushed", evt.data, end='') @@ -74,7 +79,7 @@ if d is None: if self.verbose: print("invalid") - if self.stack or len(key) > 1 or unicodedata_.category(key) == 'C': + if self.stack or len(key) > 1 or unicodedata.category(key) == 'C': self.results.append( (self.invalid_cls, self.stack + [key])) else: @@ -88,10 +93,12 @@ self.results.append((d, self.stack + [key])) self.stack = [] self.k = self.ck + def get(self): if self.results: - return self.results.pop(0) + return self.results.popleft() else: return None + def empty(self): return not self.results diff --git a/lib_pypy/pyrepl/keymap.py b/lib_pypy/pyrepl/keymap.py --- a/lib_pypy/pyrepl/keymap.py +++ b/lib_pypy/pyrepl/keymap.py @@ -101,7 +101,7 @@ while not ret and s < len(key): if key[s] == '\\': c = key[s+1].lower() - if _escapes.has_key(c): + if c in _escapes: ret = _escapes[c] s += 2 elif c == "c": @@ -137,7 +137,7 @@ if t == -1: raise KeySpecError( "unterminated \\< starting at char %d of %s"%( - s + 1, repr(key))) + s + 1, repr(key))) ret = key[s+2:t].lower() if ret not in _keynames: raise KeySpecError( @@ -170,13 +170,17 @@ r.extend(k) return r -def compile_keymap(keymap, empty=''): +def compile_keymap(keymap, empty=b''): r = {} for key, value in keymap.items(): - r.setdefault(key[0], {})[key[1:]] = value + if isinstance(key, bytes): + first = key[:1] + else: + first = key[0] + r.setdefault(first, {})[key[1:]] = value for key, value in r.items(): if empty in value: - if len(value) <> 1: + if len(value) != 1: raise KeySpecError( "key definitions for %s clash"%(value.values(),)) else: diff --git a/lib_pypy/pyrepl/module_lister.py b/lib_pypy/pyrepl/module_lister.py --- a/lib_pypy/pyrepl/module_lister.py +++ b/lib_pypy/pyrepl/module_lister.py @@ -45,13 +45,7 @@ def _make_module_list(): import imp suffs = [x[0] for x in imp.get_suffixes() if x[0] != '.pyc'] - def compare(x, y): - c = -cmp(len(x), len(y)) - if c: - return c - else: - return -cmp(x, y) - suffs.sort(compare) + suffs.sort(reverse=True) _packages[''] = list(sys.builtin_module_names) for dir in sys.path: if dir == '': @@ -66,5 +60,5 @@ try: mods = _packages[pack] except KeyError: - raise ImportError, "can't find \"%s\" package"%pack + raise ImportError("can't find \"%s\" package" % pack) return [mod for mod in mods if mod.startswith(stem)] diff --git a/lib_pypy/pyrepl/pygame_console.py b/lib_pypy/pyrepl/pygame_console.py --- a/lib_pypy/pyrepl/pygame_console.py +++ b/lib_pypy/pyrepl/pygame_console.py @@ -130,7 +130,7 @@ s.fill(c, [0, 600 - bmargin, 800, bmargin]) s.fill(c, [800 - rmargin, 0, lmargin, 600]) - def refresh(self, screen, cxy): + def refresh(self, screen, (cx, cy)): self.screen = screen self.pygame_screen.fill(colors.bg, [0, tmargin + self.cur_top + self.scroll, @@ -139,8 +139,8 @@ line_top = self.cur_top width, height = self.fontsize - self.cxy = cxy - cp = self.char_pos(*cxy) + self.cxy = (cx, cy) + cp = self.char_pos(cx, cy) if cp[1] < tmargin: self.scroll = - (cy*self.fh + self.cur_top) self.repaint() @@ -148,7 +148,7 @@ self.scroll += (600 - bmargin) - (cp[1] + self.fh) self.repaint() if self.curs_vis: - self.pygame_screen.blit(self.cursor, self.char_pos(*cxy)) + self.pygame_screen.blit(self.cursor, self.char_pos(cx, cy)) for line in screen: if 0 <= line_top + self.scroll <= (600 - bmargin - tmargin - self.fh): if line: diff --git a/lib_pypy/pyrepl/python_reader.py b/lib_pypy/pyrepl/python_reader.py --- a/lib_pypy/pyrepl/python_reader.py +++ b/lib_pypy/pyrepl/python_reader.py @@ -20,22 +20,23 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # one impressive collections of imports: +from __future__ import print_function +from __future__ import unicode_literals from pyrepl.completing_reader import CompletingReader from pyrepl.historical_reader import HistoricalReader from pyrepl import completing_reader, reader -from pyrepl import copy_code, commands, completer +from pyrepl import commands, completer from pyrepl import module_lister -import new, sys, os, re, code, traceback +import imp, sys, os, re, code, traceback import atexit, warnings + try: - import cPickle as pickle -except ImportError: - import pickle + unicode +except: + unicode = str + try: - import imp imp.find_module("twisted") - from twisted.internet import reactor - from twisted.internet.abstract import FileDescriptor except ImportError: default_interactmethod = "interact" else: @@ -47,13 +48,28 @@ """this function eats warnings, if you were wondering""" pass +if sys.version_info >= (3,0): + def _reraise(cls, val, tb): + __tracebackhide__ = True + assert hasattr(val, '__traceback__') + raise val +else: + exec (""" +def _reraise(cls, val, tb): + __tracebackhide__ = True + raise cls, val, tb +""") + + + + class maybe_accept(commands.Command): def do(self): r = self.reader text = r.get_unicode() try: # ooh, look at the hack: - code = r.compiler("#coding:utf-8\n"+text.encode('utf-8')) + code = r.compiler(text) except (OverflowError, SyntaxError, ValueError): self.finish = 1 else: @@ -67,16 +83,14 @@ import_line_prog = re.compile( "^(?:import|from)\s+(?P[A-Za-z_.0-9]*)\s*$") -def mk_saver(reader): - def saver(reader=reader): - try: - file = open(os.path.expanduser("~/.pythoni.hist"), "w") - except IOError: - pass - else: - pickle.dump(reader.history, file) - file.close() - return saver +def saver(reader=reader): + try: + with open(os.path.expanduser("~/.pythoni.hist"), "wb") as fp: + fp.write(b'\n'.join(item.encode('unicode_escape') + for item in reader.history)) + except IOError as e: + print(e) + pass class PythonicReader(CompletingReader, HistoricalReader): def collect_keymap(self): @@ -97,17 +111,18 @@ else: self.compiler = compiler try: - file = open(os.path.expanduser("~/.pythoni.hist")) + file = open(os.path.expanduser("~/.pythoni.hist"), 'rb') except IOError: - pass + self.history = [] else: try: - self.history = pickle.load(file) + lines = file.readlines() + self.history = [ x.rstrip(b'\n').decode('unicode_escape') for x in lines] except: self.history = [] self.historyi = len(self.history) file.close() - atexit.register(mk_saver(self)) + atexit.register(lambda: saver(self)) for c in [maybe_accept]: self.commands[c.__name__] = c self.commands[c.__name__.replace('_', '-')] = c @@ -172,13 +187,13 @@ def execute(self, text): try: # ooh, look at the hack: - code = self.compile("# coding:utf8\n"+text.encode('utf-8'), - '', 'single') + code = self.compile(text, '', 'single') except (OverflowError, SyntaxError, ValueError): self.showsyntaxerror("") else: self.runcode(code) - sys.stdout.flush() + if sys.stdout and not sys.stdout.closed: + sys.stdout.flush() def interact(self): while 1: @@ -192,7 +207,7 @@ finally: warnings.showwarning = sv except KeyboardInterrupt: - print "KeyboardInterrupt" + print("KeyboardInterrupt") else: if l: self.execute(l) @@ -217,7 +232,7 @@ r = self.reader.handle1(block) except KeyboardInterrupt: self.restore() - print "KeyboardInterrupt" + print("KeyboardInterrupt") self.prepare() else: if self.reader.finished: @@ -253,7 +268,7 @@ if self.exc_info: type, value, tb = self.exc_info self.exc_info = None - raise type, value, tb + _reraise(type, value, tb) def tkinteract(self): """Run a Tk-aware Python interactive session. @@ -368,15 +383,15 @@ encoding = None else: encoding = None # so you get ASCII... - con = UnixConsole(0, 1, None, encoding) + con = UnixConsole(os.dup(0), os.dup(1), None, encoding) if print_banner: - print "Python", sys.version, "on", sys.platform - print 'Type "help", "copyright", "credits" or "license" '\ - 'for more information.' + print("Python", sys.version, "on", sys.platform) + print('Type "help", "copyright", "credits" or "license" '\ + 'for more information.') sys.path.insert(0, os.getcwd()) if clear_main and __name__ != '__main__': - mainmod = new.module('__main__') + mainmod = imp.new_module('__main__') sys.modules['__main__'] = mainmod else: mainmod = sys.modules['__main__'] diff --git a/lib_pypy/pyrepl/reader.py b/lib_pypy/pyrepl/reader.py --- a/lib_pypy/pyrepl/reader.py +++ b/lib_pypy/pyrepl/reader.py @@ -19,64 +19,65 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import types -from pyrepl import unicodedata_ +from __future__ import unicode_literals +import unicodedata from pyrepl import commands from pyrepl import input +try: + unicode +except NameError: + unicode = str + unichr = chr + def _make_unctrl_map(): uc_map = {} - for c in map(chr, range(256)): - if unicodedata_.category(c)[0] <> 'C': - uc_map[c] = c + for i in range(256): + c = unichr(i) + if unicodedata.category(c)[0] != 'C': + uc_map[i] = c for i in range(32): - c = chr(i) - uc_map[c] = u'^' + chr(ord('A') + i - 1) - uc_map['\t'] = ' ' # display TABs as 4 characters - uc_map['\177'] = u'^?' + uc_map[i] = '^' + unichr(ord('A') + i - 1) + uc_map[ord(b'\t')] = ' ' # display TABs as 4 characters + uc_map[ord(b'\177')] = unicode('^?') for i in range(256): - c = chr(i) - if c not in uc_map: - uc_map[c] = u'\\%03o'%i + if i not in uc_map: + uc_map[i] = unicode('\\%03o') % i return uc_map -# disp_str proved to be a bottleneck for large inputs, so it's been -# rewritten in C; it's not required though. -try: - raise ImportError # currently it's borked by the unicode support - from _pyrepl_utils import disp_str, init_unctrl_map +def _my_unctrl(c, u=_make_unctrl_map()): + if c in u: + return u[c] + else: + if unicodedata.category(c).startswith('C'): + return br'\u%04x' % ord(c) + else: + return c - init_unctrl_map(_make_unctrl_map()) - del init_unctrl_map -except ImportError: - def _my_unctrl(c, u=_make_unctrl_map()): - if c in u: - return u[c] - else: - if unicodedata_.category(c).startswith('C'): - return '\\u%04x'%(ord(c),) - else: - return c +def disp_str(buffer, join=''.join, uc=_my_unctrl): + """ disp_str(buffer:string) -> (string, [int]) - def disp_str(buffer, join=''.join, uc=_my_unctrl): - """ disp_str(buffer:string) -> (string, [int]) + Return the string that should be the printed represenation of + |buffer| and a list detailing where the characters of |buffer| + get used up. E.g.: - Return the string that should be the printed represenation of - |buffer| and a list detailing where the characters of |buffer| - get used up. E.g.: + >>> disp_str(chr(3)) + ('^C', [1, 0]) - >>> disp_str(chr(3)) - ('^C', [1, 0]) + the list always contains 0s or 1s at present; it could conceivably + go higher as and when unicode support happens.""" + # disp_str proved to be a bottleneck for large inputs, + # so it needs to be rewritten in C; it's not required though. + s = [uc(x) for x in buffer] + b = [] # XXX: bytearray + for x in s: + b.append(1) + b.extend([0] * (len(x) - 1)) + return join(s), b - the list always contains 0s or 1s at present; it could conceivably - go higher as and when unicode support happens.""" - s = map(uc, buffer) - return (join(s), - map(ord, join(map(lambda x:'\001'+(len(x)-1)*'\000', s)))) - - del _my_unctrl +del _my_unctrl del _make_unctrl_map @@ -86,6 +87,7 @@ SYNTAX_WORD, SYNTAX_SYMBOL] = range(3) + def make_default_syntax_table(): # XXX perhaps should use some unicodedata here? st = {} @@ -93,7 +95,7 @@ st[c] = SYNTAX_SYMBOL for c in [a for a in map(unichr, range(256)) if a.isalpha()]: st[c] = SYNTAX_WORD - st[u'\n'] = st[u' '] = SYNTAX_WHITESPACE + st[unicode('\n')] = st[unicode(' ')] = SYNTAX_WHITESPACE return st default_keymap = tuple( @@ -141,7 +143,7 @@ #(r'\M-\n', 'insert-nl'), ('\\\\', 'self-insert')] + \ [(c, 'self-insert') - for c in map(chr, range(32, 127)) if c <> '\\'] + \ + for c in map(chr, range(32, 127)) if c != '\\'] + \ [(c, 'self-insert') for c in map(chr, range(128, 256)) if c.isalpha()] + \ [(r'\', 'up'), @@ -155,12 +157,14 @@ (r'\', 'end-of-line'), # was 'end' (r'\', 'beginning-of-line'), # was 'home' (r'\', 'help'), - (r'\EOF', 'end'), # the entries in the terminfo database for xterms - (r'\EOH', 'home'), # seem to be wrong. this is a less than ideal - # workaround + (r'\EOF', 'end'), # the entries in the terminfo database for xterms + (r'\EOH', 'home'), # seem to be wrong. this is a less than ideal + # workaround ]) -del c # from the listcomps +if 'c' in globals(): # only on python 2.x + del c # from the listcomps + class Reader(object): """The Reader class implements the bare bones of a command reader, @@ -238,9 +242,9 @@ self.commands = {} self.msg = '' for v in vars(commands).values(): - if ( isinstance(v, type) - and issubclass(v, commands.Command) - and v.__name__[0].islower() ): + if (isinstance(v, type) + and issubclass(v, commands.Command) + and v.__name__[0].islower()): self.commands[v.__name__] = v self.commands[v.__name__.replace('_', '-')] = v self.syntax_table = make_default_syntax_table() @@ -281,18 +285,18 @@ p -= ll + 1 prompt, lp = self.process_prompt(prompt) l, l2 = disp_str(line) - wrapcount = (len(l) + lp) / w + wrapcount = (len(l) + lp) // w if wrapcount == 0: screen.append(prompt + l) - screeninfo.append((lp, l2+[1])) + screeninfo.append((lp, l2 + [1])) else: - screen.append(prompt + l[:w-lp] + "\\") - screeninfo.append((lp, l2[:w-lp])) - for i in range(-lp + w, -lp + wrapcount*w, w): - screen.append(l[i:i+w] + "\\") + screen.append(prompt + l[:w - lp] + "\\") + screeninfo.append((lp, l2[:w - lp])) + for i in range(-lp + w, -lp + wrapcount * w, w): + screen.append(l[i:i + w] + "\\") screeninfo.append((0, l2[i:i + w])) - screen.append(l[wrapcount*w - lp:]) - screeninfo.append((0, l2[wrapcount*w - lp:]+[1])) + screen.append(l[wrapcount * w - lp:]) + screeninfo.append((0, l2[wrapcount * w - lp:] + [1])) self.screeninfo = screeninfo self.cxy = self.pos2xy(self.pos) if self.msg and self.msg_at_bottom: @@ -320,9 +324,9 @@ if e == -1: break # Found start and end brackets, subtract from string length - l = l - (e-s+1) - out_prompt += prompt[pos:s] + prompt[s+1:e] - pos = e+1 + l = l - (e - s + 1) + out_prompt += prompt[pos:s] + prompt[s + 1:e] + pos = e + 1 out_prompt += prompt[pos:] return out_prompt, l @@ -337,7 +341,7 @@ st = self.syntax_table b = self.buffer p -= 1 - while p >= 0 and st.get(b[p], SYNTAX_WORD) <> SYNTAX_WORD: + while p >= 0 and st.get(b[p], SYNTAX_WORD) != SYNTAX_WORD: p -= 1 while p >= 0 and st.get(b[p], SYNTAX_WORD) == SYNTAX_WORD: p -= 1 @@ -353,7 +357,7 @@ p = self.pos st = self.syntax_table b = self.buffer - while p < len(b) and st.get(b[p], SYNTAX_WORD) <> SYNTAX_WORD: + while p < len(b) and st.get(b[p], SYNTAX_WORD) != SYNTAX_WORD: p += 1 while p < len(b) and st.get(b[p], SYNTAX_WORD) == SYNTAX_WORD: p += 1 @@ -369,7 +373,7 @@ p = self.pos b = self.buffer p -= 1 - while p >= 0 and b[p] <> '\n': + while p >= 0 and b[p] != '\n': p -= 1 return p + 1 @@ -381,7 +385,7 @@ if p is None: p = self.pos b = self.buffer - while p < len(b) and b[p] <> '\n': + while p < len(b) and b[p] != '\n': p += 1 return p @@ -398,7 +402,7 @@ """Return what should be in the left-hand margin for line `lineno'.""" if self.arg is not None and cursor_on_line: - return "(arg: %s) "%self.arg + return "(arg: %s) " % self.arg if "\n" in self.buffer: if lineno == 0: res = self.ps2 @@ -511,15 +515,17 @@ # this call sets up self.cxy, so call it first. screen = self.calc_screen() self.console.refresh(screen, self.cxy) - self.dirty = 0 # forgot this for a while (blush) + self.dirty = 0 # forgot this for a while (blush) def do_cmd(self, cmd): #print cmd if isinstance(cmd[0], str): cmd = self.commands.get(cmd[0], - commands.invalid_command)(self, cmd) + commands.invalid_command)(self, *cmd) elif isinstance(cmd[0], type): - cmd = cmd[0](self, cmd) + cmd = cmd[0](self, *cmd) + else: + return # nothing to do cmd.do() @@ -549,9 +555,11 @@ while 1: event = self.console.get_event(block) - if not event: # can only happen if we're not blocking + if not event: # can only happen if we're not blocking return None + translate = True + if event.evt == 'key': self.input_trans.push(event) elif event.evt == 'scroll': @@ -559,9 +567,12 @@ elif event.evt == 'resize': self.refresh() else: - pass + translate = False - cmd = self.input_trans.get() + if translate: + cmd = self.input_trans.get() + else: + cmd = event.evt, event.data if cmd is None: if block: @@ -603,11 +614,12 @@ def get_buffer(self, encoding=None): if encoding is None: encoding = self.console.encoding - return u''.join(self.buffer).encode(self.console.encoding) + return self.get_unicode().encode(encoding) def get_unicode(self): """Return the current buffer as a unicode string.""" - return u''.join(self.buffer) + return unicode('').join(self.buffer) + def test(): from pyrepl.unix_console import UnixConsole @@ -619,5 +631,5 @@ while reader.readline(): pass -if __name__=='__main__': +if __name__ == '__main__': test() 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 @@ -32,6 +32,10 @@ from pyrepl.completing_reader import CompletingReader from pyrepl.unix_console import UnixConsole, _error +try: + unicode +except NameError: + unicode = str ENCODING = sys.getfilesystemencoding() or 'latin1' # XXX review @@ -174,13 +178,15 @@ # ____________________________________________________________ class _ReadlineWrapper(object): - f_in = 0 - f_out = 1 reader = None saved_history_length = -1 startup_hook = None config = ReadlineConfig() + def __init__(self): + self.f_in = os.dup(0) + self.f_ut = os.dup(1) + def get_reader(self): if self.reader is None: console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING) @@ -194,7 +200,7 @@ except _error: return _old_raw_input(prompt) reader.ps1 = prompt - return reader.readline(startup_hook=self.startup_hook) + return reader.readline(reader, startup_hook=self.startup_hook) def multiline_input(self, more_lines, ps1, ps2, returns_unicode=False): """Read an input on possibly multiple lines, asking for more @@ -224,12 +230,14 @@ self.config.completer_delims = dict.fromkeys(string) def get_completer_delims(self): - chars = self.config.completer_delims.keys() + chars = list(self.config.completer_delims.keys()) chars.sort() return ''.join(chars) def _histline(self, line): line = line.rstrip('\n') + if isinstance(line, unicode): + return line # on py3k try: return unicode(line, ENCODING) except UnicodeDecodeError: # bah, silently fall back... @@ -269,7 +277,9 @@ history = self.get_reader().get_trimmed_history(maxlength) f = open(os.path.expanduser(filename), 'w') for entry in history: - if isinstance(entry, unicode): + # if we are on py3k, we don't need to encode strings before + # writing it to a file + if isinstance(entry, unicode) and sys.version_info < (3,): try: entry = entry.encode(ENCODING) except UnicodeEncodeError: # bah, silently fall back... @@ -417,9 +427,14 @@ else: # this is not really what readline.c does. Better than nothing I guess - import __builtin__ - _old_raw_input = __builtin__.raw_input - __builtin__.raw_input = _wrapper.raw_input + if sys.version_info < (3,): + import __builtin__ + _old_raw_input = __builtin__.raw_input + __builtin__.raw_input = _wrapper.raw_input + else: + import builtins + _old_raw_input = builtins.input + builtins.input = _wrapper.raw_input _old_raw_input = None _setup() diff --git a/lib_pypy/pyrepl/simple_interact.py b/lib_pypy/pyrepl/simple_interact.py --- a/lib_pypy/pyrepl/simple_interact.py +++ b/lib_pypy/pyrepl/simple_interact.py @@ -33,15 +33,19 @@ return False return True + def run_multiline_interactive_console(mainmodule=None): import code - if mainmodule is None: - import __main__ as mainmodule + import __main__ + mainmodule = mainmodule or __main__ console = code.InteractiveConsole(mainmodule.__dict__) def more_lines(unicodetext): # ooh, look at the hack: - src = "#coding:utf-8\n"+unicodetext.encode('utf-8') + if sys.version_info < (3,): + src = "#coding:utf-8\n"+unicodetext.encode('utf-8') + else: + src = unicodetext try: code = console.compile(src, '', 'single') except (OverflowError, SyntaxError, ValueError): diff --git a/lib_pypy/pyrepl/trace.py b/lib_pypy/pyrepl/trace.py new file mode 100644 --- /dev/null +++ b/lib_pypy/pyrepl/trace.py @@ -0,0 +1,17 @@ +import os + +trace_filename = os.environ.get("PYREPL_TRACE") + +if trace_filename is not None: + trace_file = open(trace_filename, 'a') +else: + trace_file = None + +def trace(line, *k, **kw): + if trace_file is None: + return + if k or kw: + line = line.format(*k, **kw) + trace_file.write(line+'\n') + trace_file.flush() + diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -22,14 +22,20 @@ import termios, select, os, struct, errno import signal, re, time, sys from fcntl import ioctl -from pyrepl import curses -from pyrepl.fancy_termios import tcgetattr, tcsetattr -from pyrepl.console import Console, Event -from pyrepl import unix_eventqueue +from . import curses +from .fancy_termios import tcgetattr, tcsetattr +from .console import Console, Event +from .unix_eventqueue import EventQueue +from .trace import trace class InvalidTerminal(RuntimeError): pass +try: + unicode +except NameError: + unicode = str + _error = (termios.error, curses.error, InvalidTerminal) # there are arguments for changing this to "refresh" @@ -58,7 +64,7 @@ del r, maybe_add_baudrate -delayprog = re.compile("\\$<([0-9]+)((?:/|\\*){0,2})>") +delayprog = re.compile(b"\\$<([0-9]+)((?:/|\\*){0,2})>") try: poll = select.poll @@ -93,6 +99,7 @@ else: self.output_fd = f_out.fileno() + self.pollob = poll() self.pollob.register(self.input_fd, POLLIN) curses.setupterm(term, self.output_fd) @@ -156,16 +163,15 @@ self.__move = self.__move_short - self.event_queue = unix_eventqueue.EventQueue(self.input_fd) - self.partial_char = '' + self.event_queue = EventQueue(self.input_fd, self.encoding) self.cursor_visible = 1 def change_encoding(self, encoding): self.encoding = encoding - def refresh(self, screen, cxy): + def refresh(self, screen, c_xy): # this function is still too long (over 90 lines) - + cx, cy = c_xy if not self.__gone_tall: while len(self.screen) < min(len(screen), self.height): self.__hide_cursor() @@ -185,20 +191,9 @@ old_offset = offset = self.__offset height = self.height - if 0: - global counter - try: - counter - except NameError: - counter = 0 - self.__write_code(curses.tigetstr("setaf"), counter) - counter += 1 - if counter > 8: - counter = 0 # we make sure the cursor is on the screen, and that we're # using all of the screen if we can - cx, cy = cxy if cy < offset: offset = cy elif cy >= offset + height: @@ -304,6 +299,7 @@ self.__buffer.append((text, 0)) def __write_code(self, fmt, *args): + self.__buffer.append((curses.tparm(fmt, *args), 1)) def __maybe_write_code(self, fmt, *args): @@ -404,23 +400,8 @@ self.event_queue.insert(Event('resize', None)) def push_char(self, char): - self.partial_char += char - try: - c = unicode(self.partial_char, self.encoding) - except UnicodeError as e: - if len(e.args) > 4 and \ - e.args[4] == 'unexpected end of data': - pass - else: - # was: "raise". But it crashes pyrepl, and by extension the - # pypy currently running, in which we are e.g. in the middle - # of some debugging session. Argh. Instead just print an - # error message to stderr and continue running, for now. - self.partial_char = '' - sys.stderr.write('\n%s: %s\n' % (e.__class__.__name__, e)) - else: - self.partial_char = '' - self.event_queue.push(c) + trace('push char {char!r}', char=char) + self.event_queue.push(char) def get_event(self, block=1): while self.event_queue.empty(): @@ -478,7 +459,7 @@ return int(os.environ["LINES"]), int(os.environ["COLUMNS"]) except KeyError: height, width = struct.unpack( - "hhhh", ioctl(self.input_fd, TIOCGWINSZ, "\000"*8))[0:2] + "hhhh", ioctl(self.input_fd, TIOCGWINSZ, b"\000"*8))[0:2] if not height: return 25, 80 return height, width else: @@ -540,7 +521,7 @@ if FIONREAD: def getpending(self): - e = Event('key', '', '') + e = Event('key', '', b'') while not self.event_queue.empty(): e2 = self.event_queue.get() @@ -548,14 +529,15 @@ e.raw += e.raw amount = struct.unpack( - "i", ioctl(self.input_fd, FIONREAD, "\0\0\0\0"))[0] - raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace') - e.data += raw + "i", ioctl(self.input_fd, FIONREAD, b"\0\0\0\0"))[0] + raw = os.read(self.input_fd, amount) + data = unicode(raw, self.encoding, 'replace') + e.data += data e.raw += raw return e else: def getpending(self): - e = Event('key', '', '') + e = Event('key', '', b'') while not self.event_queue.empty(): e2 = self.event_queue.get() @@ -563,8 +545,9 @@ e.raw += e.raw amount = 10000 - raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace') - e.data += raw + raw = os.read(self.input_fd, amount) + data = unicode(raw, self.encoding, 'replace') + e.data += data e.raw += raw return e diff --git a/lib_pypy/pyrepl/unix_eventqueue.py b/lib_pypy/pyrepl/unix_eventqueue.py --- a/lib_pypy/pyrepl/unix_eventqueue.py +++ b/lib_pypy/pyrepl/unix_eventqueue.py @@ -24,8 +24,14 @@ from pyrepl import keymap from pyrepl.console import Event from pyrepl import curses +from .trace import trace from termios import tcgetattr, VERASE import os +try: + unicode +except NameError: + unicode = str + _keynames = { "delete" : "kdch1", @@ -46,41 +52,70 @@ "up" : "kcuu1", } -class EventQueue(object): - def __init__(self, fd): - our_keycodes = {} - for key, tiname in _keynames.items(): - keycode = curses.tigetstr(tiname) - if keycode: - our_keycodes[keycode] = str(key) - if os.isatty(fd): - our_keycodes[tcgetattr(fd)[6][VERASE]] = u'backspace' - self.k = self.ck = keymap.compile_keymap(our_keycodes) +def general_keycodes(): + keycodes = {} + for key, tiname in _keynames.items(): + keycode = curses.tigetstr(tiname) + trace('key {key} tiname {tiname} keycode {keycode!r}', **locals()) + if keycode: + keycodes[keycode] = key + return keycodes + + + +def EventQueue(fd, encoding): + keycodes = general_keycodes() + if os.isatty(fd): + backspace = tcgetattr(fd)[6][VERASE] + keycodes[backspace] = unicode('backspace') + k = keymap.compile_keymap(keycodes) + trace('keymap {k!r}', k=k) + return EncodedQueue(k, encoding) + +class EncodedQueue(object): + def __init__(self, keymap, encoding): + self.k = self.ck = keymap self.events = [] - self.buf = [] + self.buf = bytearray() + self.encoding=encoding + def get(self): if self.events: return self.events.pop(0) else: return None + def empty(self): return not self.events + + def flush_buf(self): + old = self.buf + self.buf = bytearray() + return bytes(old) + def insert(self, event): + trace('added event {event}', event=event) self.events.append(event) + def push(self, char): + self.buf.append(ord(char)) if char in self.k: + if self.k is self.ck: + #sanity check, buffer is empty when a special key comes + assert len(self.buf) == 1 k = self.k[char] + trace('found map {k!r}', k=k) if isinstance(k, dict): - self.buf.append(char) self.k = k else: - self.events.append(Event('key', k, ''.join(self.buf) + char)) - self.buf = [] + self.insert(Event('key', k, self.flush_buf())) self.k = self.ck - elif self.buf: - self.events.extend([Event('key', c, c) for c in self.buf]) - self.buf = [] + + else: + try: + decoded = bytes(self.buf).decode(self.encoding) + except: + return + + self.insert(Event('key', decoded, self.flush_buf())) self.k = self.ck - self.push(char) - else: - self.events.append(Event('key', char, char)) From noreply at buildbot.pypy.org Thu Oct 25 03:46:33 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Thu, 25 Oct 2012 03:46:33 +0200 (CEST) Subject: [pypy-commit] pypy default: Fixed #1301 -- copystrcontents from Constant -> virtual is fully unrolled now Message-ID: <20121025014633.898861C0DBF@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r58412:15b5a4bb248a Date: 2012-10-24 18:46 -0700 http://bitbucket.org/pypy/pypy/changeset/15b5a4bb248a/ Log: Fixed #1301 -- copystrcontents from Constant -> virtual is fully unrolled now diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -4306,14 +4306,7 @@ """ expected = """ [] - p0 = newstr(11) - copystrcontent(s"hello world", p0, 0, 0, 11) - # Eventually this should just return s"hello", but ATM this test is - # just verifying that it doesn't return "\0\0\0\0\0", so being - # slightly underoptimized is ok. - p1 = newstr(5) - copystrcontent(p0, p1, 0, 0, 5) - finish(p1) + finish(s"hello") """ self.optimize_strunicode_loop(ops, expected) @@ -4963,12 +4956,7 @@ """ expected = """ [i1] - p0 = newstr(6) - copystrcontent(s"hello!", p0, 0, 0, 6) - p1 = newstr(12) - copystrcontent(p0, p1, 0, 0, 6) - copystrcontent(s"abc123", p1, 0, 6, 6) - i0 = strgetitem(p1, i1) + i0 = strgetitem(s"hello!abc123", i1) finish(i0) """ self.optimize_strunicode_loop(ops, expected) @@ -4984,10 +4972,7 @@ """ expected = """ [] - p0 = newstr(6) - copystrcontent(s"hello!", p0, 0, 0, 6) - i0 = strgetitem(p0, 0) - finish(i0) + finish(104) """ self.optimize_strunicode_loop(ops, expected) @@ -5067,6 +5052,21 @@ """ self.optimize_strunicode_loop(ops, expected) + def test_str_copy_constant_virtual(self): + ops = """ + [] + p0 = newstr(10) + copystrcontent(s"abcd", p0, 0, 0, 4) + strsetitem(p0, 4, 101) + copystrcontent(s"fghij", p0, 0, 5, 5) + finish(p0) + """ + expected = """ + [] + finish(s"abcdefghij") + """ + self.optimize_strunicode_loop(ops, expected) + def test_call_pure_vstring_const(self): py.test.skip("implement me") ops = """ diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -489,6 +489,7 @@ def optimize_COPYSTRCONTENT(self, op): self._optimize_COPYSTRCONTENT(op, mode_string) + def optimize_COPYUNICODECONTENT(self, op): self._optimize_COPYSTRCONTENT(op, mode_unicode) @@ -507,8 +508,8 @@ if length.is_constant() and length.box.getint() == 0: return - elif (src.is_virtual() and dst.is_virtual() and srcstart.is_constant() and - dststart.is_constant() and length.is_constant()): + elif ((src.is_virtual() or src.is_constant()) and dst.is_virtual() and + srcstart.is_constant() and dststart.is_constant() and length.is_constant()): src_start = srcstart.force_box(self).getint() dst_start = dststart.force_box(self).getint() From noreply at buildbot.pypy.org Thu Oct 25 04:38:45 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Thu, 25 Oct 2012 04:38:45 +0200 (CEST) Subject: [pypy-commit] pypy default: fix jit translation, don't lookinside this function until ptradd works with things besides ccharp Message-ID: <20121025023845.EFB071C0F47@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r58413:88158af0627f Date: 2012-10-24 19:38 -0700 http://bitbucket.org/pypy/pypy/changeset/88158af0627f/ Log: fix jit translation, don't lookinside this function until ptradd works with things besides ccharp 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 @@ -9,6 +9,7 @@ from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.stdtypedef import SMM, StdTypeDef from pypy.objspace.std.register_all import register_all +from pypy.rlib import jit from pypy.rlib.rarithmetic import ovfcheck, widen from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.objectmodel import specialize, keepalive_until_here @@ -466,6 +467,7 @@ self.setlen(0) self.fromsequence(w_lst) + @jit.dont_look_inside def delslice__Array_ANY_ANY(space, self, w_i, w_j): i = space.int_w(w_i) if i < 0: @@ -495,13 +497,13 @@ rffi.c_memcpy( rffi.cast(rffi.VOIDP, rffi.ptradd(self.buffer, i)), rffi.cast(rffi.VOIDP, rffi.ptradd(oldbuffer, j)), - (self.len - j) * mytype.bytes) + (self.len - j) * mytype.bytes + ) self.len -= j - i self.allocated = self.len if oldbuffer: lltype.free(oldbuffer, flavor='raw') - # Add and mul methods def add__Array_Array(space, self, other): From noreply at buildbot.pypy.org Thu Oct 25 04:38:47 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Thu, 25 Oct 2012 04:38:47 +0200 (CEST) Subject: [pypy-commit] pypy default: explanatory comment Message-ID: <20121025023847.23AD11C0F47@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r58414:f7a2f8b77652 Date: 2012-10-24 19:38 -0700 http://bitbucket.org/pypy/pypy/changeset/f7a2f8b77652/ Log: explanatory comment 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 @@ -467,6 +467,8 @@ self.setlen(0) self.fromsequence(w_lst) + # We can't look into this function until ptradd works with things (in the + # JIT) other than rffi.CCHARP @jit.dont_look_inside def delslice__Array_ANY_ANY(space, self, w_i, w_j): i = space.int_w(w_i) From noreply at buildbot.pypy.org Thu Oct 25 08:27:04 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 25 Oct 2012 08:27:04 +0200 (CEST) Subject: [pypy-commit] pypy py3k: a couple more encoding related failures Message-ID: <20121025062704.85F781C000C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58415:1df7698eebfd Date: 2012-10-24 23:19 -0700 http://bitbucket.org/pypy/pypy/changeset/1df7698eebfd/ Log: a couple more encoding related failures 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 @@ -490,6 +490,11 @@ def test_bytes_compile(self): code = b"# -*- coding: utf-8 -*-\npass\n" compile(code, "tmp", "exec") + c = compile(b"# coding: latin1\nfoo = 'caf\xe9'\n", "", "exec") + ns = {} + exec(c, ns) + assert ns['foo'] == 'café' + assert eval(b"# coding: latin1\n'caf\xe9'\n") == 'café' def test_recompile_ast(self): import _ast From noreply at buildbot.pypy.org Thu Oct 25 12:56:20 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 25 Oct 2012 12:56:20 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: slow progress on changing all APIs yet again Message-ID: <20121025105620.5EE101C069F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58416:856e6f99d11b Date: 2012-10-25 12:55 +0200 http://bitbucket.org/pypy/pypy/changeset/856e6f99d11b/ Log: slow progress on changing all APIs yet again diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -27,19 +27,19 @@ # FIXME: This takes care of the instruction where box is the reuslt # but the bounds produced by all instructions where box is # an argument might also be tighten + xxx v = self.getvalue(box) - b = v.intbound + b = v.getintbound() if b.has_lower and b.has_upper and b.lower == b.upper: v.make_constant(ConstInt(b.lower)) if isinstance(box, AbstractResOp): dispatch_bounds_ops(self, box) - def optimize_GUARD_TRUE(self, op): - self.emit_operation(op) + def postprocess_GUARD_TRUE(self, op): self.propagate_bounds_backward(op.getarg(0)) - optimize_GUARD_FALSE = optimize_GUARD_TRUE - optimize_GUARD_VALUE = optimize_GUARD_TRUE + postprocess_GUARD_FALSE = postprocess_GUARD_TRUE + postprocess_GUARD_VALUE = postprocess_GUARD_TRUE def optimize_INT_XOR(self, op): v1 = self.getvalue(op.getarg(0)) @@ -48,10 +48,10 @@ self.make_constant_int(op, 0) return self.emit_operation(op) - if v1.intbound.known_ge(IntBound(0, 0)) and \ - v2.intbound.known_ge(IntBound(0, 0)): + if v1.getintbound().known_ge(IntBound(0, 0)) and \ + v2.getintbound().known_ge(IntBound(0, 0)): r = self.getvalue(op) - r.intbound.make_ge(IntLowerBound(0)) + r.getintbound().make_ge(IntLowerBound(0)) def optimize_INT_AND(self, op): v1 = self.getvalue(op.getarg(0)) @@ -62,51 +62,50 @@ if v2.is_constant(): val = v2.op.getint() if val >= 0: - r.intbound.intersect(IntBound(0,val)) + r.getintbound().intersect(IntBound(0,val)) elif v1.is_constant(): val = v1.op.getint() if val >= 0: - r.intbound.intersect(IntBound(0,val)) + r.getintbound().intersect(IntBound(0,val)) - def optimize_INT_SUB(self, op): - v1 = self.getvalue(op.getarg(0)) - v2 = self.getvalue(op.getarg(1)) - self.emit_operation(op) - r = self.getvalue(op) - b = v1.intbound.sub_bound(v2.intbound) + def postprocess_INT_SUB(self, op): + v1 = self.getforwarded(op.getarg(0)) + v2 = self.getforwarded(op.getarg(1)) + r = self.getforwarded(op) + b = v1.getintbound().sub_bound(v2.getintbound()) if b.bounded(): - r.intbound.intersect(b) + r.getintbound().intersect(b) def optimize_INT_ADD(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) self.emit_operation(op) r = self.getvalue(op) - b = v1.intbound.add_bound(v2.intbound) + b = v1.getintbound().add_bound(v2.getintbound()) if b.bounded(): - r.intbound.intersect(b) + r.getintbound().intersect(b) def optimize_INT_MUL(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) self.emit_operation(op) r = self.getvalue(op) - b = v1.intbound.mul_bound(v2.intbound) + b = v1.getintbound().mul_bound(v2.getintbound()) if b.bounded(): - r.intbound.intersect(b) + r.getintbound().intersect(b) def optimize_INT_FLOORDIV(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) self.emit_operation(op) r = self.getvalue(op) - r.intbound.intersect(v1.intbound.div_bound(v2.intbound)) + r.getintbound().intersect(v1.getintbound().div_bound(v2.getintbound())) def optimize_INT_MOD(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - known_nonneg = (v1.intbound.known_ge(IntBound(0, 0)) and - v2.intbound.known_ge(IntBound(0, 0))) + known_nonneg = (v1.getintbound().known_ge(IntBound(0, 0)) and + v2.getintbound().known_ge(IntBound(0, 0))) if known_nonneg and v2.is_constant(): val = v2.op.getint() if (val & (val-1)) == 0: @@ -124,18 +123,18 @@ return # give up val = -val if known_nonneg: - r.intbound.make_ge(IntBound(0, 0)) + r.getintbound().make_ge(IntBound(0, 0)) else: - r.intbound.make_gt(IntBound(-val, -val)) - r.intbound.make_lt(IntBound(val, val)) + r.getintbound().make_gt(IntBound(-val, -val)) + r.getintbound().make_lt(IntBound(val, val)) def optimize_INT_LSHIFT(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) self.emit_operation(op) r = self.getvalue(op) - b = v1.intbound.lshift_bound(v2.intbound) - r.intbound.intersect(b) + b = v1.getintbound().lshift_bound(v2.getintbound()) + r.getintbound().intersect(b) # intbound.lshift_bound checks for an overflow and if the # lshift can be proven not to overflow sets b.has_upper and # b.has_lower @@ -147,14 +146,14 @@ def optimize_INT_RSHIFT(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - b = v1.intbound.rshift_bound(v2.intbound) + b = v1.getintbound().rshift_bound(v2.getintbound()) if b.has_lower and b.has_upper and b.lower == b.upper: # constant result (likely 0, for rshifts that kill all bits) self.make_constant_int(op, b.lower) else: self.emit_operation(op) r = self.getvalue(op) - r.intbound.intersect(b) + r.getintbound().intersect(b) def optimize_GUARD_NO_OVERFLOW(self, op): lastop = self.last_emitted_operation @@ -199,7 +198,7 @@ def optimize_INT_ADD_OVF(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - resbound = v1.intbound.add_bound(v2.intbound) + resbound = v1.getintbound().add_bound(v2.getintbound()) if resbound.bounded(): # Transform into INT_ADD. The following guard will be killed # by optimize_GUARD_NO_OVERFLOW; if we see instead an @@ -207,34 +206,34 @@ op = self.optimizer.copy_and_change(op, rop.INT_ADD) self.emit_operation(op) # emit the op r = self.getvalue(op) - r.intbound.intersect(resbound) + r.getintbound().intersect(resbound) def optimize_INT_SUB_OVF(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - resbound = v1.intbound.sub_bound(v2.intbound) + resbound = v1.getintbound().sub_bound(v2.getintbound()) if resbound.bounded(): op = self.optimizer.copy_and_change(op, rop.INT_SUB) self.emit_operation(op) # emit the op r = self.getvalue(op) - r.intbound.intersect(resbound) + r.getintbound().intersect(resbound) def optimize_INT_MUL_OVF(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - resbound = v1.intbound.mul_bound(v2.intbound) + resbound = v1.getintbound().mul_bound(v2.getintbound()) if resbound.bounded(): op = self.optimizer.copy_and_change(op, rop.INT_MUL) self.emit_operation(op) r = self.getvalue(op) - r.intbound.intersect(resbound) + r.getintbound().intersect(resbound) def optimize_INT_LT(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - if v1.intbound.known_lt(v2.intbound): + if v1.getintbound().known_lt(v2.getintbound()): self.make_constant_int(op, 1) - elif v1.intbound.known_ge(v2.intbound) or v1 is v2: + elif v1.getintbound().known_ge(v2.getintbound()) or v1 is v2: self.make_constant_int(op, 0) else: self.emit_operation(op) @@ -242,9 +241,9 @@ def optimize_INT_GT(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - if v1.intbound.known_gt(v2.intbound): + if v1.getintbound().known_gt(v2.getintbound()): self.make_constant_int(op, 1) - elif v1.intbound.known_le(v2.intbound) or v1 is v2: + elif v1.getintbound().known_le(v2.getintbound()) or v1 is v2: self.make_constant_int(op, 0) else: self.emit_operation(op) @@ -252,9 +251,9 @@ def optimize_INT_LE(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - if v1.intbound.known_le(v2.intbound) or v1 is v2: + if v1.getintbound().known_le(v2.getintbound()) or v1 is v2: self.make_constant_int(op, 1) - elif v1.intbound.known_gt(v2.intbound): + elif v1.getintbound().known_gt(v2.getintbound()): self.make_constant_int(op, 0) else: self.emit_operation(op) @@ -262,9 +261,9 @@ def optimize_INT_GE(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - if v1.intbound.known_ge(v2.intbound) or v1 is v2: + if v1.getintbound().known_ge(v2.getintbound()) or v1 is v2: self.make_constant_int(op, 1) - elif v1.intbound.known_lt(v2.intbound): + elif v1.getintbound().known_lt(v2.getintbound()): self.make_constant_int(op, 0) else: self.emit_operation(op) @@ -272,9 +271,9 @@ def optimize_INT_EQ(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - if v1.intbound.known_gt(v2.intbound): + if v1.getintbound().known_gt(v2.getintbound()): self.make_constant_int(op, 0) - elif v1.intbound.known_lt(v2.intbound): + elif v1.getintbound().known_lt(v2.getintbound()): self.make_constant_int(op, 0) elif v1 is v2: self.make_constant_int(op, 1) @@ -284,9 +283,9 @@ def optimize_INT_NE(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - if v1.intbound.known_gt(v2.intbound): + if v1.getintbound().known_gt(v2.getintbound()): self.make_constant_int(op, 1) - elif v1.intbound.known_lt(v2.intbound): + elif v1.getintbound().known_lt(v2.getintbound()): self.make_constant_int(op, 1) elif v1 is v2: self.make_constant_int(op, 0) @@ -298,50 +297,50 @@ array = self.getvalue(op.getarg(0)) result = self.getvalue(op) array.make_len_gt(MODE_ARRAY, op.getdescr(), -1) - array.lenbound.bound.intersect(result.intbound) - result.intbound = array.lenbound.bound + array.lenbound.bound.intersect(result.getintbound()) + result.setintbound(array.lenbound.bound) def optimize_STRLEN(self, op): self.emit_operation(op) array = self.getvalue(op.getarg(0)) result = self.getvalue(op) array.make_len_gt(MODE_STR, op.getdescr(), -1) - array.lenbound.bound.intersect(result.intbound) - result.intbound = array.lenbound.bound + array.lenbound.bound.intersect(result.getintbound()) + result.setintbound(array.lenbound.bound) def optimize_UNICODELEN(self, op): self.emit_operation(op) array = self.getvalue(op.getarg(0)) result = self.getvalue(op) array.make_len_gt(MODE_UNICODE, op.getdescr(), -1) - array.lenbound.bound.intersect(result.intbound) - result.intbound = array.lenbound.bound + array.lenbound.bound.intersect(result.getintbound()) + result.setintbound(array.lenbound.bound) def optimize_STRGETITEM(self, op): self.emit_operation(op) v1 = self.getvalue(op) - v1.intbound.make_ge(IntLowerBound(0)) - v1.intbound.make_lt(IntUpperBound(256)) + v1.getintbound().make_ge(IntLowerBound(0)) + v1.getintbound().make_lt(IntUpperBound(256)) def optimize_UNICODEGETITEM(self, op): self.emit_operation(op) v1 = self.getvalue(op) - v1.intbound.make_ge(IntLowerBound(0)) + v1.getintbound().make_ge(IntLowerBound(0)) def make_int_lt(self, box1, box2): v1 = self.getvalue(box1) v2 = self.getvalue(box2) - if v1.intbound.make_lt(v2.intbound): + if v1.getintbound().make_lt(v2.getintbound()): self.propagate_bounds_backward(box1) - if v2.intbound.make_gt(v1.intbound): + if v2.getintbound().make_gt(v1.getintbound()): self.propagate_bounds_backward(box2) def make_int_le(self, box1, box2): v1 = self.getvalue(box1) v2 = self.getvalue(box2) - if v1.intbound.make_le(v2.intbound): + if v1.getintbound().make_le(v2.getintbound()): self.propagate_bounds_backward(box1) - if v2.intbound.make_ge(v1.intbound): + if v2.getintbound().make_ge(v1.getintbound()): self.propagate_bounds_backward(box2) def make_int_gt(self, box1, box2): @@ -388,9 +387,9 @@ if r.op.same_constant(CONST_1): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - if v1.intbound.intersect(v2.intbound): + if v1.getintbound().intersect(v2.getintbound()): self.propagate_bounds_backward(op.getarg(0)) - if v2.intbound.intersect(v1.intbound): + if v2.getintbound().intersect(v1.getintbound()): self.propagate_bounds_backward(op.getarg(1)) def propagate_bounds_INT_NE(self, op): @@ -399,9 +398,9 @@ if r.op.same_constant(CONST_0): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) - if v1.intbound.intersect(v2.intbound): + if v1.getintbound().intersect(v2.getintbound()): self.propagate_bounds_backward(op.getarg(0)) - if v2.intbound.intersect(v1.intbound): + if v2.getintbound().intersect(v1.getintbound()): self.propagate_bounds_backward(op.getarg(1)) def propagate_bounds_INT_IS_TRUE(self, op): @@ -409,8 +408,8 @@ if r.is_constant(): if r.op.same_constant(CONST_1): v1 = self.getvalue(op.getarg(0)) - if v1.intbound.known_ge(IntBound(0, 0)): - v1.intbound.make_gt(IntBound(0, 0)) + if v1.getintbound().known_ge(IntBound(0, 0)): + v1.getintbound().make_gt(IntBound(0, 0)) self.propagate_bounds_backward(op.getarg(0)) def propagate_bounds_INT_IS_ZERO(self, op): @@ -421,49 +420,49 @@ # Clever hack, we can't use self.make_constant_int yet because # the args aren't in the values dictionary yet so it runs into # an assert, this is a clever way of expressing the same thing. - v1.intbound.make_ge(IntBound(0, 0)) - v1.intbound.make_lt(IntBound(1, 1)) + v1.getintbound().make_ge(IntBound(0, 0)) + v1.getintbound().make_lt(IntBound(1, 1)) self.propagate_bounds_backward(op.getarg(0)) def propagate_bounds_INT_ADD(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) r = self.getvalue(op) - b = r.intbound.sub_bound(v2.intbound) - if v1.intbound.intersect(b): + b = r.getintbound().sub_bound(v2.getintbound()) + if v1.getintbound().intersect(b): self.propagate_bounds_backward(op.getarg(0)) - b = r.intbound.sub_bound(v1.intbound) - if v2.intbound.intersect(b): + b = r.getintbound().sub_bound(v1.getintbound()) + if v2.getintbound().intersect(b): self.propagate_bounds_backward(op.getarg(1)) def propagate_bounds_INT_SUB(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) r = self.getvalue(op) - b = r.intbound.add_bound(v2.intbound) - if v1.intbound.intersect(b): + b = r.getintbound().add_bound(v2.getintbound()) + if v1.getintbound().intersect(b): self.propagate_bounds_backward(op.getarg(0)) - b = r.intbound.sub_bound(v1.intbound).mul(-1) - if v2.intbound.intersect(b): + b = r.getintbound().sub_bound(v1.getintbound()).mul(-1) + if v2.getintbound().intersect(b): self.propagate_bounds_backward(op.getarg(1)) def propagate_bounds_INT_MUL(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) r = self.getvalue(op) - b = r.intbound.div_bound(v2.intbound) - if v1.intbound.intersect(b): + b = r.getintbound().div_bound(v2.getintbound()) + if v1.getintbound().intersect(b): self.propagate_bounds_backward(op.getarg(0)) - b = r.intbound.div_bound(v1.intbound) - if v2.intbound.intersect(b): + b = r.getintbound().div_bound(v1.getintbound()) + if v2.getintbound().intersect(b): self.propagate_bounds_backward(op.getarg(1)) def propagate_bounds_INT_LSHIFT(self, op): v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) r = self.getvalue(op) - b = r.intbound.rshift_bound(v2.intbound) - if v1.intbound.intersect(b): + b = r.getintbound().rshift_bound(v2.getintbound()) + if v1.getintbound().intersect(b): self.propagate_bounds_backward(op.getarg(0)) propagate_bounds_INT_ADD_OVF = propagate_bounds_INT_ADD diff --git a/pypy/jit/metainterp/optimizeopt/intutils.py b/pypy/jit/metainterp/optimizeopt/intutils.py --- a/pypy/jit/metainterp/optimizeopt/intutils.py +++ b/pypy/jit/metainterp/optimizeopt/intutils.py @@ -248,7 +248,14 @@ guards.append(op) op = ResOperation(rop.GUARD_TRUE, [res], None) guards.append(op) - + +class ConstantIntBound(IntBound): + has_upper = True + has_lower = True + + def __init__(self, v): + self.upper = v + self.lower = v class IntUpperBound(IntBound): def __init__(self, upper): diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -297,6 +297,15 @@ self.last_emitted_operation = op return op + def postprocess_op(self, op): + name = 'postprocess_' + opname[op.getopnum()] + next_func = getattr(self, name, self.postprocess_default) + if next_func is not None: + next_func(op) + + def postprocess_default(self, op): + pass + # FIXME: Move some of these here? def getforwarded(self, op): return self.optimizer.getforwarded(op) @@ -434,7 +443,11 @@ return op value = op._forwarded if value is None: - value = op.make_forwarded_copy() + # we only need to make a new copy if the old one is immutable + if op.is_mutable: + value = op + else: + value = op.make_forwarded_copy() else: if value._forwarded: while value._forwarded: @@ -531,12 +544,15 @@ i = 0 while i < len(self.loop.operations): op = self.loop.operations[i] + orig_op = op for opt in self.optimizations: op = opt.optimize_operation(op) if op is None: break else: self.emit_operation(op) + for opt in self.optimizations: + opt.postprocess_op(orig_op) i += 1 self.loop.operations = self.get_newoperations() self.loop.quasi_immutable_deps = self.quasi_immutable_deps diff --git a/pypy/jit/metainterp/optimizeopt/pure.py b/pypy/jit/metainterp/optimizeopt/pure.py --- a/pypy/jit/metainterp/optimizeopt/pure.py +++ b/pypy/jit/metainterp/optimizeopt/pure.py @@ -47,7 +47,7 @@ self.remember_emitting_pure(op) # otherwise, the operation remains - if op.returns_bool_result(): + if newop.returns_bool_result(): newop.is_bool_box = True if nextop: self.emit_operation(nextop) diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -89,15 +89,15 @@ self.emit_operation(op) def optimize_INT_SUB(self, op): - v2 = self.getvalue(op.getarg(1)) - if v2.is_constant() and v2.op.getint() == 0: + v2 = self.getforwarded(op.getarg(1)) + if v2.is_constant() and v2.getint() == 0: self.replace(op, op.getarg(0)) else: - self.emit_operation(op) # Synthesize the reverse ops for optimize_default to reuse self.pure(op.getarg(0), rop.INT_ADD, op.getarg(1), op) self.pure(op.getarg(0), rop.INT_ADD, op, op.getarg(1)) self.pure(op.getarg(1), rop.INT_SUB, op.getarg(0), op) + return op def optimize_INT_ADD(self, op): arg1 = op.getarg(0) @@ -193,8 +193,9 @@ self.pure(op.getarg(0), rop.FLOAT_NEG, op) def optimize_guard(self, op, constbox, emit_operation=True): - value = self.getvalue(op.getarg(0)) + value = self.getforwarded(op.getarg(0)) if value.is_constant(): + xxx box = value.op assert isinstance(box, Const) if not box.same_constant(constbox): @@ -202,11 +203,17 @@ 'always fail') return if emit_operation: - self.emit_operation(op) - value = self.getvalue(op.getarg(0)) # might have been forwarded + return self.getforwarded(op) + + def postprocess_guard(self, op): + value = self.getforwarded(op.getarg(0)) value.make_constant(constbox) self.optimizer.turned_constant(value) + def postprocess_op(self, op): + if op.is_guard(): + self.postprocess_guard(op) + def optimize_GUARD_ISNULL(self, op): value = self.getvalue(op.getarg(0)) if value.is_null(): @@ -227,12 +234,12 @@ value.make_nonnull(op, pos) def optimize_GUARD_VALUE(self, op): - value = self.getvalue(op.getarg(0)) - if value.last_guard: + value = self.getforwarded(op.getarg(0)) + if value.getlastguard(): # there already has been a guard_nonnull or guard_class or # guard_nonnull_class on this value, which is rather silly. # replace the original guard with a guard_value - old_guard_op = value.last_guard + old_guard_op = value.getlastguard() if old_guard_op.getopnum() != rop.GUARD_NONNULL: # This is only safe if the class of the guard_value matches the # class of the guard_*_class, otherwise the intermediate ops might diff --git a/pypy/jit/metainterp/optimizeopt/simplify.py b/pypy/jit/metainterp/optimizeopt/simplify.py --- a/pypy/jit/metainterp/optimizeopt/simplify.py +++ b/pypy/jit/metainterp/optimizeopt/simplify.py @@ -43,7 +43,7 @@ xxx return self.optimize_JUMP(op.copy_and_change(rop.JUMP)) self.last_label_descr = op.getdescr() - self.emit_operation(op) + return op def optimize_JUMP(self, op): if not self.unroll: diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -3,10 +3,18 @@ """ from pypy.tool.sourcetools import func_with_new_name -from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable, rop +from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable, rop,\ + INT, ConstInt +from pypy.jit.metainterp.optimizeopt.intutils import ImmutableIntUnbounded,\ + ConstantIntBound + +class __extend__(ConstInt): + def getintbound(self): + return ConstantIntBound(self.getint()) def create_mutable_subclasses(): def addattr(cls, attr, default_value=None): + cls.attributes_to_copy.append('_' + attr) def getter(self): return getattr(self, '_' + attr) def setter(self, value): @@ -15,17 +23,35 @@ setattr(cls, 'get' + attr, func_with_new_name(getter, 'get' + attr)) setattr(cls, 'set' + attr, func_with_new_name(setter, 'set' + attr)) + def make_new_copy_function(cls, paren_cls): + def _copy_extra_attrs(self, new): + paren_cls._copy_extra_attrs(self, new) + for attr in cls.attributes_to_copy: + setattr(new, getattr(self, attr)) + cls._copy_extra_attrs = _copy_extra_attrs + + imm_int_unbound = ImmutableIntUnbounded() for i, cls in enumerate(opclasses): if cls is None: Mutable = None else: class Mutable(cls): is_mutable = True + attributes_to_copy = [] if cls.is_guard() or cls.getopnum() == rop.FINISH: addattr(Mutable, 'failargs') if cls.is_guard(): addattr(Mutable, 'descr') # mutable guards have descrs + if cls.type == INT: + # all the integers have bounds + addattr(Mutable, 'intbound', imm_int_unbound) + # for tracking last guard and merging GUARD_VALUE with + # GUARD_NONNULL etc + addattr(Mutable, 'lastguard', None) + addattr(Mutable, 'lastguardpos', -1) Mutable.__name__ = cls.__name__ + '_mutable' + if Mutable.attributes_to_copy: + make_new_copy_function(Mutable, cls) assert len(opclasses_mutable) == i opclasses_mutable.append(Mutable) assert len(opclasses) == len(opclasses_mutable) diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -12,14 +12,14 @@ """ -from pypy.rlib.objectmodel import we_are_translated, specialize +from pypy.jit.codewriter import longlong +from pypy.jit.codewriter import heaptracker from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.ootypesystem import ootype -from pypy.jit.codewriter import longlong +from pypy.rlib.rarithmetic import is_valid_int, intmask from pypy.rlib.objectmodel import compute_identity_hash, newlist_hint,\ - compute_unique_id, Symbolic -from pypy.jit.codewriter import heaptracker -from pypy.rlib.rarithmetic import is_valid_int, intmask + compute_unique_id, Symbolic, we_are_translated, specialize +from pypy.tool.pairtype import extendabletype INT = 'i' REF = 'r' @@ -156,6 +156,8 @@ class AbstractValue(object): __slots__ = () + __metaclass__ = extendabletype + def getint(self): """ Get an integer value, if the box supports it, otherwise crash """ @@ -456,8 +458,8 @@ """The central ResOperation class, representing one operation.""" # debug - name = "" - pc = 0 + _name = "" + _pc = 0 _counter = 0 _hash = 0 @@ -566,8 +568,8 @@ sres = '%s = ' % (str(self),) else: sres = '' - if self.name: - prefix = "%s:%s " % (self.name, self.pc) + if self._name: + prefix = "%s:%s " % (self._name, self._pc) if graytext: prefix = "\f%s\f" % prefix else: @@ -650,6 +652,9 @@ return False # for tests return opboolresult[opnum] + def _copy_extra_attrs(self, new): + pass + # some debugging help def __setattr__(self, attr, val): @@ -657,6 +662,17 @@ assert self._forwarded is None object.__setattr__(self, attr, val) + def __getattribute__(self, attr): + if not attr.startswith('_') and attr != 'type': + # methods are fine + if not callable(getattr(self.__class__, attr, None)): + try: + assert self._forwarded is None + except AssertionError: + import pdb + pdb.set_trace() + return object.__getattribute__(self, attr) + # =========== # type mixins # =========== @@ -690,27 +706,27 @@ intval = int(intval) else: assert isinstance(intval, Symbolic) - self.intval = intval + self._intval = intval def getint(self): - return self.intval + return self._intval getresult = getint def getresultrepr(self): - return str(self.intval) + return str(self._intval) @staticmethod def wrap_constant(intval): return ConstInt(intval) def constbox(self): - return ConstInt(self.intval) + return ConstInt(self._intval) def get_result_hash(self): - return make_hashable_int(self.intval) + return make_hashable_int(self._intval) def eq_value(self, other): - return self.intval == other.getint() + return self._intval == other.getint() class ResOpFloat(object): _mixin_ = True @@ -719,13 +735,13 @@ def __init__(self, floatval): #assert isinstance(floatval, float) # XXX not sure between float or float storage - self.floatval = floatval + self._floatval = floatval def getresultrepr(self): - return str(self.floatval) + return str(self._floatval) def getfloatstorage(self): - return self.floatval + return self._floatval getresult = getfloatstorage @staticmethod @@ -733,13 +749,13 @@ return ConstFloat(floatval) def constbox(self): - return ConstFloat(self.floatval) + return ConstFloat(self._floatval) def get_result_hash(self): - return longlong.gethash(self.floatval) + return longlong.gethash(self._floatval) def eq_value(self, other): - return self.floatval == other.getfloatstorage() + return self._floatval == other.getfloatstorage() class ResOpPointer(object): _mixin_ = True @@ -747,10 +763,10 @@ def __init__(self, pval): assert lltype.typeOf(pval) == llmemory.GCREF - self.pval = pval + self._pval = pval def getref_base(self): - return self.pval + return self._pval getresult = getref_base def getref(self, TYPE): @@ -758,11 +774,11 @@ def getresultrepr(self): # XXX what do we want to put in here? - return str(self.pval) + return str(self._pval) def get_result_hash(self): - if self.pval: - return lltype.identityhash(self.pval) + if self._pval: + return lltype.identityhash(self._pval) else: return 0 @@ -771,10 +787,10 @@ return ConstPtr(pval) def constbox(self): - return ConstPtr(self.pval) + return ConstPtr(self._pval) def eq_value(self, other): - return self.pval == other.getref_base() + return self._pval == other.getref_base() # =================== # Top of the hierachy @@ -852,6 +868,10 @@ descr.rd_frame_info_list = self._rd_frame_info_list return descr + def _copy_extra_attrs(self, res): + res.set_rd_frame_info_list(self.get_rd_frame_info_list()) + res.set_rd_snapshot(self.get_rd_snapshot()) + # ============ # arity mixins # ============ @@ -879,12 +899,9 @@ newopnum = self.getopnum() res = create_resop_0(newopnum, self.getresult(), descr or self.getdescr(), mutable=True) - if self.is_guard(): - res.set_rd_frame_info_list(self.get_rd_frame_info_list()) - res.set_rd_snapshot(self.get_rd_snapshot()) - assert not self.is_mutable assert not self._forwarded self._forwarded = res + self._copy_extra_attrs(res) return res def get_key_op(self, opt): @@ -932,12 +949,9 @@ newopnum = self.getopnum() res = create_resop_1(newopnum, self.getresult(), arg0 or self._arg0, descr or self.getdescr(), mutable=True) - if self.is_guard(): - res.set_rd_frame_info_list(self.get_rd_frame_info_list()) - res.set_rd_snapshot(self.get_rd_snapshot()) - assert not self.is_mutable assert not self._forwarded self._forwarded = res + self._copy_extra_attrs(res) return res def get_arg_hash(self): @@ -994,8 +1008,8 @@ res.set_rd_frame_info_list(self.get_rd_frame_info_list()) res.set_rd_snapshot(self.get_rd_snapshot()) assert not self._forwarded - assert not self.is_mutable self._forwarded = res + self._copy_extra_attrs(res) return res def get_arg_hash(self): @@ -1055,10 +1069,9 @@ r = create_resop_3(newopnum, self.getresult(), arg0 or self._arg0, arg1 or self._arg1, arg2 or self._arg2, descr or self.getdescr(), mutable=True) - assert not r.is_guard() assert not self._forwarded - assert not self.is_mutable self._forwarded = r + self._copy_extra_attrs(r) return r def get_arg_hash(self): @@ -1116,9 +1129,8 @@ r = create_resop(newopnum, self.getresult(), newargs or self.getarglist(), descr or self.getdescr(), mutable=True) - assert not r.is_guard() assert not self._forwarded - assert not self.is_mutable + self._copy_extra_attrs(r) self._forwarded = r return r diff --git a/pypy/jit/metainterp/test/test_optmodel.py b/pypy/jit/metainterp/test/test_optmodel.py --- a/pypy/jit/metainterp/test/test_optmodel.py +++ b/pypy/jit/metainterp/test/test_optmodel.py @@ -42,7 +42,7 @@ def test_failargs(): op = rop.create_resop_0(rop.rop.GUARD_NO_OVERFLOW, None) - assert not hasattr(op, 'set_failargs') + assert not hasattr(op, 'setfailargs') op2 = op.make_forwarded_copy() assert op._forwarded is op2 op2.setfailargs([1, 2, 3]) From noreply at buildbot.pypy.org Thu Oct 25 13:24:04 2012 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 25 Oct 2012 13:24:04 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: slow progress Message-ID: <20121025112404.1963C1C069F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58417:3681c767716a Date: 2012-10-25 13:23 +0200 http://bitbucket.org/pypy/pypy/changeset/3681c767716a/ Log: slow progress diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py --- a/pypy/jit/metainterp/optimizeopt/heap.py +++ b/pypy/jit/metainterp/optimizeopt/heap.py @@ -294,14 +294,12 @@ # of virtualref_info and virtualizable_info are not gcptrs. def turned_constant(self, value): - assert value.is_constant() - newvalue = self.getvalue(value.op) - if value is not newvalue: - for cf in self.cached_fields.itervalues(): + value = self.getforwarded(value) + for cf in self.cached_fields.itervalues(): + cf.turned_constant(newvalue, value) + for submap in self.cached_arrayitems.itervalues(): + for cf in submap.itervalues(): cf.turned_constant(newvalue, value) - for submap in self.cached_arrayitems.itervalues(): - for cf in submap.itervalues(): - cf.turned_constant(newvalue, value) def force_lazy_setfield(self, descr, can_cache=True): try: diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -2,9 +2,9 @@ from pypy.jit.metainterp.optimizeopt.optimizer import Optimization, CONST_1,\ CONST_0, MODE_ARRAY, MODE_STR, MODE_UNICODE from pypy.jit.metainterp.optimizeopt.intutils import (IntBound, IntLowerBound, - IntUpperBound) + IntUpperBound, MININT, MAXINT) from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method -from pypy.jit.metainterp.resoperation import rop, ConstInt, AbstractResOp +from pypy.jit.metainterp.resoperation import rop, ConstInt, INT from pypy.jit.metainterp.optimize import InvalidLoop @@ -15,25 +15,25 @@ def new(self): return OptIntBounds() - #def propagate_forward(self, op): - # dispatch_opt(self, op) + def process_inputargs(self, args): + for arg in args: + if arg.type == INT: + self.getforwarded(arg).setintbound(IntBound(MININT, MAXINT)) + + def optimize_operation(self, op): + if op.type == INT: + self.getforwarded(op).setintbound(IntBound(MININT, MAXINT)) + return Optimization.optimize_operation(self, op) - #def opt_default(self, op): - # assert not op.is_ovf() - # self.emit_operation(op) - - - def propagate_bounds_backward(self, box): + def propagate_bounds_backward(self, op): # FIXME: This takes care of the instruction where box is the reuslt # but the bounds produced by all instructions where box is # an argument might also be tighten - xxx - v = self.getvalue(box) + v = self.getforwarded(op) b = v.getintbound() if b.has_lower and b.has_upper and b.lower == b.upper: v.make_constant(ConstInt(b.lower)) - if isinstance(box, AbstractResOp): - dispatch_bounds_ops(self, box) + dispatch_bounds_ops(self, op) def postprocess_GUARD_TRUE(self, op): self.propagate_bounds_backward(op.getarg(0)) @@ -436,9 +436,9 @@ self.propagate_bounds_backward(op.getarg(1)) def propagate_bounds_INT_SUB(self, op): - v1 = self.getvalue(op.getarg(0)) - v2 = self.getvalue(op.getarg(1)) - r = self.getvalue(op) + v1 = self.getforwarded(op.getarg(0)) + v2 = self.getforwarded(op.getarg(1)) + r = self.getforwarded(op) b = r.getintbound().add_bound(v2.getintbound()) if v1.getintbound().intersect(b): self.propagate_bounds_backward(op.getarg(0)) @@ -470,6 +470,4 @@ propagate_bounds_INT_MUL_OVF = propagate_bounds_INT_MUL -#dispatch_opt = make_dispatcher_method(OptIntBounds, 'optimize_', -# default=OptIntBounds.opt_default) -#dispatch_bounds_ops = make_dispatcher_method(OptIntBounds, 'propagate_bounds_') +dispatch_bounds_ops = make_dispatcher_method(OptIntBounds, 'propagate_bounds_') diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -165,18 +165,6 @@ return self.box.same_constant(other.box) return self is other - def make_constant(self, constbox): - """Replace 'self.box' with a Const box.""" - assert isinstance(constbox, Const) - self.op = constbox - self.level = LEVEL_CONSTANT - - if isinstance(constbox, ConstInt): - val = constbox.getint() - self.intbound = IntBound(val, val) - else: - self.intbound = IntUnbounded() - def get_constant_class(self, cpu): xxx level = self.level @@ -286,6 +274,9 @@ # self.last_emitted_operation = op # self.next_optimization.propagate_forward(op) + def process_inputargs(self, args): + pass + def optimize_operation(self, op): name = 'optimize_' + opname[op.getopnum()] next_func = getattr(self, name, self.optimize_default) @@ -497,8 +488,8 @@ def clear_newoperations(self): self._newoperations = [] - def make_constant(self, box, constbox): - self.getvalue(box).make_constant(constbox) + def make_constant(self, op, constbox): + self.getforwarded(op)._forwarded = constbox def make_constant_int(self, box, intvalue): self.getvalue(box).make_constant(ConstInt(intvalue)) @@ -542,6 +533,8 @@ if clear: self.clear_newoperations() i = 0 + for opt in self.optimizations: + opt.process_inputargs(self.loop.inputargs) while i < len(self.loop.operations): op = self.loop.operations[i] orig_op = op @@ -567,6 +560,7 @@ def emit_operation(self, op): if op.returns_bool_result(): + xxxx self.getvalue(op).is_bool_box = True self._emit_operation(op) @@ -584,10 +578,11 @@ self.exception_might_have_happened = True elif op.getopnum() == rop.FINISH: op = self.store_final_boxes_in_guard(op) + assert op is not None self._newoperations.append(op) def store_final_boxes_in_guard(self, op): - return # XXX we disable it for tests + return op # XXX we disable it for tests assert op.getdescr() is None descr = op.invent_descr(self.jitdriver_sd, self.metainterp_sd) op.setdescr(descr) diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -1,11 +1,10 @@ from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntBound -from pypy.jit.metainterp.optimizeopt.optimizer import * -from pypy.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method +from pypy.jit.metainterp.optimizeopt.optimizer import Optimization from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ConstInt, make_hashable_int, - create_resop_2) + create_resop_2, Const) from pypy.rlib.rarithmetic import highest_bit @@ -205,14 +204,19 @@ if emit_operation: return self.getforwarded(op) - def postprocess_guard(self, op): + def postprocess_guard(self, op, constbox): value = self.getforwarded(op.getarg(0)) - value.make_constant(constbox) - self.optimizer.turned_constant(value) + self.optimizer.make_constant(value, constbox) + self.optimizer.turned_constant(op.getarg(0)) - def postprocess_op(self, op): + def postprocess_GUARD_VALUE(self, op): + constbox = op.getarg(1) + assert isinstance(constbox, Const) + self.postprocess_guard(op, constbox) + + def postprocess_default(self, op): if op.is_guard(): - self.postprocess_guard(op) + xxx def optimize_GUARD_ISNULL(self, op): value = self.getvalue(op.getarg(0)) @@ -236,6 +240,7 @@ def optimize_GUARD_VALUE(self, op): value = self.getforwarded(op.getarg(0)) if value.getlastguard(): + xxx # there already has been a guard_nonnull or guard_class or # guard_nonnull_class on this value, which is rather silly. # replace the original guard with a guard_value @@ -271,7 +276,7 @@ emit_operation = True constbox = op.getarg(1) assert isinstance(constbox, Const) - self.optimize_guard(op, constbox, emit_operation=emit_operation) + return self.optimize_guard(op, constbox, emit_operation=emit_operation) def optimize_GUARD_TRUE(self, op): self.optimize_guard(op, CONST_1) diff --git a/pypy/jit/metainterp/optimizeopt/simplify.py b/pypy/jit/metainterp/optimizeopt/simplify.py --- a/pypy/jit/metainterp/optimizeopt/simplify.py +++ b/pypy/jit/metainterp/optimizeopt/simplify.py @@ -46,6 +46,7 @@ return op def optimize_JUMP(self, op): + op = self.getforwarded(op) if not self.unroll: descr = op.getdescr() newdescr = None @@ -60,9 +61,8 @@ assert len(descr.target_tokens) == 1 newdescr = descr.target_tokens[0] if newdescr is not descr or op.opnum != rop.JUMP: - op = self.optimizer.copy_and_change(op, op.opnum, - descr=newdescr) - self.emit_operation(op) + op.setdescr(newdescr) + return op #dispatch_opt = make_dispatcher_method(OptSimplify, 'optimize_', # default=OptSimplify.emit_operation) diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -279,6 +279,8 @@ class Const(AbstractValue): __slots__ = () + _forwarded = None # always + def constbox(self): return self @@ -658,7 +660,7 @@ # some debugging help def __setattr__(self, attr, val): - if attr not in ['_hash', '_str']: + if attr not in ['_hash', '_str', '_forwarded']: assert self._forwarded is None object.__setattr__(self, attr, val) @@ -814,7 +816,7 @@ # backend provides it with cpu.fielddescrof(), cpu.arraydescrof(), # cpu.calldescrof(), and cpu.typedescrof(). self._check_descr(descr) - if self._descr is not None: + if self._descr is not None and not self.is_mutable: raise Exception("descr already set!") self._descr = descr From noreply at buildbot.pypy.org Thu Oct 25 15:07:26 2012 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 25 Oct 2012 15:07:26 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: merge default into branch and a few consequent fixes for translation Message-ID: <20121025130726.CDAB11C1DC2@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r58418:86b72e5b66a3 Date: 2012-10-24 10:03 -0700 http://bitbucket.org/pypy/pypy/changeset/86b72e5b66a3/ Log: merge default into branch and a few consequent fixes for translation diff too long, truncating to 2000 out of 52559 lines diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py --- a/lib_pypy/_ctypes/structure.py +++ b/lib_pypy/_ctypes/structure.py @@ -69,7 +69,8 @@ resnames.append(name) names = resnames self._names = names - self.__dict__.update(fields) + for name, field in fields.items(): + setattr(self, name, field) class Field(object): def __init__(self, name, offset, size, ctype, num, is_bitfield): diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,11 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - libpath = ctypes.util.find_library('db-4.5') - if not libpath: + for c in '56789': + libpath = ctypes.util.find_library('db-4.%s' % c) + if libpath: + break + else: raise ImportError("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' diff --git a/lib_pypy/pypy_test/test_ctypes_support.py b/lib_pypy/pypy_test/test_ctypes_support.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_ctypes_support.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import absolute_import - -import py -from ctypes import * -try: - from ctypes_support import standard_c_lib, get_errno, set_errno -except ImportError: # on top of cpython - from lib_pypy.ctypes_support import standard_c_lib, get_errno, set_errno - - -def test_stdlib_and_errno(): - py.test.skip("this is expected on top of pypy, we need to fix ctypes in a way that is now in 2.6 in order to make this reliable") - write = standard_c_lib.write - write.argtypes = [c_int, c_char_p, c_size_t] - write.restype = c_size_t - # clear errno first - set_errno(0) - assert get_errno() == 0 - write(-345, "abc", 3) - assert get_errno() != 0 - set_errno(0) - assert get_errno() == 0 - -def test_argument_conversion_and_checks(): - strlen = standard_c_lib.strlen - strlen.argtypes = [c_char_p] - strlen.restype = c_size_t - assert strlen("eggs") == 4 - - # Should raise ArgumentError, not segfault - py.test.raises(ArgumentError, strlen, False) - diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -118,7 +118,7 @@ # 1. find the start of the statement from codeop import compile_command end = None - for start in range(lineno, -1, -1): + for start in range(lineno, -1, max(-1, lineno - 10)): if assertion: line = self.lines[start] # the following lines are not fully tested, change with care @@ -135,9 +135,9 @@ compile_command(trysource) except (SyntaxError, OverflowError, ValueError): continue - + # 2. find the end of the statement - for end in range(lineno+1, len(self)+1): + for end in range(lineno+1, min(len(self)+1, lineno + 10)): trysource = self[start:end] if trysource.isparseable(): return start, end diff --git a/py/_io/capture.py b/py/_io/capture.py --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -176,7 +176,7 @@ class StdCaptureFD(Capture): - """ This class allows to capture writes to FD1 and FD2 + """ This class allows capturing writes to FD1 and FD2 and may connect a NULL file to FD0 (and prevent reads from sys.stdin). If any of the 0,1,2 file descriptors is invalid it will not be captured. @@ -267,8 +267,8 @@ return l class StdCapture(Capture): - """ This class allows to capture writes to sys.stdout|stderr "in-memory" - and will raise errors on tries to read from sys.stdin. It only + """ This class allows capturing writes to sys.stdout|stderr "in-memory" + and will raise errors on read attempts from sys.stdin. It only modifies sys.stdout|stderr|stdin attributes and does not touch underlying File Descriptors (use StdCaptureFD for that). """ diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -1,9 +1,8 @@ -import sys import types -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception +from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - format_someobject_error, AnnotatorError) + AnnotatorError, gather_error, ErrorWrapper) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -38,22 +37,9 @@ self.links_followed = {} # set of links that have ever been followed self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + self.blocked_blocks = {} # set of {blocked_block: (graph, index)} + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +63,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +164,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +181,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +192,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +242,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +265,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +283,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +333,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -414,7 +340,7 @@ self.flowin(graph, block) except BlockedInference, e: self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, e.opindex) except Exception, e: # hack for debug tools only if not hasattr(e, '__annotator_block'): @@ -433,25 +359,24 @@ self.pendingblocks[block] = graph assert block in self.annotated self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -471,14 +396,11 @@ for i in range(len(block.operations)): try: self.bookkeeper.enter((graph, block, i)) - self.consider_op(block.operations[i]) + self.consider_op(block, i) finally: self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +484,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +494,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +530,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell @@ -653,7 +572,8 @@ #___ creating the annotations based on operations ______ - def consider_op(self, op): + def consider_op(self, block, opindex): + op = block.operations[opindex] argcells = [self.binding(a) for a in op.args] consider_meth = getattr(self,'consider_op_'+op.opname, None) @@ -668,16 +588,18 @@ # boom -- in the assert of setbinding() for arg in argcells: if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op) + raise BlockedInference(self, op, opindex) try: resultcell = consider_meth(*argcells) - except Exception: + except Exception, e: graph = self.bookkeeper.position_key[0] - raise_nicer_exception(op, str(graph)) + e.args = e.args + ( + ErrorWrapper(gather_error(self, graph, block, opindex)),) + raise if resultcell is None: resultcell = self.noreturnvalue(op) elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op) # the operation cannot succeed + raise BlockedInference(self, op, opindex) # the operation cannot succeed assert isinstance(resultcell, annmodel.SomeObject) assert isinstance(op.result, Variable) self.setbinding(op.result, resultcell) # bind resultcell to op.result @@ -728,13 +650,14 @@ """This exception signals the type inference engine that the situation is currently blocked, and that it should try to progress elsewhere.""" - def __init__(self, annotator, op): + def __init__(self, annotator, op, opindex): self.annotator = annotator try: self.break_at = annotator.bookkeeper.position_key except AttributeError: self.break_at = None self.op = op + self.opindex = opindex def __repr__(self): if not self.break_at: diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,32 +29,23 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', - 'truediv', 'floordiv', 'divmod', 'pow', + 'truediv', 'floordiv', 'divmod', 'and_', 'or_', 'xor', 'lshift', 'rshift', 'getitem', 'setitem', 'delitem', 'getitem_idx', 'getitem_key', 'getitem_idx_key', 'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv', 'inplace_floordiv', 'inplace_div', - 'inplace_mod', 'inplace_pow', + 'inplace_mod', 'inplace_lshift', 'inplace_rshift', 'inplace_and', 'inplace_or', 'inplace_xor', 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'is_', 'cmp', 'coerce', ] +[opname+'_ovf' for opname in - """add sub mul floordiv div mod pow lshift + """add sub mul floordiv div mod lshift """.split() ]) @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -102,7 +65,6 @@ def inplace_floordiv((obj1, obj2)): return pair(obj1, obj2).floordiv() def inplace_div((obj1, obj2)): return pair(obj1, obj2).div() def inplace_mod((obj1, obj2)): return pair(obj1, obj2).mod() - def inplace_pow((obj1, obj2)): return pair(obj1, obj2).pow(s_None) def inplace_lshift((obj1, obj2)): return pair(obj1, obj2).lshift() def inplace_rshift((obj1, obj2)): return pair(obj1, obj2).rshift() def inplace_and((obj1, obj2)): return pair(obj1, obj2).and_() @@ -238,7 +200,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -315,19 +300,6 @@ return SomeInteger(nonneg=int1.nonneg, knowntype=int1.knowntype) rshift.can_only_throw = [] - def pow((int1, int2), obj3): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - pow.can_only_throw = [ZeroDivisionError] - pow_ovf = _clone(pow, [ZeroDivisionError, OverflowError]) - - def inplace_pow((int1, int2)): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - inplace_pow.can_only_throw = [ZeroDivisionError] - def _compare_helper((int1, int2), opname, operation): r = SomeBool() if int1.is_immutable_constant() and int2.is_immutable_constant(): @@ -514,9 +486,6 @@ div.can_only_throw = [] truediv = div - def pow((flt1, flt2), obj3): - raise NotImplementedError("float power not supported, use math.pow") - # repeat these in order to copy the 'can_only_throw' attribute inplace_div = div inplace_truediv = truediv @@ -564,14 +533,30 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - return SomeObject() + raise UnionError("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): return SomeTuple(items = tup1.items + tup2.items) + def eq(tup1tup2): + tup1tup2.union() + return s_Bool + ne = eq + + def lt((tup1, tup2)): + raise Exception("unsupported: (...) < (...)") + def le((tup1, tup2)): + raise Exception("unsupported: (...) <= (...)") + def gt((tup1, tup2)): + raise Exception("unsupported: (...) > (...)") + def ge((tup1, tup2)): + raise Exception("unsupported: (...) >= (...)") + class __extend__(pairtype(SomeDict, SomeDict)): @@ -723,8 +708,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -764,7 +748,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -778,7 +762,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -806,7 +790,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,13 +10,13 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef from pypy.annotation import description from pypy.annotation.signature import annotationoftype -from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.rlib.objectmodel import r_dict, Symbolic from pypy.tool.algo.unionfind import UnionFind from pypy.rpython.lltypesystem import lltype, llmemory @@ -101,7 +101,7 @@ def consider_list_delitem(self, idx): return self.indexrepr(idx) - + def consider_str_join(self, s): if s.is_constant(): return repr(s.const) @@ -148,7 +148,6 @@ self.descs = {} # map Python objects to their XxxDesc wrappers self.methoddescs = {} # map (funcdesc, classdef) to the MethodDesc self.classdefs = [] # list of all ClassDefs - self.pbctypes = {} self.seen_mutable = {} self.listdefs = {} # map position_keys to ListDefs self.dictdefs = {} # map position_keys to DictDefs @@ -167,9 +166,6 @@ self.stats = Stats(self) - # used in SomeObject.__new__ for keeping debugging info - self._isomeobject_coming_from = identity_dict() - delayed_imports() def count(self, category, *args): @@ -228,7 +224,7 @@ check_no_flags(s_value_or_def.listdef.listitem) elif isinstance(s_value_or_def, SomeDict): check_no_flags(s_value_or_def.dictdef.dictkey) - check_no_flags(s_value_or_def.dictdef.dictvalue) + check_no_flags(s_value_or_def.dictdef.dictvalue) elif isinstance(s_value_or_def, SomeTuple): for s_item in s_value_or_def.items: check_no_flags(s_item) @@ -242,9 +238,9 @@ elif isinstance(s_value_or_def, ListItem): if s_value_or_def in seen: return - seen.add(s_value_or_def) + seen.add(s_value_or_def) check_no_flags(s_value_or_def.s_value) - + for clsdef in self.classdefs: check_no_flags(clsdef) @@ -275,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() @@ -325,8 +320,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -373,14 +366,14 @@ listdef = ListDef(self, s_ImpossibleValue) for e in x: listdef.generalize(self.immutablevalue(e, False)) - result = SomeList(listdef) + result = SomeList(listdef) elif tp is dict or tp is r_dict: if need_const: key = Constant(x) try: return self.immutable_cache[key] except KeyError: - result = SomeDict(DictDef(self, + result = SomeDict(DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict)) @@ -403,7 +396,7 @@ result.const_box = key return result else: - dictdef = DictDef(self, + dictdef = DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict) @@ -445,6 +438,12 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if (x is type(None) or # add cases here if needed + x.__module__ == 'pypy.rpython.lltypesystem.lltype'): + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) 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 @@ -455,20 +454,13 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) - elif hasattr(x, '_freeze_') and x._freeze_(): + result = SomePBC([self.getdesc(x)]) + elif hasattr(x, '_freeze_'): + assert x._freeze_() is True # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method # returns True, the instance is considered immutable and becomes @@ -476,16 +468,18 @@ result = SomePBC([self.getdesc(x)]) elif hasattr(x, '__class__') \ and x.__class__.__module__ != '__builtin__': + if hasattr(x, '_cleanup_'): + x._cleanup_() self.see_mutable(x) result = SomeInstance(self.getuniqueclassdef(x.__class__)) elif x is None: return s_None else: - result = SomeObject() + raise Exception("Don't know how to represent %r" % (x,)) if need_const: result.const = x return result - + def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: @@ -509,8 +503,10 @@ elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) - elif (hasattr(pyobj.im_self, '_freeze_') and - pyobj.im_self._freeze_()): # method of frozen + if hasattr(pyobj.im_self, '_cleanup_'): + pyobj.im_self._cleanup_() + if hasattr(pyobj.im_self, '_freeze_'): # method of frozen + assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc(self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc @@ -529,9 +525,9 @@ name) else: # must be a frozen pre-built constant, but let's check - try: - assert pyobj._freeze_() - except AttributeError: + if hasattr(pyobj, '_freeze_'): + assert pyobj._freeze_() is True + else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: @@ -549,13 +545,9 @@ return True else: return False - + def getfrozen(self, pyobj): - result = description.FrozenDesc(self, pyobj) - cls = result.knowntype - if cls not in self.pbctypes: - self.pbctypes[cls] = True - return result + return description.FrozenDesc(self, pyobj) def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, flags={}): @@ -574,7 +566,7 @@ key = (x.__class__, x) if key in self.seen_mutable: return - clsdef = self.getuniqueclassdef(x.__class__) + clsdef = self.getuniqueclassdef(x.__class__) self.seen_mutable[key] = True self.event('mutable', x) source = InstanceSource(self, x) @@ -594,7 +586,7 @@ except KeyError: access_sets = map[attrname] = UnionFind(description.ClassAttrFamily) return access_sets - + def pbc_getattr(self, pbc, s_attr): assert s_attr.is_constant() attr = s_attr.const @@ -606,7 +598,7 @@ first = descs[0] if len(descs) == 1: return first.s_read_attribute(attr) - + change = first.mergeattrfamilies(descs[1:], attr) attrfamily = first.getattrfamily(attr) @@ -708,7 +700,7 @@ def ondegenerated(self, what, s_value, where=None, called_from_graph=None): self.annotator.ondegenerated(what, s_value, where=where, called_from_graph=called_from_graph) - + def whereami(self): return self.annotator.whereami(self.position_key) diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -150,7 +150,7 @@ def builtin_isinstance(s_obj, s_type, variables=None): - r = SomeBool() + r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,8 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + + if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r @@ -329,10 +323,12 @@ def robjmodel_hlinvoke(s_repr, s_llcallable, *args_s): from pypy.rpython import rmodel - assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr),"hlinvoke expects a constant repr as first argument" - r_func, nimplicitarg = s_repr.const.get_r_implfunc() + from pypy.rpython.error import TyperError - nbargs = len(args_s) + nimplicitarg + assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr), "hlinvoke expects a constant repr as first argument" + r_func, nimplicitarg = s_repr.const.get_r_implfunc() + + nbargs = len(args_s) + nimplicitarg s_sigs = r_func.get_s_signatures((nbargs, (), False, False)) if len(s_sigs) != 1: raise TyperError("cannot hlinvoke callable %r with not uniform" @@ -343,6 +339,7 @@ return lltype_to_annotation(rresult.lowleveltype) + def robjmodel_keepalive_until_here(*args_s): return immutablevalue(None) @@ -410,7 +407,10 @@ BUILTIN_ANALYZERS[unicodedata.decimal] = unicodedata_decimal # xxx # object - just ignore object.__init__ -BUILTIN_ANALYZERS[object.__init__] = object_init +if hasattr(object.__init__, 'im_func'): + BUILTIN_ANALYZERS[object.__init__.im_func] = object_init +else: + BUILTIN_ANALYZERS[object.__init__] = object_init # import BUILTIN_ANALYZERS[__import__] = import_func diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -1,8 +1,7 @@ import types, py from pypy.objspace.flow.model import Constant, FunctionGraph -from pypy.interpreter.pycode import cpython_code_signature -from pypy.interpreter.argument import rawshape -from pypy.interpreter.argument import ArgErr +from pypy.objspace.flow.bytecode import cpython_code_signature +from pypy.objspace.flow.argument import rawshape, ArgErr from pypy.tool.sourcetools import valid_identifier from pypy.tool.pairtype import extendabletype @@ -181,7 +180,7 @@ name = pyobj.func_name if signature is None: if hasattr(pyobj, '_generator_next_method_of_'): - from pypy.interpreter.argument import Signature + from pypy.objspace.flow.argument import Signature signature = Signature(['entry']) # haaaaaack defaults = () else: @@ -247,17 +246,20 @@ defs_s = [] if graph is None: signature = self.signature - defaults = self.defaults + defaults = self.defaults else: signature = graph.signature - defaults = graph.defaults + defaults = graph.defaults if defaults: for x in defaults: - defs_s.append(self.bookkeeper.immutablevalue(x)) + if x is NODEFAULT: + defs_s.append(None) + else: + defs_s.append(self.bookkeeper.immutablevalue(x)) try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: - raise TypeError("signature mismatch: %s() %s" % + raise TypeError("signature mismatch: %s() %s" % (self.name, e.getmsg())) return inputcells diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,8 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype + immutable = False knowntype = object - immutable = False + + def __init__(self): + assert type(self) is not SomeObject def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -105,60 +106,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: - self = new(cls, *args, **kw) - if DEBUG: - try: - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - position_key = bookkeeper.position_key - except AttributeError: - pass - else: - bookkeeper._isomeobject_coming_from[self] = position_key, None + def can_be_none(self): + return True + + def nonnoneify(self): return self - def origin(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] - origin = property(origin) - def caused_by_merge(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] - def set_caused_by_merge(self, nvalue): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return - bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue - caused_by_merge = property(caused_by_merge, set_caused_by_merge) - del set_caused_by_merge +class SomeType(SomeObject): + "Stands for a type. We might not be sure which one it is." + knowntype = type + immutable = True def can_be_none(self): - return True - - def nonnoneify(self): - return self + return False class SomeFloat(SomeObject): "Stands for a float or an integer." @@ -517,6 +486,7 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) @@ -710,14 +680,8 @@ # this is just a performance shortcut if s1 != s2: s1 = pair(s1, s2).union() - if DEBUG: - if s1.caused_by_merge is None and len(somevalues) > 1: - s1.caused_by_merge = somevalues return s1 -def isdegenerated(s_value): - return s_value.__class__ is SomeObject and s_value.knowntype is not type - # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -10,7 +10,6 @@ class BasicAnnotatorPolicy(object): - allow_someobjects = True def event(pol, bookkeeper, what, *args): pass @@ -80,6 +79,3 @@ def specialize__ll_and_arg(pol, *args): from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args) - -class StrictAnnotatorPolicy(AnnotatorPolicy): - allow_someobjects = False diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -3,9 +3,9 @@ from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF -from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF + unionof, SomeUnicodeString, SomeType +from pypy.annotation.listdef import ListDef +from pypy.annotation.dictdef import DictDef _annotation_cache = {} @@ -78,24 +78,18 @@ return SomeString() elif t is unicode: return SomeUnicodeString() - elif t is list: - return SomeList(MOST_GENERAL_LISTDEF) - elif t is dict: - return SomeDict(MOST_GENERAL_DICTDEF) - # can't do tuple elif t is types.NoneType: return s_None elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) - elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes: + elif t is type: + return SomeType() + elif bookkeeper and not hasattr(t, '_freeze_'): classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) else: - o = SomeObject() - if t != object: - o.knowntype = t - return o + raise AssertionError("annotationoftype(%r)" % (t,)) class Sig(object): diff --git a/pypy/annotation/specialize.py b/pypy/annotation/specialize.py --- a/pypy/annotation/specialize.py +++ b/pypy/annotation/specialize.py @@ -6,7 +6,7 @@ from pypy.objspace.flow.model import Block, Link, Variable, SpaceOperation from pypy.objspace.flow.model import Constant, checkgraph from pypy.annotation import model as annmodel -from pypy.interpreter.argument import Signature +from pypy.objspace.flow.argument import Signature def flatten_star_args(funcdesc, args_s): argnames, vararg, kwarg = funcdesc.signature diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -13,7 +13,7 @@ from pypy.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong from pypy.rlib.rarithmetic import r_singlefloat from pypy.rlib import objectmodel -from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.objspace.flow.objspace import FlowObjSpace, FlowingError from pypy.translator.test import snippet @@ -24,7 +24,7 @@ assert isinstance(s_list, annmodel.SomeList) return s_list.listdef.listitem.s_value -def somelist(s_type=annmodel.SomeObject()): +def somelist(s_type): return annmodel.SomeList(ListDef(None, s_type)) def dictkey(s_dict): @@ -35,7 +35,7 @@ assert isinstance(s_dict, annmodel.SomeDict) return s_dict.dictdef.dictvalue.s_value -def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()): +def somedict(s_key, s_value): return annmodel.SomeDict(DictDef(None, s_key, s_value)) @@ -205,15 +205,6 @@ annmodel.SomeInteger() ]) - def test_inheritance2(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet._inheritance_nonrunnable, []) - # result should be exactly: - assert s == annmodel.SomeTuple([ - annmodel.SomeInteger(), - annmodel.SomeObject() - ]) - def test_poor_man_range(self): a = self.RPythonAnnotator() s = a.build_types(snippet.poor_man_range, [int]) @@ -336,9 +327,13 @@ def test_flow_type_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_type_info, [object]) + s = a.build_types(snippet.flow_type_info, [int]) a.simplify() - #a.translator.view() + assert s.knowntype == int + + a = self.RPythonAnnotator() + s = a.build_types(snippet.flow_type_info, [str]) + a.simplify() assert s.knowntype == int def test_flow_type_info_2(self): @@ -351,7 +346,7 @@ def test_flow_usertype_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_usertype_info, [object]) + s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit]) #a.translator.view() assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit) @@ -363,13 +358,6 @@ assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit) - def test_flow_identity_info(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_identity_info, [object, object]) - a.simplify() - #a.translator.view() - assert s == a.bookkeeper.immutablevalue((None, None)) - def test_mergefunctions(self): a = self.RPythonAnnotator() s = a.build_types(snippet.mergefunctions, [int]) @@ -431,11 +419,11 @@ # the annotator (it doesn't check that they operate property, though) for example, methname, s_example in [ ('', 'join', annmodel.SomeString()), - ([], 'append', somelist()), - ([], 'extend', somelist()), - ([], 'reverse', somelist()), - ([], 'insert', somelist()), - ([], 'pop', somelist()), + ([], 'append', somelist(annmodel.s_Int)), + ([], 'extend', somelist(annmodel.s_Int)), + ([], 'reverse', somelist(annmodel.s_Int)), + ([], 'insert', somelist(annmodel.s_Int)), + ([], 'pop', somelist(annmodel.s_Int)), ]: constmeth = getattr(example, methname) s_constmeth = iv(constmeth) @@ -497,12 +485,12 @@ def test_simple_slicing(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_slice, [list]) + s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeList) def test_simple_iter_list(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_iter, [list]) + s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeIterator) def test_simple_iter_next(self): @@ -542,11 +530,6 @@ assert isinstance(dictkey(s), annmodel.SomeInteger) assert isinstance(dictvalue(s), annmodel.SomeInteger) - a = self.RPythonAnnotator() - s = a.build_types(snippet.dict_update, [str]) - assert not isinstance(dictkey(s), annmodel.SomeString) - assert not isinstance(dictvalue(s), annmodel.SomeString) - def test_dict_update_2(self): a = self.RPythonAnnotator() def g(n): @@ -568,7 +551,7 @@ def test_dict_keys2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_keys2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_values(self): a = self.RPythonAnnotator() @@ -578,7 +561,7 @@ def test_dict_values2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_items(self): a = self.RPythonAnnotator() @@ -643,25 +626,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_bltin_code_frame_confusion(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_confusion,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - # annotator confused by original bltin code/frame setup, we just get SomeObject here - assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - - def test_bltin_code_frame_reorg(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_reorg,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - assert isinstance(a.binding(f_flowgraph.getreturnvar()), - annmodel.SomeInteger) - assert isinstance(a.binding(g_flowgraph.getreturnvar()), - annmodel.SomeString) - def test_propagation_of_fresh_instances_through_attrs(self): a = self.RPythonAnnotator() s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int]) @@ -748,14 +712,15 @@ assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc) def test_type_is(self): - class C(object): + class B(object): + pass + class C(B): pass def f(x): - if type(x) is C: - return x - raise Exception - a = self.RPythonAnnotator() - s = a.build_types(f, [object]) + assert type(x) is C + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) def test_ann_assert(self): @@ -793,24 +758,30 @@ return None a = self.RPythonAnnotator() - s = a.build_types(f, [list]) + s = a.build_types(f, [somelist(annmodel.s_Int)]) assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list def test_freeze_protocol(self): class Stuff: - def __init__(self, flag): + def __init__(self): self.called = False - self.flag = flag def _freeze_(self): self.called = True - return self.flag - myobj = Stuff(True) + return True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - myobj = Stuff(False) + + def test_cleanup_protocol(self): + class Stuff: + def __init__(self): + self.called = False + def _cleanup_(self): + self.called = True + myobj = Stuff() a = self.RPythonAnnotator() s = a.build_types(lambda: myobj, []) assert myobj.called @@ -854,7 +825,7 @@ def f(a,b): return bool(a) or bool(b) a = self.RPythonAnnotator() - s = a.build_types(f, [int,list]) + s = a.build_types(f, [int, somelist(annmodel.s_Int)]) assert s.knowntype == bool def test_float(self): @@ -1299,22 +1270,6 @@ assert isinstance(s_item, annmodel.SomeInstance) assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - def test_assert_type_is_list_doesnt_lose_info(self): - class T(object): - pass - def g(l): - assert type(l) is list - return l - def f(): - l = [T()] - return g(l) - a = self.RPythonAnnotator() - s = a.build_types(f, []) - s_item = listitem(s) - assert isinstance(s_item, annmodel.SomeInstance) - assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - - def test_int_str_mul(self): def f(x,a,b): return a*x+x*b @@ -1395,11 +1350,10 @@ except KeyError: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.const = KeyError t.is_type_of = [ev] assert a.binding(et) == t @@ -1412,11 +1366,10 @@ except: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t @@ -1448,11 +1401,10 @@ finally: h() a = self.RPythonAnnotator() - a.build_types(f, [int, list]) + a.build_types(f, [int, somelist(annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) @@ -1474,33 +1426,11 @@ a.build_types(f, []) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_sys_attrs(self): - def f(): - return sys.argv[0] - a = self.RPythonAnnotator() - try: - oldvalue = sys.argv - sys.argv = [] - s = a.build_types(f, []) - finally: - sys.argv = oldvalue - assert s is not None - - def test_pow(self): - def f(n): - n **= 2 - return 2 ** n - a = self.RPythonAnnotator() - s = a.build_types(f, [int]) - # result should be an integer - assert s.knowntype == int - def test_inplace_div(self): def f(n): n /= 2 @@ -1523,7 +1453,6 @@ a = self.RPythonAnnotator() 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)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] def test_is_true_coalesce2(self): def f(a,b,a1,b1,c,d,e): @@ -1532,9 +1461,12 @@ return d,c return e,c a = self.RPythonAnnotator() - s = a.build_types(f, [int, str, float, list, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) - assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] + s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int), + 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_coalesce_sanity(self): def f(a): @@ -1954,16 +1886,7 @@ t = type(x) return issubclass(t, A) - def f(): - x = g(1) - y = g(0) - return x or y - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert s.knowntype == bool - assert not s.is_constant() - a = self.RPythonAnnotator() - # sanity check + a = self.RPythonAnnotator() x = annmodel.SomeInteger() x.const = 1 s = a.build_types(g, [x]) @@ -2383,8 +2306,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int]) - assert s.__class__ == annmodel.SomeObject - assert s.knowntype == type + assert isinstance(s, annmodel.SomeType) def test_annotate_iter_empty_container(self): def f(): @@ -3075,7 +2997,6 @@ v = -maxint return intmask(v * 10) P = policy.AnnotatorPolicy() - P.allow_someobjects = False a = self.RPythonAnnotator(policy=P) s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) @@ -3226,10 +3147,9 @@ x **= y return x ** y a = self.RPythonAnnotator() - s = a.build_types(f, [int, int]) - assert isinstance(s, annmodel.SomeInteger) - a = self.RPythonAnnotator() - py.test.raises(NotImplementedError, a.build_types, f, [float, float]) + py.test.raises(FlowingError, a.build_types, f, [int, int]) + a = self.RPythonAnnotator() + py.test.raises(FlowingError, a.build_types, f, [float, float]) def test_intcmp_bug(self): def g(x, y): @@ -3859,6 +3779,46 @@ a = self.RPythonAnnotator() py.test.raises(Exception, a.build_types, fn, []) + def test_lower_char(self): + def fn(c): + return c.lower() + a = self.RPythonAnnotator() + s = a.build_types(fn, [annmodel.SomeChar()]) + assert s == annmodel.SomeChar() + + def test_isinstance_double_const(self): + class X(object): + def _freeze_(self): + return True + + x = X() + + def f(i): + if i: + x1 = x + else: + x1 = None + print "hello" # this is to force the merge of blocks + return isinstance(x1, X) + + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeBool) + + def test_object_init(self): + class A(object): + pass + + class B(A): + def __init__(self): + A.__init__(self) + + def f(): + B() + + a = self.RPythonAnnotator() + a.build_types(f, []) # assert did not explode + def g(n): return [0,1,2,n] diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -2,20 +2,20 @@ import autopath import py from pypy.annotation.model import * -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF +from pypy.annotation.listdef import ListDef from pypy.rpython.ootypesystem.ootype import ROOT listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) -s1 = SomeObject() +s1 = SomeType() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s1,s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s1, s2, s3, s4, s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -42,7 +42,7 @@ def test_equality(): assert s1 != s2 != s3 != s4 != s5 != s6 - assert s1 == SomeObject() + assert s1 == SomeType() assert s2 == SomeInteger(nonneg=True) assert s3 == SomeInteger(nonneg=False) assert s4 == SomeList(listdef1) @@ -51,19 +51,11 @@ def test_contains(): assert ([(s,t) for s in slist for t in slist if s.contains(t)] == - [(s1,s1), (s1,s2), (s1,s3), (s1,s4), (s1,s6), - (s2,s2), (s2,s6), - (s3,s2), (s3,s3), (s3,s6), - (s4,s4), (s4,s6), - (s6,s6)]) - -def test_union(): - assert ([unionof(s,t) for s in slist for t in slist] == - [s1, s1, s1, s1, s1, - s1, s2, s3, s1, s2, - s1, s3, s3, s1, s3, - s1, s1, s1, s4, s4, - s1, s2, s3, s4, s6]) + [(s1, s1), (s1, s6), + (s2, s2), (s2, s6), + (s3, s2), (s3, s3), (s3, s6), + (s4, s4), (s4, s6), + (s6, s6)]) def test_commonbase_simple(): class A0: @@ -100,9 +92,10 @@ def test_list_contains(): listdef1 = ListDef(None, SomeInteger(nonneg=True)) s1 = SomeList(listdef1) - s2 = SomeList(MOST_GENERAL_LISTDEF) + listdef2 = ListDef(None, SomeInteger(nonneg=False)) + s2 = SomeList(listdef2) assert s1 != s2 - assert s2.contains(s1) + assert not s2.contains(s1) assert s1 != s2 assert not s1.contains(s2) assert s1 != s2 diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -7,7 +7,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -39,14 +39,7 @@ def type(obj, *moreargs): if moreargs: raise Exception, 'type() called with more than one argument' - if obj.is_constant(): - if isinstance(obj, SomeInstance): - r = SomePBC([obj.classdef.classdesc]) - else: - r = immutablevalue(obj.knowntype) - else: - r = SomeObject() - r.knowntype = type + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator @@ -133,9 +126,6 @@ def float(obj): return SomeFloat() - def long(obj): - return SomeObject() # XXX - def delattr(obj, s_attr): if obj.__class__ != SomeObject or obj.knowntype != object: getbookkeeper().warning( @@ -154,18 +144,17 @@ def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it - if s_attr.is_constant() and isinstance(s_attr.const, str): - attr = s_attr.const - s_method = obj.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)) - else: - getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' % - (obj, s_attr)) - return SomeObject() + 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)) + attr = s_attr.const + s_method = obj.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)) getattr.can_only_throw = [] def bind_callables_under(obj, classdef, name): @@ -586,6 +575,12 @@ def method_isupper(chr): return s_Bool + def method_lower(chr): + return chr + + def method_upper(chr): + return chr + class __extend__(SomeIterator): def iter(itr): diff --git a/pypy/bin/reportstaticdata.py b/pypy/bin/reportstaticdata.py --- a/pypy/bin/reportstaticdata.py +++ b/pypy/bin/reportstaticdata.py @@ -2,9 +2,9 @@ """ Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME -Print a report for the static data informations contained in FILENAME +Print a report for the static data information contained in FILENAME -The static data informations are saved in the file staticdata.info when +The static data information is saved in the file staticdata.info when passing --dump_static_data_info to translate.py. Options: diff --git a/pypy/bin/translatorshell.py b/pypy/bin/translatorshell.py --- a/pypy/bin/translatorshell.py +++ b/pypy/bin/translatorshell.py @@ -8,10 +8,10 @@ Example: - t = Translation(func) + t = Translation(func, [int]) # pass the list of args types t.view() # control flow graph From noreply at buildbot.pypy.org Thu Oct 25 15:07:28 2012 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 25 Oct 2012 15:07:28 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: merge default into branch and nudge the annotator; translation works again Message-ID: <20121025130728.19EA51C1DC2@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r58419:e1f77fb74300 Date: 2012-10-25 02:37 -0700 http://bitbucket.org/pypy/pypy/changeset/e1f77fb74300/ Log: merge default into branch and nudge the annotator; translation works again diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -4306,14 +4306,7 @@ """ expected = """ [] - p0 = newstr(11) - copystrcontent(s"hello world", p0, 0, 0, 11) - # Eventually this should just return s"hello", but ATM this test is - # just verifying that it doesn't return "\0\0\0\0\0", so being - # slightly underoptimized is ok. - p1 = newstr(5) - copystrcontent(p0, p1, 0, 0, 5) - finish(p1) + finish(s"hello") """ self.optimize_strunicode_loop(ops, expected) @@ -4963,12 +4956,7 @@ """ expected = """ [i1] - p0 = newstr(6) - copystrcontent(s"hello!", p0, 0, 0, 6) - p1 = newstr(12) - copystrcontent(p0, p1, 0, 0, 6) - copystrcontent(s"abc123", p1, 0, 6, 6) - i0 = strgetitem(p1, i1) + i0 = strgetitem(s"hello!abc123", i1) finish(i0) """ self.optimize_strunicode_loop(ops, expected) @@ -4984,10 +4972,7 @@ """ expected = """ [] - p0 = newstr(6) - copystrcontent(s"hello!", p0, 0, 0, 6) - i0 = strgetitem(p0, 0) - finish(i0) + finish(104) """ self.optimize_strunicode_loop(ops, expected) @@ -5067,6 +5052,21 @@ """ self.optimize_strunicode_loop(ops, expected) + def test_str_copy_constant_virtual(self): + ops = """ + [] + p0 = newstr(10) + copystrcontent(s"abcd", p0, 0, 0, 4) + strsetitem(p0, 4, 101) + copystrcontent(s"fghij", p0, 0, 5, 5) + finish(p0) + """ + expected = """ + [] + finish(s"abcdefghij") + """ + self.optimize_strunicode_loop(ops, expected) + def test_call_pure_vstring_const(self): py.test.skip("implement me") ops = """ diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -489,6 +489,7 @@ def optimize_COPYSTRCONTENT(self, op): self._optimize_COPYSTRCONTENT(op, mode_string) + def optimize_COPYUNICODECONTENT(self, op): self._optimize_COPYSTRCONTENT(op, mode_unicode) @@ -507,8 +508,8 @@ if length.is_constant() and length.box.getint() == 0: return - elif (src.is_virtual() and dst.is_virtual() and srcstart.is_constant() and - dststart.is_constant() and length.is_constant()): + elif ((src.is_virtual() or src.is_constant()) and dst.is_virtual() and + srcstart.is_constant() and dststart.is_constant() and length.is_constant()): src_start = srcstart.force_box(self).getint() dst_start = dststart.force_box(self).getint() 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 @@ -9,6 +9,7 @@ from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.stdtypedef import SMM, StdTypeDef from pypy.objspace.std.register_all import register_all +from pypy.rlib import jit from pypy.rlib.rarithmetic import ovfcheck, widen from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.objectmodel import specialize, keepalive_until_here @@ -466,6 +467,9 @@ self.setlen(0) self.fromsequence(w_lst) + # We can't look into this function until ptradd works with things (in the + # JIT) other than rffi.CCHARP + @jit.dont_look_inside def delslice__Array_ANY_ANY(space, self, w_i, w_j): i = space.int_w(w_i) if i < 0: @@ -495,13 +499,13 @@ rffi.c_memcpy( rffi.cast(rffi.VOIDP, rffi.ptradd(self.buffer, i)), rffi.cast(rffi.VOIDP, rffi.ptradd(oldbuffer, j)), - (self.len - j) * mytype.bytes) + (self.len - j) * mytype.bytes + ) self.len -= j - i self.allocated = self.len if oldbuffer: lltype.free(oldbuffer, flavor='raw') - # Add and mul methods def add__Array_Array(space, self, other): 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 @@ -422,10 +422,9 @@ self.functions = debug.make_sure_not_resized(functions) def is_static(self): - if not isinstance(self.functions[0], CPPFunction): - return self.space.w_False - return self.space.w_True - #self.space.wrap(isinstance(self.functions[0], CPPFunction)) + f = self.functions[0] + assert isinstance(f, CPPMethod) + self.space.wrap(isinstance(f, CPPFunction)) @jit.unroll_safe @unwrap_spec(args_w='args_w') From noreply at buildbot.pypy.org Thu Oct 25 15:07:29 2012 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 25 Oct 2012 15:07:29 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: force return value of bool in is_static Message-ID: <20121025130729.4C32E1C1DC2@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r58420:2512d81cc6f3 Date: 2012-10-25 05:59 -0700 http://bitbucket.org/pypy/pypy/changeset/2512d81cc6f3/ Log: force return value of bool in is_static 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 @@ -424,7 +424,9 @@ def is_static(self): f = self.functions[0] assert isinstance(f, CPPMethod) - self.space.wrap(isinstance(f, CPPFunction)) + if isinstance(f, CPPFunction): + return self.space.w_True + return self.space.w_False @jit.unroll_safe @unwrap_spec(args_w='args_w') From noreply at buildbot.pypy.org Thu Oct 25 15:07:30 2012 From: noreply at buildbot.pypy.org (wlav) Date: Thu, 25 Oct 2012 15:07:30 +0200 (CEST) Subject: [pypy-commit] pypy reflex-support: from Scott Snyder: fix aliasing bug Message-ID: <20121025130730.72C611C1DC2@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r58421:1ea25f421fd8 Date: 2012-10-25 06:06 -0700 http://bitbucket.org/pypy/pypy/changeset/1ea25f421fd8/ Log: from Scott Snyder: fix aliasing bug 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 @@ -199,10 +199,8 @@ break; } case 'f': { - assert(sizeof(float) <= sizeof(long)); - long val = libp->para[i].obj.i; - void* pval = (void*)&val; - libp->para[i].obj.d = *(float*)pval; + float val = libp->para[i].obj.fl; + libp->para[i].obj.d = val; break; } case 'F': { From noreply at buildbot.pypy.org Thu Oct 25 20:50:50 2012 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 25 Oct 2012 20:50:50 +0200 (CEST) Subject: [pypy-commit] cffi default: Uh, this method is misnamed in the docs. Message-ID: <20121025185050.7A48F1C0FAB@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1005:3be96f74ff77 Date: 2012-10-25 20:50 +0200 http://bitbucket.org/cffi/cffi/changeset/3be96f74ff77/ Log: Uh, this method is misnamed in the docs. diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1039,12 +1039,12 @@ ``ffi.offsetof("C struct type", "fieldname")``: return the offset within the struct of the given field. Corresponds to ``offsetof()`` in C. -``ffi.getcname("C type" or , extra="")``: return the string +``ffi.getctype("C type" or , extra="")``: return the string representation of the given C type. If non-empty, the "extra" string is appended (or inserted at the right place in more complicated cases); it can be the name of a variable to declare, or an extra part of the type like ``"*"`` or ``"[5]"``. For example -``ffi.getcname(ffi.typeof(x), "*")`` returns the string representation +``ffi.getctype(ffi.typeof(x), "*")`` returns the string representation of the C type "pointer to the same type than x". ``ffi.gc(cdata, destructor)``: return a new cdata object that points to the From noreply at buildbot.pypy.org Fri Oct 26 00:50:38 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 26 Oct 2012 00:50:38 +0200 (CEST) Subject: [pypy-commit] pypy py3k: clarify the intent of compile(), fix eval's bytes handling Message-ID: <20121025225038.894F51C1DC0@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58422:178958be7335 Date: 2012-10-25 15:44 -0700 http://bitbucket.org/pypy/pypy/changeset/178958be7335/ Log: clarify the intent of compile(), fix eval's bytes handling diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -38,12 +38,18 @@ if space.is_true(space.isinstance(w_source, w_ast_type)): ast_node = space.interp_w(ast.mod, w_source) ast_node.sync_app_attrs(space) + elif space.isinstance_w(w_source, space.w_unicode): + w_utf_8_source = space.call_method(w_source, "encode", + space.wrap("utf-8")) + source_str = space.bytes0_w(w_utf_8_source) + flags |= consts.PyCF_IGNORE_COOKIE elif space.isinstance_w(w_source, space.w_bytes): source_str = space.bytes0_w(w_source) flags |= consts.PyCF_IGNORE_COOKIE else: - source_str = space.str0_w(w_source) - flags |= consts.PyCF_IGNORE_COOKIE + msg = space.wrap( + "compile() arg 1 must be a string, bytes, AST or code object") + raise OperationError(space.w_TypeError, msg) if not dont_inherit: caller = ec.gettopframe_nohidden() @@ -76,11 +82,10 @@ """ w = space.wrap - if (space.is_true(space.isinstance(w_code, space.w_str)) or - space.is_true(space.isinstance(w_code, space.w_unicode))): - w_code = compile(space, - space.call_method(w_code, 'lstrip', - space.wrap(' \t')), + is_unicode = space.is_true(space.isinstance(w_code, space.w_unicode)) + if (is_unicode or space.is_true(space.isinstance(w_code, space.w_bytes))): + w_strip = w(u' \t') if is_unicode else space.wrapbytes(' \t') + w_code = compile(space, space.call_method(w_code, 'lstrip', w_strip), "", "eval") codeobj = space.interpclass_w(w_code) From noreply at buildbot.pypy.org Fri Oct 26 00:50:39 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 26 Oct 2012 00:50:39 +0200 (CEST) Subject: [pypy-commit] pypy py3k: check for the magic encoding comment even w/ bytes and or PyCF_SOURCE_IS_UTF8 Message-ID: <20121025225039.ECB101C1DC0@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58423:d28fd7705d86 Date: 2012-10-25 15:48 -0700 http://bitbucket.org/pypy/pypy/changeset/d28fd7705d86/ Log: check for the magic encoding comment even w/ bytes and or PyCF_SOURCE_IS_UTF8 (which seems irrelevant now that the default encoding is utf8 anyway) diff --git a/pypy/interpreter/pyparser/pyparse.py b/pypy/interpreter/pyparser/pyparse.py --- a/pypy/interpreter/pyparser/pyparse.py +++ b/pypy/interpreter/pyparser/pyparse.py @@ -102,7 +102,12 @@ """ # Detect source encoding. enc = None - if bytessrc.startswith("\xEF\xBB\xBF"): + if compile_info.flags & consts.PyCF_SOURCE_IS_UTF8: + enc = 'utf-8' + + if compile_info.flags & consts.PyCF_IGNORE_COOKIE: + textsrc = bytessrc + elif bytessrc.startswith("\xEF\xBB\xBF"): bytessrc = bytessrc[3:] enc = 'utf-8' # If an encoding is explicitly given check that it is utf-8. @@ -111,13 +116,6 @@ raise error.SyntaxError("UTF-8 BOM with non-utf8 coding cookie", filename=compile_info.filename) textsrc = bytessrc - elif compile_info.flags & consts.PyCF_SOURCE_IS_UTF8: - enc = 'utf-8' - if (not compile_info.flags & consts.PyCF_IGNORE_COOKIE and - _check_for_encoding(bytessrc) is not None): - raise error.SyntaxError("coding declaration in unicode string", - filename=compile_info.filename) - textsrc = bytessrc else: enc = _normalize_encoding(_check_for_encoding(bytessrc)) if enc is None: diff --git a/pypy/interpreter/pyparser/test/test_pyparse.py b/pypy/interpreter/pyparser/test/test_pyparse.py --- a/pypy/interpreter/pyparser/test/test_pyparse.py +++ b/pypy/interpreter/pyparser/test/test_pyparse.py @@ -168,10 +168,14 @@ self.parse(input, info=info) assert info.encoding == "utf-8" # - input = "# coding: utf-8\nx" info.flags |= consts.PyCF_SOURCE_IS_UTF8 - exc = py.test.raises(SyntaxError, self.parse, input, info=info).value - assert exc.msg == "coding declaration in unicode string" + input = "#\nx" + info.encoding = None + self.parse(input, info=info) + assert info.encoding == "utf-8" + input = "# coding: latin1\nquux" + self.parse(input, info=info) + assert info.encoding == "latin1" info.flags |= consts.PyCF_IGNORE_COOKIE self.parse(input, info=info) assert info.encoding == "utf-8" diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -45,7 +45,6 @@ flags |= consts.PyCF_IGNORE_COOKIE elif space.isinstance_w(w_source, space.w_bytes): source_str = space.bytes0_w(w_source) - flags |= consts.PyCF_IGNORE_COOKIE else: msg = space.wrap( "compile() arg 1 must be a string, bytes, AST or code object") From noreply at buildbot.pypy.org Fri Oct 26 03:09:38 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 26 Oct 2012 03:09:38 +0200 (CEST) Subject: [pypy-commit] pypy py3k: add the surrogatepass error handler Message-ID: <20121026010938.0DFE31C1DC0@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58424:6e0ce8d44be5 Date: 2012-10-25 18:03 -0700 http://bitbucket.org/pypy/pypy/changeset/6e0ce8d44be5/ Log: add the surrogatepass error handler diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -248,6 +248,50 @@ raise operationerrfmt(space.w_TypeError, "don't know how to handle %s in error callback", typename) +def surrogatepass_errors(space, w_exc): + check_exception(space, w_exc) + if space.isinstance_w(w_exc, space.w_UnicodeEncodeError): + obj = space.realunicode_w(space.getattr(w_exc, space.wrap('object'))) + start = space.int_w(space.getattr(w_exc, space.wrap('start'))) + w_end = space.getattr(w_exc, space.wrap('end')) + end = space.int_w(w_end) + res = '' + pos = start + while pos < end: + ch = ord(obj[pos]) + pos += 1 + if ch < 0xd800 or ch > 0xdfff: + # Not a surrogate, fail with original exception + raise OperationError(space.type(w_exc), w_exc) + res += chr(0xe0 | (ch >> 12)) + res += chr(0x80 | ((ch >> 6) & 0x3f)) + res += chr(0x80 | (ch >> 0x3f)) + return space.newtuple([space.wrapbytes(res), w_end]) + elif space.isinstance_w(w_exc, space.w_UnicodeDecodeError): + start = space.int_w(space.getattr(w_exc, space.wrap('start'))) + obj = space.bytes_w(space.getattr(w_exc, space.wrap('object'))) + ch = 0 + # Try decoding a single surrogate character. If there are more, + # let the codec call us again + ch0 = ord(obj[start + 0]) + ch1 = ord(obj[start + 1]) + ch2 = ord(obj[start + 2]) + if (ch0 & 0xf0 == 0xe0 or + ch1 & 0xc0 == 0x80 or + ch2 & 0xc0 == 0x80): + # it's a three-byte code + ch = ((ch0 & 0x0f) << 12) + ((ch1 & 0x3f) << 6) + (ch2 & 0x3f) + if ch < 0xd800 or ch > 0xdfff: + # it's not a surrogate - fail + ch = 0 + if ch == 0: + raise OperationError(space.type(w_exc), w_exc) + return space.newtuple([space.wrap(unichr(ch)), space.wrap(start + 3)]) + else: + typename = space.type(w_exc).getname(space) + raise operationerrfmt(space.w_TypeError, + "don't know how to handle %s in error callback", typename) + def surrogateescape_errors(space, w_exc): check_exception(space, w_exc) if space.isinstance_w(w_exc, space.w_UnicodeEncodeError): @@ -292,7 +336,7 @@ "NOT_RPYTHON" state = space.fromcache(CodecState) for error in ("strict", "ignore", "replace", "xmlcharrefreplace", - "backslashreplace", "surrogateescape"): + "backslashreplace", "surrogateescape", "surrogatepass"): name = error + "_errors" state.codec_error_registry[error] = space.wrap(interp2app(globals()[name])) diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py --- a/pypy/module/_codecs/test/test_codecs.py +++ b/pypy/module/_codecs/test/test_codecs.py @@ -492,6 +492,14 @@ assert b'a\x80b'.decode('utf-8', 'surrogateescape') == 'a\udc80b' assert 'a\udc80b'.encode('utf-8', 'surrogateescape') == b'a\x80b' + def test_surrogatepass_handler(self): + import _codecs + assert _codecs.lookup_error("surrogatepass") + assert ("abc\ud800def".encode("utf-8", "surrogatepass") == + b"abc\xed\xa0\x80def") + assert (b"abc\xed\xa0\x80def".decode("utf-8", "surrogatepass") == + "abc\ud800def") + def test_badhandler(self): import codecs results = ( 42, "foo", (1,2,3), ("foo", 1, 3), ("foo", None), ("foo",), ("foo", 1, 3), ("foo", None), ("foo",) ) From noreply at buildbot.pypy.org Fri Oct 26 09:23:49 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 09:23:49 +0200 (CEST) Subject: [pypy-commit] cffi default: Fix docstring to work around xemacs syntax highlighting issues. Message-ID: <20121026072349.F13B51C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1006:fe0269906048 Date: 2012-10-26 09:23 +0200 http://bitbucket.org/cffi/cffi/changeset/fe0269906048/ Log: Fix docstring to work around xemacs syntax highlighting issues. diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -201,7 +201,7 @@ it as a string or unicode string. If 'cdata' is an enum, returns the value of the enumerator as a - string, or "#NUMBER" if the value is out of range. + string, or '#NUMBER' if the value is out of range. """ return self._backend.string(cdata, maxlen) From noreply at buildbot.pypy.org Fri Oct 26 10:03:10 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 10:03:10 +0200 (CEST) Subject: [pypy-commit] cffi default: Fix function name in error message Message-ID: <20121026080310.CCE881C0B54@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1007:3cd724b5f677 Date: 2012-10-26 09:59 +0200 http://bitbucket.org/cffi/cffi/changeset/3cd724b5f677/ Log: Fix function name in error message diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2637,7 +2637,7 @@ char *varname; char *data; - if (!PyArg_ParseTuple(args, "O!sO:read_variable", + if (!PyArg_ParseTuple(args, "O!sO:write_variable", &CTypeDescr_Type, &ct, &varname, &value)) return NULL; From noreply at buildbot.pypy.org Fri Oct 26 10:03:12 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 10:03:12 +0200 (CEST) Subject: [pypy-commit] cffi default: Tests and fixes that include directly using a file as "FILE *". Message-ID: <20121026080312.19C041C0B54@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1008:fa7aacc08b34 Date: 2012-10-26 10:03 +0200 http://bitbucket.org/cffi/cffi/changeset/fa7aacc08b34/ Log: Tests and fixes that include directly using a file as "FILE *". diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -87,6 +87,7 @@ #define CT_CUSTOM_FIELD_POS 32768 #define CT_IS_LONGDOUBLE 65536 #define CT_IS_BOOL 131072 +#define CT_IS_FILE 262144 #define CT_PRIMITIVE_ANY (CT_PRIMITIVE_SIGNED | \ CT_PRIMITIVE_UNSIGNED | \ CT_PRIMITIVE_CHAR | \ @@ -942,6 +943,11 @@ CTypeDescrObject *ctinit; if (!CData_Check(init)) { + if (PyFile_Check(init) && + (ct->ct_itemdescr->ct_flags & CT_IS_FILE)) { + *(FILE **)data = PyFile_AsFile(init); + return 0; + } expected = "cdata pointer"; goto cannot_convert; } @@ -1726,9 +1732,8 @@ /* from a unicode, we add the null terminator */ length = _my_PyUnicode_SizeAsWideChar(init) + 1; } - else if (PyFile_Check(init)) { - if (strcmp(ctptr->ct_itemdescr->ct_name, "struct _IO_FILE") != 0) - return 0; + else if (PyFile_Check(init) && + (ctptr->ct_itemdescr->ct_flags & CT_IS_FILE)) { output_data[0] = (char *)PyFile_AsFile(init); return 1; } @@ -3028,9 +3033,14 @@ static PyObject *b_new_struct_type(PyObject *self, PyObject *args) { char *name; + int flag; if (!PyArg_ParseTuple(args, "s:new_struct_type", &name)) return NULL; - return _b_struct_or_union_type("struct", name, CT_STRUCT); + + flag = CT_STRUCT; + if (strcmp(name, "_IO_FILE") == 0) + flag |= CT_IS_FILE; + return _b_struct_or_union_type("struct", name, flag); } static PyObject *b_new_union_type(PyObject *self, PyObject *args) diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1222,3 +1222,56 @@ assert ffi_r() is not None assert lib_r() is not None assert func() == 42 + +def test_FILE_stored_in_stdout(): + ffi = FFI() + ffi.cdef("int printf(const char *, ...); FILE *setstdout(FILE *);") + lib = ffi.verify(""" + #include + FILE *setstdout(FILE *f) { + FILE *result = stdout; + stdout = f; + return result; + } + """) + import posix + fdr, fdw = posix.pipe() + fw1 = posix.fdopen(fdw, 'wb', 256) + old_stdout = lib.setstdout(fw1) + try: + # + fw1.write(b"X") + r = lib.printf(b"hello, %d!\n", ffi.cast("int", 42)) + fw1.close() + assert r == len("hello, 42!\n") + # + finally: + lib.setstdout(old_stdout) + # + result = posix.read(fdr, 256) + posix.close(fdr) + assert result == b"Xhello, 42!\n" + +def test_FILE_stored_explicitly(): + ffi = FFI() + ffi.cdef("int myprintf(const char *, int); FILE *myfile;") + lib = ffi.verify(""" + #include + FILE *myfile; + int myprintf(const char *out, int value) { + return fprintf(myfile, out, value); + } + """) + import posix + fdr, fdw = posix.pipe() + fw1 = posix.fdopen(fdw, 'wb', 256) + lib.myfile = fw1 + # + fw1.write(b"X") + r = lib.myprintf(b"hello, %d!\n", ffi.cast("int", 42)) + fw1.close() + assert r == len("hello, 42!\n") + # + result = posix.read(fdr, 256) + posix.close(fdr) + assert result == b"Xhello, 42!\n" From noreply at buildbot.pypy.org Fri Oct 26 10:50:08 2012 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 26 Oct 2012 10:50:08 +0200 (CEST) Subject: [pypy-commit] pypy default: simple test for float(bytearray) - issue #1219 Message-ID: <20121026085008.F41E41C004F@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: Changeset: r58425:f5b988d30d44 Date: 2012-07-20 21:58 +0400 http://bitbucket.org/pypy/pypy/changeset/f5b988d30d44/ Log: simple test for float(bytearray) - issue #1219 diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py --- a/pypy/objspace/std/test/test_bytearrayobject.py +++ b/pypy/objspace/std/test/test_bytearrayobject.py @@ -439,6 +439,9 @@ def test_int(self): assert int(bytearray('-1234')) == -1234 + def test_float(self): + assert float(bytearray(b'10.4')) == 10.4 + def test_reduce(self): assert bytearray('caf\xe9').__reduce__() == ( bytearray, (u'caf\xe9', 'latin-1'), None) From noreply at buildbot.pypy.org Fri Oct 26 10:50:10 2012 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 26 Oct 2012 10:50:10 +0200 (CEST) Subject: [pypy-commit] pypy default: test passes, but fix looks like an awful hack Message-ID: <20121026085010.36B001C004F@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: Changeset: r58426:63d00213f726 Date: 2012-07-20 22:11 +0400 http://bitbucket.org/pypy/pypy/changeset/63d00213f726/ Log: test passes, but fix looks like an awful hack diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -81,6 +81,9 @@ data = makebytearraydata_w(space, w_source) w_bytearray.data = data +def float__Bytearray(space, w_bytearray): + return space.wrap(float(''.join(w_bytearray.data))) + def len__Bytearray(space, w_bytearray): result = len(w_bytearray.data) return wrapint(space, result) From noreply at buildbot.pypy.org Fri Oct 26 10:50:11 2012 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 26 Oct 2012 10:50:11 +0200 (CEST) Subject: [pypy-commit] pypy default: some more tests, fix feels ok after looking around more Message-ID: <20121026085011.5F5911C004F@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: Changeset: r58427:19376e234a52 Date: 2012-07-20 22:20 +0400 http://bitbucket.org/pypy/pypy/changeset/19376e234a52/ Log: some more tests, fix feels ok after looking around more diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py --- a/pypy/objspace/std/test/test_bytearrayobject.py +++ b/pypy/objspace/std/test/test_bytearrayobject.py @@ -441,6 +441,8 @@ def test_float(self): assert float(bytearray(b'10.4')) == 10.4 + assert float(bytearray('-1.7e-1')) == -1.7e-1 + assert float(bytearray(u'.9e10', 'utf-8')) == .9e10 def test_reduce(self): assert bytearray('caf\xe9').__reduce__() == ( From noreply at buildbot.pypy.org Fri Oct 26 10:50:12 2012 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 26 Oct 2012 10:50:12 +0200 (CEST) Subject: [pypy-commit] pypy default: catch ParseStringError, raise app-level exception Message-ID: <20121026085012.896441C004F@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: Changeset: r58428:be5d72b50028 Date: 2012-07-20 23:21 +0400 http://bitbucket.org/pypy/pypy/changeset/be5d72b50028/ Log: catch ParseStringError, raise app-level exception diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -13,6 +13,8 @@ from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.strutil import ParseStringError +from pypy.objspace.std.strutil import string_to_float from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std.unicodeobject import W_UnicodeObject from pypy.objspace.std import slicetype @@ -82,7 +84,12 @@ w_bytearray.data = data def float__Bytearray(space, w_bytearray): - return space.wrap(float(''.join(w_bytearray.data))) + try: + value = string_to_float(''.join(w_bytearray.data)) + except ParseStringError, e: + raise OperationError(space.w_ValueError, space.wrap(e.msg)) + else: + return space.wrap(value) def len__Bytearray(space, w_bytearray): result = len(w_bytearray.data) From noreply at buildbot.pypy.org Fri Oct 26 10:50:13 2012 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Fri, 26 Oct 2012 10:50:13 +0200 (CEST) Subject: [pypy-commit] pypy default: add test for invalid float argument and for nan Message-ID: <20121026085013.A77DB1C004F@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: Changeset: r58429:cb3d6f20e44c Date: 2012-07-21 00:05 +0400 http://bitbucket.org/pypy/pypy/changeset/cb3d6f20e44c/ Log: add test for invalid float argument and for nan diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py --- a/pypy/objspace/std/test/test_bytearrayobject.py +++ b/pypy/objspace/std/test/test_bytearrayobject.py @@ -443,6 +443,9 @@ assert float(bytearray(b'10.4')) == 10.4 assert float(bytearray('-1.7e-1')) == -1.7e-1 assert float(bytearray(u'.9e10', 'utf-8')) == .9e10 + import math + assert math.isnan(float(bytearray('nan'))) + raises(ValueError, float, bytearray('not_a_number')) def test_reduce(self): assert bytearray('caf\xe9').__reduce__() == ( From noreply at buildbot.pypy.org Fri Oct 26 10:50:14 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 10:50:14 +0200 (CEST) Subject: [pypy-commit] pypy default: Merged in kostialopuhin/pypy (pull request #79) Message-ID: <20121026085014.E08961C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58430:58260cf95e05 Date: 2012-10-26 10:49 +0200 http://bitbucket.org/pypy/pypy/changeset/58260cf95e05/ Log: Merged in kostialopuhin/pypy (pull request #79) diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -13,6 +13,8 @@ from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.strutil import ParseStringError +from pypy.objspace.std.strutil import string_to_float from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std.unicodeobject import W_UnicodeObject from pypy.objspace.std import slicetype @@ -81,6 +83,14 @@ data = makebytearraydata_w(space, w_source) w_bytearray.data = data +def float__Bytearray(space, w_bytearray): + try: + value = string_to_float(''.join(w_bytearray.data)) + except ParseStringError, e: + raise OperationError(space.w_ValueError, space.wrap(e.msg)) + else: + return space.wrap(value) + def len__Bytearray(space, w_bytearray): result = len(w_bytearray.data) return wrapint(space, result) diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py --- a/pypy/objspace/std/test/test_bytearrayobject.py +++ b/pypy/objspace/std/test/test_bytearrayobject.py @@ -439,6 +439,14 @@ def test_int(self): assert int(bytearray('-1234')) == -1234 + def test_float(self): + assert float(bytearray(b'10.4')) == 10.4 + assert float(bytearray('-1.7e-1')) == -1.7e-1 + assert float(bytearray(u'.9e10', 'utf-8')) == .9e10 + import math + assert math.isnan(float(bytearray('nan'))) + raises(ValueError, float, bytearray('not_a_number')) + def test_reduce(self): assert bytearray('caf\xe9').__reduce__() == ( bytearray, (u'caf\xe9', 'latin-1'), None) From noreply at buildbot.pypy.org Fri Oct 26 11:19:28 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 11:19:28 +0200 (CEST) Subject: [pypy-commit] pyrepl py3k-readline: we need to explicitly use integer division here Message-ID: <20121026091928.1EA931C0448@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k-readline Changeset: r201:c385792628a7 Date: 2012-10-26 11:19 +0200 http://bitbucket.org/pypy/pyrepl/changeset/c385792628a7/ Log: we need to explicitly use integer division here diff --git a/pyrepl/completing_reader.py b/pyrepl/completing_reader.py --- a/pyrepl/completing_reader.py +++ b/pyrepl/completing_reader.py @@ -67,8 +67,8 @@ item = "%s " padding = 2 maxlen = min(max(map(real_len, wordlist)), cons.width - padding) - cols = cons.width / (maxlen + padding) - rows = (len(wordlist) - 1)/cols + 1 + cols = cons.width // (maxlen + padding) + rows = (len(wordlist) - 1)//cols + 1 if sort_in_column: # sort_in_column=False (default) sort_in_column=True From noreply at buildbot.pypy.org Fri Oct 26 11:20:42 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 11:20:42 +0200 (CEST) Subject: [pypy-commit] pypy py3k: update to pyrepl c385792628a7 (py3k-readline branch); now even fancycompleter and colored tab-completion works :) Message-ID: <20121026092042.87BAE1C0448@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k Changeset: r58431:746d3737d53f Date: 2012-10-26 11:20 +0200 http://bitbucket.org/pypy/pypy/changeset/746d3737d53f/ Log: update to pyrepl c385792628a7 (py3k-readline branch); now even fancycompleter and colored tab-completion works :) diff --git a/lib_pypy/pyrepl/completing_reader.py b/lib_pypy/pyrepl/completing_reader.py --- a/lib_pypy/pyrepl/completing_reader.py +++ b/lib_pypy/pyrepl/completing_reader.py @@ -67,8 +67,8 @@ item = "%s " padding = 2 maxlen = min(max(map(real_len, wordlist)), cons.width - padding) - cols = cons.width / (maxlen + padding) - rows = (len(wordlist) - 1)/cols + 1 + cols = cons.width // (maxlen + padding) + rows = (len(wordlist) - 1)//cols + 1 if sort_in_column: # sort_in_column=False (default) sort_in_column=True From noreply at buildbot.pypy.org Fri Oct 26 12:01:40 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 12:01:40 +0200 (CEST) Subject: [pypy-commit] pypy default: issue1299: BZ2Decompressor.decompress('') does not raise EOFError at Message-ID: <20121026100140.18E1E1C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58432:469ecc21fa11 Date: 2012-10-24 16:45 +0200 http://bitbucket.org/pypy/pypy/changeset/469ecc21fa11/ Log: issue1299: BZ2Decompressor.decompress('') does not raise EOFError at end-of-stream. Patch by nadeem.vawda. 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 @@ -406,12 +406,16 @@ read += length def readall(self): - w_result = self.decompressor.decompress(self.stream.readall()) - if self.decompressor.running: - raise OperationError(self.space.w_EOFError, - self.space.wrap("compressed file ended before the logical end-of-the-stream was detected")) - result = self.space.str_w(w_result) - self.readlength += len(result) + raw = self.stream.readall() + if raw: + w_result = self.decompressor.decompress(raw) + if self.decompressor.running: + raise OperationError(self.space.w_EOFError, + self.space.wrap("compressed file ended before the logical end-of-the-stream was detected")) + result = self.space.str_w(w_result) + self.readlength += len(result) + else: + result = "" if len(self.buffer) != self.pos: pos = self.pos assert pos >= 0 @@ -649,11 +653,11 @@ was found after the end of stream, it'll be ignored and saved in unused_data attribute.""" - if data == '': - return self.space.wrap('') if not self.running: raise OperationError(self.space.w_EOFError, self.space.wrap("end of stream was already found")) + if data == '': + return self.space.wrap('') in_bufsize = len(data) diff --git a/pypy/module/bz2/test/test_bz2_compdecomp.py b/pypy/module/bz2/test/test_bz2_compdecomp.py --- a/pypy/module/bz2/test/test_bz2_compdecomp.py +++ b/pypy/module/bz2/test/test_bz2_compdecomp.py @@ -156,6 +156,7 @@ bz2d = BZ2Decompressor() bz2d.decompress(self.DATA) raises(EOFError, bz2d.decompress, "foo") + raises(EOFError, bz2d.decompress, "") def test_buffer(self): from bz2 import BZ2Decompressor From noreply at buildbot.pypy.org Fri Oct 26 12:01:41 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 12:01:41 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121026100141.5B2591C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58433:6b60148cc3bb Date: 2012-10-26 12:01 +0200 http://bitbucket.org/pypy/pypy/changeset/6b60148cc3bb/ Log: merge heads diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -4306,14 +4306,7 @@ """ expected = """ [] - p0 = newstr(11) - copystrcontent(s"hello world", p0, 0, 0, 11) - # Eventually this should just return s"hello", but ATM this test is - # just verifying that it doesn't return "\0\0\0\0\0", so being - # slightly underoptimized is ok. - p1 = newstr(5) - copystrcontent(p0, p1, 0, 0, 5) - finish(p1) + finish(s"hello") """ self.optimize_strunicode_loop(ops, expected) @@ -4963,12 +4956,7 @@ """ expected = """ [i1] - p0 = newstr(6) - copystrcontent(s"hello!", p0, 0, 0, 6) - p1 = newstr(12) - copystrcontent(p0, p1, 0, 0, 6) - copystrcontent(s"abc123", p1, 0, 6, 6) - i0 = strgetitem(p1, i1) + i0 = strgetitem(s"hello!abc123", i1) finish(i0) """ self.optimize_strunicode_loop(ops, expected) @@ -4984,10 +4972,7 @@ """ expected = """ [] - p0 = newstr(6) - copystrcontent(s"hello!", p0, 0, 0, 6) - i0 = strgetitem(p0, 0) - finish(i0) + finish(104) """ self.optimize_strunicode_loop(ops, expected) @@ -5067,6 +5052,21 @@ """ self.optimize_strunicode_loop(ops, expected) + def test_str_copy_constant_virtual(self): + ops = """ + [] + p0 = newstr(10) + copystrcontent(s"abcd", p0, 0, 0, 4) + strsetitem(p0, 4, 101) + copystrcontent(s"fghij", p0, 0, 5, 5) + finish(p0) + """ + expected = """ + [] + finish(s"abcdefghij") + """ + self.optimize_strunicode_loop(ops, expected) + def test_call_pure_vstring_const(self): py.test.skip("implement me") ops = """ diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -489,6 +489,7 @@ def optimize_COPYSTRCONTENT(self, op): self._optimize_COPYSTRCONTENT(op, mode_string) + def optimize_COPYUNICODECONTENT(self, op): self._optimize_COPYSTRCONTENT(op, mode_unicode) @@ -507,8 +508,8 @@ if length.is_constant() and length.box.getint() == 0: return - elif (src.is_virtual() and dst.is_virtual() and srcstart.is_constant() and - dststart.is_constant() and length.is_constant()): + elif ((src.is_virtual() or src.is_constant()) and dst.is_virtual() and + srcstart.is_constant() and dststart.is_constant() and length.is_constant()): src_start = srcstart.force_box(self).getint() dst_start = dststart.force_box(self).getint() 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 @@ -9,6 +9,7 @@ from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.stdtypedef import SMM, StdTypeDef from pypy.objspace.std.register_all import register_all +from pypy.rlib import jit from pypy.rlib.rarithmetic import ovfcheck, widen from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.objectmodel import specialize, keepalive_until_here @@ -466,6 +467,9 @@ self.setlen(0) self.fromsequence(w_lst) + # We can't look into this function until ptradd works with things (in the + # JIT) other than rffi.CCHARP + @jit.dont_look_inside def delslice__Array_ANY_ANY(space, self, w_i, w_j): i = space.int_w(w_i) if i < 0: @@ -495,13 +499,13 @@ rffi.c_memcpy( rffi.cast(rffi.VOIDP, rffi.ptradd(self.buffer, i)), rffi.cast(rffi.VOIDP, rffi.ptradd(oldbuffer, j)), - (self.len - j) * mytype.bytes) + (self.len - j) * mytype.bytes + ) self.len -= j - i self.allocated = self.len if oldbuffer: lltype.free(oldbuffer, flavor='raw') - # Add and mul methods def add__Array_Array(space, self, other): diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -13,6 +13,8 @@ from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.strutil import ParseStringError +from pypy.objspace.std.strutil import string_to_float from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std.unicodeobject import W_UnicodeObject from pypy.objspace.std import slicetype @@ -81,6 +83,14 @@ data = makebytearraydata_w(space, w_source) w_bytearray.data = data +def float__Bytearray(space, w_bytearray): + try: + value = string_to_float(''.join(w_bytearray.data)) + except ParseStringError, e: + raise OperationError(space.w_ValueError, space.wrap(e.msg)) + else: + return space.wrap(value) + def len__Bytearray(space, w_bytearray): result = len(w_bytearray.data) return wrapint(space, result) diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py --- a/pypy/objspace/std/test/test_bytearrayobject.py +++ b/pypy/objspace/std/test/test_bytearrayobject.py @@ -439,6 +439,14 @@ def test_int(self): assert int(bytearray('-1234')) == -1234 + def test_float(self): + assert float(bytearray(b'10.4')) == 10.4 + assert float(bytearray('-1.7e-1')) == -1.7e-1 + assert float(bytearray(u'.9e10', 'utf-8')) == .9e10 + import math + assert math.isnan(float(bytearray('nan'))) + raises(ValueError, float, bytearray('not_a_number')) + def test_reduce(self): assert bytearray('caf\xe9').__reduce__() == ( bytearray, (u'caf\xe9', 'latin-1'), None) From noreply at buildbot.pypy.org Fri Oct 26 12:05:30 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 12:05:30 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix check_number(), as per comments on pull request #80. Message-ID: <20121026100530.18B1D1C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58434:64035d1ba94d Date: 2012-10-26 12:05 +0200 http://bitbucket.org/pypy/pypy/changeset/64035d1ba94d/ Log: Fix check_number(), as per comments on pull request #80. diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -43,9 +43,8 @@ space.newtuple(args_w)]) def check_number(space, w_obj): - if (space.lookup(w_obj, '__add__') is None or - space.is_true(space.isinstance(w_obj, space.w_str)) or - space.is_true(space.isinstance(w_obj, space.w_unicode))): + if (space.lookup(w_obj, '__int__') is None and + space.lookup(w_obj, '__float__') is None): raise OperationError(space.w_TypeError, space.wrap("expected a number")) diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -35,6 +35,7 @@ raises(TypeError, itertools.count, None) raises(TypeError, itertools.count, 'a') + raises(TypeError, itertools.count, []) def test_repeat(self): import itertools From noreply at buildbot.pypy.org Fri Oct 26 12:16:05 2012 From: noreply at buildbot.pypy.org (cbjadwani) Date: Fri, 26 Oct 2012 12:16:05 +0200 (CEST) Subject: [pypy-commit] pypy default: Fix lib_pypy/itertools.py Message-ID: <20121026101605.D4AC51C0448@cobra.cs.uni-duesseldorf.de> Author: Chirag Jadwani Branch: Changeset: r58435:4b82a089ad3b Date: 2012-07-28 17:28 +0530 http://bitbucket.org/pypy/pypy/changeset/4b82a089ad3b/ Log: Fix lib_pypy/itertools.py diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py --- a/lib_pypy/itertools.py +++ b/lib_pypy/itertools.py @@ -23,14 +23,24 @@ groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v) """ -__all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', - 'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap', - 'takewhile', 'tee', 'compress', 'product'] +import sys + + +__all__ = ['chain', 'combinations', 'combinations_with_replacement', + 'compress', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', + 'ifilterfalse', 'imap', 'islice', 'izip', 'izip_longest', + 'permutations', 'product', 'repeat', 'starmap', 'takewhile', 'tee'] + try: from __pypy__ import builtinify except ImportError: builtinify = lambda f: f +def check_number(n): + if not hasattr(n, '__add__') or isinstance(n, basestring): + raise TypeError('expected a number') + + class chain(object): """Make an iterator that returns elements from the first iterable until it is exhausted, then proceeds to the next iterable, until @@ -45,7 +55,7 @@ yield element """ def __init__(self, *iterables): - self._iterables_iter = iter(map(iter, iterables)) + self._iterables_iter = iter(iterables) # little trick for the first chain.next() call self._cur_iterable_iter = iter([]) @@ -57,12 +67,102 @@ try: return self._cur_iterable_iter.next() except StopIteration: - self._cur_iterable_iter = self._iterables_iter.next() + self._cur_iterable_iter = iter(self._iterables_iter.next()) except AttributeError: # CPython raises a TypeError when next() is not defined raise TypeError('%s has no next() method' % \ (self._cur_iterable_iter)) + @classmethod + def from_iterable(cls, iterables): + c = cls() + c._iterables_iter = iter(iterables) + return c + + +class combinations(object): + """combinations(iterable, r) --> combinations object + + Return successive r-length combinations of elements in the iterable. + + combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3) + """ + def __init__(self, iterable, r): + self.pool = list(iterable) + if r < 0: + raise ValueError('r must be non-negative') + self.r = r + self.indices = range(len(self.pool)) + self.last_result = None + self.stopped = r > len(self.pool) + + def __iter__(self): + return self + + def get_maximum(self, i): + return i + len(self.pool) - self.r + + def max_index(self, j): + return self.indices[j - 1] + 1 + + def next(self): + if self.stopped: + raise StopIteration() + if self.last_result is None: + # On the first pass, initialize result tuple using the indices + result = [None] * self.r + for i in xrange(self.r): + index = self.indices[i] + result[i] = self.pool[index] + else: + # Copy the previous result + result = self.last_result[:] + # Scan indices right-to-left until finding one that is not at its + # maximum + i = self.r - 1 + while i >= 0 and self.indices[i] == self.get_maximum(i): + i -= 1 + + # If i is negative, then the indices are all at their maximum value + # and we're done + if i < 0: + self.stopped = True + raise StopIteration() + + # Increment the current index which we know is not at its maximum. + # Then move back to the right setting each index to its lowest + # possible value + self.indices[i] += 1 + for j in range(i + 1, self.r): + self.indices[j] = self.max_index(j) + + # Update the result for the new indices starting with i, the + # leftmost index that changed + for i in range(i, self.r): + index = self.indices[i] + result[i] = self.pool[index] + self.last_result = result + return tuple(result) + + +class combinations_with_replacement(combinations): + """combinations_with_replacement(iterable, r) --> combinations_with_replacement object + + Return successive r-length combinations of elements in the iterable + allowing individual elements to have successive repeats. + combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC + """ + def __init__(self, iterable, r): + super(combinations_with_replacement, self).__init__(iterable, r) + self.indices = [0] * r + self.stopped = len(self.pool) == 0 and r > 0 + + def get_maximum(self, i): + return len(self.pool) - 1 + + def max_index(self, j): + return self.indices[j - 1] + class compress(object): def __init__(self, data, selectors): @@ -74,42 +174,59 @@ def next(self): while True: - next_item = self.data.next() - next_selector = self.selectors.next() + try: + next_item = self.data.next() + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % (self.data)) + try: + next_selector = self.selectors.next() + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % (self.selectors)) if bool(next_selector): return next_item class count(object): - """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. + """Make an iterator that returns evenly spaced values starting + with n. If not specified n defaults to zero. Often used as an + argument to imap() to generate consecutive data points. Also, + used with izip() to add sequence numbers. - Equivalent to : + Equivalent to: - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) + def count(start=0, step=1): + n = start while True: yield n - n += 1 + n += step """ - def __init__(self, n=0): - if not isinstance(n, int): - raise TypeError('%s is not a regular integer' % n) - self.times = n-1 + def __init__(self, start=0, step=1): + check_number(start) + check_number(step) + self.counter = start + self.step = step def __iter__(self): return self def next(self): - self.times += 1 - return self.times + c = self.counter + self.counter += self.step + return c + + def __reduce__(self): + if self.step is 1: + args = (self.counter,) + else: + args = (self.counter, self.step) + return (self.__class__, args) def __repr__(self): - return 'count(%d)' % (self.times + 1) + if self.step is 1: + return 'count(%r)' % (self.counter) + return 'count(%r, %r)' % (self.counter, self.step) @@ -368,37 +485,35 @@ """ def __init__(self, iterable, *args): s = slice(*args) - self.start, self.stop, self.step = s.start or 0, s.stop, s.step - if not isinstance(self.start, (int, long)): - raise ValueError("Start argument must be an integer") - if self.stop is not None and not isinstance(self.stop, (int,long)): - raise ValueError("Stop argument must be an integer or None") - if self.step is None: - self.step = 1 - if self.start<0 or (self.stop is not None and self.stop<0 - ) or self.step<=0: - raise ValueError, "indices for islice() must be positive" - self.it = iter(iterable) - self.donext = None - self.cnt = 0 + for n, v in zip(['Start', 'Stop', 'Step'], [s.start, s.stop, s.step]): + if not (v is None or isinstance(v, int) and 0 <= v): + msg = ('%s for islice must be None or an integer: ' + '0 <= x <= maxint') + raise ValueError(msg % n) + start, stop, self.step = s.indices(sys.maxint) + self.iterable = iter(iterable) + self.pos = -1 + self.next_pos = start + self.max_pos = stop - 1 def __iter__(self): return self - def next(self): - if self.donext is None: + def next(self): + i = self.pos + while i < self.next_pos: + if i >= self.max_pos: + raise StopIteration() try: - self.donext = self.it.next + item = self.iterable.next() except AttributeError: - raise TypeError - nextindex = self.start - if self.stop is not None and nextindex >= self.stop: - raise StopIteration - while self.cnt <= nextindex: - nextitem = self.donext() - self.cnt += 1 - self.start += self.step - return nextitem + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % (self.iterable)) + i += 1 + + self.pos = i + self.next_pos += self.step + return item class izip(object): """Make an iterator that aggregates elements from each of the @@ -416,7 +531,6 @@ """ def __init__(self, *iterables): self._iterators = map(iter, iterables) - self._result = [None] * len(self._iterators) def __iter__(self): return self @@ -431,53 +545,169 @@ raise TypeError('%s has no next() method' % (i)) -class product(object): - - def __init__(self, *args, **kw): - if len(kw) > 1: - raise TypeError("product() takes at most 1 argument (%d given)" % - len(kw)) - self.repeat = kw.get('repeat', 1) - self.gears = [x for x in args] * self.repeat - self.num_gears = len(self.gears) - # initialization of indicies to loop over - self.indicies = [(0, len(self.gears[x])) - for x in range(0, self.num_gears)] - self.cont = True - - def roll_gears(self): - # Starting from the end of the gear indicies work to the front - # incrementing the gear until the limit is reached. When the limit - # is reached carry operation to the next gear - should_carry = True - for n in range(0, self.num_gears): - nth_gear = self.num_gears - n - 1 - if should_carry: - count, lim = self.indicies[nth_gear] - count += 1 - if count == lim and nth_gear == 0: - self.cont = False - if count == lim: - should_carry = True - count = 0 - else: - should_carry = False - self.indicies[nth_gear] = (count, lim) - else: - break +class izip_longest(object): + """Return an izip_longest object whose .next() method returns a tuple where + the i-th element comes from the i-th iterable argument. The .next() + method continues until the longest iterable in the argument sequence + is exhausted and then it raises StopIteration. When the shorter iterables + are exhausted, the fillvalue is substituted in their place. The fillvalue + defaults to None or can be specified by a keyword argument. + """ + def __init__(self, *iterables, **kwargs): + self.fillvalue = kwargs.pop('fillvalue', None) + if kwargs: + msg = 'izip_longest() got unexpected keyword arguments' + raise TypeError(msg) + self.iterators = map(iter, iterables) + self.repeaters_left = len(self.iterators) def __iter__(self): return self def next(self): - if not self.cont: - raise StopIteration - l = [] - for x in range(0, self.num_gears): - index, limit = self.indicies[x] - l.append(self.gears[x][index]) - self.roll_gears() - return tuple(l) + if self.repeaters_left <= 0: + raise StopIteration() + result = [None] * len(self.iterators) + for i, iterator in enumerate(self.iterators): + try: + item = iterator.next() + except StopIteration: + self.repeaters_left -= 1 + if self.repeaters_left <= 0: + raise + self.iterators[i] = repeat(self.fillvalue) + item = self.fillvalue + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % (iterator)) + result[i] = item + return tuple(result) + + +class permutations(object): + """permutations(iterable[, r]) --> permutations object + + Return successive r-length permutations of elements in the iterable. + + permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1) + """ + def __init__(self, iterable, r=None): + self.pool = list(iterable) + n = len(self.pool) + if r is None: + r = n + elif r < 0: + raise ValueError('r must be non-negative') + self.r = r + self.indices = range(n) + self.cycles = range(n, n - r, -1) + self.stopped = r > n + + def __iter__(self): + return self + + def next(self): + if self.stopped: + raise StopIteration() + + r = self.r + indices = self.indices + cycles = self.cycles + + result = tuple([self.pool[indices[i]] for i in range(r)]) + i = r - 1 + while i >= 0: + j = cycles[i] - 1 + if j > 0: + cycles[i] = j + indices[i], indices[-j] = indices[-j], indices[i] + return result + cycles[i] = len(indices) - i + n1 = len(indices) - 1 + assert n1 >= 0 + num = indices[i] + for k in range(i, n1): + indices[k] = indices[k+1] + indices[n1] = num + i -= 1 + self.stopped = True + return result + + +class product(object): + """Cartesian product of input iterables. + + Equivalent to nested for-loops in a generator expression. For example, + ``product(A, B)`` returns the same as ``((x,y) for x in A for y in B)``. + + The nested loops cycle like an odometer with the rightmost element advancing + on every iteration. This pattern creates a lexicographic ordering so that if + the input's iterables are sorted, the product tuples are emitted in sorted + order. + + To compute the product of an iterable with itself, specify the number of + repetitions with the optional *repeat* keyword argument. For example, + ``product(A, repeat=4)`` means the same as ``product(A, A, A, A)``. + + This function is equivalent to the following code, except that the + actual implementation does not build up intermediate results in memory:: + + def product(*args, **kwds): + # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy + # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 + pools = map(tuple, args) * kwds.get('repeat', 1) + result = [[]] + for pool in pools: + result = [x+[y] for x in result for y in pool] + for prod in result: + yield tuple(prod) + """ + def __init__(self, *args, **kw): + if len(kw) > 1: + raise TypeError("product() takes at most 1 argument (%d given)" % + len(kw)) + repeat = kw.get('repeat', 1) + self.sources = map(tuple, args) * repeat + self.indices = [0] * len(self.sources) + try: + self.next_result = [s[0] for s in self.sources] + except IndexError: + self.next_result = None + + def next(self): + sources = self.sources + indices = self.indices + + if self.next_result is None: + raise StopIteration() + + result = tuple(self.next_result) + + i = len(sources) + while True: + i -= 1 + if i < 0: + self.next_result = None + return result + j = indices[i] + j += 1 + if j < len(sources[i]): + break + + self.next_result[i] = sources[i][j] + indices[i] = j + + while True: + i += 1 + if i >= len(sources): + break + indices[i] = 0 + self.next_result[i] = sources[i][0] + + return result + + def __iter__(self): + return self class repeat(object): @@ -497,8 +727,8 @@ for i in xrange(times): yield object """ - def __init__(self, obj, times=None): - self._obj = obj + def __init__(self, object, times=None): + self._obj = object if times is not None: xrange(times) # Raise a TypeError if times < 0: @@ -557,8 +787,6 @@ except AttributeError: # CPython raises a TypeError when next() is not defined raise TypeError('%s has no next() method' % self._iter) - if not isinstance(t, tuple): - raise TypeError("iterator must return a tuple") return self._func(*t) @@ -662,6 +890,8 @@ it = iter(iterable) return tuple([gen(it.next) for i in range(n)]) """ + if n < 0: + raise ValueError('n must be >= 0') if isinstance(iterable, TeeObject): # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) return tuple([iterable] + From noreply at buildbot.pypy.org Fri Oct 26 12:16:07 2012 From: noreply at buildbot.pypy.org (cbjadwani) Date: Fri, 26 Oct 2012 12:16:07 +0200 (CEST) Subject: [pypy-commit] pypy default: Use built-in next function and fix bugs in lib_pypy/itertools.py Message-ID: <20121026101607.1D7A41C0448@cobra.cs.uni-duesseldorf.de> Author: Chirag Jadwani Branch: Changeset: r58436:c086d7f312fa Date: 2012-07-29 16:35 +0530 http://bitbucket.org/pypy/pypy/changeset/c086d7f312fa/ Log: Use built-in next function and fix bugs in lib_pypy/itertools.py diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py --- a/lib_pypy/itertools.py +++ b/lib_pypy/itertools.py @@ -37,7 +37,7 @@ def check_number(n): - if not hasattr(n, '__add__') or isinstance(n, basestring): + if not hasattr(n, '__int__') and not hasattr(n, '__float__'): raise TypeError('expected a number') @@ -65,13 +65,9 @@ def next(self): while True: try: - return self._cur_iterable_iter.next() + return next(self._cur_iterable_iter) except StopIteration: - self._cur_iterable_iter = iter(self._iterables_iter.next()) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iterable_iter)) + self._cur_iterable_iter = iter(next(self._iterables_iter)) @classmethod def from_iterable(cls, iterables): @@ -165,6 +161,17 @@ class compress(object): + """Make an iterator that filters elements from data returning + only those that have a corresponding element in selectors that + evaluates to True. Stops when either the data or selectors + iterables has been exhausted. + + Equivalent to: + + def compress(data, selectors): + # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F + return (d for d, s in izip(data, selectors) if s) + """ def __init__(self, data, selectors): self.data = iter(data) self.selectors = iter(selectors) @@ -174,16 +181,8 @@ def next(self): while True: - try: - next_item = self.data.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (self.data)) - try: - next_selector = self.selectors.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (self.selectors)) + next_item = next(self.data) + next_selector = next(self.selectors) if bool(next_selector): return next_item @@ -247,28 +246,25 @@ yield element """ def __init__(self, iterable): - self._cur_iter = iter(iterable) + self._cur_iter = self._saving_iter(iter(iterable)) self._saved = [] - self._must_save = True def __iter__(self): return self + def _saving_iter(self, iterable): + while True: + item = next(iterable) + self._saved.append(item) + yield item + def next(self): - # XXX Could probably be improved try: - next_elt = self._cur_iter.next() - if self._must_save: - self._saved.append(next_elt) + item = next(self._cur_iter) except StopIteration: self._cur_iter = iter(self._saved) - next_elt = self._cur_iter.next() - self._must_save = False - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iter)) - return next_elt + item = next(self._cur_iter) + return item class dropwhile(object): @@ -297,16 +293,11 @@ return self def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) + value = next(self._iter) if self._dropped: return value while self._predicate(value): - value = self._iter.next() + value = next(self._iter) self._dropped = True return value @@ -341,12 +332,7 @@ def next(self): while self.currkey == self.tgtkey: - try: - self.currvalue = self.it.next() # Exit on StopIteration - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self.it)) + self.currvalue = next(self.it) # Exit on StopIteration self.currkey = self.keyfunc(self.currvalue) self.tgtkey = self.currkey return (self.currkey, self._grouper(self.tgtkey)) @@ -354,7 +340,7 @@ def _grouper(self, tgtkey): while self.currkey == tgtkey: yield self.currvalue - self.currvalue = self.it.next() # Exit on StopIteration + self.currvalue = next(self.it) # Exit on StopIteration self.currkey = self.keyfunc(self.currvalue) @@ -387,16 +373,10 @@ yield x """ def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) while True: + next_elt = next(self._iter) if self._predicate(next_elt): return next_elt - next_elt = self._iter.next() class ifilterfalse(_ifilter_base): """Make an iterator that filters elements from iterable returning @@ -413,16 +393,10 @@ yield x """ def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) while True: + next_elt = next(self._iter) if not self._predicate(next_elt): return next_elt - next_elt = self._iter.next() @@ -450,6 +424,8 @@ """ def __init__(self, function, iterable, *other_iterables): + if function is None: + function = lambda *args: args self._func = function self._iters = map(iter, (iterable, ) + other_iterables) @@ -457,16 +433,8 @@ return self def next(self): - try: - args = [it.next() for it in self._iters] - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (it)) - if self._func is None: - return tuple(args) - else: - return self._func(*args) + args = [next(it) for it in self._iters] + return self._func(*args) @@ -504,11 +472,7 @@ while i < self.next_pos: if i >= self.max_pos: raise StopIteration() - try: - item = self.iterable.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (self.iterable)) + item = next(self.iterable) i += 1 self.pos = i @@ -538,11 +502,7 @@ def next(self): if not self._iterators: raise StopIteration() - try: - return tuple([i.next() for i in self._iterators]) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (i)) + return tuple([next(i) for i in self._iterators]) class izip_longest(object): @@ -556,7 +516,7 @@ def __init__(self, *iterables, **kwargs): self.fillvalue = kwargs.pop('fillvalue', None) if kwargs: - msg = 'izip_longest() got unexpected keyword arguments' + msg = 'izip_longest() got unexpected keyword argument(s)' raise TypeError(msg) self.iterators = map(iter, iterables) self.repeaters_left = len(self.iterators) @@ -570,16 +530,13 @@ result = [None] * len(self.iterators) for i, iterator in enumerate(self.iterators): try: - item = iterator.next() + item = next(iterator) except StopIteration: self.repeaters_left -= 1 if self.repeaters_left <= 0: raise self.iterators[i] = repeat(self.fillvalue) item = self.fillvalue - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (iterator)) result[i] = item return tuple(result) @@ -663,10 +620,10 @@ yield tuple(prod) """ def __init__(self, *args, **kw): - if len(kw) > 1: - raise TypeError("product() takes at most 1 argument (%d given)" % - len(kw)) - repeat = kw.get('repeat', 1) + repeat = kw.pop('repeat', 1) + if kw: + msg = 'product() got unexpected keyword argument(s)' + raise TypeError(msg) self.sources = map(tuple, args) * repeat self.indices = [0] * len(self.sources) try: @@ -754,7 +711,7 @@ def __len__(self): if self._times == -1 or self._times is None: - raise TypeError("len() of uniszed object") + raise TypeError("len() of unsized object") return self._times @@ -781,12 +738,7 @@ return self def next(self): - # CPython raises a TypeError when the iterator doesn't return a tuple - try: - t = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) + t = next(self._iter) return self._func(*t) @@ -812,13 +764,9 @@ return self def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) + value = next(self._iter) if not self._predicate(value): + self._iter = iter([]) raise StopIteration() return value @@ -831,12 +779,9 @@ def __getitem__(self, i): # iterates until 'i' if not done yet - while i>= len(self.data): - try: - self.data.append( self._iter.next() ) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) + while i >= len(self.data): + value = next(self._iter) + self.data.append(value) return self.data[i] @@ -894,7 +839,6 @@ raise ValueError('n must be >= 0') if isinstance(iterable, TeeObject): # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) - return tuple([iterable] + - [TeeObject(tee_data=iterable.tee_data) for i in xrange(n-1)]) + return tuple([iterable] + [TeeObject(iterable) for i in xrange(n-1)]) tee_data = TeeData(iter(iterable)) return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)]) From noreply at buildbot.pypy.org Fri Oct 26 12:16:08 2012 From: noreply at buildbot.pypy.org (cbjadwani) Date: Fri, 26 Oct 2012 12:16:08 +0200 (CEST) Subject: [pypy-commit] pypy default: Make helper methods/attributes private in lib_pypy.itertools Message-ID: <20121026101608.502731C0448@cobra.cs.uni-duesseldorf.de> Author: Chirag Jadwani Branch: Changeset: r58437:7260a1f69a8a Date: 2012-08-01 00:36 +0530 http://bitbucket.org/pypy/pypy/changeset/7260a1f69a8a/ Log: Make helper methods/attributes private in lib_pypy.itertools diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py --- a/lib_pypy/itertools.py +++ b/lib_pypy/itertools.py @@ -36,7 +36,7 @@ except ImportError: builtinify = lambda f: f -def check_number(n): +def _check_number(n): if not hasattr(n, '__int__') and not hasattr(n, '__float__'): raise TypeError('expected a number') @@ -84,60 +84,60 @@ combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3) """ def __init__(self, iterable, r): - self.pool = list(iterable) + self._pool = list(iterable) if r < 0: raise ValueError('r must be non-negative') - self.r = r - self.indices = range(len(self.pool)) - self.last_result = None - self.stopped = r > len(self.pool) + self._r = r + self._indices = range(len(self._pool)) + self._last_result = None + self._stopped = r > len(self._pool) def __iter__(self): return self - def get_maximum(self, i): - return i + len(self.pool) - self.r + def _get_maximum(self, i): + return i + len(self._pool) - self._r - def max_index(self, j): - return self.indices[j - 1] + 1 + def _max_index(self, j): + return self._indices[j - 1] + 1 def next(self): - if self.stopped: + if self._stopped: raise StopIteration() - if self.last_result is None: + if self._last_result is None: # On the first pass, initialize result tuple using the indices - result = [None] * self.r - for i in xrange(self.r): - index = self.indices[i] - result[i] = self.pool[index] + result = [None] * self._r + for i in xrange(self._r): + index = self._indices[i] + result[i] = self._pool[index] else: # Copy the previous result - result = self.last_result[:] + result = self._last_result[:] # Scan indices right-to-left until finding one that is not at its # maximum - i = self.r - 1 - while i >= 0 and self.indices[i] == self.get_maximum(i): + i = self._r - 1 + while i >= 0 and self._indices[i] == self._get_maximum(i): i -= 1 # If i is negative, then the indices are all at their maximum value # and we're done if i < 0: - self.stopped = True + self._stopped = True raise StopIteration() # Increment the current index which we know is not at its maximum. # Then move back to the right setting each index to its lowest # possible value - self.indices[i] += 1 - for j in range(i + 1, self.r): - self.indices[j] = self.max_index(j) + self._indices[i] += 1 + for j in range(i + 1, self._r): + self._indices[j] = self._max_index(j) # Update the result for the new indices starting with i, the # leftmost index that changed - for i in range(i, self.r): - index = self.indices[i] - result[i] = self.pool[index] - self.last_result = result + for i in range(i, self._r): + index = self._indices[i] + result[i] = self._pool[index] + self._last_result = result return tuple(result) @@ -150,14 +150,14 @@ """ def __init__(self, iterable, r): super(combinations_with_replacement, self).__init__(iterable, r) - self.indices = [0] * r - self.stopped = len(self.pool) == 0 and r > 0 + self._indices = [0] * r + self._stopped = len(self._pool) == 0 and r > 0 - def get_maximum(self, i): - return len(self.pool) - 1 + def _get_maximum(self, i): + return len(self._pool) - 1 - def max_index(self, j): - return self.indices[j - 1] + def _max_index(self, j): + return self._indices[j - 1] class compress(object): @@ -173,16 +173,16 @@ return (d for d, s in izip(data, selectors) if s) """ def __init__(self, data, selectors): - self.data = iter(data) - self.selectors = iter(selectors) + self._data = iter(data) + self._selectors = iter(selectors) def __iter__(self): return self def next(self): while True: - next_item = next(self.data) - next_selector = next(self.selectors) + next_item = next(self._data) + next_selector = next(self._selectors) if bool(next_selector): return next_item @@ -202,30 +202,30 @@ n += step """ def __init__(self, start=0, step=1): - check_number(start) - check_number(step) - self.counter = start - self.step = step + _check_number(start) + _check_number(step) + self._counter = start + self._step = step def __iter__(self): return self def next(self): - c = self.counter - self.counter += self.step + c = self._counter + self._counter += self._step return c def __reduce__(self): - if self.step is 1: - args = (self.counter,) + if self._step is 1: + args = (self._counter,) else: - args = (self.counter, self.step) + args = (self._counter, self._step) return (self.__class__, args) def __repr__(self): - if self.step is 1: - return 'count(%r)' % (self.counter) - return 'count(%r, %r)' % (self.counter, self.step) + if self._step is 1: + return 'count(%r)' % (self._counter) + return 'count(%r, %r)' % (self._counter, self._step) @@ -323,25 +323,25 @@ def __init__(self, iterable, key=None): if key is None: key = lambda x: x - self.keyfunc = key - self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = xrange(0) + self._keyfunc = key + self._iter = iter(iterable) + self._tgtkey = self._currkey = self._currvalue = xrange(0) def __iter__(self): return self def next(self): - while self.currkey == self.tgtkey: - self.currvalue = next(self.it) # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) - self.tgtkey = self.currkey - return (self.currkey, self._grouper(self.tgtkey)) + while self._currkey == self._tgtkey: + self._currvalue = next(self._iter) # Exit on StopIteration + self._currkey = self._keyfunc(self._currvalue) + self._tgtkey = self._currkey + return (self._currkey, self._grouper(self._tgtkey)) def _grouper(self, tgtkey): - while self.currkey == tgtkey: - yield self.currvalue - self.currvalue = next(self.it) # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) + while self._currkey == tgtkey: + yield self._currvalue + self._currvalue = next(self._iter) # Exit on StopIteration + self._currkey = self._keyfunc(self._currvalue) @@ -458,25 +458,25 @@ msg = ('%s for islice must be None or an integer: ' '0 <= x <= maxint') raise ValueError(msg % n) - start, stop, self.step = s.indices(sys.maxint) - self.iterable = iter(iterable) - self.pos = -1 - self.next_pos = start - self.max_pos = stop - 1 + start, stop, self._step = s.indices(sys.maxint) + self._iter = iter(iterable) + self._pos = -1 + self._next_pos = start + self._max_pos = stop - 1 def __iter__(self): return self def next(self): - i = self.pos - while i < self.next_pos: - if i >= self.max_pos: + i = self._pos + while i < self._next_pos: + if i >= self._max_pos: raise StopIteration() - item = next(self.iterable) + item = next(self._iter) i += 1 - self.pos = i - self.next_pos += self.step + self._pos = i + self._next_pos += self._step return item class izip(object): @@ -514,29 +514,29 @@ defaults to None or can be specified by a keyword argument. """ def __init__(self, *iterables, **kwargs): - self.fillvalue = kwargs.pop('fillvalue', None) + self._fillvalue = kwargs.pop('fillvalue', None) if kwargs: msg = 'izip_longest() got unexpected keyword argument(s)' raise TypeError(msg) - self.iterators = map(iter, iterables) - self.repeaters_left = len(self.iterators) + self._iters = map(iter, iterables) + self._iters_yielding = len(self._iters) def __iter__(self): return self def next(self): - if self.repeaters_left <= 0: + if self._iters_yielding <= 0: raise StopIteration() - result = [None] * len(self.iterators) - for i, iterator in enumerate(self.iterators): + result = [None] * len(self._iters) + for i, iterator in enumerate(self._iters): try: item = next(iterator) except StopIteration: - self.repeaters_left -= 1 - if self.repeaters_left <= 0: + self._iters_yielding -= 1 + if self._iters_yielding <= 0: raise - self.iterators[i] = repeat(self.fillvalue) - item = self.fillvalue + self._iters[i] = repeat(self._fillvalue) + item = self._fillvalue result[i] = item return tuple(result) @@ -549,29 +549,29 @@ permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1) """ def __init__(self, iterable, r=None): - self.pool = list(iterable) - n = len(self.pool) + self._pool = list(iterable) + n = len(self._pool) if r is None: r = n elif r < 0: raise ValueError('r must be non-negative') - self.r = r - self.indices = range(n) - self.cycles = range(n, n - r, -1) - self.stopped = r > n + self._r = r + self._indices = range(n) + self._cycles = range(n, n - r, -1) + self._stopped = r > n def __iter__(self): return self def next(self): - if self.stopped: + if self._stopped: raise StopIteration() - r = self.r - indices = self.indices - cycles = self.cycles + r = self._r + indices = self._indices + cycles = self._cycles - result = tuple([self.pool[indices[i]] for i in range(r)]) + result = tuple([self._pool[indices[i]] for i in range(r)]) i = r - 1 while i >= 0: j = cycles[i] - 1 @@ -587,7 +587,7 @@ indices[k] = indices[k+1] indices[n1] = num i -= 1 - self.stopped = True + self._stopped = True return result @@ -624,48 +624,48 @@ if kw: msg = 'product() got unexpected keyword argument(s)' raise TypeError(msg) - self.sources = map(tuple, args) * repeat - self.indices = [0] * len(self.sources) + self._pools = map(tuple, args) * repeat + self._indices = [0] * len(self._pools) try: - self.next_result = [s[0] for s in self.sources] + self._next_result = [s[0] for s in self._pools] except IndexError: - self.next_result = None + self._next_result = None + + def __iter__(self): + return self def next(self): - sources = self.sources - indices = self.indices + pools = self._pools + indices = self._indices - if self.next_result is None: + if self._next_result is None: raise StopIteration() - result = tuple(self.next_result) + result = tuple(self._next_result) - i = len(sources) + i = len(pools) while True: i -= 1 if i < 0: - self.next_result = None + self._next_result = None return result j = indices[i] j += 1 - if j < len(sources[i]): + if j < len(pools[i]): break - self.next_result[i] = sources[i][j] + self._next_result[i] = pools[i][j] indices[i] = j while True: i += 1 - if i >= len(sources): + if i >= len(pools): break indices[i] = 0 - self.next_result[i] = sources[i][0] + self._next_result[i] = pools[i][0] return result - def __iter__(self): - return self - class repeat(object): """Make an iterator that returns object over and over again. @@ -771,7 +771,7 @@ return value -class TeeData(object): +class _TeeData(object): """Holds cached values for TeeObjects""" def __init__(self, iterator): self.data = [] @@ -785,18 +785,18 @@ return self.data[i] -class TeeObject(object): +class _TeeObject(object): """Iterables / Iterators as returned by the tee() function""" def __init__(self, iterable=None, tee_data=None): if tee_data: self.tee_data = tee_data self.pos = 0 # <=> Copy constructor - elif isinstance(iterable, TeeObject): + elif isinstance(iterable, _TeeObject): self.tee_data = iterable.tee_data self.pos = iterable.pos else: - self.tee_data = TeeData(iter(iterable)) + self.tee_data = _TeeData(iter(iterable)) self.pos = 0 def next(self): @@ -837,8 +837,8 @@ """ if n < 0: raise ValueError('n must be >= 0') - if isinstance(iterable, TeeObject): + if isinstance(iterable, _TeeObject): # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) - return tuple([iterable] + [TeeObject(iterable) for i in xrange(n-1)]) - tee_data = TeeData(iter(iterable)) - return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)]) + return tuple([iterable] + [_TeeObject(iterable) for i in xrange(n-1)]) + tee_data = _TeeData(iter(iterable)) + return tuple([_TeeObject(tee_data=tee_data) for i in xrange(n)]) From noreply at buildbot.pypy.org Fri Oct 26 12:16:09 2012 From: noreply at buildbot.pypy.org (cbjadwani) Date: Fri, 26 Oct 2012 12:16:09 +0200 (CEST) Subject: [pypy-commit] pypy default: Add lib_pypy.itertools tests, fix check_number in interp_itertools Message-ID: <20121026101609.683D91C0448@cobra.cs.uni-duesseldorf.de> Author: Chirag Jadwani Branch: Changeset: r58438:2f592ec771aa Date: 2012-08-01 01:43 +0530 http://bitbucket.org/pypy/pypy/changeset/2f592ec771aa/ Log: Add lib_pypy.itertools tests, fix check_number in interp_itertools diff --git a/lib_pypy/pypy_test/test_itertools.py b/lib_pypy/pypy_test/test_itertools.py --- a/lib_pypy/pypy_test/test_itertools.py +++ b/lib_pypy/pypy_test/test_itertools.py @@ -48,3 +48,20 @@ l = [1, 2] m = ['a'] raises(TypeError, itertools.product, l, m, repeat=1, foo=2) + + def test_tee_copy_constructor(self): + a, b = itertools.tee(range(10)) + next(a) + next(a) + c, d = itertools.tee(a) + assert list(a) == list(d) + + def test_product_kwargs(self): + raises(TypeError, itertools.product, range(10), garbage=1) + + def test_takewhile_stops(self): + tw = itertools.takewhile(lambda x: bool(x), [1, 1, 0, 1, 1]) + next(tw) + next(tw) + raises(StopIteration, next, tw) + raises(StopIteration, next, tw) diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -43,9 +43,8 @@ space.newtuple(args_w)]) def check_number(space, w_obj): - if (space.lookup(w_obj, '__add__') is None or - space.is_true(space.isinstance(w_obj, space.w_str)) or - space.is_true(space.isinstance(w_obj, space.w_unicode))): + if (space.lookup(w_obj, '__int__') is None and + space.lookup(w_obj, '__float__') is None): raise OperationError(space.w_TypeError, space.wrap("expected a number")) @@ -64,20 +63,18 @@ next = interp2app(W_Count.next_w), __reduce__ = interp2app(W_Count.reduce_w), __repr__ = interp2app(W_Count.repr_w), - __doc__ = """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. + __doc__ = """Make an iterator that returns evenly spaced values starting + with n. If not specified n defaults to zero. Often used as an + argument to imap() to generate consecutive data points. Also, + used with izip() to add sequence numbers. - Equivalent to : + Equivalent to: - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) + def count(start=0, step=1): + n = start while True: yield n - n += 1 + n += step """) From noreply at buildbot.pypy.org Fri Oct 26 12:16:10 2012 From: noreply at buildbot.pypy.org (cbjadwani) Date: Fri, 26 Oct 2012 12:16:10 +0200 (CEST) Subject: [pypy-commit] pypy default: Change _is 1_ to _== 1_ in lib_pypy.itertools tests Message-ID: <20121026101610.863C61C0448@cobra.cs.uni-duesseldorf.de> Author: Chirag Jadwani Branch: Changeset: r58439:3eb41b3bf182 Date: 2012-08-01 01:46 +0530 http://bitbucket.org/pypy/pypy/changeset/3eb41b3bf182/ Log: Change _is 1_ to _== 1_ in lib_pypy.itertools tests diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py --- a/lib_pypy/itertools.py +++ b/lib_pypy/itertools.py @@ -216,14 +216,14 @@ return c def __reduce__(self): - if self._step is 1: + if self._step == 1: args = (self._counter,) else: args = (self._counter, self._step) return (self.__class__, args) def __repr__(self): - if self._step is 1: + if self._step == 1: return 'count(%r)' % (self._counter) return 'count(%r, %r)' % (self._counter, self._step) From noreply at buildbot.pypy.org Fri Oct 26 12:16:11 2012 From: noreply at buildbot.pypy.org (cbjadwani) Date: Fri, 26 Oct 2012 12:16:11 +0200 (CEST) Subject: [pypy-commit] pypy default: Minor fix in lib_pypy.itertools.count, added test Message-ID: <20121026101611.A58E21C0448@cobra.cs.uni-duesseldorf.de> Author: Chirag Jadwani Branch: Changeset: r58440:8d78e41a3511 Date: 2012-08-01 02:09 +0530 http://bitbucket.org/pypy/pypy/changeset/8d78e41a3511/ Log: Minor fix in lib_pypy.itertools.count, added test diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py --- a/lib_pypy/itertools.py +++ b/lib_pypy/itertools.py @@ -215,15 +215,18 @@ self._counter += self._step return c + def _single_argument(self): + return self._step == 1 and isinstance(self._step, int) + def __reduce__(self): - if self._step == 1: + if self._single_argument(): args = (self._counter,) else: args = (self._counter, self._step) return (self.__class__, args) def __repr__(self): - if self._step == 1: + if self._single_argument(): return 'count(%r)' % (self._counter) return 'count(%r, %r)' % (self._counter, self._step) diff --git a/lib_pypy/pypy_test/test_itertools.py b/lib_pypy/pypy_test/test_itertools.py --- a/lib_pypy/pypy_test/test_itertools.py +++ b/lib_pypy/pypy_test/test_itertools.py @@ -65,3 +65,7 @@ next(tw) raises(StopIteration, next, tw) raises(StopIteration, next, tw) + + def test_count_repr(self): + c = itertools.count(10, 1.0) + assert repr(c) == 'count(10, 1.0)' From noreply at buildbot.pypy.org Fri Oct 26 12:16:12 2012 From: noreply at buildbot.pypy.org (cbjadwani) Date: Fri, 26 Oct 2012 12:16:12 +0200 (CEST) Subject: [pypy-commit] pypy default: Make itertools.tee shared data a linked list Message-ID: <20121026101612.BD3671C0448@cobra.cs.uni-duesseldorf.de> Author: Chirag Jadwani Branch: Changeset: r58441:c1a38c26cf83 Date: 2012-08-02 01:55 +0530 http://bitbucket.org/pypy/pypy/changeset/c1a38c26cf83/ Log: Make itertools.tee shared data a linked list diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py --- a/lib_pypy/itertools.py +++ b/lib_pypy/itertools.py @@ -773,40 +773,56 @@ raise StopIteration() return value - + class _TeeData(object): - """Holds cached values for TeeObjects""" + """Holds cached values shared by _TeeObjects + + _TeeData instances form linked list where in any instance (node) at most + CHUNK_SIZE items are cached. + """ + CHUNK_SIZE = 64 def __init__(self, iterator): - self.data = [] - self._iter = iterator + self.data = [None] * _TeeData.CHUNK_SIZE + self.iterator = iterator # must be an iterator not an iterable + self.num_read = 0 + self.next_link = None def __getitem__(self, i): - # iterates until 'i' if not done yet - while i >= len(self.data): - value = next(self._iter) - self.data.append(value) + if i == self.num_read: + item = next(self.iterator) + self.data[i] = item + self.num_read += 1 + assert i < self.num_read return self.data[i] + def get_next_link(self): + assert self.num_read == _TeeData.CHUNK_SIZE + if self.next_link is None: + self.next_link = _TeeData(self.iterator) + return self.next_link + class _TeeObject(object): """Iterables / Iterators as returned by the tee() function""" - def __init__(self, iterable=None, tee_data=None): - if tee_data: - self.tee_data = tee_data - self.pos = 0 - # <=> Copy constructor - elif isinstance(iterable, _TeeObject): + def __init__(self, iterable): + if isinstance(iterable, _TeeObject): self.tee_data = iterable.tee_data self.pos = iterable.pos else: self.tee_data = _TeeData(iter(iterable)) self.pos = 0 - + def next(self): + assert self.pos <= _TeeData.CHUNK_SIZE + + if self.pos == _TeeData.CHUNK_SIZE: + self.tee_data = self.tee_data.get_next_link() + self.pos = 0 + data = self.tee_data[self.pos] self.pos += 1 return data - + def __iter__(self): return self @@ -814,34 +830,38 @@ @builtinify def tee(iterable, n=2): """Return n independent iterators from a single iterable. + Note : once tee() has made a split, the original iterable should not be used anywhere else; otherwise, the iterable could get advanced without the tee objects being informed. - + Note : this member of the toolkit may require significant auxiliary storage (depending on how much temporary data needs to be stored). In general, if one iterator is going to use most or all of the data before the other iterator, it is faster to use list() instead of tee() - + Equivalent to : - + def tee(iterable, n=2): - def gen(next, data={}, cnt=[0]): - for i in count(): - if i == cnt[0]: - item = data[i] = next() - cnt[0] += 1 - else: - item = data.pop(i) - yield item it = iter(iterable) - return tuple([gen(it.next) for i in range(n)]) + deques = [collections.deque() for i in range(n)] + def gen(mydeque): + while True: + if not mydeque: # when the local deque is empty + newval = next(it) # fetch a new value and + for d in deques: # load it to all the deques + d.append(newval) + yield mydeque.popleft() + return tuple(gen(d) for d in deques) """ if n < 0: raise ValueError('n must be >= 0') + if n == 0: + return () if isinstance(iterable, _TeeObject): # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) - return tuple([iterable] + [_TeeObject(iterable) for i in xrange(n-1)]) - tee_data = _TeeData(iter(iterable)) - return tuple([_TeeObject(tee_data=tee_data) for i in xrange(n)]) + tee_obj = iterable + else: + tee_obj = _TeeObject(iterable) + return tuple([tee_obj] + [_TeeObject(tee_obj) for i in xrange(n-1)]) From noreply at buildbot.pypy.org Fri Oct 26 12:16:23 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 12:16:23 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121026101623.B13841C0448@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58442:9727f742576f Date: 2012-10-26 12:14 +0200 http://bitbucket.org/pypy/pypy/changeset/9727f742576f/ Log: merge heads diff too long, truncating to 2000 out of 109628 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,5 +1,6 @@ syntax: glob *.py[co] +*.sw[po] *~ .*.swp .idea diff --git a/lib-python/2.7/BaseHTTPServer.py b/lib-python/2.7/BaseHTTPServer.py --- a/lib-python/2.7/BaseHTTPServer.py +++ b/lib-python/2.7/BaseHTTPServer.py @@ -244,14 +244,11 @@ self.request_version = version = self.default_request_version self.close_connection = 1 requestline = self.raw_requestline - if requestline[-2:] == '\r\n': - requestline = requestline[:-2] - elif requestline[-1:] == '\n': - requestline = requestline[:-1] + requestline = requestline.rstrip('\r\n') self.requestline = requestline words = requestline.split() if len(words) == 3: - [command, path, version] = words + command, path, version = words if version[:5] != 'HTTP/': self.send_error(400, "Bad request version (%r)" % version) return False @@ -277,7 +274,7 @@ "Invalid HTTP Version (%s)" % base_version_number) return False elif len(words) == 2: - [command, path] = words + command, path = words self.close_connection = 1 if command != 'GET': self.send_error(400, diff --git a/lib-python/2.7/ConfigParser.py b/lib-python/2.7/ConfigParser.py --- a/lib-python/2.7/ConfigParser.py +++ b/lib-python/2.7/ConfigParser.py @@ -142,6 +142,7 @@ def __init__(self, section): Error.__init__(self, 'No section: %r' % (section,)) self.section = section + self.args = (section, ) class DuplicateSectionError(Error): """Raised when a section is multiply-created.""" @@ -149,6 +150,7 @@ def __init__(self, section): Error.__init__(self, "Section %r already exists" % section) self.section = section + self.args = (section, ) class NoOptionError(Error): """A requested option was not found.""" @@ -158,6 +160,7 @@ (option, section)) self.option = option self.section = section + self.args = (option, section) class InterpolationError(Error): """Base class for interpolation-related exceptions.""" @@ -166,6 +169,7 @@ Error.__init__(self, msg) self.option = option self.section = section + self.args = (option, section, msg) class InterpolationMissingOptionError(InterpolationError): """A string substitution required a setting which was not available.""" @@ -179,6 +183,7 @@ % (section, option, reference, rawval)) InterpolationError.__init__(self, option, section, msg) self.reference = reference + self.args = (option, section, rawval, reference) class InterpolationSyntaxError(InterpolationError): """Raised when the source text into which substitutions are made @@ -194,6 +199,7 @@ "\trawval : %s\n" % (section, option, rawval)) InterpolationError.__init__(self, option, section, msg) + self.args = (option, section, rawval) class ParsingError(Error): """Raised when a configuration file does not follow legal syntax.""" @@ -202,6 +208,7 @@ Error.__init__(self, 'File contains parsing errors: %s' % filename) self.filename = filename self.errors = [] + self.args = (filename, ) def append(self, lineno, line): self.errors.append((lineno, line)) @@ -218,6 +225,7 @@ self.filename = filename self.lineno = lineno self.line = line + self.args = (filename, lineno, line) class RawConfigParser: @@ -570,7 +578,7 @@ def keys(self): result = [] seen = set() - for mapping in self_maps: + for mapping in self._maps: for key in mapping: if key not in seen: result.append(key) diff --git a/lib-python/2.7/HTMLParser.py b/lib-python/2.7/HTMLParser.py --- a/lib-python/2.7/HTMLParser.py +++ b/lib-python/2.7/HTMLParser.py @@ -14,7 +14,6 @@ # Regular expressions used for parsing interesting_normal = re.compile('[&<]') -interesting_cdata = re.compile(r'<(/|\Z)') incomplete = re.compile('&[a-zA-Z#]') entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') @@ -24,25 +23,31 @@ piclose = re.compile('>') commentclose = re.compile(r'--\s*>') tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*') +# see http://www.w3.org/TR/html5/tokenization.html#tag-open-state +# and http://www.w3.org/TR/html5/tokenization.html#tag-name-state +tagfind_tolerant = re.compile('[a-zA-Z][^\t\n\r\f />\x00]*') + attrfind = re.compile( - r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' - r'(\'[^\']*\'|"[^"]*"|[^\s"\'=<>`]*))?') + r'[\s/]*((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' + r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*') locatestarttagend = re.compile(r""" <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name - (?:\s+ # whitespace before attribute name - (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name - (?:\s*=\s* # value indicator + (?:[\s/]* # optional whitespace before attribute name + (?:(?<=['"\s/])[^\s/>][^\s/=>]* # attribute name + (?:\s*=+\s* # value indicator (?:'[^']*' # LITA-enclosed value - |\"[^\"]*\" # LIT-enclosed value - |[^'\">\s]+ # bare value + |"[^"]*" # LIT-enclosed value + |(?!['"])[^>\s]* # bare value ) - )? - ) - )* + )?(?:\s|/(?!>))* + )* + )? \s* # trailing whitespace """, re.VERBOSE) endendtag = re.compile('>') +# the HTML 5 spec, section 8.1.2.2, doesn't allow spaces between +# ') @@ -96,6 +101,7 @@ self.rawdata = '' self.lasttag = '???' self.interesting = interesting_normal + self.cdata_elem = None markupbase.ParserBase.reset(self) def feed(self, data): @@ -120,11 +126,13 @@ """Return full source of start tag: '<...>'.""" return self.__starttag_text - def set_cdata_mode(self): - self.interesting = interesting_cdata + def set_cdata_mode(self, elem): + self.cdata_elem = elem.lower() + self.interesting = re.compile(r'' % self.cdata_elem, re.I) def clear_cdata_mode(self): self.interesting = interesting_normal + self.cdata_elem = None # Internal -- handle data as far as reasonable. May leave state # and data to be processed by a subsequent call. If 'end' is @@ -138,6 +146,8 @@ if match: j = match.start() else: + if self.cdata_elem: + break j = n if i < j: self.handle_data(rawdata[i:j]) i = self.updatepos(i, j) @@ -153,16 +163,23 @@ elif startswith("', i + 1) + if k < 0: + k = rawdata.find('<', i + 1) + if k < 0: + k = i + 1 + else: + k += 1 + self.handle_data(rawdata[i:k]) i = self.updatepos(i, k) elif startswith("&#", i): match = charref.match(rawdata, i) @@ -206,11 +223,46 @@ else: assert 0, "interesting.search() lied" # end while - if end and i < n: + if end and i < n and not self.cdata_elem: self.handle_data(rawdata[i:n]) i = self.updatepos(i, n) self.rawdata = rawdata[i:] + # Internal -- parse html declarations, return length or -1 if not terminated + # See w3.org/TR/html5/tokenization.html#markup-declaration-open-state + # See also parse_declaration in _markupbase + def parse_html_declaration(self, i): + rawdata = self.rawdata + if rawdata[i:i+2] != ' + gtpos = rawdata.find('>', i+9) + if gtpos == -1: + return -1 + self.handle_decl(rawdata[i+2:gtpos]) + return gtpos+1 + else: + return self.parse_bogus_comment(i) + + # Internal -- parse bogus comment, return length or -1 if not terminated + # see http://www.w3.org/TR/html5/tokenization.html#bogus-comment-state + def parse_bogus_comment(self, i, report=1): + rawdata = self.rawdata + if rawdata[i:i+2] not in ('', i+2) + if pos == -1: + return -1 + if report: + self.handle_comment(rawdata[i+2:pos]) + return pos + 1 + # Internal -- parse processing instr, return end or -1 if not terminated def parse_pi(self, i): rawdata = self.rawdata @@ -249,6 +301,7 @@ elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ attrvalue[:1] == '"' == attrvalue[-1:]: attrvalue = attrvalue[1:-1] + if attrvalue: attrvalue = self.unescape(attrvalue) attrs.append((attrname.lower(), attrvalue)) k = m.end() @@ -262,15 +315,15 @@ - self.__starttag_text.rfind("\n") else: offset = offset + len(self.__starttag_text) - self.error("junk characters in start tag: %r" - % (rawdata[k:endpos][:20],)) + self.handle_data(rawdata[i:endpos]) + return endpos if end.endswith('/>'): # XHTML-style empty tag: self.handle_startendtag(tag, attrs) else: self.handle_starttag(tag, attrs) if tag in self.CDATA_CONTENT_ELEMENTS: - self.set_cdata_mode() + self.set_cdata_mode(tag) return endpos # Internal -- check to see if we have a complete starttag; return end @@ -300,8 +353,10 @@ # end of input in or before attribute value, or we have the # '/' from a '/>' ending return -1 - self.updatepos(i, j) - self.error("malformed start tag") + if j > i: + return j + else: + return i + 1 raise AssertionError("we should not get here!") # Internal -- parse endtag, return end or -1 if incomplete @@ -311,14 +366,38 @@ match = endendtag.search(rawdata, i+1) # > if not match: return -1 - j = match.end() + gtpos = match.end() match = endtagfind.match(rawdata, i) # if not match: - self.error("bad end tag: %r" % (rawdata[i:j],)) - tag = match.group(1) - self.handle_endtag(tag.lower()) + if self.cdata_elem is not None: + self.handle_data(rawdata[i:gtpos]) + return gtpos + # find the name: w3.org/TR/html5/tokenization.html#tag-name-state + namematch = tagfind_tolerant.match(rawdata, i+2) + if not namematch: + # w3.org/TR/html5/tokenization.html#end-tag-open-state + if rawdata[i:i+3] == '': + return i+3 + else: + return self.parse_bogus_comment(i) + tagname = namematch.group().lower() + # consume and ignore other stuff between the name and the > + # Note: this is not 100% correct, since we might have things like + # , but looking for > after tha name should cover + # most of the cases and is much simpler + gtpos = rawdata.find('>', namematch.end()) + self.handle_endtag(tagname) + return gtpos+1 + + elem = match.group(1).lower() # script or style + if self.cdata_elem is not None: + if elem != self.cdata_elem: + self.handle_data(rawdata[i:gtpos]) + return gtpos + + self.handle_endtag(elem) self.clear_cdata_mode() - return j + return gtpos # Overridable -- finish processing of start+end tag: def handle_startendtag(self, tag, attrs): @@ -358,7 +437,7 @@ pass def unknown_decl(self, data): - self.error("unknown declaration: %r" % (data,)) + pass # Internal -- helper to remove special character quoting entitydefs = None diff --git a/lib-python/2.7/SocketServer.py b/lib-python/2.7/SocketServer.py --- a/lib-python/2.7/SocketServer.py +++ b/lib-python/2.7/SocketServer.py @@ -82,7 +82,7 @@ data is stored externally (e.g. in the file system), a synchronous class will essentially render the service "deaf" while one request is being handled -- which may be for a very long time if a client is slow -to reqd all the data it has requested. Here a threading or forking +to read all the data it has requested. Here a threading or forking server is appropriate. In some cases, it may be appropriate to process part of a request @@ -589,8 +589,7 @@ """Start a new thread to process the request.""" t = threading.Thread(target = self.process_request_thread, args = (request, client_address)) - if self.daemon_threads: - t.setDaemon (1) + t.daemon = self.daemon_threads t.start() diff --git a/lib-python/2.7/_pyio.py b/lib-python/2.7/_pyio.py --- a/lib-python/2.7/_pyio.py +++ b/lib-python/2.7/_pyio.py @@ -8,6 +8,7 @@ import abc import codecs import warnings +import errno # Import thread instead of threading to reduce startup cost try: from thread import allocate_lock as Lock @@ -720,8 +721,11 @@ def close(self): if self.raw is not None and not self.closed: - self.flush() - self.raw.close() + try: + # may raise BlockingIOError or BrokenPipeError etc + self.flush() + finally: + self.raw.close() def detach(self): if self.raw is None: @@ -1074,13 +1078,9 @@ # XXX we can implement some more tricks to try and avoid # partial writes if len(self._write_buf) > self.buffer_size: - # We're full, so let's pre-flush the buffer - try: - self._flush_unlocked() - except BlockingIOError as e: - # We can't accept anything else. - # XXX Why not just let the exception pass through? - raise BlockingIOError(e.errno, e.strerror, 0) + # We're full, so let's pre-flush the buffer. (This may + # raise BlockingIOError with characters_written == 0.) + self._flush_unlocked() before = len(self._write_buf) self._write_buf.extend(b) written = len(self._write_buf) - before @@ -1111,24 +1111,23 @@ def _flush_unlocked(self): if self.closed: raise ValueError("flush of closed file") - written = 0 - try: - while self._write_buf: - try: - n = self.raw.write(self._write_buf) - except IOError as e: - if e.errno != EINTR: - raise - continue - if n > len(self._write_buf) or n < 0: - raise IOError("write() returned incorrect number of bytes") - del self._write_buf[:n] - written += n - except BlockingIOError as e: - n = e.characters_written + while self._write_buf: + try: + n = self.raw.write(self._write_buf) + except BlockingIOError: + raise RuntimeError("self.raw should implement RawIOBase: it " + "should not raise BlockingIOError") + except IOError as e: + if e.errno != EINTR: + raise + continue + if n is None: + raise BlockingIOError( + errno.EAGAIN, + "write could not complete without blocking", 0) + if n > len(self._write_buf) or n < 0: + raise IOError("write() returned incorrect number of bytes") del self._write_buf[:n] - written += n - raise BlockingIOError(e.errno, e.strerror, written) def tell(self): return _BufferedIOMixin.tell(self) + len(self._write_buf) diff --git a/lib-python/2.7/aifc.py b/lib-python/2.7/aifc.py --- a/lib-python/2.7/aifc.py +++ b/lib-python/2.7/aifc.py @@ -162,6 +162,12 @@ except struct.error: raise EOFError +def _read_ushort(file): + try: + return struct.unpack('>H', file.read(2))[0] + except struct.error: + raise EOFError + def _read_string(file): length = ord(file.read(1)) if length == 0: @@ -194,13 +200,19 @@ def _write_short(f, x): f.write(struct.pack('>h', x)) +def _write_ushort(f, x): + f.write(struct.pack('>H', x)) + def _write_long(f, x): + f.write(struct.pack('>l', x)) + +def _write_ulong(f, x): f.write(struct.pack('>L', x)) def _write_string(f, s): if len(s) > 255: raise ValueError("string exceeds maximum pstring length") - f.write(chr(len(s))) + f.write(struct.pack('B', len(s))) f.write(s) if len(s) & 1 == 0: f.write(chr(0)) @@ -218,7 +230,7 @@ lomant = 0 else: fmant, expon = math.frexp(x) - if expon > 16384 or fmant >= 1: # Infinity or NaN + if expon > 16384 or fmant >= 1 or fmant != fmant: # Infinity or NaN expon = sign|0x7FFF himant = 0 lomant = 0 @@ -234,9 +246,9 @@ fmant = math.ldexp(fmant - fsmant, 32) fsmant = math.floor(fmant) lomant = long(fsmant) - _write_short(f, expon) - _write_long(f, himant) - _write_long(f, lomant) + _write_ushort(f, expon) + _write_ulong(f, himant) + _write_ulong(f, lomant) from chunk import Chunk @@ -840,15 +852,15 @@ if self._aifc: self._file.write('AIFC') self._file.write('FVER') - _write_long(self._file, 4) - _write_long(self._file, self._version) + _write_ulong(self._file, 4) + _write_ulong(self._file, self._version) else: self._file.write('AIFF') self._file.write('COMM') - _write_long(self._file, commlength) + _write_ulong(self._file, commlength) _write_short(self._file, self._nchannels) self._nframes_pos = self._file.tell() - _write_long(self._file, self._nframes) + _write_ulong(self._file, self._nframes) _write_short(self._file, self._sampwidth * 8) _write_float(self._file, self._framerate) if self._aifc: @@ -856,9 +868,9 @@ _write_string(self._file, self._compname) self._file.write('SSND') self._ssnd_length_pos = self._file.tell() - _write_long(self._file, self._datalength + 8) - _write_long(self._file, 0) - _write_long(self._file, 0) + _write_ulong(self._file, self._datalength + 8) + _write_ulong(self._file, 0) + _write_ulong(self._file, 0) def _write_form_length(self, datalength): if self._aifc: @@ -869,8 +881,8 @@ else: commlength = 18 verslength = 0 - _write_long(self._file, 4 + verslength + self._marklength + \ - 8 + commlength + 16 + datalength) + _write_ulong(self._file, 4 + verslength + self._marklength + \ + 8 + commlength + 16 + datalength) return commlength def _patchheader(self): @@ -888,9 +900,9 @@ self._file.seek(self._form_length_pos, 0) dummy = self._write_form_length(datalength) self._file.seek(self._nframes_pos, 0) - _write_long(self._file, self._nframeswritten) + _write_ulong(self._file, self._nframeswritten) self._file.seek(self._ssnd_length_pos, 0) - _write_long(self._file, datalength + 8) + _write_ulong(self._file, datalength + 8) self._file.seek(curpos, 0) self._nframes = self._nframeswritten self._datalength = datalength @@ -905,13 +917,13 @@ length = length + len(name) + 1 + 6 if len(name) & 1 == 0: length = length + 1 - _write_long(self._file, length) + _write_ulong(self._file, length) self._marklength = length + 8 _write_short(self._file, len(self._markers)) for marker in self._markers: id, pos, name = marker _write_short(self._file, id) - _write_long(self._file, pos) + _write_ulong(self._file, pos) _write_string(self._file, name) def open(f, mode=None): diff --git a/lib-python/2.7/asyncore.py b/lib-python/2.7/asyncore.py --- a/lib-python/2.7/asyncore.py +++ b/lib-python/2.7/asyncore.py @@ -132,7 +132,8 @@ is_w = obj.writable() if is_r: r.append(fd) - if is_w: + # accepting sockets should not be writable + if is_w and not obj.accepting: w.append(fd) if is_r or is_w: e.append(fd) @@ -179,7 +180,8 @@ flags = 0 if obj.readable(): flags |= select.POLLIN | select.POLLPRI - if obj.writable(): + # accepting sockets should not be writable + if obj.writable() and not obj.accepting: flags |= select.POLLOUT if flags: # Only check for exceptions if object was either readable diff --git a/lib-python/2.7/cgi.py b/lib-python/2.7/cgi.py --- a/lib-python/2.7/cgi.py +++ b/lib-python/2.7/cgi.py @@ -293,7 +293,7 @@ while s[:1] == ';': s = s[1:] end = s.find(';') - while end > 0 and s.count('"', 0, end) % 2: + while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: end = s.find(';', end + 1) if end < 0: end = len(s) diff --git a/lib-python/2.7/cmd.py b/lib-python/2.7/cmd.py --- a/lib-python/2.7/cmd.py +++ b/lib-python/2.7/cmd.py @@ -209,6 +209,8 @@ if cmd is None: return self.default(line) self.lastcmd = line + if line == 'EOF' : + self.lastcmd = '' if cmd == '': return self.default(line) else: diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -312,6 +312,7 @@ def _asdict(self): 'Return a new OrderedDict which maps field names to their values' return OrderedDict(zip(self._fields, self)) \n + __dict__ = property(_asdict) \n def _replace(_self, **kwds): 'Return a new %(typename)s object replacing specified fields with new values' result = _self._make(map(kwds.pop, %(field_names)r, _self)) diff --git a/lib-python/2.7/compileall.py b/lib-python/2.7/compileall.py --- a/lib-python/2.7/compileall.py +++ b/lib-python/2.7/compileall.py @@ -1,4 +1,4 @@ -"""Module/script to "compile" all .py files to .pyc (or .pyo) file. +"""Module/script to byte-compile all .py files to .pyc (or .pyo) files. When called as a script with arguments, this compiles the directories given as arguments recursively; the -l option prevents it from @@ -26,8 +26,8 @@ dir: the directory to byte-compile maxlevels: maximum recursion level (default 10) - ddir: if given, purported directory name (this is the - directory name that will show up in error messages) + ddir: the directory that will be prepended to the path to the + file as it is compiled into each byte-code file. force: if 1, force compilation, even if timestamps are up-to-date quiet: if 1, be quiet during compilation """ @@ -64,8 +64,8 @@ Arguments (only fullname is required): fullname: the file to byte-compile - ddir: if given, purported directory name (this is the - directory name that will show up in error messages) + ddir: if given, the directory name compiled in to the + byte-code file. force: if 1, force compilation, even if timestamps are up-to-date quiet: if 1, be quiet during compilation """ @@ -157,14 +157,27 @@ print msg print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \ "[-x regexp] [-i list] [directory|file ...]" - print "-l: don't recurse down" + print + print "arguments: zero or more file and directory names to compile; " \ + "if no arguments given, " + print " defaults to the equivalent of -l sys.path" + print + print "options:" + print "-l: don't recurse into subdirectories" print "-f: force rebuild even if timestamps are up-to-date" - print "-q: quiet operation" - print "-d destdir: purported directory name for error messages" - print " if no directory arguments, -l sys.path is assumed" - print "-x regexp: skip files matching the regular expression regexp" - print " the regexp is searched for in the full path of the file" - print "-i list: expand list with its content (file and directory names)" + print "-q: output only error messages" + print "-d destdir: directory to prepend to file paths for use in " \ + "compile-time tracebacks and in" + print " runtime tracebacks in cases where the source " \ + "file is unavailable" + print "-x regexp: skip files matching the regular expression regexp; " \ + "the regexp is searched for" + print " in the full path of each file considered for " \ + "compilation" + print "-i file: add all the files and directories listed in file to " \ + "the list considered for" + print ' compilation; if "-", names are read from stdin' + sys.exit(2) maxlevels = 10 ddir = None @@ -205,7 +218,7 @@ else: success = compile_path() except KeyboardInterrupt: - print "\n[interrupt]" + print "\n[interrupted]" success = 0 return success diff --git a/lib-python/2.7/cookielib.py b/lib-python/2.7/cookielib.py --- a/lib-python/2.7/cookielib.py +++ b/lib-python/2.7/cookielib.py @@ -1014,7 +1014,7 @@ (not erhn.startswith(".") and not ("."+erhn).endswith(domain))): _debug(" effective request-host %s (even with added " - "initial dot) does not end end with %s", + "initial dot) does not end with %s", erhn, domain) return False if (cookie.version > 0 or diff --git a/lib-python/2.7/ctypes/__init__.py b/lib-python/2.7/ctypes/__init__.py --- a/lib-python/2.7/ctypes/__init__.py +++ b/lib-python/2.7/ctypes/__init__.py @@ -263,6 +263,22 @@ from _ctypes import POINTER, pointer, _pointer_type_cache +def _reset_cache(): + _pointer_type_cache.clear() + _c_functype_cache.clear() + if _os.name in ("nt", "ce"): + _win_functype_cache.clear() + # _SimpleCData.c_wchar_p_from_param + POINTER(c_wchar).from_param = c_wchar_p.from_param + # _SimpleCData.c_char_p_from_param + POINTER(c_char).from_param = c_char_p.from_param + _pointer_type_cache[None] = c_void_p + # XXX for whatever reasons, creating the first instance of a callback + # function is needed for the unittests on Win64 to succeed. This MAY + # be a compiler bug, since the problem occurs only when _ctypes is + # compiled with the MS SDK compiler. Or an uninitialized variable? + CFUNCTYPE(c_int)(lambda: None) + try: from _ctypes import set_conversion_mode except ImportError: @@ -279,8 +295,6 @@ class c_wchar(_SimpleCData): _type_ = "u" - POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param - def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array @@ -299,8 +313,6 @@ return buf raise TypeError(init) -POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param - # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: @@ -463,8 +475,6 @@ descr = FormatError(code).strip() return WindowsError(code, descr) -_pointer_type_cache[None] = c_void_p - if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int @@ -550,8 +560,4 @@ elif sizeof(kind) == 8: c_uint64 = kind del(kind) -# XXX for whatever reasons, creating the first instance of a callback -# function is needed for the unittests on Win64 to succeed. This MAY -# be a compiler bug, since the problem occurs only when _ctypes is -# compiled with the MS SDK compiler. Or an uninitialized variable? -CFUNCTYPE(c_int)(lambda: None) +_reset_cache() diff --git a/lib-python/2.7/ctypes/_endian.py b/lib-python/2.7/ctypes/_endian.py --- a/lib-python/2.7/ctypes/_endian.py +++ b/lib-python/2.7/ctypes/_endian.py @@ -4,20 +4,24 @@ import sys from ctypes import * -_array_type = type(c_int * 3) +_array_type = type(Array) def _other_endian(typ): """Return the type with the 'other' byte order. Simple types like c_int and so on already have __ctype_be__ and __ctype_le__ attributes which contain the types, for more complicated types - only arrays are supported. + arrays and structures are supported. """ - try: + # check _OTHER_ENDIAN attribute (present if typ is primitive type) + if hasattr(typ, _OTHER_ENDIAN): return getattr(typ, _OTHER_ENDIAN) - except AttributeError: - if type(typ) == _array_type: - return _other_endian(typ._type_) * typ._length_ - raise TypeError("This type does not support other endian: %s" % typ) + # if typ is array + if isinstance(typ, _array_type): + return _other_endian(typ._type_) * typ._length_ + # if typ is structure + if issubclass(typ, Structure): + return typ + raise TypeError("This type does not support other endian: %s" % typ) class _swapped_meta(type(Structure)): def __setattr__(self, attrname, value): diff --git a/lib-python/2.7/ctypes/test/test_as_parameter.py b/lib-python/2.7/ctypes/test/test_as_parameter.py --- a/lib-python/2.7/ctypes/test/test_as_parameter.py +++ b/lib-python/2.7/ctypes/test/test_as_parameter.py @@ -74,6 +74,7 @@ def test_callbacks(self): f = dll._testfunc_callback_i_if f.restype = c_int + f.argtypes = None MyCallback = CFUNCTYPE(c_int, c_int) diff --git a/lib-python/2.7/ctypes/test/test_buffers.py b/lib-python/2.7/ctypes/test/test_buffers.py --- a/lib-python/2.7/ctypes/test/test_buffers.py +++ b/lib-python/2.7/ctypes/test/test_buffers.py @@ -20,6 +20,10 @@ self.assertEqual(b[::2], "ac") self.assertEqual(b[::5], "a") + def test_buffer_interface(self): + self.assertEqual(len(bytearray(create_string_buffer(0))), 0) + self.assertEqual(len(bytearray(create_string_buffer(1))), 1) + def test_string_conversion(self): b = create_string_buffer(u"abc") self.assertEqual(len(b), 4) # trailing nul char diff --git a/lib-python/2.7/ctypes/test/test_byteswap.py b/lib-python/2.7/ctypes/test/test_byteswap.py --- a/lib-python/2.7/ctypes/test/test_byteswap.py +++ b/lib-python/2.7/ctypes/test/test_byteswap.py @@ -1,4 +1,4 @@ -import sys, unittest, struct, math +import sys, unittest, struct, math, ctypes from binascii import hexlify from ctypes import * @@ -191,19 +191,34 @@ pass self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)]) + @xfail def test_struct_struct(self): - # Nested structures with different byte order not (yet) supported - if sys.byteorder == "little": - base = BigEndianStructure - else: - base = LittleEndianStructure + # nested structures with different byteorders - class T(Structure): - _fields_ = [("a", c_int), - ("b", c_int)] - class S(base): - pass - self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)]) + # create nested structures with given byteorders and set memory to data + + for nested, data in ( + (BigEndianStructure, b'\0\0\0\1\0\0\0\2'), + (LittleEndianStructure, b'\1\0\0\0\2\0\0\0'), + ): + for parent in ( + BigEndianStructure, + LittleEndianStructure, + Structure, + ): + class NestedStructure(nested): + _fields_ = [("x", c_uint32), + ("y", c_uint32)] + + class TestStructure(parent): + _fields_ = [("point", NestedStructure)] + + self.assertEqual(len(data), sizeof(TestStructure)) + ptr = POINTER(TestStructure) + s = cast(data, ptr)[0] + del ctypes._pointer_type_cache[TestStructure] + self.assertEqual(s.point.x, 1) + self.assertEqual(s.point.y, 2) @xfail def test_struct_fields_2(self): diff --git a/lib-python/2.7/ctypes/test/test_callbacks.py b/lib-python/2.7/ctypes/test/test_callbacks.py --- a/lib-python/2.7/ctypes/test/test_callbacks.py +++ b/lib-python/2.7/ctypes/test/test_callbacks.py @@ -142,6 +142,14 @@ if isinstance(x, X)] self.assertEqual(len(live), 0) + def test_issue12483(self): + import gc + class Nasty: + def __del__(self): + gc.collect() + CFUNCTYPE(None)(lambda x=Nasty(): None) + + try: WINFUNCTYPE except NameError: diff --git a/lib-python/2.7/ctypes/test/test_functions.py b/lib-python/2.7/ctypes/test/test_functions.py --- a/lib-python/2.7/ctypes/test/test_functions.py +++ b/lib-python/2.7/ctypes/test/test_functions.py @@ -253,6 +253,7 @@ def test_callbacks(self): f = dll._testfunc_callback_i_if f.restype = c_int + f.argtypes = None MyCallback = CFUNCTYPE(c_int, c_int) diff --git a/lib-python/2.7/ctypes/test/test_structures.py b/lib-python/2.7/ctypes/test/test_structures.py --- a/lib-python/2.7/ctypes/test/test_structures.py +++ b/lib-python/2.7/ctypes/test/test_structures.py @@ -239,6 +239,14 @@ pass self.assertRaises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)]) + def test_invalid_name(self): + # field name must be string + def declare_with_name(name): + class S(Structure): + _fields_ = [(name, c_int)] + + self.assertRaises(TypeError, declare_with_name, u"x\xe9") + def test_intarray_fields(self): class SomeInts(Structure): _fields_ = [("a", c_int * 4)] @@ -324,6 +332,18 @@ else: self.assertEqual(msg, "(Phone) exceptions.TypeError: too many initializers") + def test_huge_field_name(self): + # issue12881: segfault with large structure field names + def create_class(length): + class S(Structure): + _fields_ = [('x' * length, c_int)] + + for length in [10 ** i for i in range(0, 8)]: + try: + create_class(length) + except MemoryError: + # MemoryErrors are OK, we just don't want to segfault + pass def get_except(self, func, *args): try: diff --git a/lib-python/2.7/ctypes/util.py b/lib-python/2.7/ctypes/util.py --- a/lib-python/2.7/ctypes/util.py +++ b/lib-python/2.7/ctypes/util.py @@ -182,28 +182,6 @@ else: - def _findLib_ldconfig(name): - # XXX assuming GLIBC's ldconfig (with option -p) - expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) - f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null') - try: - data = f.read() - finally: - f.close() - res = re.search(expr, data) - if not res: - # Hm, this works only for libs needed by the python executable. - cmd = 'ldd %s 2>/dev/null' % sys.executable - f = os.popen(cmd) - try: - data = f.read() - finally: - f.close() - res = re.search(expr, data) - if not res: - return None - return res.group(0) - def _findSoname_ldconfig(name): import struct if struct.calcsize('l') == 4: @@ -220,8 +198,7 @@ abi_type = mach_map.get(machine, 'libc6') # XXX assuming GLIBC's ldconfig (with option -p) - expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \ - % (abi_type, re.escape(name)) + expr = r'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type) f = os.popen('/sbin/ldconfig -p 2>/dev/null') try: data = f.read() diff --git a/lib-python/2.7/decimal.py b/lib-python/2.7/decimal.py --- a/lib-python/2.7/decimal.py +++ b/lib-python/2.7/decimal.py @@ -21,7 +21,7 @@ This is a Py2.3 implementation of decimal floating point arithmetic based on the General Decimal Arithmetic Specification: - www2.hursley.ibm.com/decimal/decarith.html + http://speleotrove.com/decimal/decarith.html and IEEE standard 854-1987: @@ -1942,9 +1942,9 @@ nonzero. For efficiency, other._exp should not be too large, so that 10**abs(other._exp) is a feasible calculation.""" - # In the comments below, we write x for the value of self and - # y for the value of other. Write x = xc*10**xe and y = - # yc*10**ye. + # In the comments below, we write x for the value of self and y for the + # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc + # and yc positive integers not divisible by 10. # The main purpose of this method is to identify the *failure* # of x**y to be exactly representable with as little effort as @@ -1952,13 +1952,12 @@ # eliminate the possibility of x**y being exact. Only if all # these tests are passed do we go on to actually compute x**y. - # Here's the main idea. First normalize both x and y. We - # express y as a rational m/n, with m and n relatively prime - # and n>0. Then for x**y to be exactly representable (at - # *any* precision), xc must be the nth power of a positive - # integer and xe must be divisible by n. If m is negative - # then additionally xc must be a power of either 2 or 5, hence - # a power of 2**n or 5**n. + # Here's the main idea. Express y as a rational number m/n, with m and + # n relatively prime and n>0. Then for x**y to be exactly + # representable (at *any* precision), xc must be the nth power of a + # positive integer and xe must be divisible by n. If y is negative + # then additionally xc must be a power of either 2 or 5, hence a power + # of 2**n or 5**n. # # There's a limit to how small |y| can be: if y=m/n as above # then: @@ -2030,21 +2029,43 @@ return None # now xc is a power of 2; e is its exponent e = _nbits(xc)-1 - # find e*y and xe*y; both must be integers - if ye >= 0: - y_as_int = yc*10**ye - e = e*y_as_int - xe = xe*y_as_int - else: - ten_pow = 10**-ye - e, remainder = divmod(e*yc, ten_pow) - if remainder: - return None - xe, remainder = divmod(xe*yc, ten_pow) - if remainder: - return None - - if e*65 >= p*93: # 93/65 > log(10)/log(5) + + # We now have: + # + # x = 2**e * 10**xe, e > 0, and y < 0. + # + # The exact result is: + # + # x**y = 5**(-e*y) * 10**(e*y + xe*y) + # + # provided that both e*y and xe*y are integers. Note that if + # 5**(-e*y) >= 10**p, then the result can't be expressed + # exactly with p digits of precision. + # + # Using the above, we can guard against large values of ye. + # 93/65 is an upper bound for log(10)/log(5), so if + # + # ye >= len(str(93*p//65)) + # + # then + # + # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), + # + # so 5**(-e*y) >= 10**p, and the coefficient of the result + # can't be expressed in p digits. + + # emax >= largest e such that 5**e < 10**p. + emax = p*93//65 + if ye >= len(str(emax)): + return None + + # Find -e*y and -xe*y; both must be integers + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: return None xc = 5**e @@ -2058,19 +2079,20 @@ while xc % 5 == 0: xc //= 5 e -= 1 - if ye >= 0: - y_as_integer = yc*10**ye - e = e*y_as_integer - xe = xe*y_as_integer - else: - ten_pow = 10**-ye - e, remainder = divmod(e*yc, ten_pow) - if remainder: - return None - xe, remainder = divmod(xe*yc, ten_pow) - if remainder: - return None - if e*3 >= p*10: # 10/3 > log(10)/log(2) + + # Guard against large values of ye, using the same logic as in + # the 'xc is a power of 2' branch. 10/3 is an upper bound for + # log(10)/log(2). + emax = p*10//3 + if ye >= len(str(emax)): + return None + + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: return None xc = 2**e else: @@ -5463,6 +5485,27 @@ hex_n = "%x" % n return 4*len(hex_n) - correction[hex_n[0]] +def _decimal_lshift_exact(n, e): + """ Given integers n and e, return n * 10**e if it's an integer, else None. + + The computation is designed to avoid computing large powers of 10 + unnecessarily. + + >>> _decimal_lshift_exact(3, 4) + 30000 + >>> _decimal_lshift_exact(300, -999999999) # returns None + + """ + if n == 0: + return 0 + elif e >= 0: + return n * 10**e + else: + # val_n = largest power of 10 dividing n. + str_n = str(abs(n)) + val_n = len(str_n) - len(str_n.rstrip('0')) + return None if val_n < -e else n // 10**-e + def _sqrt_nearest(n, a): """Closest integer to the square root of the positive integer n. a is an initial approximation to the square root. Any positive integer diff --git a/lib-python/2.7/distutils/__init__.py b/lib-python/2.7/distutils/__init__.py --- a/lib-python/2.7/distutils/__init__.py +++ b/lib-python/2.7/distutils/__init__.py @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "2.7.2" +__version__ = "2.7.3" #--end constants-- diff --git a/lib-python/2.7/distutils/ccompiler.py b/lib-python/2.7/distutils/ccompiler.py --- a/lib-python/2.7/distutils/ccompiler.py +++ b/lib-python/2.7/distutils/ccompiler.py @@ -18,58 +18,6 @@ from distutils.util import split_quoted, execute from distutils import log -_sysconfig = __import__('sysconfig') - -def customize_compiler(compiler): - """Do any platform-specific customization of a CCompiler instance. - - Mainly needed on Unix, so we can plug in the information that - varies across Unices and is stored in Python's Makefile. - """ - if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ - _sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO', 'AR', - 'ARFLAGS') - - if 'CC' in os.environ: - cc = os.environ['CC'] - if 'CXX' in os.environ: - cxx = os.environ['CXX'] - if 'LDSHARED' in os.environ: - ldshared = os.environ['LDSHARED'] - if 'CPP' in os.environ: - cpp = os.environ['CPP'] - else: - cpp = cc + " -E" # not always - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: - cflags = opt + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] - cflags = cflags + ' ' + os.environ['CPPFLAGS'] - ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - if 'AR' in os.environ: - ar = os.environ['AR'] - if 'ARFLAGS' in os.environ: - archiver = ar + ' ' + os.environ['ARFLAGS'] - else: - archiver = ar + ' ' + ar_flags - - cc_cmd = cc + ' ' + cflags - compiler.set_executables( - preprocessor=cpp, - compiler=cc_cmd, - compiler_so=cc_cmd + ' ' + ccshared, - compiler_cxx=cxx, - linker_so=ldshared, - linker_exe=cc, - archiver=archiver) - - compiler.shared_lib_extension = so_ext - class CCompiler: """Abstract base class to define the interface that must be implemented by real compiler classes. Also has some utility methods used by diff --git a/lib-python/2.7/distutils/command/bdist_dumb.py b/lib-python/2.7/distutils/command/bdist_dumb.py --- a/lib-python/2.7/distutils/command/bdist_dumb.py +++ b/lib-python/2.7/distutils/command/bdist_dumb.py @@ -58,7 +58,7 @@ self.format = None self.keep_temp = 0 self.dist_dir = None - self.skip_build = 0 + self.skip_build = None self.relative = 0 self.owner = None self.group = None @@ -78,7 +78,8 @@ self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'), - ('plat_name', 'plat_name')) + ('plat_name', 'plat_name'), + ('skip_build', 'skip_build')) def run(self): if not self.skip_build: diff --git a/lib-python/2.7/distutils/command/bdist_msi.py b/lib-python/2.7/distutils/command/bdist_msi.py --- a/lib-python/2.7/distutils/command/bdist_msi.py +++ b/lib-python/2.7/distutils/command/bdist_msi.py @@ -131,18 +131,22 @@ self.no_target_optimize = 0 self.target_version = None self.dist_dir = None - self.skip_build = 0 + self.skip_build = None self.install_script = None self.pre_install_script = None self.versions = None def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'msi') + short_version = get_python_version() if (not self.target_version) and self.distribution.has_ext_modules(): self.target_version = short_version + if self.target_version: self.versions = [self.target_version] if not self.skip_build and self.distribution.has_ext_modules()\ diff --git a/lib-python/2.7/distutils/command/bdist_wininst.py b/lib-python/2.7/distutils/command/bdist_wininst.py --- a/lib-python/2.7/distutils/command/bdist_wininst.py +++ b/lib-python/2.7/distutils/command/bdist_wininst.py @@ -71,7 +71,7 @@ self.dist_dir = None self.bitmap = None self.title = None - self.skip_build = 0 + self.skip_build = None self.install_script = None self.pre_install_script = None self.user_access_control = None @@ -80,6 +80,8 @@ def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + if self.bdist_dir is None: if self.skip_build and self.plat_name: # If build is skipped and plat_name is overridden, bdist will @@ -89,8 +91,10 @@ # next the command will be initialized using that name bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'wininst') + if not self.target_version: self.target_version = "" + if not self.skip_build and self.distribution.has_ext_modules(): short_version = get_python_version() if self.target_version and self.target_version != short_version: diff --git a/lib-python/2.7/distutils/command/build_clib.py b/lib-python/2.7/distutils/command/build_clib.py --- a/lib-python/2.7/distutils/command/build_clib.py +++ b/lib-python/2.7/distutils/command/build_clib.py @@ -19,7 +19,7 @@ import os from distutils.core import Command from distutils.errors import DistutilsSetupError -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler from distutils import log def show_compilers(): diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py --- a/lib-python/2.7/distutils/command/build_ext.py +++ b/lib-python/2.7/distutils/command/build_ext.py @@ -160,8 +160,7 @@ if plat_py_include != py_include: self.include_dirs.append(plat_py_include) - if isinstance(self.libraries, str): - self.libraries = [self.libraries] + self.ensure_string_list('libraries') # Life is easier if we're not forever checking for None, so # simplify these options to empty lists if unset diff --git a/lib-python/2.7/distutils/command/check.py b/lib-python/2.7/distutils/command/check.py --- a/lib-python/2.7/distutils/command/check.py +++ b/lib-python/2.7/distutils/command/check.py @@ -5,6 +5,7 @@ __revision__ = "$Id$" from distutils.core import Command +from distutils.dist import PKG_INFO_ENCODING from distutils.errors import DistutilsSetupError try: @@ -108,6 +109,8 @@ def check_restructuredtext(self): """Checks if the long string fields are reST-compliant.""" data = self.distribution.get_long_description() + if not isinstance(data, unicode): + data = data.decode(PKG_INFO_ENCODING) for warning in self._check_rst_data(data): line = warning[-1].get('line') if line is None: diff --git a/lib-python/2.7/distutils/command/config.py b/lib-python/2.7/distutils/command/config.py --- a/lib-python/2.7/distutils/command/config.py +++ b/lib-python/2.7/distutils/command/config.py @@ -16,7 +16,7 @@ from distutils.core import Command from distutils.errors import DistutilsExecError -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler from distutils import log LANG_EXT = {'c': '.c', 'c++': '.cxx'} diff --git a/lib-python/2.7/distutils/command/register.py b/lib-python/2.7/distutils/command/register.py --- a/lib-python/2.7/distutils/command/register.py +++ b/lib-python/2.7/distutils/command/register.py @@ -10,7 +10,6 @@ import urllib2 import getpass import urlparse -import StringIO from warnings import warn from distutils.core import PyPIRCCommand @@ -260,21 +259,30 @@ boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = '\n--' + boundary end_boundary = sep_boundary + '--' - body = StringIO.StringIO() + chunks = [] for key, value in data.items(): # handle multiple entries for the same name if type(value) not in (type([]), type( () )): value = [value] for value in value: - body.write(sep_boundary) - body.write('\nContent-Disposition: form-data; name="%s"'%key) - body.write("\n\n") - body.write(value) + chunks.append(sep_boundary) + chunks.append('\nContent-Disposition: form-data; name="%s"'%key) + chunks.append("\n\n") + chunks.append(value) if value and value[-1] == '\r': - body.write('\n') # write an extra newline (lurve Macs) - body.write(end_boundary) - body.write("\n") - body = body.getvalue() + chunks.append('\n') # write an extra newline (lurve Macs) + chunks.append(end_boundary) + chunks.append("\n") + + # chunks may be bytes (str) or unicode objects that we need to encode + body = [] + for chunk in chunks: + if isinstance(chunk, unicode): + body.append(chunk.encode('utf-8')) + else: + body.append(chunk) + + body = ''.join(body) # build the Request headers = { diff --git a/lib-python/2.7/distutils/command/sdist.py b/lib-python/2.7/distutils/command/sdist.py --- a/lib-python/2.7/distutils/command/sdist.py +++ b/lib-python/2.7/distutils/command/sdist.py @@ -182,14 +182,20 @@ reading the manifest, or just using the default file set -- it all depends on the user's options. """ - # new behavior: + # new behavior when using a template: # the file list is recalculated everytime because # even if MANIFEST.in or setup.py are not changed # the user might have added some files in the tree that # need to be included. # - # This makes --force the default and only behavior. + # This makes --force the default and only behavior with templates. template_exists = os.path.isfile(self.template) + if not template_exists and self._manifest_is_not_generated(): + self.read_manifest() + self.filelist.sort() + self.filelist.remove_duplicates() + return + if not template_exists: self.warn(("manifest template '%s' does not exist " + "(using default file list)") % @@ -314,7 +320,10 @@ try: self.filelist.process_template_line(line) - except DistutilsTemplateError, msg: + # the call above can raise a DistutilsTemplateError for + # malformed lines, or a ValueError from the lower-level + # convert_path function + except (DistutilsTemplateError, ValueError) as msg: self.warn("%s, line %d: %s" % (template.filename, template.current_line, msg)) @@ -352,23 +361,28 @@ by 'add_defaults()' and 'read_template()') to the manifest file named by 'self.manifest'. """ - if os.path.isfile(self.manifest): - fp = open(self.manifest) - try: - first_line = fp.readline() - finally: - fp.close() - - if first_line != '# file GENERATED by distutils, do NOT edit\n': - log.info("not writing to manually maintained " - "manifest file '%s'" % self.manifest) - return + if self._manifest_is_not_generated(): + log.info("not writing to manually maintained " + "manifest file '%s'" % self.manifest) + return content = self.filelist.files[:] content.insert(0, '# file GENERATED by distutils, do NOT edit') self.execute(file_util.write_file, (self.manifest, content), "writing manifest file '%s'" % self.manifest) + def _manifest_is_not_generated(self): + # check for special comment used in 2.7.1 and higher + if not os.path.isfile(self.manifest): + return False + + fp = open(self.manifest, 'rU') + try: + first_line = fp.readline() + finally: + fp.close() + return first_line != '# file GENERATED by distutils, do NOT edit\n' + def read_manifest(self): """Read the manifest file (named by 'self.manifest') and use it to fill in 'self.filelist', the list of files to include in the source @@ -376,12 +390,11 @@ """ log.info("reading manifest file '%s'", self.manifest) manifest = open(self.manifest) - while 1: - line = manifest.readline() - if line == '': # end of file - break - if line[-1] == '\n': - line = line[0:-1] + for line in manifest: + # ignore comments and blank lines + line = line.strip() + if line.startswith('#') or not line: + continue self.filelist.append(line) manifest.close() diff --git a/lib-python/2.7/distutils/dep_util.py b/lib-python/2.7/distutils/dep_util.py --- a/lib-python/2.7/distutils/dep_util.py +++ b/lib-python/2.7/distutils/dep_util.py @@ -7,6 +7,7 @@ __revision__ = "$Id$" import os +from stat import ST_MTIME from distutils.errors import DistutilsFileError def newer(source, target): @@ -27,7 +28,7 @@ if not os.path.exists(target): return True - return os.stat(source).st_mtime > os.stat(target).st_mtime + return os.stat(source)[ST_MTIME] > os.stat(target)[ST_MTIME] def newer_pairwise(sources, targets): """Walk two filename lists in parallel, testing if each source is newer @@ -71,7 +72,7 @@ # is more recent than 'target', then 'target' is out-of-date and # we can immediately return true. If we fall through to the end # of the loop, then 'target' is up-to-date and we return false. - target_mtime = os.stat(target).st_mtime + target_mtime = os.stat(target)[ST_MTIME] for source in sources: if not os.path.exists(source): @@ -82,7 +83,7 @@ elif missing == 'newer': # missing source means target is return True # out-of-date - if os.stat(source).st_mtime > target_mtime: + if os.stat(source)[ST_MTIME] > target_mtime: return True return False diff --git a/lib-python/2.7/distutils/dist.py b/lib-python/2.7/distutils/dist.py --- a/lib-python/2.7/distutils/dist.py +++ b/lib-python/2.7/distutils/dist.py @@ -1111,7 +1111,8 @@ """Write the PKG-INFO format data to a file object. """ version = '1.0' - if self.provides or self.requires or self.obsoletes: + if (self.provides or self.requires or self.obsoletes or + self.classifiers or self.download_url): version = '1.1' self._write_field(file, 'Metadata-Version', version) diff --git a/lib-python/2.7/distutils/filelist.py b/lib-python/2.7/distutils/filelist.py --- a/lib-python/2.7/distutils/filelist.py +++ b/lib-python/2.7/distutils/filelist.py @@ -210,6 +210,7 @@ Return 1 if files are found. """ + # XXX docstring lying about what the special chars are? files_found = 0 pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) self.debug_print("include_pattern: applying regex r'%s'" % @@ -297,11 +298,14 @@ # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, # and by extension they shouldn't match such "special characters" under # any OS. So change all non-escaped dots in the RE to match any - # character except the special characters. - # XXX currently the "special characters" are just slash -- i.e. this is - # Unix-only. - pattern_re = re.sub(r'((?\s*" manifest_buf = re.sub(pattern, "", manifest_buf) + # Now see if any other assemblies are referenced - if not, we + # don't want a manifest embedded. + pattern = re.compile( + r"""|)""", re.DOTALL) + if re.search(pattern, manifest_buf) is None: + return None + manifest_f = open(manifest_file, 'w') try: manifest_f.write(manifest_buf) + return manifest_file finally: manifest_f.close() except IOError: diff --git a/lib-python/2.7/distutils/spawn.py b/lib-python/2.7/distutils/spawn.py --- a/lib-python/2.7/distutils/spawn.py +++ b/lib-python/2.7/distutils/spawn.py @@ -96,17 +96,43 @@ raise DistutilsExecError, \ "command '%s' failed with exit status %d" % (cmd[0], rc) +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return exec_fn = search_path and os.execvp or os.execv + exec_args = [cmd[0], cmd] + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(cmd[0], cmd) + exec_fn(*exec_args) except OSError, e: sys.stderr.write("unable to execute %s: %s\n" % (cmd[0], e.strerror)) diff --git a/lib-python/2.7/distutils/sysconfig.py b/lib-python/2.7/distutils/sysconfig.py --- a/lib-python/2.7/distutils/sysconfig.py +++ b/lib-python/2.7/distutils/sysconfig.py @@ -26,4 +26,5 @@ from distutils.sysconfig_cpython import _config_vars # needed by setuptools from distutils.sysconfig_cpython import _variable_rx # read_setup_file() +_USE_CLANG = None diff --git a/lib-python/2.7/distutils/sysconfig_cpython.py b/lib-python/2.7/distutils/sysconfig_cpython.py --- a/lib-python/2.7/distutils/sysconfig_cpython.py +++ b/lib-python/2.7/distutils/sysconfig_cpython.py @@ -149,12 +149,43 @@ varies across Unices and is stored in Python's Makefile. """ if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \ + (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO') + 'CCSHARED', 'LDSHARED', 'SO', 'AR', + 'ARFLAGS') + newcc = None if 'CC' in os.environ: - cc = os.environ['CC'] + newcc = os.environ['CC'] + elif sys.platform == 'darwin' and cc == 'gcc-4.2': + # Issue #13590: + # Since Apple removed gcc-4.2 in Xcode 4.2, we can no + # longer assume it is available for extension module builds. + # If Python was built with gcc-4.2, check first to see if + # it is available on this system; if not, try to use clang + # instead unless the caller explicitly set CC. + global _USE_CLANG + if _USE_CLANG is None: + from distutils import log + from subprocess import Popen, PIPE + p = Popen("! type gcc-4.2 && type clang && exit 2", + shell=True, stdout=PIPE, stderr=PIPE) + p.wait() + if p.returncode == 2: + _USE_CLANG = True + log.warn("gcc-4.2 not found, using clang instead") + else: + _USE_CLANG = False + if _USE_CLANG: + newcc = 'clang' + if newcc: + # On OS X, if CC is overridden, use that as the default + # command for LDSHARED as well + if (sys.platform == 'darwin' + and 'LDSHARED' not in os.environ + and ldshared.startswith(cc)): + ldshared = newcc + ldshared[len(cc):] + cc = newcc if 'CXX' in os.environ: cxx = os.environ['CXX'] if 'LDSHARED' in os.environ: @@ -172,6 +203,12 @@ cpp = cpp + ' ' + os.environ['CPPFLAGS'] cflags = cflags + ' ' + os.environ['CPPFLAGS'] ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] + if 'AR' in os.environ: + ar = os.environ['AR'] + if 'ARFLAGS' in os.environ: + archiver = ar + ' ' + os.environ['ARFLAGS'] + else: + archiver = ar + ' ' + ar_flags cc_cmd = cc + ' ' + cflags compiler.set_executables( @@ -180,7 +217,8 @@ compiler_so=cc_cmd + ' ' + ccshared, compiler_cxx=cxx, linker_so=ldshared, - linker_exe=cc) + linker_exe=cc, + archiver=archiver) compiler.shared_lib_extension = so_ext @@ -380,21 +418,6 @@ raise DistutilsPlatformError(my_msg) - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target - elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')): - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. diff --git a/lib-python/2.7/distutils/tests/Setup.sample b/lib-python/2.7/distutils/tests/Setup.sample old mode 100755 new mode 100644 diff --git a/lib-python/2.7/distutils/tests/support.py b/lib-python/2.7/distutils/tests/support.py --- a/lib-python/2.7/distutils/tests/support.py +++ b/lib-python/2.7/distutils/tests/support.py @@ -1,7 +1,10 @@ """Support code for distutils test cases.""" import os +import sys import shutil import tempfile +import unittest +import sysconfig from copy import deepcopy import warnings @@ -9,6 +12,7 @@ from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL from distutils.core import Distribution + def capture_warnings(func): def _capture_warnings(*args, **kw): with warnings.catch_warnings(): @@ -16,6 +20,7 @@ return func(*args, **kw) return _capture_warnings + class LoggingSilencer(object): def setUp(self): @@ -49,6 +54,7 @@ def clear_logs(self): self.logs = [] + class TempdirManager(object): """Mix-in class that handles temporary directories for test cases. @@ -57,9 +63,13 @@ def setUp(self): super(TempdirManager, self).setUp() + self.old_cwd = os.getcwd() self.tempdirs = [] def tearDown(self): + # Restore working dir, for Solaris and derivatives, where rmdir() + # on the current directory fails. + os.chdir(self.old_cwd) super(TempdirManager, self).tearDown() while self.tempdirs: d = self.tempdirs.pop() @@ -105,6 +115,7 @@ return pkg_dir, dist + class DummyCommand: """Class to store options for retrieval via set_undefined_options().""" @@ -115,6 +126,7 @@ def ensure_finalized(self): pass + class EnvironGuard(object): def setUp(self): @@ -131,3 +143,79 @@ del os.environ[key] super(EnvironGuard, self).tearDown() + + +def copy_xxmodule_c(directory): From noreply at buildbot.pypy.org Fri Oct 26 12:16:24 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 12:16:24 +0200 (CEST) Subject: [pypy-commit] pypy default: Remove the pure Python itertools.py. Having it around just means Message-ID: <20121026101624.D38731C0448@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58443:698b7e10156b Date: 2012-10-26 12:15 +0200 http://bitbucket.org/pypy/pypy/changeset/698b7e10156b/ Log: Remove the pure Python itertools.py. Having it around just means extra maintenance burden for very little gain. diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py deleted file mode 100644 --- a/lib_pypy/itertools.py +++ /dev/null @@ -1,867 +0,0 @@ -# Note that PyPy contains also a built-in module 'itertools' which will -# hide this one if compiled in. - -"""Functional tools for creating and using iterators. - -Infinite iterators: -count([n]) --> n, n+1, n+2, ... -cycle(p) --> p0, p1, ... plast, p0, p1, ... -repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times - -Iterators terminating on the shortest input sequence: -izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... -ifilter(pred, seq) --> elements of seq where pred(elem) is True -ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False -islice(seq, [start,] stop [, step]) --> elements from - seq[start:stop:step] -imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ... -starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ... -tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n -chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... -takewhile(pred, seq) --> seq[0], seq[1], until pred fails -dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails -groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v) -""" - -import sys - - -__all__ = ['chain', 'combinations', 'combinations_with_replacement', - 'compress', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', - 'ifilterfalse', 'imap', 'islice', 'izip', 'izip_longest', - 'permutations', 'product', 'repeat', 'starmap', 'takewhile', 'tee'] - - -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f - - -def _check_number(n): - if not hasattr(n, '__int__') and not hasattr(n, '__float__'): - raise TypeError('expected a number') - - -class chain(object): - """Make an iterator that returns elements from the first iterable - until it is exhausted, then proceeds to the next iterable, until - all of the iterables are exhausted. Used for treating consecutive - sequences as a single sequence. - - Equivalent to : - - def chain(*iterables): - for it in iterables: - for element in it: - yield element - """ - def __init__(self, *iterables): - self._iterables_iter = iter(iterables) - # little trick for the first chain.next() call - self._cur_iterable_iter = iter([]) - - def __iter__(self): - return self - - def next(self): - while True: - try: - return next(self._cur_iterable_iter) - except StopIteration: - self._cur_iterable_iter = iter(next(self._iterables_iter)) - - @classmethod - def from_iterable(cls, iterables): - c = cls() - c._iterables_iter = iter(iterables) - return c - - -class combinations(object): - """combinations(iterable, r) --> combinations object - - Return successive r-length combinations of elements in the iterable. - - combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3) - """ - def __init__(self, iterable, r): - self._pool = list(iterable) - if r < 0: - raise ValueError('r must be non-negative') - self._r = r - self._indices = range(len(self._pool)) - self._last_result = None - self._stopped = r > len(self._pool) - - def __iter__(self): - return self - - def _get_maximum(self, i): - return i + len(self._pool) - self._r - - def _max_index(self, j): - return self._indices[j - 1] + 1 - - def next(self): - if self._stopped: - raise StopIteration() - if self._last_result is None: - # On the first pass, initialize result tuple using the indices - result = [None] * self._r - for i in xrange(self._r): - index = self._indices[i] - result[i] = self._pool[index] - else: - # Copy the previous result - result = self._last_result[:] - # Scan indices right-to-left until finding one that is not at its - # maximum - i = self._r - 1 - while i >= 0 and self._indices[i] == self._get_maximum(i): - i -= 1 - - # If i is negative, then the indices are all at their maximum value - # and we're done - if i < 0: - self._stopped = True - raise StopIteration() - - # Increment the current index which we know is not at its maximum. - # Then move back to the right setting each index to its lowest - # possible value - self._indices[i] += 1 - for j in range(i + 1, self._r): - self._indices[j] = self._max_index(j) - - # Update the result for the new indices starting with i, the - # leftmost index that changed - for i in range(i, self._r): - index = self._indices[i] - result[i] = self._pool[index] - self._last_result = result - return tuple(result) - - -class combinations_with_replacement(combinations): - """combinations_with_replacement(iterable, r) --> combinations_with_replacement object - - Return successive r-length combinations of elements in the iterable - allowing individual elements to have successive repeats. - combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC - """ - def __init__(self, iterable, r): - super(combinations_with_replacement, self).__init__(iterable, r) - self._indices = [0] * r - self._stopped = len(self._pool) == 0 and r > 0 - - def _get_maximum(self, i): - return len(self._pool) - 1 - - def _max_index(self, j): - return self._indices[j - 1] - - -class compress(object): - """Make an iterator that filters elements from data returning - only those that have a corresponding element in selectors that - evaluates to True. Stops when either the data or selectors - iterables has been exhausted. - - Equivalent to: - - def compress(data, selectors): - # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F - return (d for d, s in izip(data, selectors) if s) - """ - def __init__(self, data, selectors): - self._data = iter(data) - self._selectors = iter(selectors) - - def __iter__(self): - return self - - def next(self): - while True: - next_item = next(self._data) - next_selector = next(self._selectors) - if bool(next_selector): - return next_item - - -class count(object): - """Make an iterator that returns evenly spaced values starting - with n. If not specified n defaults to zero. Often used as an - argument to imap() to generate consecutive data points. Also, - used with izip() to add sequence numbers. - - Equivalent to: - - def count(start=0, step=1): - n = start - while True: - yield n - n += step - """ - def __init__(self, start=0, step=1): - _check_number(start) - _check_number(step) - self._counter = start - self._step = step - - def __iter__(self): - return self - - def next(self): - c = self._counter - self._counter += self._step - return c - - def _single_argument(self): - return self._step == 1 and isinstance(self._step, int) - - def __reduce__(self): - if self._single_argument(): - args = (self._counter,) - else: - args = (self._counter, self._step) - return (self.__class__, args) - - def __repr__(self): - if self._single_argument(): - return 'count(%r)' % (self._counter) - return 'count(%r, %r)' % (self._counter, self._step) - - - -class cycle(object): - """Make an iterator returning elements from the iterable and - saving a copy of each. When the iterable is exhausted, return - elements from the saved copy. Repeats indefinitely. - - Equivalent to : - - def cycle(iterable): - saved = [] - for element in iterable: - yield element - saved.append(element) - while saved: - for element in saved: - yield element - """ - def __init__(self, iterable): - self._cur_iter = self._saving_iter(iter(iterable)) - self._saved = [] - - def __iter__(self): - return self - - def _saving_iter(self, iterable): - while True: - item = next(iterable) - self._saved.append(item) - yield item - - def next(self): - try: - item = next(self._cur_iter) - except StopIteration: - self._cur_iter = iter(self._saved) - item = next(self._cur_iter) - return item - - -class dropwhile(object): - """Make an iterator that drops elements from the iterable as long - as the predicate is true; afterwards, returns every - element. Note, the iterator does not produce any output until the - predicate is true, so it may have a lengthy start-up time. - - Equivalent to : - - def dropwhile(predicate, iterable): - iterable = iter(iterable) - for x in iterable: - if not predicate(x): - yield x - break - for x in iterable: - yield x - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - self._dropped = False - - def __iter__(self): - return self - - def next(self): - value = next(self._iter) - if self._dropped: - return value - while self._predicate(value): - value = next(self._iter) - self._dropped = True - return value - -class groupby(object): - """Make an iterator that returns consecutive keys and groups from the - iterable. The key is a function computing a key value for each - element. If not specified or is None, key defaults to an identity - function and returns the element unchanged. Generally, the - iterable needs to already be sorted on the same key function. - - The returned group is itself an iterator that shares the - underlying iterable with groupby(). Because the source is shared, - when the groupby object is advanced, the previous group is no - longer visible. So, if that data is needed later, it should be - stored as a list: - - groups = [] - uniquekeys = [] - for k, g in groupby(data, keyfunc): - groups.append(list(g)) # Store group iterator as a list - uniquekeys.append(k) - """ - def __init__(self, iterable, key=None): - if key is None: - key = lambda x: x - self._keyfunc = key - self._iter = iter(iterable) - self._tgtkey = self._currkey = self._currvalue = xrange(0) - - def __iter__(self): - return self - - def next(self): - while self._currkey == self._tgtkey: - self._currvalue = next(self._iter) # Exit on StopIteration - self._currkey = self._keyfunc(self._currvalue) - self._tgtkey = self._currkey - return (self._currkey, self._grouper(self._tgtkey)) - - def _grouper(self, tgtkey): - while self._currkey == tgtkey: - yield self._currvalue - self._currvalue = next(self._iter) # Exit on StopIteration - self._currkey = self._keyfunc(self._currvalue) - - - -class _ifilter_base(object): - """base class for ifilter and ifilterflase""" - def __init__(self, predicate, iterable): - # Make sure iterable *IS* iterable - self._iter = iter(iterable) - if predicate is None: - self._predicate = bool - else: - self._predicate = predicate - - def __iter__(self): - return self - -class ifilter(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is True. If predicate is - None, return the items that are true. - - Equivalent to : - - def ifilter: - if predicate is None: - predicate = bool - for x in iterable: - if predicate(x): - yield x - """ - def next(self): - while True: - next_elt = next(self._iter) - if self._predicate(next_elt): - return next_elt - -class ifilterfalse(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is False. If predicate is - None, return the items that are false. - - Equivalent to : - - def ifilterfalse(predicate, iterable): - if predicate is None: - predicate = bool - for x in iterable: - if not predicate(x): - yield x - """ - def next(self): - while True: - next_elt = next(self._iter) - if not self._predicate(next_elt): - return next_elt - - - - -class imap(object): - """Make an iterator that computes the function using arguments - from each of the iterables. If function is set to None, then - imap() returns the arguments as a tuple. Like map() but stops - when the shortest iterable is exhausted instead of filling in - None for shorter iterables. The reason for the difference is that - infinite iterator arguments are typically an error for map() - (because the output is fully evaluated) but represent a common - and useful way of supplying arguments to imap(). - - Equivalent to : - - def imap(function, *iterables): - iterables = map(iter, iterables) - while True: - args = [i.next() for i in iterables] - if function is None: - yield tuple(args) - else: - yield function(*args) - - """ - def __init__(self, function, iterable, *other_iterables): - if function is None: - function = lambda *args: args - self._func = function - self._iters = map(iter, (iterable, ) + other_iterables) - - def __iter__(self): - return self - - def next(self): - args = [next(it) for it in self._iters] - return self._func(*args) - - - -class islice(object): - """Make an iterator that returns selected elements from the - iterable. If start is non-zero, then elements from the iterable - are skipped until start is reached. Afterward, elements are - returned consecutively unless step is set higher than one which - results in items being skipped. If stop is None, then iteration - continues until the iterator is exhausted, if at all; otherwise, - it stops at the specified position. Unlike regular slicing, - islice() does not support negative values for start, stop, or - step. Can be used to extract related fields from data where the - internal structure has been flattened (for example, a multi-line - report may list a name field on every third line). - """ - def __init__(self, iterable, *args): - s = slice(*args) - for n, v in zip(['Start', 'Stop', 'Step'], [s.start, s.stop, s.step]): - if not (v is None or isinstance(v, int) and 0 <= v): - msg = ('%s for islice must be None or an integer: ' - '0 <= x <= maxint') - raise ValueError(msg % n) - start, stop, self._step = s.indices(sys.maxint) - self._iter = iter(iterable) - self._pos = -1 - self._next_pos = start - self._max_pos = stop - 1 - - def __iter__(self): - return self - - def next(self): - i = self._pos - while i < self._next_pos: - if i >= self._max_pos: - raise StopIteration() - item = next(self._iter) - i += 1 - - self._pos = i - self._next_pos += self._step - return item - -class izip(object): - """Make an iterator that aggregates elements from each of the - iterables. Like zip() except that it returns an iterator instead - of a list. Used for lock-step iteration over several iterables at - a time. - - Equivalent to : - - def izip(*iterables): - iterables = map(iter, iterables) - while iterables: - result = [i.next() for i in iterables] - yield tuple(result) - """ - def __init__(self, *iterables): - self._iterators = map(iter, iterables) - - def __iter__(self): - return self - - def next(self): - if not self._iterators: - raise StopIteration() - return tuple([next(i) for i in self._iterators]) - - -class izip_longest(object): - """Return an izip_longest object whose .next() method returns a tuple where - the i-th element comes from the i-th iterable argument. The .next() - method continues until the longest iterable in the argument sequence - is exhausted and then it raises StopIteration. When the shorter iterables - are exhausted, the fillvalue is substituted in their place. The fillvalue - defaults to None or can be specified by a keyword argument. - """ - def __init__(self, *iterables, **kwargs): - self._fillvalue = kwargs.pop('fillvalue', None) - if kwargs: - msg = 'izip_longest() got unexpected keyword argument(s)' - raise TypeError(msg) - self._iters = map(iter, iterables) - self._iters_yielding = len(self._iters) - - def __iter__(self): - return self - - def next(self): - if self._iters_yielding <= 0: - raise StopIteration() - result = [None] * len(self._iters) - for i, iterator in enumerate(self._iters): - try: - item = next(iterator) - except StopIteration: - self._iters_yielding -= 1 - if self._iters_yielding <= 0: - raise - self._iters[i] = repeat(self._fillvalue) - item = self._fillvalue - result[i] = item - return tuple(result) - - -class permutations(object): - """permutations(iterable[, r]) --> permutations object - - Return successive r-length permutations of elements in the iterable. - - permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1) - """ - def __init__(self, iterable, r=None): - self._pool = list(iterable) - n = len(self._pool) - if r is None: - r = n - elif r < 0: - raise ValueError('r must be non-negative') - self._r = r - self._indices = range(n) - self._cycles = range(n, n - r, -1) - self._stopped = r > n - - def __iter__(self): - return self - - def next(self): - if self._stopped: - raise StopIteration() - - r = self._r - indices = self._indices - cycles = self._cycles - - result = tuple([self._pool[indices[i]] for i in range(r)]) - i = r - 1 - while i >= 0: - j = cycles[i] - 1 - if j > 0: - cycles[i] = j - indices[i], indices[-j] = indices[-j], indices[i] - return result - cycles[i] = len(indices) - i - n1 = len(indices) - 1 - assert n1 >= 0 - num = indices[i] - for k in range(i, n1): - indices[k] = indices[k+1] - indices[n1] = num - i -= 1 - self._stopped = True - return result - - -class product(object): - """Cartesian product of input iterables. - - Equivalent to nested for-loops in a generator expression. For example, - ``product(A, B)`` returns the same as ``((x,y) for x in A for y in B)``. - - The nested loops cycle like an odometer with the rightmost element advancing - on every iteration. This pattern creates a lexicographic ordering so that if - the input's iterables are sorted, the product tuples are emitted in sorted - order. - - To compute the product of an iterable with itself, specify the number of - repetitions with the optional *repeat* keyword argument. For example, - ``product(A, repeat=4)`` means the same as ``product(A, A, A, A)``. - - This function is equivalent to the following code, except that the - actual implementation does not build up intermediate results in memory:: - - def product(*args, **kwds): - # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy - # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 - pools = map(tuple, args) * kwds.get('repeat', 1) - result = [[]] - for pool in pools: - result = [x+[y] for x in result for y in pool] - for prod in result: - yield tuple(prod) - """ - def __init__(self, *args, **kw): - repeat = kw.pop('repeat', 1) - if kw: - msg = 'product() got unexpected keyword argument(s)' - raise TypeError(msg) - self._pools = map(tuple, args) * repeat - self._indices = [0] * len(self._pools) - try: - self._next_result = [s[0] for s in self._pools] - except IndexError: - self._next_result = None - - def __iter__(self): - return self - - def next(self): - pools = self._pools - indices = self._indices - - if self._next_result is None: - raise StopIteration() - - result = tuple(self._next_result) - - i = len(pools) - while True: - i -= 1 - if i < 0: - self._next_result = None - return result - j = indices[i] - j += 1 - if j < len(pools[i]): - break - - self._next_result[i] = pools[i][j] - indices[i] = j - - while True: - i += 1 - if i >= len(pools): - break - indices[i] = 0 - self._next_result[i] = pools[i][0] - - return result - - -class repeat(object): - """Make an iterator that returns object over and over again. - Runs indefinitely unless the times argument is specified. Used - as argument to imap() for invariant parameters to the called - function. Also used with izip() to create an invariant part of a - tuple record. - - Equivalent to : - - def repeat(object, times=None): - if times is None: - while True: - yield object - else: - for i in xrange(times): - yield object - """ - def __init__(self, object, times=None): - self._obj = object - if times is not None: - xrange(times) # Raise a TypeError - if times < 0: - times = 0 - self._times = times - - def __iter__(self): - return self - - def next(self): - # next() *need* to decrement self._times when consumed - if self._times is not None: - if self._times <= 0: - raise StopIteration() - self._times -= 1 - return self._obj - - def __repr__(self): - if self._times is not None: - return 'repeat(%r, %r)' % (self._obj, self._times) - else: - return 'repeat(%r)' % (self._obj,) - - def __len__(self): - if self._times == -1 or self._times is None: - raise TypeError("len() of unsized object") - return self._times - - -class starmap(object): - """Make an iterator that computes the function using arguments - tuples obtained from the iterable. Used instead of imap() when - argument parameters are already grouped in tuples from a single - iterable (the data has been ``pre-zipped''). The difference - between imap() and starmap() parallels the distinction between - function(a,b) and function(*c). - - Equivalent to : - - def starmap(function, iterable): - iterable = iter(iterable) - while True: - yield function(*iterable.next()) - """ - def __init__(self, function, iterable): - self._func = function - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - t = next(self._iter) - return self._func(*t) - - - -class takewhile(object): - """Make an iterator that returns elements from the iterable as - long as the predicate is true. - - Equivalent to : - - def takewhile(predicate, iterable): - for x in iterable: - if predicate(x): - yield x - else: - break - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - value = next(self._iter) - if not self._predicate(value): - self._iter = iter([]) - raise StopIteration() - return value - - -class _TeeData(object): - """Holds cached values shared by _TeeObjects - - _TeeData instances form linked list where in any instance (node) at most - CHUNK_SIZE items are cached. - """ - CHUNK_SIZE = 64 - def __init__(self, iterator): - self.data = [None] * _TeeData.CHUNK_SIZE - self.iterator = iterator # must be an iterator not an iterable - self.num_read = 0 - self.next_link = None - - def __getitem__(self, i): - if i == self.num_read: - item = next(self.iterator) - self.data[i] = item - self.num_read += 1 - assert i < self.num_read - return self.data[i] - - def get_next_link(self): - assert self.num_read == _TeeData.CHUNK_SIZE - if self.next_link is None: - self.next_link = _TeeData(self.iterator) - return self.next_link - - -class _TeeObject(object): - """Iterables / Iterators as returned by the tee() function""" - def __init__(self, iterable): - if isinstance(iterable, _TeeObject): - self.tee_data = iterable.tee_data - self.pos = iterable.pos - else: - self.tee_data = _TeeData(iter(iterable)) - self.pos = 0 - - def next(self): - assert self.pos <= _TeeData.CHUNK_SIZE - - if self.pos == _TeeData.CHUNK_SIZE: - self.tee_data = self.tee_data.get_next_link() - self.pos = 0 - - data = self.tee_data[self.pos] - self.pos += 1 - return data - - def __iter__(self): - return self - - - at builtinify -def tee(iterable, n=2): - """Return n independent iterators from a single iterable. - - Note : once tee() has made a split, the original iterable - should not be used anywhere else; otherwise, the iterable could get - advanced without the tee objects being informed. - - Note : this member of the toolkit may require significant auxiliary - storage (depending on how much temporary data needs to be stored). - In general, if one iterator is going to use most or all of the - data before the other iterator, it is faster to use list() instead - of tee() - - Equivalent to : - - def tee(iterable, n=2): - it = iter(iterable) - deques = [collections.deque() for i in range(n)] - def gen(mydeque): - while True: - if not mydeque: # when the local deque is empty - newval = next(it) # fetch a new value and - for d in deques: # load it to all the deques - d.append(newval) - yield mydeque.popleft() - return tuple(gen(d) for d in deques) - """ - if n < 0: - raise ValueError('n must be >= 0') - if n == 0: - return () - if isinstance(iterable, _TeeObject): - # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) - tee_obj = iterable - else: - tee_obj = _TeeObject(iterable) - return tuple([tee_obj] + [_TeeObject(tee_obj) for i in xrange(n-1)]) diff --git a/lib_pypy/pypy_test/test_itertools.py b/lib_pypy/pypy_test/test_itertools.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_itertools.py +++ /dev/null @@ -1,71 +0,0 @@ -from py.test import raises -from lib_pypy import itertools - -class TestItertools(object): - - def test_compress(self): - it = itertools.compress(['a', 'b', 'c'], [0, 1, 0]) - - assert list(it) == ['b'] - - def test_compress_diff_len(self): - it = itertools.compress(['a'], []) - raises(StopIteration, it.next) - - def test_product(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')] - - def test_product_repeat(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m, repeat=2) - ans = [(1, 'a', 1, 'a'), (1, 'a', 1, 'b'), (1, 'a', 2, 'a'), - (1, 'a', 2, 'b'), (1, 'b', 1, 'a'), (1, 'b', 1, 'b'), - (1, 'b', 2, 'a'), (1, 'b', 2, 'b'), (2, 'a', 1, 'a'), - (2, 'a', 1, 'b'), (2, 'a', 2, 'a'), (2, 'a', 2, 'b'), - (2, 'b', 1, 'a'), (2, 'b', 1, 'b'), (2, 'b', 2, 'a'), - (2, 'b', 2, 'b')] - assert list(prodlist) == ans - - def test_product_diff_sizes(self): - l = [1, 2] - m = ['a'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (2, 'a')] - - l = [1] - m = ['a', 'b'] - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b')] - - def test_product_toomany_args(self): - l = [1, 2] - m = ['a'] - raises(TypeError, itertools.product, l, m, repeat=1, foo=2) - - def test_tee_copy_constructor(self): - a, b = itertools.tee(range(10)) - next(a) - next(a) - c, d = itertools.tee(a) - assert list(a) == list(d) - - def test_product_kwargs(self): - raises(TypeError, itertools.product, range(10), garbage=1) - - def test_takewhile_stops(self): - tw = itertools.takewhile(lambda x: bool(x), [1, 1, 0, 1, 1]) - next(tw) - next(tw) - raises(StopIteration, next, tw) - raises(StopIteration, next, tw) - - def test_count_repr(self): - c = itertools.count(10, 1.0) - assert repr(c) == 'count(10, 1.0)' From noreply at buildbot.pypy.org Fri Oct 26 13:28:29 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 13:28:29 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: almost pass the first test Message-ID: <20121026112829.8E2911C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58444:ec91b4280c8d Date: 2012-10-25 13:32 +0200 http://bitbucket.org/pypy/pypy/changeset/ec91b4280c8d/ Log: almost pass the first test diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -432,24 +432,7 @@ self.interned_refs[op.getref_base()] = op return op return op - value = op._forwarded - if value is None: - # we only need to make a new copy if the old one is immutable - if op.is_mutable: - value = op - else: - value = op.make_forwarded_copy() - else: - if value._forwarded: - while value._forwarded: - value = value._forwarded - to_patch = op - while to_patch._forwarded: - next = to_patch._forwarded - to_patch._forwarded = value - to_patch = next - #self.ensure_imported(value) - return value + return op.getforwarded() def setvalue(self, box, value): xxx @@ -579,6 +562,11 @@ elif op.getopnum() == rop.FINISH: op = self.store_final_boxes_in_guard(op) assert op is not None + if op.getopnum() == rop.JUMP: + import pdb + pdb.set_trace() + for i in range(op.numargs()): + op.setarg(i, self.getforwarded(op.getarg(i))) self._newoperations.append(op) def store_final_boxes_in_guard(self, op): diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py b/pypy/jit/metainterp/optimizeopt/test/test_util.py --- a/pypy/jit/metainterp/optimizeopt/test/test_util.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py @@ -414,7 +414,7 @@ assert len(optimized.inputargs) == len(expected.inputargs) remap = {} for box1, box2 in zip(optimized.inputargs, expected.inputargs): - assert box1.__class__ == box2.__class__ + #assert box1.__class__ == box2.__class__ remap[box2] = box1 assert equaloplists(optimized.operations, expected.operations, False, remap, text_right) diff --git a/pypy/jit/metainterp/optimizeopt/util.py b/pypy/jit/metainterp/optimizeopt/util.py --- a/pypy/jit/metainterp/optimizeopt/util.py +++ b/pypy/jit/metainterp/optimizeopt/util.py @@ -193,27 +193,27 @@ remap[op2] = op1 if op1.is_guard(): assert op2.is_guard() - if op1.get_extra("failargs") or op2.get_extra("failargs"): - assert (len(op1.get_extra("failargs")) == - len(op2.get_extra("failargs"))) - if strict_fail_args: - for x, y in zip(op1.get_extra("failargs"), - op2.get_extra("failargs")): - if x is None: - assert remap.get(y, y) is None - else: - assert x.eq(remap.get(y, y)) - else: - fail_args1 = set(op1.get_extra("failargs")) - fail_args2 = set([remap.get(y, y) for y in - op2.get_extra("failargs")]) - for x in fail_args1: - for y in fail_args2: - if x.eq(y): - fail_args2.remove(y) - break - else: - assert False + # if op1.get_extra("failargs") or op2.get_extra("failargs"): + # assert (len(op1.get_extra("failargs")) == + # len(op2.get_extra("failargs"))) + # if strict_fail_args: + # for x, y in zip(op1.get_extra("failargs"), + # op2.get_extra("failargs")): + # if x is None: + # assert remap.get(y, y) is None + # else: + # assert x.eq(remap.get(y, y)) + # else: + # fail_args1 = set(op1.get_extra("failargs")) + # fail_args2 = set([remap.get(y, y) for y in + # op2.get_extra("failargs")]) + # for x in fail_args1: + # for y in fail_args2: + # if x.eq(y): + # fail_args2.remove(y) + # break + # else: + # assert False elif op1.getopnum() not in (rop.JUMP, rop.LABEL): # xxx obscure assert op1.getdescr() == op2.getdescr() assert len(oplist1) == len(oplist2) diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -675,6 +675,26 @@ pdb.set_trace() return object.__getattribute__(self, attr) + def getforwarded(self): + value = self._forwarded + if value is None: + # we only need to make a new copy if the old one is immutable + if self.is_mutable: + value = self + else: + value = self.make_forwarded_copy() + else: + if value._forwarded: + while value._forwarded: + value = value._forwarded + to_patch = self + while to_patch._forwarded: + next = to_patch._forwarded + to_patch._forwarded = value + to_patch = next + #self.ensure_imported(value) + return value + # =========== # type mixins # =========== @@ -892,6 +912,9 @@ def getarg(self, i): raise IndexError + def setarg(self, i, v): + raise IndexError + def foreach_arg(self, func, arg): pass @@ -933,6 +956,12 @@ else: raise IndexError + def setarg(self, i, v): + if i == 0: + self._arg0 = v + else: + raise IndexError + @specialize.arg(1) def foreach_arg(self, func, arg): func(arg, self.getopnum(), 0, self._arg0) @@ -981,6 +1010,14 @@ else: raise IndexError + def setarg(self, i, v): + if i == 0: + self._arg0 = v + elif i == 1: + self._arg1 = v + else: + raise IndexError + def getarglist(self): return [self._arg0, self._arg1] @@ -1046,6 +1083,16 @@ else: raise IndexError + def setarg(self, i, v): + if i == 0: + self._arg0 = v + elif i == 1: + self._arg1 = v + elif i == 2: + self._arg2 = v + else: + raise IndexError + @specialize.arg(1) def foreach_arg(self, func, arg): func(arg, self.getopnum(), 0, self._arg0) @@ -1101,6 +1148,9 @@ def getarg(self, i): return self._args[i] + def setarg(self, i, v): + self._args[i] = v + @specialize.arg(1) def foreach_arg(self, func, func_arg): for i, arg in enumerate(self._args): From noreply at buildbot.pypy.org Fri Oct 26 13:28:30 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 13:28:30 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: wuhu pass, the first test Message-ID: <20121026112830.C42231C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58445:efa78ad453e4 Date: 2012-10-25 13:45 +0200 http://bitbucket.org/pypy/pypy/changeset/efa78ad453e4/ Log: wuhu pass, the first test diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -32,7 +32,7 @@ v = self.getforwarded(op) b = v.getintbound() if b.has_lower and b.has_upper and b.lower == b.upper: - v.make_constant(ConstInt(b.lower)) + self.make_constant(v, ConstInt(b.lower)) dispatch_bounds_ops(self, op) def postprocess_GUARD_TRUE(self, op): diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -472,7 +472,8 @@ self._newoperations = [] def make_constant(self, op, constbox): - self.getforwarded(op)._forwarded = constbox + if not op.is_constant(): + self.getforwarded(op)._forwarded = constbox def make_constant_int(self, box, intvalue): self.getvalue(box).make_constant(ConstInt(intvalue)) @@ -527,7 +528,7 @@ break else: self.emit_operation(op) - for opt in self.optimizations: + for opt in reversed(self.optimizations): opt.postprocess_op(orig_op) i += 1 self.loop.operations = self.get_newoperations() @@ -562,9 +563,6 @@ elif op.getopnum() == rop.FINISH: op = self.store_final_boxes_in_guard(op) assert op is not None - if op.getopnum() == rop.JUMP: - import pdb - pdb.set_trace() for i in range(op.numargs()): op.setarg(i, self.getforwarded(op.getarg(i))) self._newoperations.append(op) From noreply at buildbot.pypy.org Fri Oct 26 13:28:31 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 13:28:31 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: sharing lists is not a good idea. ever Message-ID: <20121026112831.E0B1B1C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58446:f84873f1f80a Date: 2012-10-25 15:17 +0200 http://bitbucket.org/pypy/pypy/changeset/f84873f1f80a/ Log: sharing lists is not a good idea. ever diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -531,6 +531,11 @@ for opt in reversed(self.optimizations): opt.postprocess_op(orig_op) i += 1 + # clean up + for op in self.loop.operations: + op._forwarded = None + for arg in self.loop.inputargs: + arg._forwarded = None self.loop.operations = self.get_newoperations() self.loop.quasi_immutable_deps = self.quasi_immutable_deps # accumulate counters diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -118,7 +118,7 @@ def optimize_loop(self, ops, optops, results=None): loop = self.parse(ops, results=results) token = JitCellToken() - loop.operations = [create_resop(rop.LABEL, None, loop.inputargs, descr=TargetToken(token))] + \ + loop.operations = [create_resop(rop.LABEL, None, loop.inputargs[:], descr=TargetToken(token))] + \ loop.operations if loop.operations[-1].getopnum() == rop.JUMP: loop.operations[-1]._descr = token @@ -148,18 +148,18 @@ def test_constant_propagate(self): ops = """ [i] - guard_value(i, 2) [] + guard_value(i, 2) i0 = int_add(i, 3) i1 = int_is_true(i0) - guard_true(i1) [] + guard_true(i1) i2 = int_is_zero(i1) - guard_false(i2) [] - guard_value(i0, 5) [] + guard_false(i2) + guard_value(i0, 5) jump(i) """ expected = """ [i] - guard_value(i, 2) [] + guard_value(i, 2) jump(2) """ self.optimize_loop(ops, expected) diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py b/pypy/jit/metainterp/optimizeopt/test/test_util.py --- a/pypy/jit/metainterp/optimizeopt/test/test_util.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py @@ -413,7 +413,7 @@ from pypy.jit.metainterp.optimizeopt.util import equaloplists assert len(optimized.inputargs) == len(expected.inputargs) remap = {} - for box1, box2 in zip(optimized.inputargs, expected.inputargs): + for box1, box2 in zip(optimized.operations[0].getarglist(), expected.inputargs): #assert box1.__class__ == box2.__class__ remap[box2] = box1 assert equaloplists(optimized.operations, @@ -501,7 +501,7 @@ def convert_old_style_to_targets(loop, jump): newloop = TreeLoop(loop.name) newloop.inputargs = loop.inputargs - newloop.operations = [create_resop(rop.LABEL, None, loop.inputargs, descr=FakeDescr())] + \ + newloop.operations = [create_resop(rop.LABEL, None, loop.inputargs[:], descr=FakeDescr())] + \ loop.operations if not jump: assert newloop.operations[-1].getopnum() == rop.JUMP From noreply at buildbot.pypy.org Fri Oct 26 13:28:33 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 13:28:33 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: hack enough to make the next test pass Message-ID: <20121026112833.09B0B1C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58447:2b413dc0ef40 Date: 2012-10-25 15:29 +0200 http://bitbucket.org/pypy/pypy/changeset/2b413dc0ef40/ Log: hack enough to make the next test pass diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -76,11 +76,10 @@ if b.bounded(): r.getintbound().intersect(b) - def optimize_INT_ADD(self, op): - v1 = self.getvalue(op.getarg(0)) - v2 = self.getvalue(op.getarg(1)) - self.emit_operation(op) - r = self.getvalue(op) + def postprocess_INT_ADD(self, op): + v1 = self.getforwarded(op.getarg(0)) + v2 = self.getforwarded(op.getarg(1)) + r = self.getforwarded(op) b = v1.getintbound().add_bound(v2.getintbound()) if b.bounded(): r.getintbound().intersect(b) @@ -404,19 +403,19 @@ self.propagate_bounds_backward(op.getarg(1)) def propagate_bounds_INT_IS_TRUE(self, op): - r = self.getvalue(op) + r = self.getforwarded(op) if r.is_constant(): - if r.op.same_constant(CONST_1): - v1 = self.getvalue(op.getarg(0)) + if r.same_constant(CONST_1): + v1 = self.getforwarded(op.getarg(0)) if v1.getintbound().known_ge(IntBound(0, 0)): v1.getintbound().make_gt(IntBound(0, 0)) self.propagate_bounds_backward(op.getarg(0)) def propagate_bounds_INT_IS_ZERO(self, op): - r = self.getvalue(op) + r = self.getforwarded(op) if r.is_constant(): - if r.op.same_constant(CONST_1): - v1 = self.getvalue(op.getarg(0)) + if r.same_constant(CONST_1): + v1 = self.getforwarded(op.getarg(0)) # Clever hack, we can't use self.make_constant_int yet because # the args aren't in the values dictionary yet so it runs into # an assert, this is a clever way of expressing the same thing. @@ -425,9 +424,9 @@ self.propagate_bounds_backward(op.getarg(0)) def propagate_bounds_INT_ADD(self, op): - v1 = self.getvalue(op.getarg(0)) - v2 = self.getvalue(op.getarg(1)) - r = self.getvalue(op) + v1 = self.getforwarded(op.getarg(0)) + v2 = self.getforwarded(op.getarg(1)) + r = self.getforwarded(op) b = r.getintbound().sub_bound(v2.getintbound()) if v1.getintbound().intersect(b): self.propagate_bounds_backward(op.getarg(0)) diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -587,6 +587,7 @@ descr.store_final_boxes(op, newboxes) # if op.getopnum() == rop.GUARD_VALUE: + xxx if self.getvalue(op.getarg(0)).is_bool_box: # Hack: turn guard_value(bool) into guard_true/guard_false. # This is done after the operation is emitted to let @@ -620,7 +621,7 @@ self._newoperations[value.last_guard_pos] = new_guard_op def constant_fold(self, op): - argboxes = [self.get_constant_box(op.getarg(i)) + argboxes = [self.get_constant_op(op.getarg(i)) for i in range(op.numargs())] resbox = execute_nonspec(self.cpu, None, op.getopnum(), argboxes, op.getdescr()) diff --git a/pypy/jit/metainterp/optimizeopt/pure.py b/pypy/jit/metainterp/optimizeopt/pure.py --- a/pypy/jit/metainterp/optimizeopt/pure.py +++ b/pypy/jit/metainterp/optimizeopt/pure.py @@ -48,7 +48,7 @@ # otherwise, the operation remains if newop.returns_bool_result(): - newop.is_bool_box = True + newop.setboolbox(True) if nextop: self.emit_operation(nextop) return newop diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -1,7 +1,8 @@ from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntBound -from pypy.jit.metainterp.optimizeopt.optimizer import Optimization +from pypy.jit.metainterp.optimizeopt.optimizer import Optimization, CONST_1,\ + CONST_0 from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ConstInt, make_hashable_int, create_resop_2, Const) @@ -23,12 +24,6 @@ for op in self.loop_invariant_producer.values(): sb.add_potential(op) - def propagate_forward(self, op): - if self.find_rewritable_bool(op): - return - - dispatch_opt(self, op) - def try_boolinvers(self, op, key_op): oldop = self.get_pure_result(key_op) if oldop is not None and oldop.getdescr() is op.getdescr(): @@ -101,19 +96,19 @@ def optimize_INT_ADD(self, op): arg1 = op.getarg(0) arg2 = op.getarg(1) - v1 = self.getvalue(arg1) - v2 = self.getvalue(arg2) + v1 = self.getforwarded(arg1) + v2 = self.getforwarded(arg2) # If one side of the op is 0 the result is the other side. - if v1.is_constant() and v1.op.getint() == 0: + if v1.is_constant() and v1.getint() == 0: self.replace(op, arg2) - elif v2.is_constant() and v2.op.getint() == 0: + elif v2.is_constant() and v2.getint() == 0: self.replace(op, arg1) else: - self.emit_operation(op) # Synthesize the reverse op for optimize_default to reuse self.pure(op.getarg(0), rop.INT_SUB, op, op.getarg(1)) self.pure(op.getarg(1), rop.INT_SUB, op, op.getarg(0)) + return op def optimize_INT_MUL(self, op): v1 = self.getvalue(op.getarg(0)) @@ -194,10 +189,7 @@ def optimize_guard(self, op, constbox, emit_operation=True): value = self.getforwarded(op.getarg(0)) if value.is_constant(): - xxx - box = value.op - assert isinstance(box, Const) - if not box.same_constant(constbox): + if not value.same_constant(constbox): raise InvalidLoop('A GUARD_{VALUE,TRUE,FALSE} was proven to' + 'always fail') return @@ -214,6 +206,12 @@ assert isinstance(constbox, Const) self.postprocess_guard(op, constbox) + def postprocess_GUARD_TRUE(self, op): + self.postprocess_guard(op, CONST_1) + + def postprocess_GUARD_FALSE(self, op): + self.postprocess_guard(op, CONST_0) + def postprocess_default(self, op): if op.is_guard(): xxx @@ -364,6 +362,7 @@ optimize_CALL_LOOPINVARIANT_v = _new_optimize_call_loopinvariant(rop.CALL_v) def _optimize_nullness(self, op, box, expect_nonnull): + return op value = self.getvalue(box) if value.is_nonnull(): self.make_constant_int(op, expect_nonnull) @@ -373,10 +372,11 @@ self.emit_operation(op) def optimize_INT_IS_TRUE(self, op): - if self.getvalue(op.getarg(0)).is_bool_box: + value = self.getforwarded(op.getarg(0)) + if value.getboolbox(): self.replace(op, op.getarg(0)) return - self._optimize_nullness(op, op.getarg(0), True) + return self._optimize_nullness(op, op.getarg(0), True) def optimize_INT_IS_ZERO(self, op): self._optimize_nullness(op, op.getarg(0), False) diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -45,6 +45,7 @@ if cls.type == INT: # all the integers have bounds addattr(Mutable, 'intbound', imm_int_unbound) + addattr(Mutable, 'boolbox', False) # for tracking last guard and merging GUARD_VALUE with # GUARD_NONNULL etc addattr(Mutable, 'lastguard', None) diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -296,6 +296,9 @@ def is_constant(self): return True + def getlastguard(self): + return None + def repr_rpython(box, typechars): return '%s/%s%d' % (box._get_hash_(), typechars, compute_unique_id(box)) @@ -365,6 +368,9 @@ def repr_rpython(self): return repr_rpython(self, 'ci') + def getboolbox(self): + return False # for optimization + CONST_FALSE = ConstInt(0) CONST_TRUE = ConstInt(1) From noreply at buildbot.pypy.org Fri Oct 26 13:28:34 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 13:28:34 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: hack differently Message-ID: <20121026112834.324841C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58448:d7ca4dbc4ab7 Date: 2012-10-25 15:29 +0200 http://bitbucket.org/pypy/pypy/changeset/d7ca4dbc4ab7/ Log: hack differently diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -4,7 +4,7 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable, rop,\ - INT, ConstInt + INT, ConstInt, Const from pypy.jit.metainterp.optimizeopt.intutils import ImmutableIntUnbounded,\ ConstantIntBound @@ -12,6 +12,10 @@ def getintbound(self): return ConstantIntBound(self.getint()) +class __extend__(Const): + def getlastguard(self): + return None + def create_mutable_subclasses(): def addattr(cls, attr, default_value=None): cls.attributes_to_copy.append('_' + attr) diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -296,9 +296,6 @@ def is_constant(self): return True - def getlastguard(self): - return None - def repr_rpython(box, typechars): return '%s/%s%d' % (box._get_hash_(), typechars, compute_unique_id(box)) From noreply at buildbot.pypy.org Fri Oct 26 13:28:35 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 13:28:35 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: another one Message-ID: <20121026112835.D831C1C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58449:d7e2f9e57135 Date: 2012-10-25 15:29 +0200 http://bitbucket.org/pypy/pypy/changeset/d7e2f9e57135/ Log: another one diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -12,6 +12,9 @@ def getintbound(self): return ConstantIntBound(self.getint()) + def getboolbox(self): + return False # for optimization + class __extend__(Const): def getlastguard(self): return None diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -365,9 +365,6 @@ def repr_rpython(self): return repr_rpython(self, 'ci') - def getboolbox(self): - return False # for optimization - CONST_FALSE = ConstInt(0) CONST_TRUE = ConstInt(1) From noreply at buildbot.pypy.org Fri Oct 26 13:28:37 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 13:28:37 +0200 (CEST) Subject: [pypy-commit] pypy default: a test and a fix Message-ID: <20121026112837.007761C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58450:36f4ff25d012 Date: 2012-10-26 13:23 +0200 http://bitbucket.org/pypy/pypy/changeset/36f4ff25d012/ Log: a test and a fix 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 @@ -433,9 +433,7 @@ def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): - dtype = interp_ufuncs.find_dtype_for_scalar(space, w_other, - self.get_dtype()) - w_other = W_NDimArray.new_scalar(space, dtype, w_other) + w_other = convert_to_array(space, w_other) return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self, w_out]) return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name) 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 @@ -694,6 +694,8 @@ r = 3 + array(range(3)) for i in range(3): assert r[i] == i + 3 + r = [1, 2] + array([1, 2]) + assert (r == [2, 4]).all() def test_add_list(self): from _numpypy import array, ndarray From noreply at buildbot.pypy.org Fri Oct 26 13:28:38 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 13:28:38 +0200 (CEST) Subject: [pypy-commit] pypy default: merge Message-ID: <20121026112838.0E8F91C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58451:6a45075e5fba Date: 2012-10-26 13:28 +0200 http://bitbucket.org/pypy/pypy/changeset/6a45075e5fba/ Log: merge 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 @@ -433,9 +433,7 @@ def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): - dtype = interp_ufuncs.find_dtype_for_scalar(space, w_other, - self.get_dtype()) - w_other = W_NDimArray.new_scalar(space, dtype, w_other) + w_other = convert_to_array(space, w_other) return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self, w_out]) return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name) 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 @@ -694,6 +694,8 @@ r = 3 + array(range(3)) for i in range(3): assert r[i] == i + 3 + r = [1, 2] + array([1, 2]) + assert (r == [2, 4]).all() def test_add_list(self): from _numpypy import array, ndarray From noreply at buildbot.pypy.org Fri Oct 26 15:16:43 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 15:16:43 +0200 (CEST) Subject: [pypy-commit] cffi default: Add another test for FILE being kept alive, this time in test_c. Message-ID: <20121026131643.429071C0448@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1009:58a810ad199c Date: 2012-10-26 15:16 +0200 http://bitbucket.org/cffi/cffi/changeset/58a810ad199c/ Log: Add another test for FILE being kept alive, this time in test_c. diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2268,3 +2268,36 @@ e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " "be a cdata pointer, not file") + +def test_FILE_object(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BFILEPP = new_pointer_type(BFILEP) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP,), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fileno = ll.load_function(BFunc2, "fileno") + # + import posix + fdr, fdw = posix.pipe() + fw1 = posix.fdopen(fdw, 'wb', 256) + # + fw1p = newp(BFILEPP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p[0]) + assert res >= 0 + res = fileno(fw1p[0]) + assert res == fdw + fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) From noreply at buildbot.pypy.org Fri Oct 26 15:58:17 2012 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 26 Oct 2012 15:58:17 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: merge default into branch Message-ID: <20121026135818.1BA671C1E03@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-problems Changeset: r58452:71273fd7f75a Date: 2012-10-26 15:46 +0200 http://bitbucket.org/pypy/pypy/changeset/71273fd7f75a/ Log: merge default into branch diff too long, truncating to 2000 out of 5395 lines diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py deleted file mode 100644 --- a/lib_pypy/itertools.py +++ /dev/null @@ -1,670 +0,0 @@ -# Note that PyPy contains also a built-in module 'itertools' which will -# hide this one if compiled in. - -"""Functional tools for creating and using iterators. - -Infinite iterators: -count([n]) --> n, n+1, n+2, ... -cycle(p) --> p0, p1, ... plast, p0, p1, ... -repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times - -Iterators terminating on the shortest input sequence: -izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... -ifilter(pred, seq) --> elements of seq where pred(elem) is True -ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False -islice(seq, [start,] stop [, step]) --> elements from - seq[start:stop:step] -imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ... -starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ... -tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n -chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... -takewhile(pred, seq) --> seq[0], seq[1], until pred fails -dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails -groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v) -""" - -__all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', - 'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap', - 'takewhile', 'tee', 'compress', 'product'] - -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f - - -class chain(object): - """Make an iterator that returns elements from the first iterable - until it is exhausted, then proceeds to the next iterable, until - all of the iterables are exhausted. Used for treating consecutive - sequences as a single sequence. - - Equivalent to : - - def chain(*iterables): - for it in iterables: - for element in it: - yield element - """ - def __init__(self, *iterables): - self._iterables_iter = iter(map(iter, iterables)) - # little trick for the first chain.next() call - self._cur_iterable_iter = iter([]) - - def __iter__(self): - return self - - def next(self): - while True: - try: - return self._cur_iterable_iter.next() - except StopIteration: - self._cur_iterable_iter = self._iterables_iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iterable_iter)) - - -class compress(object): - def __init__(self, data, selectors): - self.data = iter(data) - self.selectors = iter(selectors) - - def __iter__(self): - return self - - def next(self): - while True: - next_item = self.data.next() - next_selector = self.selectors.next() - if bool(next_selector): - return next_item - - -class count(object): - """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. - - Equivalent to : - - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) - while True: - yield n - n += 1 - """ - def __init__(self, n=0): - if not isinstance(n, int): - raise TypeError('%s is not a regular integer' % n) - self.times = n-1 - - def __iter__(self): - return self - - def next(self): - self.times += 1 - return self.times - - def __repr__(self): - return 'count(%d)' % (self.times + 1) - - - -class cycle(object): - """Make an iterator returning elements from the iterable and - saving a copy of each. When the iterable is exhausted, return - elements from the saved copy. Repeats indefinitely. - - Equivalent to : - - def cycle(iterable): - saved = [] - for element in iterable: - yield element - saved.append(element) - while saved: - for element in saved: - yield element - """ - def __init__(self, iterable): - self._cur_iter = iter(iterable) - self._saved = [] - self._must_save = True - - def __iter__(self): - return self - - def next(self): - # XXX Could probably be improved - try: - next_elt = self._cur_iter.next() - if self._must_save: - self._saved.append(next_elt) - except StopIteration: - self._cur_iter = iter(self._saved) - next_elt = self._cur_iter.next() - self._must_save = False - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iter)) - return next_elt - - -class dropwhile(object): - """Make an iterator that drops elements from the iterable as long - as the predicate is true; afterwards, returns every - element. Note, the iterator does not produce any output until the - predicate is true, so it may have a lengthy start-up time. - - Equivalent to : - - def dropwhile(predicate, iterable): - iterable = iter(iterable) - for x in iterable: - if not predicate(x): - yield x - break - for x in iterable: - yield x - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - self._dropped = False - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if self._dropped: - return value - while self._predicate(value): - value = self._iter.next() - self._dropped = True - return value - -class groupby(object): - """Make an iterator that returns consecutive keys and groups from the - iterable. The key is a function computing a key value for each - element. If not specified or is None, key defaults to an identity - function and returns the element unchanged. Generally, the - iterable needs to already be sorted on the same key function. - - The returned group is itself an iterator that shares the - underlying iterable with groupby(). Because the source is shared, - when the groupby object is advanced, the previous group is no - longer visible. So, if that data is needed later, it should be - stored as a list: - - groups = [] - uniquekeys = [] - for k, g in groupby(data, keyfunc): - groups.append(list(g)) # Store group iterator as a list - uniquekeys.append(k) - """ - def __init__(self, iterable, key=None): - if key is None: - key = lambda x: x - self.keyfunc = key - self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = xrange(0) - - def __iter__(self): - return self - - def next(self): - while self.currkey == self.tgtkey: - try: - self.currvalue = self.it.next() # Exit on StopIteration - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self.it)) - self.currkey = self.keyfunc(self.currvalue) - self.tgtkey = self.currkey - return (self.currkey, self._grouper(self.tgtkey)) - - def _grouper(self, tgtkey): - while self.currkey == tgtkey: - yield self.currvalue - self.currvalue = self.it.next() # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) - - - -class _ifilter_base(object): - """base class for ifilter and ifilterflase""" - def __init__(self, predicate, iterable): - # Make sure iterable *IS* iterable - self._iter = iter(iterable) - if predicate is None: - self._predicate = bool - else: - self._predicate = predicate - - def __iter__(self): - return self - -class ifilter(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is True. If predicate is - None, return the items that are true. - - Equivalent to : - - def ifilter: - if predicate is None: - predicate = bool - for x in iterable: - if predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - -class ifilterfalse(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is False. If predicate is - None, return the items that are false. - - Equivalent to : - - def ifilterfalse(predicate, iterable): - if predicate is None: - predicate = bool - for x in iterable: - if not predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if not self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - - - - -class imap(object): - """Make an iterator that computes the function using arguments - from each of the iterables. If function is set to None, then - imap() returns the arguments as a tuple. Like map() but stops - when the shortest iterable is exhausted instead of filling in - None for shorter iterables. The reason for the difference is that - infinite iterator arguments are typically an error for map() - (because the output is fully evaluated) but represent a common - and useful way of supplying arguments to imap(). - - Equivalent to : - - def imap(function, *iterables): - iterables = map(iter, iterables) - while True: - args = [i.next() for i in iterables] - if function is None: - yield tuple(args) - else: - yield function(*args) - - """ - def __init__(self, function, iterable, *other_iterables): - self._func = function - self._iters = map(iter, (iterable, ) + other_iterables) - - def __iter__(self): - return self - - def next(self): - try: - args = [it.next() for it in self._iters] - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (it)) - if self._func is None: - return tuple(args) - else: - return self._func(*args) - - - -class islice(object): - """Make an iterator that returns selected elements from the - iterable. If start is non-zero, then elements from the iterable - are skipped until start is reached. Afterward, elements are - returned consecutively unless step is set higher than one which - results in items being skipped. If stop is None, then iteration - continues until the iterator is exhausted, if at all; otherwise, - it stops at the specified position. Unlike regular slicing, - islice() does not support negative values for start, stop, or - step. Can be used to extract related fields from data where the - internal structure has been flattened (for example, a multi-line - report may list a name field on every third line). - """ - def __init__(self, iterable, *args): - s = slice(*args) - self.start, self.stop, self.step = s.start or 0, s.stop, s.step - if not isinstance(self.start, (int, long)): - raise ValueError("Start argument must be an integer") - if self.stop is not None and not isinstance(self.stop, (int,long)): - raise ValueError("Stop argument must be an integer or None") - if self.step is None: - self.step = 1 - if self.start<0 or (self.stop is not None and self.stop<0 - ) or self.step<=0: - raise ValueError, "indices for islice() must be positive" - self.it = iter(iterable) - self.donext = None - self.cnt = 0 - - def __iter__(self): - return self - - def next(self): - if self.donext is None: - try: - self.donext = self.it.next - except AttributeError: - raise TypeError - nextindex = self.start - if self.stop is not None and nextindex >= self.stop: - raise StopIteration - while self.cnt <= nextindex: - nextitem = self.donext() - self.cnt += 1 - self.start += self.step - return nextitem - -class izip(object): - """Make an iterator that aggregates elements from each of the - iterables. Like zip() except that it returns an iterator instead - of a list. Used for lock-step iteration over several iterables at - a time. - - Equivalent to : - - def izip(*iterables): - iterables = map(iter, iterables) - while iterables: - result = [i.next() for i in iterables] - yield tuple(result) - """ - def __init__(self, *iterables): - self._iterators = map(iter, iterables) - self._result = [None] * len(self._iterators) - - def __iter__(self): - return self - - def next(self): - if not self._iterators: - raise StopIteration() - try: - return tuple([i.next() for i in self._iterators]) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (i)) - - -class product(object): - - def __init__(self, *args, **kw): - if len(kw) > 1: - raise TypeError("product() takes at most 1 argument (%d given)" % - len(kw)) - self.repeat = kw.get('repeat', 1) - self.gears = [x for x in args] * self.repeat - self.num_gears = len(self.gears) - # initialization of indicies to loop over - self.indicies = [(0, len(self.gears[x])) - for x in range(0, self.num_gears)] - self.cont = True - - def roll_gears(self): - # Starting from the end of the gear indicies work to the front - # incrementing the gear until the limit is reached. When the limit - # is reached carry operation to the next gear - should_carry = True - for n in range(0, self.num_gears): - nth_gear = self.num_gears - n - 1 - if should_carry: - count, lim = self.indicies[nth_gear] - count += 1 - if count == lim and nth_gear == 0: - self.cont = False - if count == lim: - should_carry = True - count = 0 - else: - should_carry = False - self.indicies[nth_gear] = (count, lim) - else: - break - - def __iter__(self): - return self - - def next(self): - if not self.cont: - raise StopIteration - l = [] - for x in range(0, self.num_gears): - index, limit = self.indicies[x] - l.append(self.gears[x][index]) - self.roll_gears() - return tuple(l) - - -class repeat(object): - """Make an iterator that returns object over and over again. - Runs indefinitely unless the times argument is specified. Used - as argument to imap() for invariant parameters to the called - function. Also used with izip() to create an invariant part of a - tuple record. - - Equivalent to : - - def repeat(object, times=None): - if times is None: - while True: - yield object - else: - for i in xrange(times): - yield object - """ - def __init__(self, obj, times=None): - self._obj = obj - if times is not None: - xrange(times) # Raise a TypeError - if times < 0: - times = 0 - self._times = times - - def __iter__(self): - return self - - def next(self): - # next() *need* to decrement self._times when consumed - if self._times is not None: - if self._times <= 0: - raise StopIteration() - self._times -= 1 - return self._obj - - def __repr__(self): - if self._times is not None: - return 'repeat(%r, %r)' % (self._obj, self._times) - else: - return 'repeat(%r)' % (self._obj,) - - def __len__(self): - if self._times == -1 or self._times is None: - raise TypeError("len() of uniszed object") - return self._times - - -class starmap(object): - """Make an iterator that computes the function using arguments - tuples obtained from the iterable. Used instead of imap() when - argument parameters are already grouped in tuples from a single - iterable (the data has been ``pre-zipped''). The difference - between imap() and starmap() parallels the distinction between - function(a,b) and function(*c). - - Equivalent to : - - def starmap(function, iterable): - iterable = iter(iterable) - while True: - yield function(*iterable.next()) - """ - def __init__(self, function, iterable): - self._func = function - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - # CPython raises a TypeError when the iterator doesn't return a tuple - try: - t = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - if not isinstance(t, tuple): - raise TypeError("iterator must return a tuple") - return self._func(*t) - - - -class takewhile(object): - """Make an iterator that returns elements from the iterable as - long as the predicate is true. - - Equivalent to : - - def takewhile(predicate, iterable): - for x in iterable: - if predicate(x): - yield x - else: - break - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if not self._predicate(value): - raise StopIteration() - return value - - -class TeeData(object): - """Holds cached values for TeeObjects""" - def __init__(self, iterator): - self.data = [] - self._iter = iterator - - def __getitem__(self, i): - # iterates until 'i' if not done yet - while i>= len(self.data): - try: - self.data.append( self._iter.next() ) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - return self.data[i] - - -class TeeObject(object): - """Iterables / Iterators as returned by the tee() function""" - def __init__(self, iterable=None, tee_data=None): - if tee_data: - self.tee_data = tee_data - self.pos = 0 - # <=> Copy constructor - elif isinstance(iterable, TeeObject): - self.tee_data = iterable.tee_data - self.pos = iterable.pos - else: - self.tee_data = TeeData(iter(iterable)) - self.pos = 0 - - def next(self): - data = self.tee_data[self.pos] - self.pos += 1 - return data - - def __iter__(self): - return self - - - at builtinify -def tee(iterable, n=2): - """Return n independent iterators from a single iterable. - Note : once tee() has made a split, the original iterable - should not be used anywhere else; otherwise, the iterable could get - advanced without the tee objects being informed. - - Note : this member of the toolkit may require significant auxiliary - storage (depending on how much temporary data needs to be stored). - In general, if one iterator is going to use most or all of the - data before the other iterator, it is faster to use list() instead - of tee() - - Equivalent to : - - def tee(iterable, n=2): - def gen(next, data={}, cnt=[0]): - for i in count(): - if i == cnt[0]: - item = data[i] = next() - cnt[0] += 1 - else: - item = data.pop(i) - yield item - it = iter(iterable) - return tuple([gen(it.next) for i in range(n)]) - """ - if isinstance(iterable, TeeObject): - # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) - return tuple([iterable] + - [TeeObject(tee_data=iterable.tee_data) for i in xrange(n-1)]) - tee_data = TeeData(iter(iterable)) - return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)]) diff --git a/lib_pypy/pypy_test/test_itertools.py b/lib_pypy/pypy_test/test_itertools.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_itertools.py +++ /dev/null @@ -1,50 +0,0 @@ -from py.test import raises -from lib_pypy import itertools - -class TestItertools(object): - - def test_compress(self): - it = itertools.compress(['a', 'b', 'c'], [0, 1, 0]) - - assert list(it) == ['b'] - - def test_compress_diff_len(self): - it = itertools.compress(['a'], []) - raises(StopIteration, it.next) - - def test_product(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')] - - def test_product_repeat(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m, repeat=2) - ans = [(1, 'a', 1, 'a'), (1, 'a', 1, 'b'), (1, 'a', 2, 'a'), - (1, 'a', 2, 'b'), (1, 'b', 1, 'a'), (1, 'b', 1, 'b'), - (1, 'b', 2, 'a'), (1, 'b', 2, 'b'), (2, 'a', 1, 'a'), - (2, 'a', 1, 'b'), (2, 'a', 2, 'a'), (2, 'a', 2, 'b'), - (2, 'b', 1, 'a'), (2, 'b', 1, 'b'), (2, 'b', 2, 'a'), - (2, 'b', 2, 'b')] - assert list(prodlist) == ans - - def test_product_diff_sizes(self): - l = [1, 2] - m = ['a'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (2, 'a')] - - l = [1] - m = ['a', 'b'] - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b')] - - def test_product_toomany_args(self): - l = [1, 2] - m = ['a'] - raises(TypeError, itertools.product, l, m, repeat=1, foo=2) diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -118,7 +118,7 @@ # 1. find the start of the statement from codeop import compile_command end = None - for start in range(lineno, -1, -1): + for start in range(lineno, -1, max(-1, lineno - 10)): if assertion: line = self.lines[start] # the following lines are not fully tested, change with care @@ -135,9 +135,9 @@ compile_command(trysource) except (SyntaxError, OverflowError, ValueError): continue - + # 2. find the end of the statement - for end in range(lineno+1, len(self)+1): + for end in range(lineno+1, min(len(self)+1, lineno + 10)): trysource = self[start:end] if trysource.isparseable(): return start, end diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -31,21 +31,21 @@ # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', - 'truediv', 'floordiv', 'divmod', 'pow', + 'truediv', 'floordiv', 'divmod', 'and_', 'or_', 'xor', 'lshift', 'rshift', 'getitem', 'setitem', 'delitem', 'getitem_idx', 'getitem_key', 'getitem_idx_key', 'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv', 'inplace_floordiv', 'inplace_div', - 'inplace_mod', 'inplace_pow', + 'inplace_mod', 'inplace_lshift', 'inplace_rshift', 'inplace_and', 'inplace_or', 'inplace_xor', 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'is_', 'cmp', 'coerce', ] +[opname+'_ovf' for opname in - """add sub mul floordiv div mod pow lshift + """add sub mul floordiv div mod lshift """.split() ]) @@ -65,7 +65,6 @@ def inplace_floordiv((obj1, obj2)): return pair(obj1, obj2).floordiv() def inplace_div((obj1, obj2)): return pair(obj1, obj2).div() def inplace_mod((obj1, obj2)): return pair(obj1, obj2).mod() - def inplace_pow((obj1, obj2)): return pair(obj1, obj2).pow(s_None) def inplace_lshift((obj1, obj2)): return pair(obj1, obj2).lshift() def inplace_rshift((obj1, obj2)): return pair(obj1, obj2).rshift() def inplace_and((obj1, obj2)): return pair(obj1, obj2).and_() @@ -301,19 +300,6 @@ return SomeInteger(nonneg=int1.nonneg, knowntype=int1.knowntype) rshift.can_only_throw = [] - def pow((int1, int2), obj3): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - pow.can_only_throw = [ZeroDivisionError] - pow_ovf = _clone(pow, [ZeroDivisionError, OverflowError]) - - def inplace_pow((int1, int2)): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - inplace_pow.can_only_throw = [ZeroDivisionError] - def _compare_helper((int1, int2), opname, operation): r = SomeBool() if int1.is_immutable_constant() and int2.is_immutable_constant(): @@ -500,9 +486,6 @@ div.can_only_throw = [] truediv = div - def pow((flt1, flt2), obj3): - raise NotImplementedError("float power not supported, use math.pow") - # repeat these in order to copy the 'can_only_throw' attribute inplace_div = div inplace_truediv = truediv diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -16,7 +16,7 @@ from pypy.annotation.dictdef import DictDef from pypy.annotation import description from pypy.annotation.signature import annotationoftype -from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.rlib.objectmodel import r_dict, Symbolic from pypy.tool.algo.unionfind import UnionFind from pypy.rpython.lltypesystem import lltype, llmemory @@ -101,7 +101,7 @@ def consider_list_delitem(self, idx): return self.indexrepr(idx) - + def consider_str_join(self, s): if s.is_constant(): return repr(s.const) @@ -224,7 +224,7 @@ check_no_flags(s_value_or_def.listdef.listitem) elif isinstance(s_value_or_def, SomeDict): check_no_flags(s_value_or_def.dictdef.dictkey) - check_no_flags(s_value_or_def.dictdef.dictvalue) + check_no_flags(s_value_or_def.dictdef.dictvalue) elif isinstance(s_value_or_def, SomeTuple): for s_item in s_value_or_def.items: check_no_flags(s_item) @@ -238,9 +238,9 @@ elif isinstance(s_value_or_def, ListItem): if s_value_or_def in seen: return - seen.add(s_value_or_def) + seen.add(s_value_or_def) check_no_flags(s_value_or_def.s_value) - + for clsdef in self.classdefs: check_no_flags(clsdef) @@ -366,14 +366,14 @@ listdef = ListDef(self, s_ImpossibleValue) for e in x: listdef.generalize(self.immutablevalue(e, False)) - result = SomeList(listdef) + result = SomeList(listdef) elif tp is dict or tp is r_dict: if need_const: key = Constant(x) try: return self.immutable_cache[key] except KeyError: - result = SomeDict(DictDef(self, + result = SomeDict(DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict)) @@ -396,7 +396,7 @@ result.const_box = key return result else: - dictdef = DictDef(self, + dictdef = DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict) @@ -545,7 +545,7 @@ return True else: return False - + def getfrozen(self, pyobj): return description.FrozenDesc(self, pyobj) @@ -566,7 +566,7 @@ key = (x.__class__, x) if key in self.seen_mutable: return - clsdef = self.getuniqueclassdef(x.__class__) + clsdef = self.getuniqueclassdef(x.__class__) self.seen_mutable[key] = True self.event('mutable', x) source = InstanceSource(self, x) @@ -586,7 +586,7 @@ except KeyError: access_sets = map[attrname] = UnionFind(description.ClassAttrFamily) return access_sets - + def pbc_getattr(self, pbc, s_attr): assert s_attr.is_constant() attr = s_attr.const @@ -598,7 +598,7 @@ first = descs[0] if len(descs) == 1: return first.s_read_attribute(attr) - + change = first.mergeattrfamilies(descs[1:], attr) attrfamily = first.getattrfamily(attr) @@ -700,7 +700,7 @@ def ondegenerated(self, what, s_value, where=None, called_from_graph=None): self.annotator.ondegenerated(what, s_value, where=where, called_from_graph=called_from_graph) - + def whereami(self): return self.annotator.whereami(self.position_key) diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -323,10 +323,12 @@ def robjmodel_hlinvoke(s_repr, s_llcallable, *args_s): from pypy.rpython import rmodel - assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr),"hlinvoke expects a constant repr as first argument" - r_func, nimplicitarg = s_repr.const.get_r_implfunc() + from pypy.rpython.error import TyperError - nbargs = len(args_s) + nimplicitarg + assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr), "hlinvoke expects a constant repr as first argument" + r_func, nimplicitarg = s_repr.const.get_r_implfunc() + + nbargs = len(args_s) + nimplicitarg s_sigs = r_func.get_s_signatures((nbargs, (), False, False)) if len(s_sigs) != 1: raise TyperError("cannot hlinvoke callable %r with not uniform" @@ -337,6 +339,7 @@ return lltype_to_annotation(rresult.lowleveltype) + def robjmodel_keepalive_until_here(*args_s): return immutablevalue(None) @@ -404,7 +407,10 @@ BUILTIN_ANALYZERS[unicodedata.decimal] = unicodedata_decimal # xxx # object - just ignore object.__init__ -BUILTIN_ANALYZERS[object.__init__] = object_init +if hasattr(object.__init__, 'im_func'): + BUILTIN_ANALYZERS[object.__init__.im_func] = object_init +else: + BUILTIN_ANALYZERS[object.__init__] = object_init # import BUILTIN_ANALYZERS[__import__] = import_func diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -1,8 +1,7 @@ import types, py from pypy.objspace.flow.model import Constant, FunctionGraph -from pypy.interpreter.pycode import cpython_code_signature -from pypy.interpreter.argument import rawshape -from pypy.interpreter.argument import ArgErr +from pypy.objspace.flow.bytecode import cpython_code_signature +from pypy.objspace.flow.argument import rawshape, ArgErr from pypy.tool.sourcetools import valid_identifier from pypy.tool.pairtype import extendabletype @@ -181,7 +180,7 @@ name = pyobj.func_name if signature is None: if hasattr(pyobj, '_generator_next_method_of_'): - from pypy.interpreter.argument import Signature + from pypy.objspace.flow.argument import Signature signature = Signature(['entry']) # haaaaaack defaults = () else: @@ -260,7 +259,7 @@ try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: - raise TypeError("signature mismatch: %s() %s" % + raise TypeError("signature mismatch: %s() %s" % (self.name, e.getmsg())) return inputcells diff --git a/pypy/annotation/specialize.py b/pypy/annotation/specialize.py --- a/pypy/annotation/specialize.py +++ b/pypy/annotation/specialize.py @@ -6,7 +6,7 @@ from pypy.objspace.flow.model import Block, Link, Variable, SpaceOperation from pypy.objspace.flow.model import Constant, checkgraph from pypy.annotation import model as annmodel -from pypy.interpreter.argument import Signature +from pypy.objspace.flow.argument import Signature def flatten_star_args(funcdesc, args_s): argnames, vararg, kwarg = funcdesc.signature diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -13,7 +13,7 @@ from pypy.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong from pypy.rlib.rarithmetic import r_singlefloat from pypy.rlib import objectmodel -from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.objspace.flow.objspace import FlowObjSpace, FlowingError from pypy.translator.test import snippet @@ -1431,15 +1431,6 @@ assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_pow(self): - def f(n): - n **= 2 - return 2 ** n - a = self.RPythonAnnotator() - s = a.build_types(f, [int]) - # result should be an integer - assert s.knowntype == int - def test_inplace_div(self): def f(n): n /= 2 @@ -3156,10 +3147,9 @@ x **= y return x ** y a = self.RPythonAnnotator() - s = a.build_types(f, [int, int]) - assert isinstance(s, annmodel.SomeInteger) - a = self.RPythonAnnotator() - py.test.raises(NotImplementedError, a.build_types, f, [float, float]) + py.test.raises(FlowingError, a.build_types, f, [int, int]) + a = self.RPythonAnnotator() + py.test.raises(FlowingError, a.build_types, f, [float, float]) def test_intcmp_bug(self): def g(x, y): @@ -3815,6 +3805,20 @@ s = a.build_types(f, [annmodel.SomeInteger()]) assert isinstance(s, annmodel.SomeBool) + def test_object_init(self): + class A(object): + pass + + class B(A): + def __init__(self): + A.__init__(self) + + def f(): + B() + + a = self.RPythonAnnotator() + a.build_types(f, []) # assert did not explode + def g(n): return [0,1,2,n] diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -285,17 +285,14 @@ Miscellaneous ------------- -* Hash randomization is not supported in PyPy. Passing ``-R`` to the - command line, or setting the ``PYTHONHASHSEED`` environment variable - will display a warning message. +* Hash randomization (``-R``) is ignored in PyPy. As documented in + http://bugs.python.org/issue14621 , some of us believe it has no + purpose in CPython either. -* ``sys.setrecursionlimit()`` is ignored (and not needed) on - PyPy. On CPython it would set the maximum number of nested - calls that can occur before a RuntimeError is raised; on PyPy - overflowing the stack also causes RuntimeErrors, but the limit - is checked at a lower level. (The limit is currently hard-coded - at 768 KB, corresponding to roughly 1480 Python calls on - Linux.) +* ``sys.setrecursionlimit(n)`` sets the limit only approximately, + by setting the usable stack space to ``n * 768`` bytes. On Linux, + depending on the compiler settings, the default of 768KB is enough + for about 1400 calls. * assignment to ``__class__`` is limited to the cases where it works on CPython 2.5. On CPython 2.6 and 2.7 it works in a bit diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -100,7 +100,7 @@ To translate and run for the CLI you must have the SDK installed: Windows users need the `.NET Framework SDK`_, while Linux and Mac users can use Mono_. To translate and run for the JVM you must have a JDK -installed (at least version 5) and ``java``/``javac`` on your path. +installed (at least version 6) and ``java``/``javac`` on your path. A slightly larger example +++++++++++++++++++++++++ diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -504,149 +504,6 @@ w_key = keyword_names_w[i - limit] space.setitem(w_kwds, w_key, keywords_w[i]) -class ArgumentsForTranslation(Arguments): - def __init__(self, space, args_w, keywords=None, keywords_w=None, - w_stararg=None, w_starstararg=None): - self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False - Arguments.__init__(self, space, args_w, keywords, keywords_w) - - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - - def prepend(self, w_firstarg): # used often - "Return a new Arguments with a new argument inserted first." - return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - def copy(self): - return ArgumentsForTranslation(self.space, self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - - - def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None, - blindargs=0): - self.combine_if_necessary() - # _match_signature is destructive - return Arguments._match_signature( - self, w_firstarg, scope_w, signature, - defaults_w, blindargs) - - def unpack(self): - self.combine_if_necessary() - return Arguments.unpack(self) - - def match_signature(self, signature, defaults_w): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - return self._parse(None, signature, defaults_w) - - def unmatch_signature(self, signature, data_w): - """kind of inverse of match_signature""" - args_w, kwds_w = self.unpack() - need_cnt = len(args_w) - need_kwds = kwds_w.keys() - space = self.space - argnames, varargname, kwargname = signature - cnt = len(argnames) - data_args_w = data_w[:cnt] - if varargname: - data_w_stararg = data_w[cnt] - cnt += 1 - else: - data_w_stararg = space.newtuple([]) - - unfiltered_kwds_w = {} - if kwargname: - data_w_starargarg = data_w[cnt] - for w_key in space.unpackiterable(data_w_starargarg): - key = space.str_w(w_key) - w_value = space.getitem(data_w_starargarg, w_key) - unfiltered_kwds_w[key] = w_value - cnt += 1 - assert len(data_w) == cnt - - ndata_args_w = len(data_args_w) - if ndata_args_w >= need_cnt: - 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) - else: - stararg_w = space.unpackiterable(data_w_stararg) - datalen = len(data_args_w) - args_w = [None] * (datalen + len(stararg_w)) - for i in range(0, datalen): - args_w[i] = data_args_w[i] - for i in range(0, len(stararg_w)): - args_w[i + datalen] = stararg_w[i] - assert len(args_w) == need_cnt - - keywords = [] - keywords_w = [] - for key in need_kwds: - keywords.append(key) - keywords_w.append(unfiltered_kwds_w[key]) - - return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) - - @staticmethod - def frompacked(space, w_args=None, w_kwds=None): - raise NotImplementedError("go away") - - @staticmethod - def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w): - args_w = data_w[:shape_cnt] - p = end_keys = shape_cnt + len(shape_keys) - if shape_star: - w_star = data_w[p] - p += 1 - else: - w_star = None - if shape_stst: - w_starstar = data_w[p] - p += 1 - else: - w_starstar = None - return ArgumentsForTranslation(space, args_w, list(shape_keys), - data_w[shape_cnt:end_keys], w_star, - w_starstar) - - def flatten(self): - """ Argument <-> list of w_objects together with "shape" information """ - shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape() - data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)] - for key in shape_keys] - if shape_star: - data_w.append(self.w_stararg) - if shape_stst: - data_w.append(self.w_starstararg) - return (shape_cnt, shape_keys, shape_star, shape_stst), data_w - - def _rawshape(self, nextra=0): - assert not self.combine_has_happened - shape_cnt = len(self.arguments_w)+nextra # Number of positional args - if self.keywords: - shape_keys = self.keywords[:] # List of keywords (strings) - shape_keys.sort() - else: - shape_keys = [] - shape_star = self.w_stararg is not None # Flag: presence of *arg - shape_stst = self.w_starstararg is not None # Flag: presence of **kwds - return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted - -def rawshape(args, nextra=0): - return args._rawshape(nextra) - - # # ArgErr family of exceptions raised in case of argument mismatch. # We try to give error messages following CPython's, which are very informative. 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 @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- import py -from pypy.interpreter.argument import (Arguments, ArgumentsForTranslation, - ArgErr, ArgErrUnknownKwds, ArgErrMultipleValues, ArgErrCount, rawshape, - Signature) +from pypy.interpreter.argument import (Arguments, ArgErr, ArgErrUnknownKwds, + ArgErrMultipleValues, ArgErrCount, Signature) from pypy.interpreter.error import OperationError @@ -687,206 +686,3 @@ def f(x): pass e = raises(TypeError, "f(**{u'ü' : 19})") assert "?" in str(e.value) - -def make_arguments_for_translation(space, args_w, keywords_w={}, - w_stararg=None, w_starstararg=None): - return ArgumentsForTranslation(space, args_w, keywords_w.keys(), - keywords_w.values(), w_stararg, - w_starstararg) - -class TestArgumentsForTranslation(object): - - def test_prepend(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ["0"]) - args1 = args.prepend("thingy") - assert args1 is not args - assert args1.arguments_w == ["thingy", "0"] - assert args1.keywords is args.keywords - assert args1.keywords_w is args.keywords_w - - def test_unmatch_signature(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - sig = Signature(['a', 'b', 'c'], 'r', None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - def test_rawshape(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert rawshape(args) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1]) - assert rawshape(args, 2) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert rawshape(args) == (5, (), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert rawshape(args) == (1, ('b', 'c'), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert rawshape(args) == (1, ('c', ), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert rawshape(args) == (1, ('c', 'd'), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert rawshape(args) == (5, ('d', 'e'), False, False) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert rawshape(args) == (0, (), True, True) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert rawshape(args) == (2, ('g', ), True, True) - - def test_copy_and_shape(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ['a'], ['x'], [1], - ['w1'], {'y': 'w2'}) - args1 = args.copy() - args.combine_if_necessary() - assert rawshape(args1) == (1, ('x',), True, True) - - - def test_flatten(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert args.flatten() == ((3, (), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1]) - assert args.flatten() == ((1, (), False, False), [1]) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert args.flatten() == ((5, (), False, False), [1,2,3,4,5]) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert args.flatten() == ((1, ('c', ), False, False), [1, 5]) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7]) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert args.flatten() == ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert args.flatten() == ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - - def test_stararg_flowspace_variable(self): - space = DummySpace() - var = object() - shape = ((2, ('g', ), True, False), [1, 2, 9, var]) - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=var) - assert args.flatten() == shape - - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - - def test_fromshape(self): - space = DummySpace() - shape = ((3, (), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, (), False, False), [1]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, (), False, False), [1,2,3,4,5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('b', 'c'), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', ), False, False), [1, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', 'd'), False, False), [1, 5, 7]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -4306,14 +4306,7 @@ """ expected = """ [] - p0 = newstr(11) - copystrcontent(s"hello world", p0, 0, 0, 11) - # Eventually this should just return s"hello", but ATM this test is - # just verifying that it doesn't return "\0\0\0\0\0", so being - # slightly underoptimized is ok. - p1 = newstr(5) - copystrcontent(p0, p1, 0, 0, 5) - finish(p1) + finish(s"hello") """ self.optimize_strunicode_loop(ops, expected) @@ -4963,12 +4956,7 @@ """ expected = """ [i1] - p0 = newstr(6) - copystrcontent(s"hello!", p0, 0, 0, 6) - p1 = newstr(12) - copystrcontent(p0, p1, 0, 0, 6) - copystrcontent(s"abc123", p1, 0, 6, 6) - i0 = strgetitem(p1, i1) + i0 = strgetitem(s"hello!abc123", i1) finish(i0) """ self.optimize_strunicode_loop(ops, expected) @@ -4984,10 +4972,7 @@ """ expected = """ [] - p0 = newstr(6) - copystrcontent(s"hello!", p0, 0, 0, 6) - i0 = strgetitem(p0, 0) - finish(i0) + finish(104) """ self.optimize_strunicode_loop(ops, expected) @@ -5067,6 +5052,21 @@ """ self.optimize_strunicode_loop(ops, expected) + def test_str_copy_constant_virtual(self): + ops = """ + [] + p0 = newstr(10) + copystrcontent(s"abcd", p0, 0, 0, 4) + strsetitem(p0, 4, 101) + copystrcontent(s"fghij", p0, 0, 5, 5) + finish(p0) + """ + expected = """ + [] + finish(s"abcdefghij") + """ + self.optimize_strunicode_loop(ops, expected) + def test_call_pure_vstring_const(self): py.test.skip("implement me") ops = """ diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -489,6 +489,7 @@ def optimize_COPYSTRCONTENT(self, op): self._optimize_COPYSTRCONTENT(op, mode_string) + def optimize_COPYUNICODECONTENT(self, op): self._optimize_COPYSTRCONTENT(op, mode_unicode) @@ -507,8 +508,8 @@ if length.is_constant() and length.box.getint() == 0: return - elif (src.is_virtual() and dst.is_virtual() and srcstart.is_constant() and - dststart.is_constant() and length.is_constant()): + elif ((src.is_virtual() or src.is_constant()) and dst.is_virtual() and + srcstart.is_constant() and dststart.is_constant() and length.is_constant()): src_start = srcstart.force_box(self).getint() dst_start = dststart.force_box(self).getint() diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,8 +4,9 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi +from pypy.rlib import jit, clibffi, jit_libffi, rposix from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -147,9 +148,13 @@ argtype = self.fargs[i] if isinstance(argtype, W_CTypePointer): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) - if get_mustfree_flag(data): + flag = get_mustfree_flag(data) + if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') + elif flag == 2: + file = rffi.cast(rffi.CCHARPP, data)[0] + rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -164,6 +169,27 @@ assert isinstance(abi, int) return space.wrap(abi) +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +def prepare_file_call_argument(fileobj): + import os + space = fileobj.space + fileobj.direct_flush() + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fd2 = os.dup(fd) + f = rffi_fdopen(fd2, fileobj.mode) + if not f: + os.close(fd2) + raise OSError(rposix.get_errno(), "fdopen failed") + except OSError, e: + raise wrap_oserror(space, e) + return f + # ____________________________________________________________ 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 @@ -157,7 +157,7 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - raise self._convert_error("compatible pointer", w_ob) + raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): from pypy.module._cffi_backend import ctypearray @@ -177,7 +177,8 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = [] + _attrs_ = ['is_file'] + _immutable_fields_ = ['is_file'] def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -186,6 +187,7 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" + self.is_file = (ctitem.name == "struct _IO_FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -234,7 +236,7 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) - def _prepare_pointer_call_argument(self, w_init): + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): @@ -242,10 +244,19 @@ elif space.isinstance_w(w_init, space.w_basestring): # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 + elif self.is_file: + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = space.interpclass_w(w_init) + if isinstance(ob, W_File): + result = ctypefunc.prepare_file_call_argument(ob) + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 2 + return 0 else: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 if self.ctitem.size <= 0: - return lltype.nullptr(rffi.CCHARP.TO) + return 0 try: datasize = ovfcheck(length * self.ctitem.size) except OverflowError: @@ -258,25 +269,19 @@ except Exception: lltype.free(result, flavor='raw') raise - return result + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return 1 def convert_argument_from_object(self, cdata, w_ob): from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag space = self.space ob = space.interpclass_w(w_ob) - if isinstance(ob, cdataobj.W_CData): - buffer = lltype.nullptr(rffi.CCHARP.TO) - else: - buffer = self._prepare_pointer_call_argument(w_ob) - # - if buffer: - rffi.cast(rffi.CCHARPP, cdata)[0] = buffer - set_mustfree_flag(cdata, True) - return True - else: - set_mustfree_flag(cdata, False) + result = (not isinstance(ob, cdataobj.W_CData) and + self._prepare_pointer_call_argument(w_ob, cdata)) + if result == 0: self.convert_from_object(cdata, w_ob) - return False + set_mustfree_flag(cdata, result) + return result def getcfield(self, attr): return self.ctitem.getcfield(attr) 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 @@ -2211,3 +2211,56 @@ buffer(p)[:] = bytearray(b"foo\x00") assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] + +def test_FILE(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP, BCharP), BInt, True) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fscanf = ll.load_function(BFunc2, "fscanf") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r', 256) + fw1 = posix.fdopen(fdw, 'w', 256) + # + fw1.write(b"X") + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.close() + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"Xhello" + fr1.close() + +def test_FILE_only_for_FILE_arg(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + B_NOT_FILE = new_struct_type("NOT_FILE") + B_NOT_FILEP = new_pointer_type(B_NOT_FILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + # + import posix + fdr, fdw = posix.pipe() + fr1 = posix.fdopen(fdr, 'r') + fw1 = posix.fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not file") diff --git a/pypy/module/_sre/test/test_app_sre.py b/pypy/module/_sre/test/test_app_sre.py --- a/pypy/module/_sre/test/test_app_sre.py +++ b/pypy/module/_sre/test/test_app_sre.py @@ -5,17 +5,20 @@ from pypy.interpreter.gateway import app2interp_temp from pypy.conftest import gettestobjspace, option -def init_globals_hack(space): - space.appexec([space.wrap(autopath.this_dir)], """(this_dir): - import __builtin__ as b - import sys, os.path - # Uh-oh, ugly hack - sys.path.insert(0, this_dir) - import support_test_app_sre - b.s = support_test_app_sre - sys.path.pop(0) +def init_app_test(cls, space): + cls.w_s = space.appexec([space.wrap(autopath.this_dir)], + """(this_dir): + import sys + # Uh-oh, ugly hack + sys.path.insert(0, this_dir) + try: + import support_test_app_sre + return support_test_app_sre + finally: + sys.path.pop(0) """) + class AppTestSrePy: def test_magic(self): @@ -326,7 +329,7 @@ def test_scanner_zero_width_match(self): import re, sys if sys.version_info[:2] == (2, 3): - return + skip("2.3 is different here") p = re.compile(".*").scanner("bla") assert ("bla", "") == (p.search().group(0), p.search().group(0)) assert None == p.search() @@ -340,7 +343,7 @@ cls.space = gettestobjspace(usemodules=('_locale',)) except py.test.skip.Exception: cls.space = gettestobjspace(usemodules=('_rawffi',)) - init_globals_hack(cls.space) + init_app_test(cls, cls.space) def setup_method(self, method): import locale @@ -351,11 +354,13 @@ locale.setlocale(locale.LC_ALL, (None, None)) def test_getlower_no_flags(self): + s = self.s UPPER_AE = "\xc4" s.assert_lower_equal([("a", "a"), ("A", "a"), (UPPER_AE, UPPER_AE), (u"\u00c4", u"\u00c4"), (u"\u4444", u"\u4444")], 0) def test_getlower_locale(self): + s = self.s import locale, sre_constants UPPER_AE = "\xc4" LOWER_AE = "\xe4" @@ -370,6 +375,7 @@ skip("unsupported locale de_DE") def test_getlower_unicode(self): + s = self.s import sre_constants UPPER_AE = "\xc4" LOWER_AE = "\xe4" @@ -596,34 +602,41 @@ class AppTestOpcodes: def setup_class(cls): + if option.runappdirect: + py.test.skip("can only be run on py.py: _sre opcodes don't match") try: cls.space = gettestobjspace(usemodules=('_locale',)) except py.test.skip.Exception: cls.space = gettestobjspace(usemodules=('_rawffi',)) # This imports support_test_sre as the global "s" - init_globals_hack(cls.space) + init_app_test(cls, cls.space) def test_length_optimization(self): + s = self.s pattern = "bla" opcodes = [s.OPCODES["info"], 3, 3, len(pattern)] \ + s.encode_literal(pattern) + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["b", "bl", "ab"]) def test_literal(self): + s = self.s opcodes = s.encode_literal("bla") + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["bl", "blu"]) s.assert_match(opcodes, ["bla", "blab", "cbla", "bbla"]) def test_not_literal(self): + s = self.s opcodes = s.encode_literal("b") \ + [s.OPCODES["not_literal"], ord("a"), s.OPCODES["success"]] s.assert_match(opcodes, ["bx", "ababy"]) s.assert_no_match(opcodes, ["ba", "jabadu"]) def test_unknown(self): + s = self.s raises(RuntimeError, s.search, [55555], "b") def test_at_beginning(self): + s = self.s for atname in ["at_beginning", "at_beginning_string"]: opcodes = [s.OPCODES["at"], s.ATCODES[atname]] \ + s.encode_literal("bla") + [s.OPCODES["success"]] @@ -631,30 +644,35 @@ s.assert_no_match(opcodes, "abla") def test_at_beginning_line(self): + s = self.s opcodes = [s.OPCODES["at"], s.ATCODES["at_beginning_line"]] \ + s.encode_literal("bla") + [s.OPCODES["success"]] s.assert_match(opcodes, ["bla", "x\nbla"]) s.assert_no_match(opcodes, ["abla", "abla\nubla"]) def test_at_end(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end"], s.OPCODES["success"]] s.assert_match(opcodes, ["bla", "bla\n"]) s.assert_no_match(opcodes, ["blau", "abla\nblau"]) def test_at_end_line(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end_line"], s.OPCODES["success"]] s.assert_match(opcodes, ["bla\n", "bla\nx", "bla"]) s.assert_no_match(opcodes, ["blau"]) def test_at_end_string(self): + s = self.s opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES["at_end_string"], s.OPCODES["success"]] s.assert_match(opcodes, "bla") s.assert_no_match(opcodes, ["blau", "bla\n"]) def test_at_boundary(self): + s = self.s for atname in "at_boundary", "at_loc_boundary", "at_uni_boundary": opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES[atname], s.OPCODES["success"]] @@ -666,6 +684,7 @@ s.assert_no_match(opcodes, "") def test_at_non_boundary(self): + s = self.s for atname in "at_non_boundary", "at_loc_non_boundary", "at_uni_non_boundary": opcodes = s.encode_literal("bla") \ + [s.OPCODES["at"], s.ATCODES[atname], s.OPCODES["success"]] @@ -673,6 +692,7 @@ s.assert_no_match(opcodes, ["bla ja", "bla"]) def test_at_loc_boundary(self): + s = self.s import locale try: s.void_locale() @@ -692,6 +712,7 @@ skip("locale error") def test_at_uni_boundary(self): + s = self.s UPPER_PI = u"\u03a0" LOWER_PI = u"\u03c0" opcodes = s.encode_literal("bl") + [s.OPCODES["any"], s.OPCODES["at"], @@ -703,6 +724,7 @@ s.assert_match(opcodes, ["blaha", u"bl%sja" % UPPER_PI]) def test_category_loc_word(self): + s = self.s import locale try: s.void_locale() @@ -723,23 +745,27 @@ skip("locale error") def test_any(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["any"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_match(opcodes, ["b a", "bla", "bboas"]) s.assert_no_match(opcodes, ["b\na", "oba", "b"]) def test_any_all(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["any_all"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_match(opcodes, ["b a", "bla", "bboas", "b\na"]) s.assert_no_match(opcodes, ["oba", "b"]) def test_in_failure(self): + s = self.s opcodes = s.encode_literal("b") + [s.OPCODES["in"], 2, s.OPCODES["failure"]] \ + s.encode_literal("a") + [s.OPCODES["success"]] s.assert_no_match(opcodes, ["ba", "bla"]) From noreply at buildbot.pypy.org Fri Oct 26 16:09:56 2012 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 26 Oct 2012 16:09:56 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: document numpypy-problems branch Message-ID: <20121026140956.A38B21C1DE9@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-problems Changeset: r58453:e606a028ed30 Date: 2012-10-26 16:09 +0200 http://bitbucket.org/pypy/pypy/changeset/e606a028ed30/ Log: document numpypy-problems 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 @@ -38,6 +38,8 @@ .. branch: numpypy-complex2 Complex dtype support for numpy +.. branch: numpypy-problems +Improve dtypes intp, uintp, void, string and record .. branch: kill-someobject major cleanups including killing some object support From noreply at buildbot.pypy.org Fri Oct 26 16:23:52 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 16:23:52 +0200 (CEST) Subject: [pypy-commit] cffi default: Change 'ffi.new("FILE**", f)' into 'ffi.cast("FILE*", f)'. Message-ID: <20121026142352.B51411C1DE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1010:65574fb4a819 Date: 2012-10-26 16:10 +0200 http://bitbucket.org/cffi/cffi/changeset/65574fb4a819/ Log: Change 'ffi.new("FILE**", f)' into 'ffi.cast("FILE*", f)'. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -943,11 +943,6 @@ CTypeDescrObject *ctinit; if (!CData_Check(init)) { - if (PyFile_Check(init) && - (ct->ct_itemdescr->ct_flags & CT_IS_FILE)) { - *(FILE **)data = PyFile_AsFile(init); - return 0; - } expected = "cdata pointer"; goto cannot_convert; } @@ -1732,8 +1727,7 @@ /* from a unicode, we add the null terminator */ length = _my_PyUnicode_SizeAsWideChar(init) + 1; } - else if (PyFile_Check(init) && - (ctptr->ct_itemdescr->ct_flags & CT_IS_FILE)) { + else if (PyFile_Check(init) && (ctitem->ct_flags & CT_IS_FILE)) { output_data[0] = (char *)PyFile_AsFile(init); return 1; } @@ -2466,6 +2460,10 @@ return new_simple_cdata(cdsrc->c_data, ct); } } + if (PyFile_Check(ob) && (ct->ct_flags & CT_POINTER) && + (ct->ct_itemdescr->ct_flags & CT_IS_FILE)) { + return new_simple_cdata((char *)PyFile_AsFile(ob), ct); + } value = _my_PyLong_AsUnsignedLongLong(ob, 0); if (value == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) return NULL; diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2275,7 +2275,6 @@ # BFILE = new_struct_type("_IO_FILE") BFILEP = new_pointer_type(BFILE) - BFILEPP = new_pointer_type(BFILEP) BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) BInt = new_primitive_type("int") @@ -2289,12 +2288,12 @@ fdr, fdw = posix.pipe() fw1 = posix.fdopen(fdw, 'wb', 256) # - fw1p = newp(BFILEPP, fw1) + fw1p = cast(BFILEP, fw1) fw1.write(b"X") fw1.flush() - res = fputs(b"hello\n", fw1p[0]) + res = fputs(b"hello\n", fw1p) assert res >= 0 - res = fileno(fw1p[0]) + res = fileno(fw1p) assert res == fdw fw1.close() # From noreply at buildbot.pypy.org Fri Oct 26 16:23:53 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 16:23:53 +0200 (CEST) Subject: [pypy-commit] cffi default: Fixes for test_verify. Message-ID: <20121026142353.C703D1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1011:2e6275abecea Date: 2012-10-26 16:23 +0200 http://bitbucket.org/cffi/cffi/changeset/2e6275abecea/ Log: Fixes for test_verify. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -4606,8 +4606,14 @@ static char *_cffi_to_c_pointer(PyObject *obj, CTypeDescrObject *ct) { char *result; - if (convert_from_object((char *)&result, ct, obj) < 0) + if (convert_from_object((char *)&result, ct, obj) < 0) { + if (PyFile_Check(obj) && (ct->ct_flags & CT_POINTER) && + (ct->ct_itemdescr->ct_flags & CT_IS_FILE)) { + PyErr_Clear(); + return (char *)PyFile_AsFile(obj); + } return NULL; + } return result; } diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1265,7 +1265,7 @@ import posix fdr, fdw = posix.pipe() fw1 = posix.fdopen(fdw, 'wb', 256) - lib.myfile = fw1 + lib.myfile = ffi.cast("FILE *", fw1) # fw1.write(b"X") r = lib.myprintf(b"hello, %d!\n", ffi.cast("int", 42)) From noreply at buildbot.pypy.org Fri Oct 26 16:24:53 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 16:24:53 +0200 (CEST) Subject: [pypy-commit] cffi default: Update the documentation about FILE. Message-ID: <20121026142453.3F80A1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1012:efa282269e02 Date: 2012-10-26 16:24 +0200 http://bitbucket.org/cffi/cffi/changeset/efa282269e02/ Log: Update the documentation about FILE. diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -397,9 +397,10 @@ some headers declare a different type (e.g. an enum) and also call it ``bool``. -* *New in version 0.4:* FILE. Limited support: just enough to declare C - functions taking a ``FILE *`` argument and calling them with a Python - file object. +* *New in version 0.4:* FILE. You can declare C functions taking a + ``FILE *`` argument and call them with a Python file object. If needed, + you can also do ``c_f = ffi.cast("FILE *", fileobj)`` and then pass around + ``c_f``. .. "versionadded:: 0.4": bool .. "versionadded:: 0.4": FILE From noreply at buildbot.pypy.org Fri Oct 26 16:31:01 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 16:31:01 +0200 (CEST) Subject: [pypy-commit] pypy py3k-listview_str: a branch where to try to re-enable listview_str Message-ID: <20121026143101.C0D3A1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k-listview_str Changeset: r58454:edf12e6d1705 Date: 2012-10-26 15:16 +0200 http://bitbucket.org/pypy/pypy/changeset/edf12e6d1705/ Log: a branch where to try to re-enable listview_str From noreply at buildbot.pypy.org Fri Oct 26 16:31:03 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 16:31:03 +0200 (CEST) Subject: [pypy-commit] pypy py3k-listview_str: attempt to re-enable space.listview_str. It was disabled because some strategies implemented it for unicode and some for bytes, so translation failed. We decide that listview_str is only for bytes, and that we will need to grow the equivalent unicode ones Message-ID: <20121026143103.1C5E41C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k-listview_str Changeset: r58455:d0c1cb8e18fc Date: 2012-10-26 14:09 +0200 http://bitbucket.org/pypy/pypy/changeset/d0c1cb8e18fc/ Log: attempt to re-enable space.listview_str. It was disabled because some strategies implemented it for unicode and some for bytes, so translation failed. We decide that listview_str is only for bytes, and that we will need to grow the equivalent unicode ones diff --git a/TODO b/TODO --- a/TODO +++ b/TODO @@ -7,7 +7,7 @@ re-enable IntDictStrategy -re-enable StdObjSpace.listview_str +write strategies for unicode list/dict/set, and add StdObjSpace.listview_unicode & co. re-enable the kwargs dict strategy in dictmultiobject.py re-enable view_as_kwargs 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 @@ -1034,7 +1034,8 @@ l.reverse() def getitems_str(self, w_list): - return self.unerase(w_list.lstorage) + return None # note that getitems_str is for bytes, not unicode + #return self.unerase(w_list.lstorage) # _______________________________________________________ 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 @@ -470,7 +470,10 @@ raise self._wrap_expected_length(expected_length, len(t)) return t - def __disabled_listview_str(self, w_obj): + def listview_str(self, w_obj): + """ + return a list of RPython bytes strings + """ # note: uses exact type checking for objects with strategies, # and isinstance() for others. See test_listobject.test_uses_custom... if type(w_obj) is W_ListObject: diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -682,7 +682,8 @@ return {} def listview_str(self, w_set): - return self.unerase(w_set.sstorage).keys() + return None # this is for bytes, not unicode + #return self.unerase(w_set.sstorage).keys() def is_correct_type(self, w_key): return type(w_key) is W_UnicodeObject From noreply at buildbot.pypy.org Fri Oct 26 16:31:04 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 16:31:04 +0200 (CEST) Subject: [pypy-commit] pypy py3k-listview_str: translation fix: we would need a BytesStrategy or a listview_unicode to make it working Message-ID: <20121026143104.4A1681C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: py3k-listview_str Changeset: r58456:18626459a9b2 Date: 2012-10-26 14:33 +0200 http://bitbucket.org/pypy/pypy/changeset/18626459a9b2/ Log: translation fix: we would need a BytesStrategy or a listview_unicode to make it working diff --git a/TODO b/TODO --- a/TODO +++ b/TODO @@ -9,6 +9,8 @@ write strategies for unicode list/dict/set, and add StdObjSpace.listview_unicode & co. +re-enable the UnicodeSetStrategy in setobject.set_strategy_and_setdata + re-enable the kwargs dict strategy in dictmultiobject.py re-enable view_as_kwargs diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -915,12 +915,14 @@ w_set.sstorage = w_iterable.get_storage_copy() return - stringlist = space.listview_str(w_iterable) - if stringlist is not None: - strategy = space.fromcache(UnicodeSetStrategy) - w_set.strategy = strategy - w_set.sstorage = strategy.get_storage_from_unwrapped_list(stringlist) - return + # we need to disable this for now: listview_str returns a list of bytes, + # we cannot use it with UnicodeSetStrategy + ## stringlist = space.listview_str(w_iterable) + ## if stringlist is not None: + ## strategy = space.fromcache(UnicodeSetStrategy) + ## w_set.strategy = strategy + ## w_set.sstorage = strategy.get_storage_from_unwrapped_list(stringlist) + ## return intlist = space.listview_int(w_iterable) if intlist is not None: From noreply at buildbot.pypy.org Fri Oct 26 16:31:05 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 16:31:05 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: a branch to add unicode strategies to list/dict/etc., which will be useful for py3k as well Message-ID: <20121026143105.779C41C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58457:01af5d1957f1 Date: 2012-10-26 15:19 +0200 http://bitbucket.org/pypy/pypy/changeset/01af5d1957f1/ Log: a branch to add unicode strategies to list/dict/etc., which will be useful for py3k as well diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -58,6 +58,7 @@ "'%s' object has no attribute '%s'", typename, name) else: + import pdb;pdb.set_trace() raise operationerrfmt(space.w_AttributeError, "'%s' object attribute '%s' is read-only", typename, name) From noreply at buildbot.pypy.org Fri Oct 26 16:31:06 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 16:31:06 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: add a UnicodeListStrategy Message-ID: <20121026143106.ABF8F1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58458:4c820346ebe3 Date: 2012-10-26 16:04 +0200 http://bitbucket.org/pypy/pypy/changeset/4c820346ebe3/ Log: add a UnicodeListStrategy 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 @@ -32,7 +32,8 @@ storage = strategy.erase(None) return W_ListObject.from_storage_and_strategy(space, storage, strategy) - at jit.look_inside_iff(lambda space, list_w, sizehint: jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF) + at jit.look_inside_iff(lambda space, list_w, sizehint: + jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF) def get_strategy_from_list_objects(space, list_w, sizehint): if not list_w: if sizehint != -1: @@ -53,6 +54,13 @@ else: return space.fromcache(StringListStrategy) + # check for unicode + for w_obj in list_w: + if not is_W_UnicodeObject(w_obj): + break + else: + return space.fromcache(UnicodeListStrategy) + # check for floats for w_obj in list_w: if not is_W_FloatObject(w_obj): @@ -70,6 +78,10 @@ from pypy.objspace.std.stringobject import W_StringObject return type(w_object) is W_StringObject +def is_W_UnicodeObject(w_object): + from pypy.objspace.std.unicodeobject import W_UnicodeObject + return type(w_object) is W_UnicodeObject + def is_W_FloatObject(w_object): from pypy.objspace.std.floatobject import W_FloatObject return type(w_object) is W_FloatObject @@ -419,6 +431,8 @@ strategy = self.space.fromcache(IntegerListStrategy) elif is_W_StringObject(w_item): strategy = self.space.fromcache(StringListStrategy) + elif is_W_UnicodeObject(w_item): + strategy = self.space.fromcache(UnicodeListStrategy) elif is_W_FloatObject(w_item): strategy = self.space.fromcache(FloatListStrategy) else: @@ -1036,6 +1050,35 @@ def getitems_str(self, w_list): return self.unerase(w_list.lstorage) + +class UnicodeListStrategy(AbstractUnwrappedStrategy, ListStrategy): + _none_value = None + _applevel_repr = "unicode" + + def wrap(self, stringval): + return self.space.wrap(stringval) + + def unwrap(self, w_string): + return self.space.unicode_w(w_string) + + erase, unerase = rerased.new_erasing_pair("unicode") + erase = staticmethod(erase) + unerase = staticmethod(unerase) + + def is_correct_type(self, w_obj): + return is_W_UnicodeObject(w_obj) + + def list_is_correct_type(self, w_list): + return w_list.strategy is self.space.fromcache(UnicodeListStrategy) + + def sort(self, w_list, reverse): + l = self.unerase(w_list.lstorage) + sorter = UnicodeSort(l, len(l)) + sorter.sort() + if reverse: + l.reverse() + + # _______________________________________________________ init_signature = Signature(['sequence'], None, None) @@ -1387,6 +1430,7 @@ IntBaseTimSort = make_timsort_class() FloatBaseTimSort = make_timsort_class() StringBaseTimSort = make_timsort_class() +UnicodeBaseTimSort = make_timsort_class() class KeyContainer(baseobjspace.W_Root): def __init__(self, w_key, w_item): @@ -1414,6 +1458,10 @@ def lt(self, a, b): return a < b +class UnicodeSort(UnicodeBaseTimSort): + def lt(self, a, b): + return a < b + class CustomCompareSort(SimpleSort): def lt(self, a, b): space = self.space diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -1,5 +1,5 @@ import sys -from pypy.objspace.std.listobject import W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy, FloatListStrategy, StringListStrategy, RangeListStrategy, make_range_list +from pypy.objspace.std.listobject import W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy, FloatListStrategy, StringListStrategy, RangeListStrategy, make_range_list, UnicodeListStrategy from pypy.objspace.std import listobject from pypy.objspace.std.test.test_listobject import TestW_ListObject @@ -8,34 +8,50 @@ class TestW_ListStrategies(TestW_ListObject): def test_check_strategy(self): - assert isinstance(W_ListObject(self.space, []).strategy, EmptyListStrategy) - assert isinstance(W_ListObject(self.space, [self.space.wrap(1),self.space.wrap('a')]).strategy, ObjectListStrategy) - assert isinstance(W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)]).strategy, IntegerListStrategy) - assert isinstance(W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap('b')]).strategy, StringListStrategy) - + space = self.space + w = space.wrap + assert isinstance(W_ListObject(space, []).strategy, EmptyListStrategy) + assert isinstance(W_ListObject(space, [w(1),w('a')]).strategy, ObjectListStrategy) + assert isinstance(W_ListObject(space, [w(1),w(2),w(3)]).strategy, + IntegerListStrategy) + assert isinstance(W_ListObject(space, [w('a'), w('b')]).strategy, + StringListStrategy) + assert isinstance(W_ListObject(space, [w(u'a'), w(u'b')]).strategy, + UnicodeListStrategy) + assert isinstance(W_ListObject(space, [w(u'a'), w('b')]).strategy, + ObjectListStrategy) # mixed unicode and bytes + def test_empty_to_any(self): - l = W_ListObject(self.space, []) + space = self.space + w = space.wrap + l = W_ListObject(space, []) assert isinstance(l.strategy, EmptyListStrategy) - l.append(self.space.wrap((1,3))) + l.append(w((1,3))) assert isinstance(l.strategy, ObjectListStrategy) - l = W_ListObject(self.space, []) + l = W_ListObject(space, []) assert isinstance(l.strategy, EmptyListStrategy) - l.append(self.space.wrap(1)) + l.append(w(1)) assert isinstance(l.strategy, IntegerListStrategy) - l = W_ListObject(self.space, []) + l = W_ListObject(space, []) assert isinstance(l.strategy, EmptyListStrategy) - l.append(self.space.wrap('a')) + l.append(w('a')) assert isinstance(l.strategy, StringListStrategy) - l = W_ListObject(self.space, []) + l = W_ListObject(space, []) assert isinstance(l.strategy, EmptyListStrategy) - l.append(self.space.wrap(1.2)) + l.append(w(u'a')) + assert isinstance(l.strategy, UnicodeListStrategy) + + l = W_ListObject(space, []) + assert isinstance(l.strategy, EmptyListStrategy) + l.append(w(1.2)) assert isinstance(l.strategy, FloatListStrategy) def test_int_to_any(self): - l = W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)]) + l = W_ListObject(self.space, + [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)]) assert isinstance(l.strategy, IntegerListStrategy) l.append(self.space.wrap(4)) assert isinstance(l.strategy, IntegerListStrategy) @@ -43,7 +59,17 @@ assert isinstance(l.strategy, ObjectListStrategy) def test_string_to_any(self): - l = W_ListObject(self.space, [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')]) + l = W_ListObject(self.space, + [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')]) + assert isinstance(l.strategy, StringListStrategy) + l.append(self.space.wrap('d')) + assert isinstance(l.strategy, StringListStrategy) + l.append(self.space.wrap(3)) + assert isinstance(l.strategy, ObjectListStrategy) + + def test_unicode_to_any(self): + l = W_ListObject(self.space, + [self.space.wrap(u'a'),self.space.wrap(u'b'),self.space.wrap('c')]) assert isinstance(l.strategy, StringListStrategy) l.append(self.space.wrap('d')) assert isinstance(l.strategy, StringListStrategy) @@ -51,7 +77,8 @@ assert isinstance(l.strategy, ObjectListStrategy) def test_float_to_any(self): - l = W_ListObject(self.space, [self.space.wrap(1.1),self.space.wrap(2.2),self.space.wrap(3.3)]) + l = W_ListObject(self.space, + [self.space.wrap(1.1),self.space.wrap(2.2),self.space.wrap(3.3)]) assert isinstance(l.strategy, FloatListStrategy) l.append(self.space.wrap(4.4)) assert isinstance(l.strategy, FloatListStrategy) From noreply at buildbot.pypy.org Fri Oct 26 16:31:07 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 16:31:07 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: fix this test Message-ID: <20121026143107.C8C261C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58459:d54c96393106 Date: 2012-10-26 16:07 +0200 http://bitbucket.org/pypy/pypy/changeset/d54c96393106/ Log: fix this test diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -68,12 +68,12 @@ assert isinstance(l.strategy, ObjectListStrategy) def test_unicode_to_any(self): - l = W_ListObject(self.space, - [self.space.wrap(u'a'),self.space.wrap(u'b'),self.space.wrap('c')]) - assert isinstance(l.strategy, StringListStrategy) - l.append(self.space.wrap('d')) - assert isinstance(l.strategy, StringListStrategy) - l.append(self.space.wrap(3)) + space = self.space + l = W_ListObject(space, [space.wrap(u'a'), space.wrap(u'b'), space.wrap(u'c')]) + assert isinstance(l.strategy, UnicodeListStrategy) + l.append(space.wrap(u'd')) + assert isinstance(l.strategy, UnicodeListStrategy) + l.append(space.wrap(3)) assert isinstance(l.strategy, ObjectListStrategy) def test_float_to_any(self): From noreply at buildbot.pypy.org Fri Oct 26 16:31:08 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 16:31:08 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: extend more test with UnicodeListStrategy (and make lines a bit shorter by using space and w instead of self.space.wrap) Message-ID: <20121026143108.E42FF1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58460:c6cb1203f9aa Date: 2012-10-26 16:12 +0200 http://bitbucket.org/pypy/pypy/changeset/c6cb1203f9aa/ Log: extend more test with UnicodeListStrategy (and make lines a bit shorter by using space and w instead of self.space.wrap) diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -86,66 +86,82 @@ assert isinstance(l.strategy, ObjectListStrategy) def test_setitem(self): + space = self.space + w = space.wrap # This should work if test_listobject.py passes - l = W_ListObject(self.space, [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')]) - assert self.space.eq_w(l.getitem(0), self.space.wrap('a')) - l.setitem(0, self.space.wrap('d')) - assert self.space.eq_w(l.getitem(0), self.space.wrap('d')) + l = W_ListObject(space, [w('a'),w('b'),w('c')]) + assert space.eq_w(l.getitem(0), w('a')) + l.setitem(0, w('d')) + assert space.eq_w(l.getitem(0), w('d')) assert isinstance(l.strategy, StringListStrategy) # IntStrategy to ObjectStrategy - l = W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)]) + l = W_ListObject(space, [w(1),w(2),w(3)]) assert isinstance(l.strategy, IntegerListStrategy) - l.setitem(0, self.space.wrap('d')) + l.setitem(0, w('d')) assert isinstance(l.strategy, ObjectListStrategy) # StringStrategy to ObjectStrategy - l = W_ListObject(self.space, [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')]) + l = W_ListObject(space, [w('a'),w('b'),w('c')]) assert isinstance(l.strategy, StringListStrategy) - l.setitem(0, self.space.wrap(2)) + l.setitem(0, w(2)) + assert isinstance(l.strategy, ObjectListStrategy) + + # UnicodeStrategy to ObjectStrategy + l = W_ListObject(space, [w(u'a'),w(u'b'),w(u'c')]) + assert isinstance(l.strategy, UnicodeListStrategy) + l.setitem(0, w(2)) assert isinstance(l.strategy, ObjectListStrategy) # FloatStrategy to ObjectStrategy - l = W_ListObject(self.space, [self.space.wrap(1.2),self.space.wrap(2.3),self.space.wrap(3.4)]) + l = W_ListObject(space, [w(1.2),w(2.3),w(3.4)]) assert isinstance(l.strategy, FloatListStrategy) - l.setitem(0, self.space.wrap("a")) + l.setitem(0, w("a")) assert isinstance(l.strategy, ObjectListStrategy) def test_insert(self): + space = self.space + w = space.wrap # no change - l = W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)]) + l = W_ListObject(space, [w(1),w(2),w(3)]) assert isinstance(l.strategy, IntegerListStrategy) - l.insert(3, self.space.wrap(4)) + l.insert(3, w(4)) assert isinstance(l.strategy, IntegerListStrategy) # StringStrategy - l = W_ListObject(self.space, [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')]) + l = W_ListObject(space, [w('a'),w('b'),w('c')]) assert isinstance(l.strategy, StringListStrategy) - l.insert(3, self.space.wrap(2)) + l.insert(3, w(2)) + assert isinstance(l.strategy, ObjectListStrategy) + + # UnicodeStrategy + l = W_ListObject(space, [w(u'a'),w(u'b'),w(u'c')]) + assert isinstance(l.strategy, UnicodeListStrategy) + l.insert(3, w(2)) assert isinstance(l.strategy, ObjectListStrategy) # IntegerStrategy - l = W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)]) + l = W_ListObject(space, [w(1),w(2),w(3)]) assert isinstance(l.strategy, IntegerListStrategy) - l.insert(3, self.space.wrap('d')) + l.insert(3, w('d')) assert isinstance(l.strategy, ObjectListStrategy) # FloatStrategy - l = W_ListObject(self.space, [self.space.wrap(1.1),self.space.wrap(2.2),self.space.wrap(3.3)]) + l = W_ListObject(space, [w(1.1),w(2.2),w(3.3)]) assert isinstance(l.strategy, FloatListStrategy) - l.insert(3, self.space.wrap('d')) + l.insert(3, w('d')) assert isinstance(l.strategy, ObjectListStrategy) # EmptyStrategy - l = W_ListObject(self.space, []) + l = W_ListObject(space, []) assert isinstance(l.strategy, EmptyListStrategy) - l.insert(0, self.space.wrap('a')) + l.insert(0, w('a')) assert isinstance(l.strategy, StringListStrategy) - l = W_ListObject(self.space, []) + l = W_ListObject(space, []) assert isinstance(l.strategy, EmptyListStrategy) - l.insert(0, self.space.wrap(2)) + l.insert(0, w(2)) assert isinstance(l.strategy, IntegerListStrategy) def test_list_empty_after_delete(self): @@ -167,47 +183,57 @@ assert isinstance(l.strategy, EmptyListStrategy) def test_setslice(self): - l = W_ListObject(self.space, []) + space = self.space + w = space.wrap + + l = W_ListObject(space, []) assert isinstance(l.strategy, EmptyListStrategy) - l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])) + l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)])) assert isinstance(l.strategy, IntegerListStrategy) # IntegerStrategy to IntegerStrategy - l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]) + l = W_ListObject(space, [w(1), w(2), w(3)]) assert isinstance(l.strategy, IntegerListStrategy) - l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5), self.space.wrap(6)])) + l.setslice(0, 1, 2, W_ListObject(space, [w(4), w(5), w(6)])) assert isinstance(l.strategy, IntegerListStrategy) # ObjectStrategy to ObjectStrategy - l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap('b'), self.space.wrap(3)]) + l = W_ListObject(space, [w(1), w('b'), w(3)]) assert isinstance(l.strategy, ObjectListStrategy) - l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])) + l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)])) assert isinstance(l.strategy, ObjectListStrategy) # IntegerStrategy to ObjectStrategy - l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]) + l = W_ListObject(space, [w(1), w(2), w(3)]) assert isinstance(l.strategy, IntegerListStrategy) - l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap('b'), self.space.wrap('c')])) + l.setslice(0, 1, 2, W_ListObject(space, [w('a'), w('b'), w('c')])) assert isinstance(l.strategy, ObjectListStrategy) # StringStrategy to ObjectStrategy - l = W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap('b'), self.space.wrap('c')]) + l = W_ListObject(space, [w('a'), w('b'), w('c')]) assert isinstance(l.strategy, StringListStrategy) - l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])) + l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)])) + assert isinstance(l.strategy, ObjectListStrategy) + + # UnicodeStrategy to ObjectStrategy + l = W_ListObject(space, [w(u'a'), w(u'b'), w(u'c')]) + assert isinstance(l.strategy, UnicodeListStrategy) + l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)])) assert isinstance(l.strategy, ObjectListStrategy) # FloatStrategy to ObjectStrategy - l = W_ListObject(self.space, [self.space.wrap(1.1), self.space.wrap(2.2), self.space.wrap(3.3)]) + l = W_ListObject(space, [w(1.1), w(2.2), w(3.3)]) assert isinstance(l.strategy, FloatListStrategy) - l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap(2), self.space.wrap(3)])) + l.setslice(0, 1, 2, W_ListObject(space, [w('a'), w(2), w(3)])) assert isinstance(l.strategy, ObjectListStrategy) def test_setslice_List(self): + space = self.space def wrapitems(items): items_w = [] for i in items: - items_w.append(self.space.wrap(i)) + items_w.append(space.wrap(i)) return items_w def keep_other_strategy(w_list, start, step, length, w_other): @@ -215,35 +241,40 @@ w_list.setslice(start, step, length, w_other) assert w_other.strategy is other_strategy - l = W_ListObject(self.space, wrapitems([1,2,3,4,5])) - other = W_ListObject(self.space, wrapitems(["a", "b", "c"])) + l = W_ListObject(space, wrapitems([1,2,3,4,5])) + other = W_ListObject(space, wrapitems(["a", "b", "c"])) keep_other_strategy(l, 0, 2, other.length(), other) - assert l.strategy is self.space.fromcache(ObjectListStrategy) + assert l.strategy is space.fromcache(ObjectListStrategy) - l = W_ListObject(self.space, wrapitems([1,2,3,4,5])) - other = W_ListObject(self.space, wrapitems([6, 6, 6])) + l = W_ListObject(space, wrapitems([1,2,3,4,5])) + other = W_ListObject(space, wrapitems([6, 6, 6])) keep_other_strategy(l, 0, 2, other.length(), other) - assert l.strategy is self.space.fromcache(IntegerListStrategy) + assert l.strategy is space.fromcache(IntegerListStrategy) - l = W_ListObject(self.space, wrapitems(["a","b","c","d","e"])) - other = W_ListObject(self.space, wrapitems(["a", "b", "c"])) + l = W_ListObject(space, wrapitems(["a","b","c","d","e"])) + other = W_ListObject(space, wrapitems(["a", "b", "c"])) keep_other_strategy(l, 0, 2, other.length(), other) - assert l.strategy is self.space.fromcache(StringListStrategy) + assert l.strategy is space.fromcache(StringListStrategy) - l = W_ListObject(self.space, wrapitems([1.1, 2.2, 3.3, 4.4, 5.5])) - other = W_ListObject(self.space, []) + l = W_ListObject(space, wrapitems([u"a",u"b",u"c",u"d",u"e"])) + other = W_ListObject(space, wrapitems([u"a", u"b", u"c"])) + keep_other_strategy(l, 0, 2, other.length(), other) + assert l.strategy is space.fromcache(UnicodeListStrategy) + + l = W_ListObject(space, wrapitems([1.1, 2.2, 3.3, 4.4, 5.5])) + other = W_ListObject(space, []) keep_other_strategy(l, 0, 1, l.length(), other) - assert l.strategy is self.space.fromcache(FloatListStrategy) + assert l.strategy is space.fromcache(FloatListStrategy) - l = W_ListObject(self.space, wrapitems(["a",3,"c",4,"e"])) - other = W_ListObject(self.space, wrapitems(["a", "b", "c"])) + l = W_ListObject(space, wrapitems(["a",3,"c",4,"e"])) + other = W_ListObject(space, wrapitems(["a", "b", "c"])) keep_other_strategy(l, 0, 2, other.length(), other) - assert l.strategy is self.space.fromcache(ObjectListStrategy) + assert l.strategy is space.fromcache(ObjectListStrategy) - l = W_ListObject(self.space, wrapitems(["a",3,"c",4,"e"])) - other = W_ListObject(self.space, []) + l = W_ListObject(space, wrapitems(["a",3,"c",4,"e"])) + other = W_ListObject(space, []) keep_other_strategy(l, 0, 1, l.length(), other) - assert l.strategy is self.space.fromcache(ObjectListStrategy) + assert l.strategy is space.fromcache(ObjectListStrategy) def test_empty_setslice_with_objectlist(self): l = W_ListObject(self.space, []) From noreply at buildbot.pypy.org Fri Oct 26 16:31:10 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 16:31:10 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: extend more tests Message-ID: <20121026143110.1619F1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58461:ee69d4c9c719 Date: 2012-10-26 16:16 +0200 http://bitbucket.org/pypy/pypy/changeset/ee69d4c9c719/ Log: extend more tests diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -277,72 +277,88 @@ assert l.strategy is space.fromcache(ObjectListStrategy) def test_empty_setslice_with_objectlist(self): - l = W_ListObject(self.space, []) - o = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap("2"), self.space.wrap(3)]) + space = self.space + w = space.wrap + + l = W_ListObject(space, []) + o = W_ListObject(space, [space.wrap(1), space.wrap("2"), space.wrap(3)]) l.setslice(0, 1, o.length(), o) assert l.getitems() == o.getitems() - l.append(self.space.wrap(17)) + l.append(space.wrap(17)) assert l.getitems() != o.getitems() def test_extend(self): - l = W_ListObject(self.space, []) + space = self.space + w = space.wrap + + l = W_ListObject(space, []) assert isinstance(l.strategy, EmptyListStrategy) - l.extend(W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])) + l.extend(W_ListObject(space, [w(1), w(2), w(3)])) assert isinstance(l.strategy, IntegerListStrategy) - l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]) + l = W_ListObject(space, [w(1), w(2), w(3)]) assert isinstance(l.strategy, IntegerListStrategy) - l.extend(W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap('b'), self.space.wrap('c')])) + l.extend(W_ListObject(space, [w('a'), w('b'), w('c')])) assert isinstance(l.strategy, ObjectListStrategy) - l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]) + l = W_ListObject(space, [w(1), w(2), w(3)]) assert isinstance(l.strategy, IntegerListStrategy) - l.extend(W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5), self.space.wrap(6)])) + l.extend(W_ListObject(space, [w(4), w(5), w(6)])) assert isinstance(l.strategy, IntegerListStrategy) - l = W_ListObject(self.space, [self.space.wrap(1.1), self.space.wrap(2.2), self.space.wrap(3.3)]) + l = W_ListObject(space, [w(1.1), w(2.2), w(3.3)]) assert isinstance(l.strategy, FloatListStrategy) - l.extend(W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5), self.space.wrap(6)])) + l.extend(W_ListObject(space, [w(4), w(5), w(6)])) assert isinstance(l.strategy, ObjectListStrategy) def test_empty_extend_with_any(self): - empty = W_ListObject(self.space, []) + space = self.space + w = space.wrap + + empty = W_ListObject(space, []) assert isinstance(empty.strategy, EmptyListStrategy) - empty.extend(W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])) + empty.extend(W_ListObject(space, [w(1), w(2), w(3)])) assert isinstance(empty.strategy, IntegerListStrategy) - empty = W_ListObject(self.space, []) + empty = W_ListObject(space, []) assert isinstance(empty.strategy, EmptyListStrategy) - empty.extend(W_ListObject(self.space, [self.space.wrap("a"), self.space.wrap("b"), self.space.wrap("c")])) + empty.extend(W_ListObject(space, [w("a"), w("b"), w("c")])) assert isinstance(empty.strategy, StringListStrategy) - empty = W_ListObject(self.space, []) + empty = W_ListObject(space, []) assert isinstance(empty.strategy, EmptyListStrategy) - r = make_range_list(self.space, 1,3,7) + empty.extend(W_ListObject(space, [w(u"a"), w(u"b"), w(u"c")])) + assert isinstance(empty.strategy, UnicodeListStrategy) + + empty = W_ListObject(space, []) + assert isinstance(empty.strategy, EmptyListStrategy) + r = make_range_list(space, 1,3,7) empty.extend(r) assert isinstance(empty.strategy, RangeListStrategy) print empty.getitem(6) - assert self.space.is_true(self.space.eq(empty.getitem(1), self.space.wrap(4))) + assert space.is_true(space.eq(empty.getitem(1), w(4))) - empty = W_ListObject(self.space, []) + empty = W_ListObject(space, []) assert isinstance(empty.strategy, EmptyListStrategy) - empty.extend(W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])) + empty.extend(W_ListObject(space, [w(1), w(2), w(3)])) assert isinstance(empty.strategy, IntegerListStrategy) - empty = W_ListObject(self.space, []) + empty = W_ListObject(space, []) assert isinstance(empty.strategy, EmptyListStrategy) - empty.extend(W_ListObject(self.space, [self.space.wrap(1.1), self.space.wrap(2.2), self.space.wrap(3.3)])) + empty.extend(W_ListObject(space, [w(1.1), w(2.2), w(3.3)])) assert isinstance(empty.strategy, FloatListStrategy) - empty = W_ListObject(self.space, []) + empty = W_ListObject(space, []) assert isinstance(empty.strategy, EmptyListStrategy) - empty.extend(W_ListObject(self.space, [])) + empty.extend(W_ListObject(space, [])) assert isinstance(empty.strategy, EmptyListStrategy) def test_extend_other_with_empty(self): - l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]) + space = self.space + w = space.wrap + l = W_ListObject(space, [w(1), w(2), w(3)]) assert isinstance(l.strategy, IntegerListStrategy) - l.extend(W_ListObject(self.space, [])) + l.extend(W_ListObject(space, [])) assert isinstance(l.strategy, IntegerListStrategy) def test_rangelist(self): @@ -489,7 +505,7 @@ l1 = W_ListObject(self.space, [self.space.wrap("eins"), self.space.wrap("zwei")]) assert isinstance(l1.strategy, StringListStrategy) l2 = W_ListObject(self.space, [self.space.wrap(u"eins"), self.space.wrap(u"zwei")]) - assert isinstance(l2.strategy, ObjectListStrategy) + assert isinstance(l2.strategy, UnicodeListStrategy) l3 = W_ListObject(self.space, [self.space.wrap("eins"), self.space.wrap(u"zwei")]) assert isinstance(l3.strategy, ObjectListStrategy) From noreply at buildbot.pypy.org Fri Oct 26 16:32:40 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 16:32:40 +0200 (CEST) Subject: [pypy-commit] pypy default: Attach the FILE to the Python file object from CFFI. This lets the FILE Message-ID: <20121026143240.C7A831C1DE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58462:1f2e3adb4ec0 Date: 2012-10-26 15:35 +0200 http://bitbucket.org/pypy/pypy/changeset/1f2e3adb4ec0/ Log: Attach the FILE to the Python file object from CFFI. This lets the FILE pointer stay valid for C code after the call to the function, and implement support for 'new("FILE **", f)'. diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,7 +4,6 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rlib import jit, clibffi, jit_libffi, rposix from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P @@ -152,9 +151,6 @@ if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') - elif flag == 2: - file = rffi.cast(rffi.CCHARPP, data)[0] - rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -169,27 +165,6 @@ assert isinstance(abi, int) return space.wrap(abi) -rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) - -def prepare_file_call_argument(fileobj): - import os - space = fileobj.space - fileobj.direct_flush() - fd = fileobj.direct_fileno() - if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file has no OS file descriptor")) - try: - fd2 = os.dup(fd) - f = rffi_fdopen(fd2, fileobj.mode) - if not f: - os.close(fd2) - raise OSError(rposix.get_errno(), "fdopen failed") - except OSError, e: - raise wrap_oserror(space, e) - return f - # ____________________________________________________________ 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 @@ -3,6 +3,7 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.rarithmetic import ovfcheck @@ -147,7 +148,15 @@ class W_CTypePtrBase(W_CTypePtrOrArray): # base class for both pointers and pointers-to-functions - _attrs_ = [] + _attrs_ = ['is_file'] + _immutable_fields_ = ['is_file'] + + def __init__(self, space, size, extra, extra_position, ctitem, + could_cast_anything=True, is_file=False): + W_CTypePtrOrArray.__init__(self, space, size, + extra, extra_position, ctitem, + could_cast_anything=could_cast_anything) + self.is_file = is_file def convert_to_object(self, cdata): ptrdata = rffi.cast(rffi.CCHARPP, cdata)[0] @@ -157,6 +166,11 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): + if self.is_file: + result = self.prepare_file(w_ob) + if result: + rffi.cast(rffi.CCHARPP, cdata)[0] = result + return raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -171,14 +185,23 @@ rffi.cast(rffi.CCHARPP, cdata)[0] = ob._cdata + def prepare_file(self, w_ob): + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = self.space.interpclass_w(w_ob) + if isinstance(ob, W_File): + return prepare_file_argument(self.space, ob) + else: + return lltype.nullptr(rffi.CCHARP.TO) + def _alignof(self): from pypy.module._cffi_backend import newtype return newtype.alignment_of_pointer class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['is_file'] - _immutable_fields_ = ['is_file'] + _attrs_ = [] + _immutable_fields_ = [] def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -187,8 +210,9 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" - self.is_file = (ctitem.name == "struct _IO_FILE") - W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) + is_file = (ctitem.name == "struct _IO_FILE") + W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem, + is_file=is_file) def newp(self, w_init): space = self.space @@ -245,11 +269,8 @@ # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 elif self.is_file: - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc - ob = space.interpclass_w(w_init) - if isinstance(ob, W_File): - result = ctypefunc.prepare_file_call_argument(ob) + result = self.prepare_file(w_init) + if result: rffi.cast(rffi.CCHARPP, cdata)[0] = result return 2 return 0 @@ -303,3 +324,31 @@ else: raise OperationError(space.w_TypeError, space.wrap("expected a 'cdata struct-or-union' object")) + +# ____________________________________________________________ + + +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +class CffiFileObj(object): + _immutable_ = True + def __init__(self, fd, mode): + self.llf = rffi_fdopen(fd, mode) + if not self.llf: + raise OSError(rposix.get_errno(), "fdopen failed") + def close(self): + rffi_fclose(self.llf) + +def prepare_file_argument(space, fileobj): + fileobj.direct_flush() + if fileobj.cffi_fileobj is None: + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + except OSError, e: + raise wrap_oserror(space, e) + return fileobj.cffi_fileobj.llf diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -2264,3 +2264,36 @@ e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " "be a cdata pointer, not file") + +def test_FILE_object(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BFILEPP = new_pointer_type(BFILEP) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP,), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fileno = ll.load_function(BFunc2, "fileno") + # + import posix + fdr, fdw = posix.pipe() + fw1 = posix.fdopen(fdw, 'wb', 256) + # + fw1p = newp(BFILEPP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p[0]) + assert res >= 0 + res = fileno(fw1p[0]) + assert res == fdw + fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,8 +1,21 @@ from pypy.objspace.fake.checkmodule import checkmodule +from pypy.module._cffi_backend import ctypeptr +from pypy.rpython.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - checkmodule('_cffi_backend') + # prepare_file_argument() is not working without translating the _file + # module too + def dummy_prepare_file_argument(space, fileobj): + return lltype.nullptr(rffi.CCHARP.TO) + old = ctypeptr.prepare_file_argument + try: + ctypeptr.prepare_file_argument = dummy_prepare_file_argument + # + checkmodule('_cffi_backend') + # + finally: + ctypeptr.prepare_file_argument = old diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -32,6 +32,7 @@ encoding = None errors = None fd = -1 + cffi_fileobj = None # pypy/module/_cffi_backend newlines = 0 # Updated when the stream is closed @@ -148,7 +149,14 @@ del openstreams[stream] except KeyError: pass - stream.close() + # close the stream. If cffi_fileobj is None, we close the + # underlying fileno too. Otherwise, we leave that to + # cffi_fileobj.close(). + cffifo = self.cffi_fileobj + self.cffi_fileobj = None + stream.close1(cffifo is None) + if cffifo is not None: + cffifo.close() def direct_fileno(self): self.getstream() # check if the file is still open diff --git a/pypy/rlib/streamio.py b/pypy/rlib/streamio.py --- a/pypy/rlib/streamio.py +++ b/pypy/rlib/streamio.py @@ -268,6 +268,9 @@ return False def close(self): + self.close1(True) + + def close1(self, closefileno): pass def peek(self): @@ -333,8 +336,9 @@ else: data = data[n:] - def close(self): - os.close(self.fd) + def close1(self, closefileno): + if closefileno: + os.close(self.fd) if sys.platform == "win32": def truncate(self, size): @@ -375,9 +379,10 @@ size = os.fstat(self.fd).st_size self.mm = mmap.mmap(self.fd, size, access=self.access) - def close(self): + def close1(self, closefileno): self.mm.close() - os.close(self.fd) + if closefileno: + os.close(self.fd) def tell(self): return self.pos @@ -470,7 +475,7 @@ ("truncate", [r_longlong]), ("flush", []), ("flushable", []), - ("close", []), + ("close1", [int]), ("peek", []), ("try_to_find_file_descriptor", []), ("getnewlines", []), @@ -715,7 +720,7 @@ truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=True) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -770,7 +775,7 @@ seek = PassThrough("seek", flush_buffers=True) truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=True) - close = PassThrough("close", flush_buffers=True) + close1 = PassThrough("close1", flush_buffers=True) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -838,7 +843,7 @@ flush = PassThrough("flush", flush_buffers=False) flushable= PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -907,7 +912,7 @@ truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=False) flushable= PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1041,7 +1046,7 @@ truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=True) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1067,7 +1072,7 @@ truncate = PassThrough("truncate", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1091,7 +1096,7 @@ peek = PassThrough("peek", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) write = PassThrough("write", flush_buffers=False) truncate = PassThrough("truncate", flush_buffers=False) getnewlines= PassThrough("getnewlines",flush_buffers=False) @@ -1144,7 +1149,7 @@ truncate = PassThrough("truncate", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1172,6 +1177,6 @@ truncate = PassThrough("truncate", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) From noreply at buildbot.pypy.org Fri Oct 26 16:32:42 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 16:32:42 +0200 (CEST) Subject: [pypy-commit] pypy default: Update to cffi rev. 65574fb4a819. Message-ID: <20121026143242.06F8A1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58463:cc32c57f0892 Date: 2012-10-26 16:32 +0200 http://bitbucket.org/pypy/pypy/changeset/cc32c57f0892/ Log: Update to cffi rev. 65574fb4a819. 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 @@ -148,15 +148,7 @@ class W_CTypePtrBase(W_CTypePtrOrArray): # base class for both pointers and pointers-to-functions - _attrs_ = ['is_file'] - _immutable_fields_ = ['is_file'] - - def __init__(self, space, size, extra, extra_position, ctitem, - could_cast_anything=True, is_file=False): - W_CTypePtrOrArray.__init__(self, space, size, - extra, extra_position, ctitem, - could_cast_anything=could_cast_anything) - self.is_file = is_file + _attrs_ = [] def convert_to_object(self, cdata): ptrdata = rffi.cast(rffi.CCHARPP, cdata)[0] @@ -166,11 +158,6 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - if self.is_file: - result = self.prepare_file(w_ob) - if result: - rffi.cast(rffi.CCHARPP, cdata)[0] = result - return raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -185,23 +172,14 @@ rffi.cast(rffi.CCHARPP, cdata)[0] = ob._cdata - def prepare_file(self, w_ob): - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc - ob = self.space.interpclass_w(w_ob) - if isinstance(ob, W_File): - return prepare_file_argument(self.space, ob) - else: - return lltype.nullptr(rffi.CCHARP.TO) - def _alignof(self): from pypy.module._cffi_backend import newtype return newtype.alignment_of_pointer class W_CTypePointer(W_CTypePtrBase): - _attrs_ = [] - _immutable_fields_ = [] + _attrs_ = ['is_file'] + _immutable_fields_ = ['is_file'] def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -210,9 +188,8 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" - is_file = (ctitem.name == "struct _IO_FILE") - W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem, - is_file=is_file) + self.is_file = (ctitem.name == "struct _IO_FILE") + W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): space = self.space @@ -260,6 +237,22 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) + def cast(self, w_ob): + if self.is_file: + value = self.prepare_file(w_ob) + if value: + return cdataobj.W_CData(self.space, value, self) + return W_CTypePtrBase.cast(self, w_ob) + + def prepare_file(self, w_ob): + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = self.space.interpclass_w(w_ob) + if isinstance(ob, W_File): + return prepare_file_argument(self.space, ob) + else: + return lltype.nullptr(rffi.CCHARP.TO) + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or 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 @@ -2271,7 +2271,6 @@ # BFILE = new_struct_type("_IO_FILE") BFILEP = new_pointer_type(BFILE) - BFILEPP = new_pointer_type(BFILEP) BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) BInt = new_primitive_type("int") @@ -2285,12 +2284,12 @@ fdr, fdw = posix.pipe() fw1 = posix.fdopen(fdw, 'wb', 256) # - fw1p = newp(BFILEPP, fw1) + fw1p = cast(BFILEP, fw1) fw1.write(b"X") fw1.flush() - res = fputs(b"hello\n", fw1p[0]) + res = fputs(b"hello\n", fw1p) assert res >= 0 - res = fileno(fw1p[0]) + res = fileno(fw1p) assert res == fdw fw1.close() # From noreply at buildbot.pypy.org Fri Oct 26 16:32:43 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 16:32:43 +0200 (CEST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121026143243.35A181C1DE9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58464:4a7d016ed03d Date: 2012-10-26 16:32 +0200 http://bitbucket.org/pypy/pypy/changeset/4a7d016ed03d/ Log: merge heads diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py deleted file mode 100644 --- a/lib_pypy/itertools.py +++ /dev/null @@ -1,670 +0,0 @@ -# Note that PyPy contains also a built-in module 'itertools' which will -# hide this one if compiled in. - -"""Functional tools for creating and using iterators. - -Infinite iterators: -count([n]) --> n, n+1, n+2, ... -cycle(p) --> p0, p1, ... plast, p0, p1, ... -repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times - -Iterators terminating on the shortest input sequence: -izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... -ifilter(pred, seq) --> elements of seq where pred(elem) is True -ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False -islice(seq, [start,] stop [, step]) --> elements from - seq[start:stop:step] -imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ... -starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ... -tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n -chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... -takewhile(pred, seq) --> seq[0], seq[1], until pred fails -dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails -groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v) -""" - -__all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', - 'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap', - 'takewhile', 'tee', 'compress', 'product'] - -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f - - -class chain(object): - """Make an iterator that returns elements from the first iterable - until it is exhausted, then proceeds to the next iterable, until - all of the iterables are exhausted. Used for treating consecutive - sequences as a single sequence. - - Equivalent to : - - def chain(*iterables): - for it in iterables: - for element in it: - yield element - """ - def __init__(self, *iterables): - self._iterables_iter = iter(map(iter, iterables)) - # little trick for the first chain.next() call - self._cur_iterable_iter = iter([]) - - def __iter__(self): - return self - - def next(self): - while True: - try: - return self._cur_iterable_iter.next() - except StopIteration: - self._cur_iterable_iter = self._iterables_iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iterable_iter)) - - -class compress(object): - def __init__(self, data, selectors): - self.data = iter(data) - self.selectors = iter(selectors) - - def __iter__(self): - return self - - def next(self): - while True: - next_item = self.data.next() - next_selector = self.selectors.next() - if bool(next_selector): - return next_item - - -class count(object): - """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. - - Equivalent to : - - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) - while True: - yield n - n += 1 - """ - def __init__(self, n=0): - if not isinstance(n, int): - raise TypeError('%s is not a regular integer' % n) - self.times = n-1 - - def __iter__(self): - return self - - def next(self): - self.times += 1 - return self.times - - def __repr__(self): - return 'count(%d)' % (self.times + 1) - - - -class cycle(object): - """Make an iterator returning elements from the iterable and - saving a copy of each. When the iterable is exhausted, return - elements from the saved copy. Repeats indefinitely. - - Equivalent to : - - def cycle(iterable): - saved = [] - for element in iterable: - yield element - saved.append(element) - while saved: - for element in saved: - yield element - """ - def __init__(self, iterable): - self._cur_iter = iter(iterable) - self._saved = [] - self._must_save = True - - def __iter__(self): - return self - - def next(self): - # XXX Could probably be improved - try: - next_elt = self._cur_iter.next() - if self._must_save: - self._saved.append(next_elt) - except StopIteration: - self._cur_iter = iter(self._saved) - next_elt = self._cur_iter.next() - self._must_save = False - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iter)) - return next_elt - - -class dropwhile(object): - """Make an iterator that drops elements from the iterable as long - as the predicate is true; afterwards, returns every - element. Note, the iterator does not produce any output until the - predicate is true, so it may have a lengthy start-up time. - - Equivalent to : - - def dropwhile(predicate, iterable): - iterable = iter(iterable) - for x in iterable: - if not predicate(x): - yield x - break - for x in iterable: - yield x - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - self._dropped = False - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if self._dropped: - return value - while self._predicate(value): - value = self._iter.next() - self._dropped = True - return value - -class groupby(object): - """Make an iterator that returns consecutive keys and groups from the - iterable. The key is a function computing a key value for each - element. If not specified or is None, key defaults to an identity - function and returns the element unchanged. Generally, the - iterable needs to already be sorted on the same key function. - - The returned group is itself an iterator that shares the - underlying iterable with groupby(). Because the source is shared, - when the groupby object is advanced, the previous group is no - longer visible. So, if that data is needed later, it should be - stored as a list: - - groups = [] - uniquekeys = [] - for k, g in groupby(data, keyfunc): - groups.append(list(g)) # Store group iterator as a list - uniquekeys.append(k) - """ - def __init__(self, iterable, key=None): - if key is None: - key = lambda x: x - self.keyfunc = key - self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = xrange(0) - - def __iter__(self): - return self - - def next(self): - while self.currkey == self.tgtkey: - try: - self.currvalue = self.it.next() # Exit on StopIteration - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self.it)) - self.currkey = self.keyfunc(self.currvalue) - self.tgtkey = self.currkey - return (self.currkey, self._grouper(self.tgtkey)) - - def _grouper(self, tgtkey): - while self.currkey == tgtkey: - yield self.currvalue - self.currvalue = self.it.next() # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) - - - -class _ifilter_base(object): - """base class for ifilter and ifilterflase""" - def __init__(self, predicate, iterable): - # Make sure iterable *IS* iterable - self._iter = iter(iterable) - if predicate is None: - self._predicate = bool - else: - self._predicate = predicate - - def __iter__(self): - return self - -class ifilter(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is True. If predicate is - None, return the items that are true. - - Equivalent to : - - def ifilter: - if predicate is None: - predicate = bool - for x in iterable: - if predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - -class ifilterfalse(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is False. If predicate is - None, return the items that are false. - - Equivalent to : - - def ifilterfalse(predicate, iterable): - if predicate is None: - predicate = bool - for x in iterable: - if not predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if not self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - - - - -class imap(object): - """Make an iterator that computes the function using arguments - from each of the iterables. If function is set to None, then - imap() returns the arguments as a tuple. Like map() but stops - when the shortest iterable is exhausted instead of filling in - None for shorter iterables. The reason for the difference is that - infinite iterator arguments are typically an error for map() - (because the output is fully evaluated) but represent a common - and useful way of supplying arguments to imap(). - - Equivalent to : - - def imap(function, *iterables): - iterables = map(iter, iterables) - while True: - args = [i.next() for i in iterables] - if function is None: - yield tuple(args) - else: - yield function(*args) - - """ - def __init__(self, function, iterable, *other_iterables): - self._func = function - self._iters = map(iter, (iterable, ) + other_iterables) - - def __iter__(self): - return self - - def next(self): - try: - args = [it.next() for it in self._iters] - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (it)) - if self._func is None: - return tuple(args) - else: - return self._func(*args) - - - -class islice(object): - """Make an iterator that returns selected elements from the - iterable. If start is non-zero, then elements from the iterable - are skipped until start is reached. Afterward, elements are - returned consecutively unless step is set higher than one which - results in items being skipped. If stop is None, then iteration - continues until the iterator is exhausted, if at all; otherwise, - it stops at the specified position. Unlike regular slicing, - islice() does not support negative values for start, stop, or - step. Can be used to extract related fields from data where the - internal structure has been flattened (for example, a multi-line - report may list a name field on every third line). - """ - def __init__(self, iterable, *args): - s = slice(*args) - self.start, self.stop, self.step = s.start or 0, s.stop, s.step - if not isinstance(self.start, (int, long)): - raise ValueError("Start argument must be an integer") - if self.stop is not None and not isinstance(self.stop, (int,long)): - raise ValueError("Stop argument must be an integer or None") - if self.step is None: - self.step = 1 - if self.start<0 or (self.stop is not None and self.stop<0 - ) or self.step<=0: - raise ValueError, "indices for islice() must be positive" - self.it = iter(iterable) - self.donext = None - self.cnt = 0 - - def __iter__(self): - return self - - def next(self): - if self.donext is None: - try: - self.donext = self.it.next - except AttributeError: - raise TypeError - nextindex = self.start - if self.stop is not None and nextindex >= self.stop: - raise StopIteration - while self.cnt <= nextindex: - nextitem = self.donext() - self.cnt += 1 - self.start += self.step - return nextitem - -class izip(object): - """Make an iterator that aggregates elements from each of the - iterables. Like zip() except that it returns an iterator instead - of a list. Used for lock-step iteration over several iterables at - a time. - - Equivalent to : - - def izip(*iterables): - iterables = map(iter, iterables) - while iterables: - result = [i.next() for i in iterables] - yield tuple(result) - """ - def __init__(self, *iterables): - self._iterators = map(iter, iterables) - self._result = [None] * len(self._iterators) - - def __iter__(self): - return self - - def next(self): - if not self._iterators: - raise StopIteration() - try: - return tuple([i.next() for i in self._iterators]) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (i)) - - -class product(object): - - def __init__(self, *args, **kw): - if len(kw) > 1: - raise TypeError("product() takes at most 1 argument (%d given)" % - len(kw)) - self.repeat = kw.get('repeat', 1) - self.gears = [x for x in args] * self.repeat - self.num_gears = len(self.gears) - # initialization of indicies to loop over - self.indicies = [(0, len(self.gears[x])) - for x in range(0, self.num_gears)] - self.cont = True - - def roll_gears(self): - # Starting from the end of the gear indicies work to the front - # incrementing the gear until the limit is reached. When the limit - # is reached carry operation to the next gear - should_carry = True - for n in range(0, self.num_gears): - nth_gear = self.num_gears - n - 1 - if should_carry: - count, lim = self.indicies[nth_gear] - count += 1 - if count == lim and nth_gear == 0: - self.cont = False - if count == lim: - should_carry = True - count = 0 - else: - should_carry = False - self.indicies[nth_gear] = (count, lim) - else: - break - - def __iter__(self): - return self - - def next(self): - if not self.cont: - raise StopIteration - l = [] - for x in range(0, self.num_gears): - index, limit = self.indicies[x] - l.append(self.gears[x][index]) - self.roll_gears() - return tuple(l) - - -class repeat(object): - """Make an iterator that returns object over and over again. - Runs indefinitely unless the times argument is specified. Used - as argument to imap() for invariant parameters to the called - function. Also used with izip() to create an invariant part of a - tuple record. - - Equivalent to : - - def repeat(object, times=None): - if times is None: - while True: - yield object - else: - for i in xrange(times): - yield object - """ - def __init__(self, obj, times=None): - self._obj = obj - if times is not None: - xrange(times) # Raise a TypeError - if times < 0: - times = 0 - self._times = times - - def __iter__(self): - return self - - def next(self): - # next() *need* to decrement self._times when consumed - if self._times is not None: - if self._times <= 0: - raise StopIteration() - self._times -= 1 - return self._obj - - def __repr__(self): - if self._times is not None: - return 'repeat(%r, %r)' % (self._obj, self._times) - else: - return 'repeat(%r)' % (self._obj,) - - def __len__(self): - if self._times == -1 or self._times is None: - raise TypeError("len() of uniszed object") - return self._times - - -class starmap(object): - """Make an iterator that computes the function using arguments - tuples obtained from the iterable. Used instead of imap() when - argument parameters are already grouped in tuples from a single - iterable (the data has been ``pre-zipped''). The difference - between imap() and starmap() parallels the distinction between - function(a,b) and function(*c). - - Equivalent to : - - def starmap(function, iterable): - iterable = iter(iterable) - while True: - yield function(*iterable.next()) - """ - def __init__(self, function, iterable): - self._func = function - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - # CPython raises a TypeError when the iterator doesn't return a tuple - try: - t = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - if not isinstance(t, tuple): - raise TypeError("iterator must return a tuple") - return self._func(*t) - - - -class takewhile(object): - """Make an iterator that returns elements from the iterable as - long as the predicate is true. - - Equivalent to : - - def takewhile(predicate, iterable): - for x in iterable: - if predicate(x): - yield x - else: - break - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if not self._predicate(value): - raise StopIteration() - return value - - -class TeeData(object): - """Holds cached values for TeeObjects""" - def __init__(self, iterator): - self.data = [] - self._iter = iterator - - def __getitem__(self, i): - # iterates until 'i' if not done yet - while i>= len(self.data): - try: - self.data.append( self._iter.next() ) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - return self.data[i] - - -class TeeObject(object): - """Iterables / Iterators as returned by the tee() function""" - def __init__(self, iterable=None, tee_data=None): - if tee_data: - self.tee_data = tee_data - self.pos = 0 - # <=> Copy constructor - elif isinstance(iterable, TeeObject): - self.tee_data = iterable.tee_data - self.pos = iterable.pos - else: - self.tee_data = TeeData(iter(iterable)) - self.pos = 0 - - def next(self): - data = self.tee_data[self.pos] - self.pos += 1 - return data - - def __iter__(self): - return self - - - at builtinify -def tee(iterable, n=2): - """Return n independent iterators from a single iterable. - Note : once tee() has made a split, the original iterable - should not be used anywhere else; otherwise, the iterable could get - advanced without the tee objects being informed. - - Note : this member of the toolkit may require significant auxiliary - storage (depending on how much temporary data needs to be stored). - In general, if one iterator is going to use most or all of the - data before the other iterator, it is faster to use list() instead - of tee() - - Equivalent to : - - def tee(iterable, n=2): - def gen(next, data={}, cnt=[0]): - for i in count(): - if i == cnt[0]: - item = data[i] = next() - cnt[0] += 1 - else: - item = data.pop(i) - yield item - it = iter(iterable) - return tuple([gen(it.next) for i in range(n)]) - """ - if isinstance(iterable, TeeObject): - # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) - return tuple([iterable] + - [TeeObject(tee_data=iterable.tee_data) for i in xrange(n-1)]) - tee_data = TeeData(iter(iterable)) - return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)]) diff --git a/lib_pypy/pypy_test/test_itertools.py b/lib_pypy/pypy_test/test_itertools.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_itertools.py +++ /dev/null @@ -1,50 +0,0 @@ -from py.test import raises -from lib_pypy import itertools - -class TestItertools(object): - - def test_compress(self): - it = itertools.compress(['a', 'b', 'c'], [0, 1, 0]) - - assert list(it) == ['b'] - - def test_compress_diff_len(self): - it = itertools.compress(['a'], []) - raises(StopIteration, it.next) - - def test_product(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')] - - def test_product_repeat(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m, repeat=2) - ans = [(1, 'a', 1, 'a'), (1, 'a', 1, 'b'), (1, 'a', 2, 'a'), - (1, 'a', 2, 'b'), (1, 'b', 1, 'a'), (1, 'b', 1, 'b'), - (1, 'b', 2, 'a'), (1, 'b', 2, 'b'), (2, 'a', 1, 'a'), - (2, 'a', 1, 'b'), (2, 'a', 2, 'a'), (2, 'a', 2, 'b'), - (2, 'b', 1, 'a'), (2, 'b', 1, 'b'), (2, 'b', 2, 'a'), - (2, 'b', 2, 'b')] - assert list(prodlist) == ans - - def test_product_diff_sizes(self): - l = [1, 2] - m = ['a'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (2, 'a')] - - l = [1] - m = ['a', 'b'] - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b')] - - def test_product_toomany_args(self): - l = [1, 2] - m = ['a'] - raises(TypeError, itertools.product, l, m, repeat=1, foo=2) diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -64,20 +64,18 @@ next = interp2app(W_Count.next_w), __reduce__ = interp2app(W_Count.reduce_w), __repr__ = interp2app(W_Count.repr_w), - __doc__ = """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. + __doc__ = """Make an iterator that returns evenly spaced values starting + with n. If not specified n defaults to zero. Often used as an + argument to imap() to generate consecutive data points. Also, + used with izip() to add sequence numbers. - Equivalent to : + Equivalent to: - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) + def count(start=0, step=1): + n = start while True: yield n - n += 1 + n += step """) 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 @@ -433,9 +433,7 @@ def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): - dtype = interp_ufuncs.find_dtype_for_scalar(space, w_other, - self.get_dtype()) - w_other = W_NDimArray.new_scalar(space, dtype, w_other) + w_other = convert_to_array(space, w_other) return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self, w_out]) return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name) 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 @@ -694,6 +694,8 @@ r = 3 + array(range(3)) for i in range(3): assert r[i] == i + 3 + r = [1, 2] + array([1, 2]) + assert (r == [2, 4]).all() def test_add_list(self): from _numpypy import array, ndarray From noreply at buildbot.pypy.org Fri Oct 26 16:47:54 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 16:47:54 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: bah, remove pdb Message-ID: <20121026144754.D73DA1C004F@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58465:ed283aa4800e Date: 2012-10-26 16:47 +0200 http://bitbucket.org/pypy/pypy/changeset/ed283aa4800e/ Log: bah, remove pdb diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -58,7 +58,6 @@ "'%s' object has no attribute '%s'", typename, name) else: - import pdb;pdb.set_trace() raise operationerrfmt(space.w_AttributeError, "'%s' object attribute '%s' is read-only", typename, name) diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -3,7 +3,7 @@ from pypy.interpreter.error import OperationError from pypy.objspace.std.dictmultiobject import \ W_DictMultiObject, setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, \ - StringDictStrategy, ObjectDictStrategy + StringDictStrategy, ObjectDictStrategy, UnicodeDictStrategy from pypy.conftest import gettestobjspace from pypy.conftest import option From noreply at buildbot.pypy.org Fri Oct 26 16:55:29 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 16:55:29 +0200 (CEST) Subject: [pypy-commit] pypy default: Move import Message-ID: <20121026145529.D2BEF1C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58466:0a4f1fce48cd Date: 2012-10-26 16:55 +0200 http://bitbucket.org/pypy/pypy/changeset/0a4f1fce48cd/ Log: Move import diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -5,7 +5,7 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi, rposix +from pypy.rlib import jit, clibffi, jit_libffi from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG 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 @@ -7,6 +7,7 @@ from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.rarithmetic import ovfcheck +from pypy.rlib import rposix from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend import cdataobj, misc, ctypeprim From noreply at buildbot.pypy.org Fri Oct 26 17:08:39 2012 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 26 Oct 2012 17:08:39 +0200 (CEST) Subject: [pypy-commit] pypy stm-thread-2: Printing "stm-perform-transaction" delimiters. Message-ID: <20121026150839.285DB1C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r58467:cc046906276f Date: 2012-10-26 17:08 +0200 http://bitbucket.org/pypy/pypy/changeset/cc046906276f/ Log: Printing "stm-perform-transaction" delimiters. diff --git a/pypy/translator/stm/src_stm/rpyintf.c b/pypy/translator/stm/src_stm/rpyintf.c --- a/pypy/translator/stm/src_stm/rpyintf.c +++ b/pypy/translator/stm/src_stm/rpyintf.c @@ -128,6 +128,7 @@ #ifndef USING_NO_GC_AT_ALL v_saved_value = *(void***)save_and_restore; #endif + PYPY_DEBUG_START("stm-perform-transaction"); /***/ setjmp(_jmpbuf); /* After setjmp(), the local variables v_* are preserved because they @@ -178,6 +179,7 @@ #ifndef USING_NO_GC_AT_ALL *(void***)save_and_restore = v_saved_value; #endif + PYPY_DEBUG_STOP("stm-perform-transaction"); } void stm_abort_and_retry(void) From noreply at buildbot.pypy.org Fri Oct 26 17:52:59 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 17:52:59 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: add a unicode dict strategy Message-ID: <20121026155259.92FDC1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58468:ff9660073713 Date: 2012-10-26 17:52 +0200 http://bitbucket.org/pypy/pypy/changeset/ff9660073713/ Log: add a unicode dict strategy diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -207,6 +207,9 @@ if type(w_key) is self.space.StringObjectCls: self.switch_to_string_strategy(w_dict) return + elif type(w_key) is self.space.UnicodeObjectCls: + self.switch_to_unicode_strategy(w_dict) + return w_type = self.space.type(w_key) if self.space.is_w(w_type, self.space.w_int): self.switch_to_int_strategy(w_dict) @@ -221,6 +224,12 @@ w_dict.strategy = strategy w_dict.dstorage = storage + def switch_to_unicode_strategy(self, w_dict): + strategy = self.space.fromcache(UnicodeDictStrategy) + storage = strategy.get_empty_storage() + w_dict.strategy = strategy + w_dict.dstorage = storage + def switch_to_int_strategy(self, w_dict): strategy = self.space.fromcache(IntDictStrategy) storage = strategy.get_empty_storage() @@ -625,6 +634,73 @@ create_iterator_classes(StringDictStrategy) +class UnicodeDictStrategy(AbstractTypedStrategy, DictStrategy): + + erase, unerase = rerased.new_erasing_pair("unicode") + erase = staticmethod(erase) + unerase = staticmethod(unerase) + + def wrap(self, unwrapped): + return self.space.wrap(unwrapped) + + def unwrap(self, wrapped): + return self.space.unicode_w(wrapped) + + def is_correct_type(self, w_obj): + space = self.space + return space.is_w(space.type(w_obj), space.w_unicode) + + def get_empty_storage(self): + res = {} + mark_dict_non_null(res) + return self.erase(res) + + def _never_equal_to(self, w_lookup_type): + return _never_equal_to_string(self.space, w_lookup_type) + + # we should implement the same shortcuts as we do for StringDictStrategy + + ## def setitem_str(self, w_dict, key, w_value): + ## assert key is not None + ## self.unerase(w_dict.dstorage)[key] = w_value + + ## def getitem(self, w_dict, w_key): + ## space = self.space + ## # -- This is called extremely often. Hack for performance -- + ## if type(w_key) is space.StringObjectCls: + ## return self.getitem_str(w_dict, w_key.unwrap(space)) + ## # -- End of performance hack -- + ## return AbstractTypedStrategy.getitem(self, w_dict, w_key) + + ## def getitem_str(self, w_dict, key): + ## assert key is not None + ## return self.unerase(w_dict.dstorage).get(key, None) + + ## def listview_str(self, w_dict): + ## return self.unerase(w_dict.dstorage).keys() + + ## def w_keys(self, w_dict): + ## return self.space.newlist_str(self.listview_str(w_dict)) + + def wrapkey(space, key): + return space.wrap(key) + + ## @jit.look_inside_iff(lambda self, w_dict: + ## w_dict_unrolling_heuristic(w_dict)) + ## def view_as_kwargs(self, w_dict): + ## d = self.unerase(w_dict.dstorage) + ## l = len(d) + ## keys, values = [None] * l, [None] * l + ## i = 0 + ## for key, val in d.iteritems(): + ## keys[i] = key + ## values[i] = val + ## i += 1 + ## return keys, values + +create_iterator_classes(UnicodeDictStrategy) + + class IntDictStrategy(AbstractTypedStrategy, DictStrategy): erase, unerase = rerased.new_erasing_pair("int") erase = staticmethod(erase) 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 @@ -29,6 +29,7 @@ from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std.smallintobject import W_SmallIntObject from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.unicodeobject import W_UnicodeObject from pypy.objspace.std.tupleobject import W_AbstractTupleObject from pypy.objspace.std.typeobject import W_TypeObject @@ -52,6 +53,8 @@ self.StringObjectCls = W_RopeObject else: self.StringObjectCls = W_StringObject + + self.UnicodeObjectCls = W_UnicodeObject self._install_multimethods() diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -3,7 +3,7 @@ from pypy.interpreter.error import OperationError from pypy.objspace.std.dictmultiobject import \ W_DictMultiObject, setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, \ - StringDictStrategy, ObjectDictStrategy, UnicodeDictStrategy + StringDictStrategy, ObjectDictStrategy from pypy.conftest import gettestobjspace from pypy.conftest import option @@ -799,6 +799,16 @@ o.a = 1 assert "StringDictStrategy" in self.get_strategy(d) + def test_empty_to_unicode(self): + d = {} + assert "EmptyDictStrategy" in self.get_strategy(d) + d[u"a"] = 1 + assert "UnicodeDictStrategy" in self.get_strategy(d) + assert d[u"a"] == 1 + assert d["a"] == 1 + assert d.keys() == [u"a"] + assert type(d.keys()[0]) is unicode + def test_empty_to_int(self): import sys d = {} From noreply at buildbot.pypy.org Fri Oct 26 21:45:26 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 21:45:26 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: add a test about string set strategy Message-ID: <20121026194526.2BD951C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58469:7a311e30b728 Date: 2012-10-26 19:09 +0200 http://bitbucket.org/pypy/pypy/changeset/7a311e30b728/ Log: add a test about string set strategy diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -13,6 +13,7 @@ from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.unicodeobject import W_UnicodeObject class W_BaseSetObject(W_Object): typedef = None diff --git a/pypy/objspace/std/test/test_setstrategies.py b/pypy/objspace/std/test/test_setstrategies.py --- a/pypy/objspace/std/test/test_setstrategies.py +++ b/pypy/objspace/std/test/test_setstrategies.py @@ -1,5 +1,6 @@ from pypy.objspace.std.setobject import W_SetObject -from pypy.objspace.std.setobject import IntegerSetStrategy, ObjectSetStrategy, EmptySetStrategy +from pypy.objspace.std.setobject import (IntegerSetStrategy, ObjectSetStrategy, + EmptySetStrategy, StringSetStrategy) from pypy.objspace.std.listobject import W_ListObject class TestW_SetStrategies: @@ -20,6 +21,9 @@ s = W_SetObject(self.space, self.wrapped([])) assert s.strategy is self.space.fromcache(EmptySetStrategy) + s = W_SetObject(self.space, self.wrapped(["a", "b"])) + assert s.strategy is self.space.fromcache(StringSetStrategy) + def test_switch_to_object(self): s = W_SetObject(self.space, self.wrapped([1,2,3,4,5])) s.add(self.space.wrap("six")) From noreply at buildbot.pypy.org Fri Oct 26 21:45:32 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 21:45:32 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: enable listview_unicode also for subclasses which do not ovverride __iter__ Message-ID: <20121026194532.60FBE1C1E0C@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58474:c83bd1c0bc81 Date: 2012-10-26 19:33 +0200 http://bitbucket.org/pypy/pypy/changeset/c83bd1c0bc81/ Log: enable listview_unicode also for subclasses which do not ovverride __iter__ 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 @@ -475,8 +475,8 @@ ## return w_obj.listview_unicode() ## if isinstance(w_obj, W_UnicodeObject): ## return w_obj.listview_unicode() - ## if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj): - ## return w_obj.getitems_unicode() + if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj): + return w_obj.getitems_unicode() return None def listview_int(self, w_obj): diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -1188,9 +1188,10 @@ # strategies, to avoid surprizes depending on the strategy. class X: pass for base, arg in [ - (list, []), (list, [5]), (list, ['x']), (list, [X]), - (set, []), (set, [5]), (set, ['x']), (set, [X]), + (list, []), (list, [5]), (list, ['x']), (list, [X]), (list, [u'x']), + (set, []), (set, [5]), (set, ['x']), (set, [X]), (set, [u'x']), (dict, []), (dict, [(5,6)]), (dict, [('x',7)]), (dict, [(X,8)]), + (dict, [(u'x', 7)]), ]: print base, arg class SubClass(base): From noreply at buildbot.pypy.org Fri Oct 26 21:45:27 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 21:45:27 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: start to implement space.listview_unicode; it works only for lists for now Message-ID: <20121026194527.870E51C1E02@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58470:87cc5b05aa76 Date: 2012-10-26 19:16 +0200 http://bitbucket.org/pypy/pypy/changeset/87cc5b05aa76/ Log: start to implement space.listview_unicode; it works only for lists for now diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -953,6 +953,13 @@ """ return None + def listview_unicode(self, w_list): + """ Return a list of unwrapped unicode out of a list of unicode. If the + argument is not a list or does not contain only unicode, return None. + May return None anyway. + """ + return None + def view_as_kwargs(self, w_dict): """ if w_dict is a kwargs-dict, return two lists, one of unwrapped strings and one of wrapped values. otherwise return (None, None) 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 @@ -223,6 +223,11 @@ not use the list strategy, return None. """ return self.strategy.getitems_str(self) + def getitems_unicode(self): + """ Return the items in the list as unwrapped unicodes. If the list does + not use the list strategy, return None. """ + return self.strategy.getitems_unicode(self) + def getitems_int(self): """ Return the items in the list as unwrapped ints. If the list does not use the list strategy, return None. """ @@ -327,6 +332,9 @@ def getitems_str(self, w_list): return None + def getitems_unicode(self, w_list): + return None + def getitems_int(self, w_list): return None @@ -1078,6 +1086,8 @@ if reverse: l.reverse() + def getitems_unicode(self, w_list): + return self.unerase(w_list.lstorage) # _______________________________________________________ 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 @@ -464,6 +464,21 @@ return w_obj.getitems_str() return None + def listview_unicode(self, w_obj): + # note: uses exact type checking for objects with strategies, + # and isinstance() for others. See test_listobject.test_uses_custom... + if type(w_obj) is W_ListObject: + return w_obj.getitems_unicode() + ## if type(w_obj) is W_DictMultiObject: + ## return w_obj.listview_unicode() + ## if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject: + ## return w_obj.listview_unicode() + ## if isinstance(w_obj, W_UnicodeObject): + ## return w_obj.listview_unicode() + ## if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj): + ## return w_obj.getitems_unicode() + return None + def listview_int(self, w_obj): if type(w_obj) is W_ListObject: return w_obj.getitems_int() diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -515,6 +515,12 @@ w_l = self.space.newlist([self.space.wrap('a'), self.space.wrap('b')]) assert space.listview_str(w_l) == ["a", "b"] + def test_listview_unicode(self): + space = self.space + assert space.listview_unicode(space.wrap(1)) == None + w_l = self.space.newlist([self.space.wrap(u'a'), self.space.wrap(u'b')]) + assert space.listview_unicode(w_l) == [u"a", u"b"] + def test_string_join_uses_listview_str(self): space = self.space w_l = self.space.newlist([self.space.wrap('a'), self.space.wrap('b')]) From noreply at buildbot.pypy.org Fri Oct 26 21:45:33 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 21:45:33 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: implement listview_unicode for dicts Message-ID: <20121026194533.796AC1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58475:3e98af414d3e Date: 2012-10-26 21:00 +0200 http://bitbucket.org/pypy/pypy/changeset/3e98af414d3e/ Log: implement listview_unicode for dicts diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -113,7 +113,7 @@ getitem_str delitem length \ clear w_keys values \ items iterkeys itervalues iteritems setdefault \ - popitem listview_str listview_int".split() + popitem listview_str listview_unicode listview_int".split() def make_method(method): def f(self, *args): @@ -187,6 +187,9 @@ def listview_str(self, w_dict): return None + def listview_unicode(self, w_dict): + return None + def listview_int(self, w_dict): return None @@ -676,8 +679,8 @@ ## assert key is not None ## return self.unerase(w_dict.dstorage).get(key, None) - ## def listview_str(self, w_dict): - ## return self.unerase(w_dict.dstorage).keys() + def listview_unicode(self, w_dict): + return self.unerase(w_dict.dstorage).keys() ## def w_keys(self, w_dict): ## return self.space.newlist_str(self.listview_str(w_dict)) 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 @@ -469,8 +469,8 @@ # and isinstance() for others. See test_listobject.test_uses_custom... if type(w_obj) is W_ListObject: return w_obj.getitems_unicode() - ## if type(w_obj) is W_DictMultiObject: - ## return w_obj.listview_unicode() + if type(w_obj) is W_DictMultiObject: + return w_obj.listview_unicode() ## if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject: ## return w_obj.listview_unicode() ## if isinstance(w_obj, W_UnicodeObject): diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -144,33 +144,48 @@ def test_listview_str_dict(self): w = self.space.wrap - w_d = self.space.newdict() w_d.initialize_content([(w("a"), w(1)), (w("b"), w(2))]) + assert self.space.listview_str(w_d) == ["a", "b"] - assert self.space.listview_str(w_d) == ["a", "b"] + def test_listview_unicode_dict(self): + w = self.space.wrap + w_d = self.space.newdict() + w_d.initialize_content([(w(u"a"), w(1)), (w(u"b"), w(2))]) + assert self.space.listview_unicode(w_d) == [u"a", u"b"] def test_listview_int_dict(self): w = self.space.wrap w_d = self.space.newdict() w_d.initialize_content([(w(1), w("a")), (w(2), w("b"))]) - assert self.space.listview_int(w_d) == [1, 2] - def test_keys_on_string_int_dict(self): + def test_keys_on_string_unicode_int_dict(self, monkeypatch): w = self.space.wrap + w_d = self.space.newdict() w_d.initialize_content([(w(1), w("a")), (w(2), w("b"))]) - w_l = self.space.call_method(w_d, "keys") assert sorted(self.space.listview_int(w_l)) == [1,2] - + + # make sure that .keys() calls newlist_str for string dicts + def not_allowed(*args): + assert False, 'should not be called' + monkeypatch.setattr(self.space, 'newlist', not_allowed) + # w_d = self.space.newdict() w_d.initialize_content([(w("a"), w(1)), (w("b"), w(6))]) - w_l = self.space.call_method(w_d, "keys") assert sorted(self.space.listview_str(w_l)) == ["a", "b"] + # XXX: it would be nice if the test passed without monkeypatch.undo(), + # but we need space.newlist_unicode for it + monkeypatch.undo() + w_d = self.space.newdict() + w_d.initialize_content([(w(u"a"), w(1)), (w(u"b"), w(6))]) + w_l = self.space.call_method(w_d, "keys") + assert sorted(self.space.listview_unicode(w_l)) == [u"a", u"b"] + class AppTest_DictObject: def setup_class(cls): cls.w_on_pypy = cls.space.wrap("__pypy__" in sys.builtin_module_names) From noreply at buildbot.pypy.org Fri Oct 26 21:45:28 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 21:45:28 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: unicode.join uses listview_unicode Message-ID: <20121026194528.B12D51C1E09@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58471:36ecc34cfb00 Date: 2012-10-26 19:18 +0200 http://bitbucket.org/pypy/pypy/changeset/36ecc34cfb00/ Log: unicode.join uses listview_unicode diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -527,6 +527,12 @@ w_l.getitems = None assert space.str_w(space.call_method(space.wrap("c"), "join", w_l)) == "acb" + def test_unicode_join_uses_listview_unicode(self): + space = self.space + w_l = self.space.newlist([self.space.wrap(u'a'), self.space.wrap(u'b')]) + w_l.getitems = None + assert space.unicode_w(space.call_method(space.wrap(u"c"), "join", w_l)) == u"acb" + def test_string_join_returns_same_instance(self): space = self.space w_text = space.wrap("text") diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -202,6 +202,11 @@ return space.newbool(container.find(item) != -1) def unicode_join__Unicode_ANY(space, w_self, w_list): + l = space.listview_unicode(w_list) + if l is not None: + if len(l) == 1: + return space.wrap(l[0]) + return space.wrap(w_self._value.join(l)) list_w = space.listview(w_list) size = len(list_w) From noreply at buildbot.pypy.org Fri Oct 26 21:45:34 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 21:45:34 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: implement unicode set strategy Message-ID: <20121026194534.9EA9B1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58476:9cbe431d72f5 Date: 2012-10-26 21:18 +0200 http://bitbucket.org/pypy/pypy/changeset/9cbe431d72f5/ Log: implement unicode set strategy diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -304,6 +304,8 @@ strategy = self.space.fromcache(IntegerSetStrategy) elif type(w_key) is W_StringObject: strategy = self.space.fromcache(StringSetStrategy) + elif type(w_key) is W_UnicodeObject: + strategy = self.space.fromcache(UnicodeSetStrategy) else: strategy = self.space.fromcache(ObjectSetStrategy) w_set.strategy = strategy @@ -714,6 +716,42 @@ def iter(self, w_set): return StringIteratorImplementation(self.space, self, w_set) + +class UnicodeSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy): + erase, unerase = rerased.new_erasing_pair("unicode") + erase = staticmethod(erase) + unerase = staticmethod(unerase) + + def get_empty_storage(self): + return self.erase({}) + + def get_empty_dict(self): + return {} + + ## def listview_unicode(self, w_set): + ## return self.unerase(w_set.sstorage).keys() + + def is_correct_type(self, w_key): + return type(w_key) is W_UnicodeObject + + def may_contain_equal_elements(self, strategy): + if strategy is self.space.fromcache(IntegerSetStrategy): + return False + if strategy is self.space.fromcache(EmptySetStrategy): + return False + return True + + def unwrap(self, w_item): + return self.space.unicode_w(w_item) + + def wrap(self, item): + return self.space.wrap(item) + + def iter(self, w_set): + XXX + return StringIteratorImplementation(self.space, self, w_set) + + class IntegerSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy): erase, unerase = rerased.new_erasing_pair("integer") erase = staticmethod(erase) @@ -932,6 +970,13 @@ w_set.sstorage = strategy.get_storage_from_unwrapped_list(stringlist) return + unicodelist = space.listview_unicode(w_iterable) + if unicodelist is not None: + strategy = space.fromcache(UnicodeSetStrategy) + w_set.strategy = strategy + w_set.sstorage = strategy.get_storage_from_unwrapped_list(unicodelist) + return + intlist = space.listview_int(w_iterable) if intlist is not None: strategy = space.fromcache(IntegerSetStrategy) diff --git a/pypy/objspace/std/test/test_setstrategies.py b/pypy/objspace/std/test/test_setstrategies.py --- a/pypy/objspace/std/test/test_setstrategies.py +++ b/pypy/objspace/std/test/test_setstrategies.py @@ -1,6 +1,7 @@ from pypy.objspace.std.setobject import W_SetObject from pypy.objspace.std.setobject import (IntegerSetStrategy, ObjectSetStrategy, - EmptySetStrategy, StringSetStrategy) + EmptySetStrategy, StringSetStrategy, + UnicodeSetStrategy) from pypy.objspace.std.listobject import W_ListObject class TestW_SetStrategies: @@ -24,6 +25,9 @@ s = W_SetObject(self.space, self.wrapped(["a", "b"])) assert s.strategy is self.space.fromcache(StringSetStrategy) + s = W_SetObject(self.space, self.wrapped([u"a", u"b"])) + assert s.strategy is self.space.fromcache(UnicodeSetStrategy) + def test_switch_to_object(self): s = W_SetObject(self.space, self.wrapped([1,2,3,4,5])) s.add(self.space.wrap("six")) @@ -34,6 +38,11 @@ s1.update(s2) assert s1.strategy is self.space.fromcache(ObjectSetStrategy) + def test_switch_to_unicode(self): + s = W_SetObject(self.space, self.wrapped([])) + s.add(self.space.wrap(u"six")) + assert s.strategy is self.space.fromcache(UnicodeSetStrategy) + def test_symmetric_difference(self): s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5])) s2 = W_SetObject(self.space, self.wrapped(["six", "seven"])) From noreply at buildbot.pypy.org Fri Oct 26 21:45:35 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 21:45:35 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: implement iterator for unicode sets Message-ID: <20121026194535.C5BEC1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58477:30b58451e900 Date: 2012-10-26 21:23 +0200 http://bitbucket.org/pypy/pypy/changeset/30b58451e900/ Log: implement iterator for unicode sets diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -748,8 +748,7 @@ return self.space.wrap(item) def iter(self, w_set): - XXX - return StringIteratorImplementation(self.space, self, w_set) + return UnicodeIteratorImplementation(self.space, self, w_set) class IntegerSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy): @@ -891,6 +890,18 @@ else: return None +class UnicodeIteratorImplementation(IteratorImplementation): + def __init__(self, space, strategy, w_set): + IteratorImplementation.__init__(self, space, strategy, w_set) + d = strategy.unerase(w_set.sstorage) + self.iterator = d.iterkeys() + + def next_entry(self): + for key in self.iterator: + return self.space.wrap(key) + else: + return None + class IntegerIteratorImplementation(IteratorImplementation): #XXX same implementation in dictmultiobject on dictstrategy-branch def __init__(self, space, strategy, w_set): diff --git a/pypy/objspace/std/test/test_setstrategies.py b/pypy/objspace/std/test/test_setstrategies.py --- a/pypy/objspace/std/test/test_setstrategies.py +++ b/pypy/objspace/std/test/test_setstrategies.py @@ -1,7 +1,10 @@ from pypy.objspace.std.setobject import W_SetObject from pypy.objspace.std.setobject import (IntegerSetStrategy, ObjectSetStrategy, EmptySetStrategy, StringSetStrategy, - UnicodeSetStrategy) + UnicodeSetStrategy, + IntegerIteratorImplementation, + StringIteratorImplementation, + UnicodeIteratorImplementation) from pypy.objspace.std.listobject import W_ListObject class TestW_SetStrategies: @@ -118,3 +121,23 @@ assert s1.has_key(self.space.wrap(FakeInt(2))) assert s1.strategy is self.space.fromcache(ObjectSetStrategy) + + def test_iter(self): + space = self.space + s = W_SetObject(space, self.wrapped([1,2])) + it = s.iter() + assert isinstance(it, IntegerIteratorImplementation) + assert space.unwrap(it.next()) == 1 + assert space.unwrap(it.next()) == 2 + # + s = W_SetObject(space, self.wrapped(["a", "b"])) + it = s.iter() + assert isinstance(it, StringIteratorImplementation) + assert space.unwrap(it.next()) == "a" + assert space.unwrap(it.next()) == "b" + # + s = W_SetObject(space, self.wrapped([u"a", u"b"])) + it = s.iter() + assert isinstance(it, UnicodeIteratorImplementation) + assert space.unwrap(it.next()) == u"a" + assert space.unwrap(it.next()) == u"b" From noreply at buildbot.pypy.org Fri Oct 26 21:45:30 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 21:45:30 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: one more test Message-ID: <20121026194530.1AF571C1E0A@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58472:c6068c310b51 Date: 2012-10-26 19:20 +0200 http://bitbucket.org/pypy/pypy/changeset/c6068c310b51/ Log: one more test diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -526,9 +526,8 @@ w_l = self.space.newlist([self.space.wrap('a'), self.space.wrap('b')]) w_l.getitems = None assert space.str_w(space.call_method(space.wrap("c"), "join", w_l)) == "acb" - - def test_unicode_join_uses_listview_unicode(self): - space = self.space + # + # the same for unicode w_l = self.space.newlist([self.space.wrap(u'a'), self.space.wrap(u'b')]) w_l.getitems = None assert space.unicode_w(space.call_method(space.wrap(u"c"), "join", w_l)) == u"acb" @@ -539,6 +538,13 @@ w_l = self.space.newlist([w_text]) w_l.getitems = None assert space.is_w(space.call_method(space.wrap(" -- "), "join", w_l), w_text) + # + # the same for unicode + w_text = space.wrap(u"text") + w_l = self.space.newlist([w_text]) + w_l.getitems = None + assert space.is_w(space.call_method(space.wrap(u" -- "), "join", w_l), w_text) + def test_newlist_str(self): space = self.space From noreply at buildbot.pypy.org Fri Oct 26 21:45:36 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 21:45:36 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: implement listview_unicode for sets Message-ID: <20121026194536.DE3301C1DE9@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58478:53359e7fb6fc Date: 2012-10-26 21:38 +0200 http://bitbucket.org/pypy/pypy/changeset/53359e7fb6fc/ Log: implement listview_unicode for sets 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 @@ -471,8 +471,8 @@ return w_obj.getitems_unicode() if type(w_obj) is W_DictMultiObject: return w_obj.listview_unicode() - ## if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject: - ## return w_obj.listview_unicode() + if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject: + return w_obj.listview_unicode() ## if isinstance(w_obj, W_UnicodeObject): ## return w_obj.listview_unicode() if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj): diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -93,6 +93,10 @@ """ If this is a string set return its contents as a list of uwnrapped strings. Otherwise return None. """ return self.strategy.listview_str(self) + def listview_unicode(self): + """ If this is a unicode set return its contents as a list of uwnrapped unicodes. Otherwise return None. """ + return self.strategy.listview_unicode(self) + def listview_int(self): """ If this is an int set return its contents as a list of uwnrapped ints. Otherwise return None. """ return self.strategy.listview_int(self) @@ -202,6 +206,9 @@ def listview_str(self, w_set): return None + def listview_unicode(self, w_set): + return None + def listview_int(self, w_set): return None @@ -728,8 +735,8 @@ def get_empty_dict(self): return {} - ## def listview_unicode(self, w_set): - ## return self.unerase(w_set.sstorage).keys() + def listview_unicode(self, w_set): + return self.unerase(w_set.sstorage).keys() def is_correct_type(self, w_key): return type(w_key) is W_UnicodeObject diff --git a/pypy/objspace/std/test/test_setstrategies.py b/pypy/objspace/std/test/test_setstrategies.py --- a/pypy/objspace/std/test/test_setstrategies.py +++ b/pypy/objspace/std/test/test_setstrategies.py @@ -141,3 +141,14 @@ assert isinstance(it, UnicodeIteratorImplementation) assert space.unwrap(it.next()) == u"a" assert space.unwrap(it.next()) == u"b" + + def test_listview(self): + space = self.space + s = W_SetObject(space, self.wrapped([1,2])) + assert sorted(space.listview_int(s)) == [1, 2] + # + s = W_SetObject(space, self.wrapped(["a", "b"])) + assert sorted(space.listview_str(s)) == ["a", "b"] + # + s = W_SetObject(space, self.wrapped([u"a", u"b"])) + assert sorted(space.listview_unicode(s)) == [u"a", u"b"] From noreply at buildbot.pypy.org Fri Oct 26 21:45:31 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Fri, 26 Oct 2012 21:45:31 +0200 (CEST) Subject: [pypy-commit] pypy unicode-strategies: yet another listview_unicode test Message-ID: <20121026194531.34BB01C1E0B@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58473:36681180d970 Date: 2012-10-26 19:21 +0200 http://bitbucket.org/pypy/pypy/changeset/36681180d970/ Log: yet another listview_unicode test diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -544,7 +544,6 @@ w_l = self.space.newlist([w_text]) w_l.getitems = None assert space.is_w(space.call_method(space.wrap(u" -- "), "join", w_l), w_text) - def test_newlist_str(self): space = self.space @@ -605,6 +604,11 @@ w_l = W_ListObject(space, [space.wrap("a"), space.wrap("b")]) assert self.space.listview_str(w_l) == ["a", "b"] + def test_listview_unicode_list(self): + space = self.space + w_l = W_ListObject(space, [space.wrap(u"a"), space.wrap(u"b")]) + assert self.space.listview_unicode(w_l) == [u"a", u"b"] + def test_listview_int_list(self): space = self.space w_l = W_ListObject(space, [space.wrap(1), space.wrap(2), space.wrap(3)]) From noreply at buildbot.pypy.org Fri Oct 26 22:32:07 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 26 Oct 2012 22:32:07 +0200 (CEST) Subject: [pypy-commit] pypy py3k: Make lib_pypy/_marshal.py work for both Python2 and Python3. Message-ID: <20121026203207.AEB3D1C1E04@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r58479:d76f4304a294 Date: 2012-10-26 22:31 +0200 http://bitbucket.org/pypy/pypy/changeset/d76f4304a294/ Log: Make lib_pypy/_marshal.py work for both Python2 and Python3. This fixes sandbox tests. diff --git a/lib_pypy/_marshal.py b/lib_pypy/_marshal.py --- a/lib_pypy/_marshal.py +++ b/lib_pypy/_marshal.py @@ -3,6 +3,9 @@ This module contains functions that can read and write Python values in a binary format. The format is specific to Python, but independent of machine architecture issues (e.g., you can write a Python value to a file on a PC, transport the file to a Sun, and read it back there). Details of the format may change between Python versions. """ +# NOTE: This module is used in the Python3 interpreter, but also by +# the "sandboxed" process. It must work for Python2 as well. + import types from _codecs import utf_8_decode, utf_8_encode import sys @@ -96,6 +99,7 @@ except NameError: pass + # In Python3, this function is not used; see dump_long() below. def dump_int(self, x): y = x>>31 if y and y != -1: @@ -119,7 +123,12 @@ self.w_long(len(digits) * sign) for d in digits: self.w_short(d) - dispatch[int] = dump_long + try: + long + except NameError: + dispatch[int] = dump_long + else: + dispatch[long] = dump_long def dump_float(self, x): write = self._write @@ -157,7 +166,12 @@ s, len_s = utf_8_encode(x) self.w_long(len_s) self._write(s) - dispatch[str] = dump_unicode + try: + unicode + except NameError: + dispatch[str] = dump_unicode + else: + dispatch[unicode] = dump_unicode def dump_tuple(self, x): self._write(TYPE_TUPLE) From noreply at buildbot.pypy.org Fri Oct 26 23:05:08 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 23:05:08 +0200 (CEST) Subject: [pypy-commit] pypy missing-ndarray-attributes: progress on sorting Message-ID: <20121026210508.030F31C1E05@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58480:6c4a7b843097 Date: 2012-10-26 20:21 +0200 http://bitbucket.org/pypy/pypy/changeset/6c4a7b843097/ Log: progress on sorting 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 @@ -10,7 +10,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rlib import jit from pypy.rlib.rawstorage import free_raw_storage -from pypy.module.micronumpy.arrayimpl.sort import sort_array +from pypy.module.micronumpy.arrayimpl.sort import argsort_array class ConcreteArrayIterator(base.BaseArrayIterator): def __init__(self, array): @@ -404,8 +404,8 @@ self.order) return SliceArray(0, strides, backstrides, new_shape, self) - def argsort(self, space): - return sort_array(self, space) + def argsort(self, space, w_axis): + return argsort_array(self, space, w_axis) class SliceArray(BaseConcreteArray): def __init__(self, start, strides, backstrides, shape, parent, dtype=None): 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 @@ -96,5 +96,5 @@ raise OperationError(space.w_ValueError, space.wrap("scalars have no address")) - def argsort(self, space): + def argsort(self, space, w_axis): return space.wrap(0) diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -56,21 +56,32 @@ return ArgArrayRepresentation, ArgSort -def sort_array(arr, space): +def argsort_array(arr, space, w_axis): itemtype = arr.dtype.itemtype if (not isinstance(itemtype, types.Float) and not isinstance(itemtype, types.Integer)): + # XXX this should probably be changed raise OperationError(space.w_NotImplementedError, space.wrap("sorting of non-numeric types is not implemented")) + if w_axis is space.w_None: + arr = arr.reshape(space, [arr.get_size()]) + axis = 0 + elif w_axis is None: + axis = -1 + else: + axis = space.int_w(w_axis) itemsize = itemtype.get_element_size() # create array of indexes dtype = interp_dtype.get_dtype_cache(space).w_longdtype - indexes = W_NDimArray.from_shape([arr.get_size()], dtype) - storage = indexes.implementation.get_storage() - for i in range(arr.get_size()): - raw_storage_setitem(storage, i * INT_SIZE, i) - Repr, Sort = make_sort_classes(space, itemtype) - r = Repr(itemsize, arr.get_size(), arr.get_storage(), - indexes.implementation.get_storage()) - Sort(r).sort() + indexes = W_NDimArray.from_shape(arr.get_shape(), dtype) + if len(arr.get_shape()) == 1: + storage = indexes.implementation.get_storage() + for i in range(arr.get_size()): + raw_storage_setitem(storage, i * INT_SIZE, i) + Repr, Sort = make_sort_classes(space, itemtype) + r = Repr(itemsize, arr.get_size(), arr.get_storage(), + indexes.implementation.get_storage()) + Sort(r).sort() + else: + xxx return indexes 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 @@ -366,7 +366,7 @@ # happily ignore the kind # create a contiguous copy of the array contig = self.descr_copy(space) - return contig.implementation.argsort(space) + return contig.implementation.argsort(space, w_axis) def descr_astype(self, space, w_type): raise OperationError(space.w_NotImplementedError, space.wrap( 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 @@ -2141,6 +2141,22 @@ assert array([1, 2, 3], 'i2')[::2].tostring() == '\x00\x01\x00\x03' + def test_argsort(self): + from _numpypy import array + a = array([[4, 2], [1, 3]]) + assert (a.argsort() == [[1, 0], [0, 1]]).all() + + def test_argsort_axis(self): + from _numpypy import array + a = array([[4, 2], [1, 3]]) + assert (a.argsort(axis=None) == [2, 1, 3, 0]).all() + assert (a.argsort(axis=-1) == [[1, 0], [0, 1]]).all() + assert (a.argsort(axis=0) == [[1, 0], [0, 1]]).all() + assert (a.argsort(axis=1) == [[1, 0], [0, 1]]).all() + a = array([[3, 2, 1], [1, 2, 3]]) + assert (a.argsort(axis=0) == [[1, 0, 0], [0, 1, 1]]).all() + assert (a.argsort(axis=1) == [[2, 1, 0], [0, 1, 2]]).all() + class AppTestRanges(BaseNumpyAppTest): def test_arange(self): from _numpypy import arange, array, dtype From noreply at buildbot.pypy.org Fri Oct 26 23:05:14 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 23:05:14 +0200 (CEST) Subject: [pypy-commit] pypy missing-ndarray-attributes: merge default Message-ID: <20121026210514.46AF11C1E05@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58481:4f4c4ce9bd79 Date: 2012-10-26 20:22 +0200 http://bitbucket.org/pypy/pypy/changeset/4f4c4ce9bd79/ Log: merge default diff too long, truncating to 2000 out of 57334 lines diff --git a/lib-python/2.7/test/test_csv.py b/lib-python/2.7/test/test_csv.py --- a/lib-python/2.7/test/test_csv.py +++ b/lib-python/2.7/test/test_csv.py @@ -20,7 +20,8 @@ """ def _test_arg_valid(self, ctor, arg): self.assertRaises(TypeError, ctor) - self.assertRaises(TypeError, ctor, None) + # PyPy gets an AttributeError instead of a TypeError + self.assertRaises((TypeError, AttributeError), ctor, None) self.assertRaises(TypeError, ctor, arg, bad_attr = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 'XX') @@ -59,7 +60,8 @@ self.assertRaises((TypeError, AttributeError), setattr, obj.dialect, 'delimiter', ':') self.assertRaises(AttributeError, delattr, obj.dialect, 'quoting') - self.assertRaises(AttributeError, setattr, obj.dialect, + # PyPy gets a TypeError instead of an AttributeError + self.assertRaises((AttributeError, TypeError), setattr, obj.dialect, 'quoting', None) def test_reader_attrs(self): @@ -133,7 +135,8 @@ os.unlink(name) def test_write_arg_valid(self): - self.assertRaises(csv.Error, self._write_test, None, '') + # PyPy gets a TypeError instead of a csv.Error for "not a sequence" + self.assertRaises((csv.Error, TypeError), self._write_test, None, '') self._write_test((), '') self._write_test([None], '""') self.assertRaises(csv.Error, self._write_test, diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -183,7 +183,7 @@ RegrTest('test_cpickle.py', core=True), RegrTest('test_cprofile.py'), RegrTest('test_crypt.py', usemodules='crypt', skip=skip_win32), - RegrTest('test_csv.py'), + RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_curses.py', skip="unsupported extension module"), RegrTest('test_datetime.py'), diff --git a/lib_pypy/_csv.py b/lib_pypy/_csv.py --- a/lib_pypy/_csv.py +++ b/lib_pypy/_csv.py @@ -363,9 +363,7 @@ (self.dialect.delimiter, self.dialect.quotechar)) elif self.state == self.EAT_CRNL: - if c in '\r\n': - pass - else: + if c not in '\r\n': raise Error("new-line character seen in unquoted field - " "do you need to open the file " "in universal-newline mode?") diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py --- a/lib_pypy/_ctypes/structure.py +++ b/lib_pypy/_ctypes/structure.py @@ -69,7 +69,8 @@ resnames.append(name) names = resnames self._names = names - self.__dict__.update(fields) + for name, field in fields.items(): + setattr(self, name, field) class Field(object): def __init__(self, name, offset, size, ctype, num, is_bitfield): diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,11 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - libpath = ctypes.util.find_library('db-4.5') - if not libpath: + for c in '56789': + libpath = ctypes.util.find_library('db-4.%s' % c) + if libpath: + break + else: raise ImportError("Cannot find dbm library") lib = CDLL(libpath) # Linux _platform = 'bdb' diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py deleted file mode 100644 --- a/lib_pypy/itertools.py +++ /dev/null @@ -1,670 +0,0 @@ -# Note that PyPy contains also a built-in module 'itertools' which will -# hide this one if compiled in. - -"""Functional tools for creating and using iterators. - -Infinite iterators: -count([n]) --> n, n+1, n+2, ... -cycle(p) --> p0, p1, ... plast, p0, p1, ... -repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times - -Iterators terminating on the shortest input sequence: -izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... -ifilter(pred, seq) --> elements of seq where pred(elem) is True -ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False -islice(seq, [start,] stop [, step]) --> elements from - seq[start:stop:step] -imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ... -starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ... -tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n -chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... -takewhile(pred, seq) --> seq[0], seq[1], until pred fails -dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails -groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v) -""" - -__all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', - 'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap', - 'takewhile', 'tee', 'compress', 'product'] - -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f - - -class chain(object): - """Make an iterator that returns elements from the first iterable - until it is exhausted, then proceeds to the next iterable, until - all of the iterables are exhausted. Used for treating consecutive - sequences as a single sequence. - - Equivalent to : - - def chain(*iterables): - for it in iterables: - for element in it: - yield element - """ - def __init__(self, *iterables): - self._iterables_iter = iter(map(iter, iterables)) - # little trick for the first chain.next() call - self._cur_iterable_iter = iter([]) - - def __iter__(self): - return self - - def next(self): - while True: - try: - return self._cur_iterable_iter.next() - except StopIteration: - self._cur_iterable_iter = self._iterables_iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iterable_iter)) - - -class compress(object): - def __init__(self, data, selectors): - self.data = iter(data) - self.selectors = iter(selectors) - - def __iter__(self): - return self - - def next(self): - while True: - next_item = self.data.next() - next_selector = self.selectors.next() - if bool(next_selector): - return next_item - - -class count(object): - """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. - - Equivalent to : - - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) - while True: - yield n - n += 1 - """ - def __init__(self, n=0): - if not isinstance(n, int): - raise TypeError('%s is not a regular integer' % n) - self.times = n-1 - - def __iter__(self): - return self - - def next(self): - self.times += 1 - return self.times - - def __repr__(self): - return 'count(%d)' % (self.times + 1) - - - -class cycle(object): - """Make an iterator returning elements from the iterable and - saving a copy of each. When the iterable is exhausted, return - elements from the saved copy. Repeats indefinitely. - - Equivalent to : - - def cycle(iterable): - saved = [] - for element in iterable: - yield element - saved.append(element) - while saved: - for element in saved: - yield element - """ - def __init__(self, iterable): - self._cur_iter = iter(iterable) - self._saved = [] - self._must_save = True - - def __iter__(self): - return self - - def next(self): - # XXX Could probably be improved - try: - next_elt = self._cur_iter.next() - if self._must_save: - self._saved.append(next_elt) - except StopIteration: - self._cur_iter = iter(self._saved) - next_elt = self._cur_iter.next() - self._must_save = False - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iter)) - return next_elt - - -class dropwhile(object): - """Make an iterator that drops elements from the iterable as long - as the predicate is true; afterwards, returns every - element. Note, the iterator does not produce any output until the - predicate is true, so it may have a lengthy start-up time. - - Equivalent to : - - def dropwhile(predicate, iterable): - iterable = iter(iterable) - for x in iterable: - if not predicate(x): - yield x - break - for x in iterable: - yield x - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - self._dropped = False - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if self._dropped: - return value - while self._predicate(value): - value = self._iter.next() - self._dropped = True - return value - -class groupby(object): - """Make an iterator that returns consecutive keys and groups from the - iterable. The key is a function computing a key value for each - element. If not specified or is None, key defaults to an identity - function and returns the element unchanged. Generally, the - iterable needs to already be sorted on the same key function. - - The returned group is itself an iterator that shares the - underlying iterable with groupby(). Because the source is shared, - when the groupby object is advanced, the previous group is no - longer visible. So, if that data is needed later, it should be - stored as a list: - - groups = [] - uniquekeys = [] - for k, g in groupby(data, keyfunc): - groups.append(list(g)) # Store group iterator as a list - uniquekeys.append(k) - """ - def __init__(self, iterable, key=None): - if key is None: - key = lambda x: x - self.keyfunc = key - self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = xrange(0) - - def __iter__(self): - return self - - def next(self): - while self.currkey == self.tgtkey: - try: - self.currvalue = self.it.next() # Exit on StopIteration - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self.it)) - self.currkey = self.keyfunc(self.currvalue) - self.tgtkey = self.currkey - return (self.currkey, self._grouper(self.tgtkey)) - - def _grouper(self, tgtkey): - while self.currkey == tgtkey: - yield self.currvalue - self.currvalue = self.it.next() # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) - - - -class _ifilter_base(object): - """base class for ifilter and ifilterflase""" - def __init__(self, predicate, iterable): - # Make sure iterable *IS* iterable - self._iter = iter(iterable) - if predicate is None: - self._predicate = bool - else: - self._predicate = predicate - - def __iter__(self): - return self - -class ifilter(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is True. If predicate is - None, return the items that are true. - - Equivalent to : - - def ifilter: - if predicate is None: - predicate = bool - for x in iterable: - if predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - -class ifilterfalse(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is False. If predicate is - None, return the items that are false. - - Equivalent to : - - def ifilterfalse(predicate, iterable): - if predicate is None: - predicate = bool - for x in iterable: - if not predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if not self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - - - - -class imap(object): - """Make an iterator that computes the function using arguments - from each of the iterables. If function is set to None, then - imap() returns the arguments as a tuple. Like map() but stops - when the shortest iterable is exhausted instead of filling in - None for shorter iterables. The reason for the difference is that - infinite iterator arguments are typically an error for map() - (because the output is fully evaluated) but represent a common - and useful way of supplying arguments to imap(). - - Equivalent to : - - def imap(function, *iterables): - iterables = map(iter, iterables) - while True: - args = [i.next() for i in iterables] - if function is None: - yield tuple(args) - else: - yield function(*args) - - """ - def __init__(self, function, iterable, *other_iterables): - self._func = function - self._iters = map(iter, (iterable, ) + other_iterables) - - def __iter__(self): - return self - - def next(self): - try: - args = [it.next() for it in self._iters] - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (it)) - if self._func is None: - return tuple(args) - else: - return self._func(*args) - - - -class islice(object): - """Make an iterator that returns selected elements from the - iterable. If start is non-zero, then elements from the iterable - are skipped until start is reached. Afterward, elements are - returned consecutively unless step is set higher than one which - results in items being skipped. If stop is None, then iteration - continues until the iterator is exhausted, if at all; otherwise, - it stops at the specified position. Unlike regular slicing, - islice() does not support negative values for start, stop, or - step. Can be used to extract related fields from data where the - internal structure has been flattened (for example, a multi-line - report may list a name field on every third line). - """ - def __init__(self, iterable, *args): - s = slice(*args) - self.start, self.stop, self.step = s.start or 0, s.stop, s.step - if not isinstance(self.start, (int, long)): - raise ValueError("Start argument must be an integer") - if self.stop is not None and not isinstance(self.stop, (int,long)): - raise ValueError("Stop argument must be an integer or None") - if self.step is None: - self.step = 1 - if self.start<0 or (self.stop is not None and self.stop<0 - ) or self.step<=0: - raise ValueError, "indices for islice() must be positive" - self.it = iter(iterable) - self.donext = None - self.cnt = 0 - - def __iter__(self): - return self - - def next(self): - if self.donext is None: - try: - self.donext = self.it.next - except AttributeError: - raise TypeError - nextindex = self.start - if self.stop is not None and nextindex >= self.stop: - raise StopIteration - while self.cnt <= nextindex: - nextitem = self.donext() - self.cnt += 1 - self.start += self.step - return nextitem - -class izip(object): - """Make an iterator that aggregates elements from each of the - iterables. Like zip() except that it returns an iterator instead - of a list. Used for lock-step iteration over several iterables at - a time. - - Equivalent to : - - def izip(*iterables): - iterables = map(iter, iterables) - while iterables: - result = [i.next() for i in iterables] - yield tuple(result) - """ - def __init__(self, *iterables): - self._iterators = map(iter, iterables) - self._result = [None] * len(self._iterators) - - def __iter__(self): - return self - - def next(self): - if not self._iterators: - raise StopIteration() - try: - return tuple([i.next() for i in self._iterators]) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (i)) - - -class product(object): - - def __init__(self, *args, **kw): - if len(kw) > 1: - raise TypeError("product() takes at most 1 argument (%d given)" % - len(kw)) - self.repeat = kw.get('repeat', 1) - self.gears = [x for x in args] * self.repeat - self.num_gears = len(self.gears) - # initialization of indicies to loop over - self.indicies = [(0, len(self.gears[x])) - for x in range(0, self.num_gears)] - self.cont = True - - def roll_gears(self): - # Starting from the end of the gear indicies work to the front - # incrementing the gear until the limit is reached. When the limit - # is reached carry operation to the next gear - should_carry = True - for n in range(0, self.num_gears): - nth_gear = self.num_gears - n - 1 - if should_carry: - count, lim = self.indicies[nth_gear] - count += 1 - if count == lim and nth_gear == 0: - self.cont = False - if count == lim: - should_carry = True - count = 0 - else: - should_carry = False - self.indicies[nth_gear] = (count, lim) - else: - break - - def __iter__(self): - return self - - def next(self): - if not self.cont: - raise StopIteration - l = [] - for x in range(0, self.num_gears): - index, limit = self.indicies[x] - l.append(self.gears[x][index]) - self.roll_gears() - return tuple(l) - - -class repeat(object): - """Make an iterator that returns object over and over again. - Runs indefinitely unless the times argument is specified. Used - as argument to imap() for invariant parameters to the called - function. Also used with izip() to create an invariant part of a - tuple record. - - Equivalent to : - - def repeat(object, times=None): - if times is None: - while True: - yield object - else: - for i in xrange(times): - yield object - """ - def __init__(self, obj, times=None): - self._obj = obj - if times is not None: - xrange(times) # Raise a TypeError - if times < 0: - times = 0 - self._times = times - - def __iter__(self): - return self - - def next(self): - # next() *need* to decrement self._times when consumed - if self._times is not None: - if self._times <= 0: - raise StopIteration() - self._times -= 1 - return self._obj - - def __repr__(self): - if self._times is not None: - return 'repeat(%r, %r)' % (self._obj, self._times) - else: - return 'repeat(%r)' % (self._obj,) - - def __len__(self): - if self._times == -1 or self._times is None: - raise TypeError("len() of uniszed object") - return self._times - - -class starmap(object): - """Make an iterator that computes the function using arguments - tuples obtained from the iterable. Used instead of imap() when - argument parameters are already grouped in tuples from a single - iterable (the data has been ``pre-zipped''). The difference - between imap() and starmap() parallels the distinction between - function(a,b) and function(*c). - - Equivalent to : - - def starmap(function, iterable): - iterable = iter(iterable) - while True: - yield function(*iterable.next()) - """ - def __init__(self, function, iterable): - self._func = function - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - # CPython raises a TypeError when the iterator doesn't return a tuple - try: - t = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - if not isinstance(t, tuple): - raise TypeError("iterator must return a tuple") - return self._func(*t) - - - -class takewhile(object): - """Make an iterator that returns elements from the iterable as - long as the predicate is true. - - Equivalent to : - - def takewhile(predicate, iterable): - for x in iterable: - if predicate(x): - yield x - else: - break - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if not self._predicate(value): - raise StopIteration() - return value - - -class TeeData(object): - """Holds cached values for TeeObjects""" - def __init__(self, iterator): - self.data = [] - self._iter = iterator - - def __getitem__(self, i): - # iterates until 'i' if not done yet - while i>= len(self.data): - try: - self.data.append( self._iter.next() ) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - return self.data[i] - - -class TeeObject(object): - """Iterables / Iterators as returned by the tee() function""" - def __init__(self, iterable=None, tee_data=None): - if tee_data: - self.tee_data = tee_data - self.pos = 0 - # <=> Copy constructor - elif isinstance(iterable, TeeObject): - self.tee_data = iterable.tee_data - self.pos = iterable.pos - else: - self.tee_data = TeeData(iter(iterable)) - self.pos = 0 - - def next(self): - data = self.tee_data[self.pos] - self.pos += 1 - return data - - def __iter__(self): - return self - - - at builtinify -def tee(iterable, n=2): - """Return n independent iterators from a single iterable. - Note : once tee() has made a split, the original iterable - should not be used anywhere else; otherwise, the iterable could get - advanced without the tee objects being informed. - - Note : this member of the toolkit may require significant auxiliary - storage (depending on how much temporary data needs to be stored). - In general, if one iterator is going to use most or all of the - data before the other iterator, it is faster to use list() instead - of tee() - - Equivalent to : - - def tee(iterable, n=2): - def gen(next, data={}, cnt=[0]): - for i in count(): - if i == cnt[0]: - item = data[i] = next() - cnt[0] += 1 - else: - item = data.pop(i) - yield item - it = iter(iterable) - return tuple([gen(it.next) for i in range(n)]) - """ - if isinstance(iterable, TeeObject): - # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) - return tuple([iterable] + - [TeeObject(tee_data=iterable.tee_data) for i in xrange(n-1)]) - tee_data = TeeData(iter(iterable)) - return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)]) diff --git a/lib_pypy/pypy_test/test_ctypes_support.py b/lib_pypy/pypy_test/test_ctypes_support.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_ctypes_support.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import absolute_import - -import py -from ctypes import * -try: - from ctypes_support import standard_c_lib, get_errno, set_errno -except ImportError: # on top of cpython - from lib_pypy.ctypes_support import standard_c_lib, get_errno, set_errno - - -def test_stdlib_and_errno(): - py.test.skip("this is expected on top of pypy, we need to fix ctypes in a way that is now in 2.6 in order to make this reliable") - write = standard_c_lib.write - write.argtypes = [c_int, c_char_p, c_size_t] - write.restype = c_size_t - # clear errno first - set_errno(0) - assert get_errno() == 0 - write(-345, "abc", 3) - assert get_errno() != 0 - set_errno(0) - assert get_errno() == 0 - -def test_argument_conversion_and_checks(): - strlen = standard_c_lib.strlen - strlen.argtypes = [c_char_p] - strlen.restype = c_size_t - assert strlen("eggs") == 4 - - # Should raise ArgumentError, not segfault - py.test.raises(ArgumentError, strlen, False) - diff --git a/lib_pypy/pypy_test/test_itertools.py b/lib_pypy/pypy_test/test_itertools.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_itertools.py +++ /dev/null @@ -1,50 +0,0 @@ -from py.test import raises -from lib_pypy import itertools - -class TestItertools(object): - - def test_compress(self): - it = itertools.compress(['a', 'b', 'c'], [0, 1, 0]) - - assert list(it) == ['b'] - - def test_compress_diff_len(self): - it = itertools.compress(['a'], []) - raises(StopIteration, it.next) - - def test_product(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')] - - def test_product_repeat(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m, repeat=2) - ans = [(1, 'a', 1, 'a'), (1, 'a', 1, 'b'), (1, 'a', 2, 'a'), - (1, 'a', 2, 'b'), (1, 'b', 1, 'a'), (1, 'b', 1, 'b'), - (1, 'b', 2, 'a'), (1, 'b', 2, 'b'), (2, 'a', 1, 'a'), - (2, 'a', 1, 'b'), (2, 'a', 2, 'a'), (2, 'a', 2, 'b'), - (2, 'b', 1, 'a'), (2, 'b', 1, 'b'), (2, 'b', 2, 'a'), - (2, 'b', 2, 'b')] - assert list(prodlist) == ans - - def test_product_diff_sizes(self): - l = [1, 2] - m = ['a'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (2, 'a')] - - l = [1] - m = ['a', 'b'] - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b')] - - def test_product_toomany_args(self): - l = [1, 2] - m = ['a'] - raises(TypeError, itertools.product, l, m, repeat=1, foo=2) diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -118,7 +118,7 @@ # 1. find the start of the statement from codeop import compile_command end = None - for start in range(lineno, -1, -1): + for start in range(lineno, -1, max(-1, lineno - 10)): if assertion: line = self.lines[start] # the following lines are not fully tested, change with care @@ -135,9 +135,9 @@ compile_command(trysource) except (SyntaxError, OverflowError, ValueError): continue - + # 2. find the end of the statement - for end in range(lineno+1, len(self)+1): + for end in range(lineno+1, min(len(self)+1, lineno + 10)): trysource = self[start:end] if trysource.isparseable(): return start, end diff --git a/py/_io/capture.py b/py/_io/capture.py --- a/py/_io/capture.py +++ b/py/_io/capture.py @@ -176,7 +176,7 @@ class StdCaptureFD(Capture): - """ This class allows to capture writes to FD1 and FD2 + """ This class allows capturing writes to FD1 and FD2 and may connect a NULL file to FD0 (and prevent reads from sys.stdin). If any of the 0,1,2 file descriptors is invalid it will not be captured. @@ -267,8 +267,8 @@ return l class StdCapture(Capture): - """ This class allows to capture writes to sys.stdout|stderr "in-memory" - and will raise errors on tries to read from sys.stdin. It only + """ This class allows capturing writes to sys.stdout|stderr "in-memory" + and will raise errors on read attempts from sys.stdin. It only modifies sys.stdout|stderr|stdin attributes and does not touch underlying File Descriptors (use StdCaptureFD for that). """ diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -1,9 +1,8 @@ -import sys import types -from pypy.tool.ansi_print import ansi_log, raise_nicer_exception +from pypy.tool.ansi_print import ansi_log from pypy.tool.pairtype import pair from pypy.tool.error import (format_blocked_annotation_error, - format_someobject_error, AnnotatorError) + AnnotatorError, gather_error, ErrorWrapper) from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, c_last_exception, checkgraph) from pypy.translator import simplify, transform @@ -38,22 +37,9 @@ self.links_followed = {} # set of links that have ever been followed self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + self.blocked_blocks = {} # set of {blocked_block: (graph, index)} + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +63,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +164,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +181,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +192,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +242,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +265,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +283,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +333,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -414,7 +340,7 @@ self.flowin(graph, block) except BlockedInference, e: self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, e.opindex) except Exception, e: # hack for debug tools only if not hasattr(e, '__annotator_block'): @@ -433,25 +359,24 @@ self.pendingblocks[block] = graph assert block in self.annotated self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = graph + self.blocked_blocks[block] = (graph, None) - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -471,14 +396,11 @@ for i in range(len(block.operations)): try: self.bookkeeper.enter((graph, block, i)) - self.consider_op(block.operations[i]) + self.consider_op(block, i) finally: self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +484,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +494,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +530,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell @@ -653,7 +572,8 @@ #___ creating the annotations based on operations ______ - def consider_op(self, op): + def consider_op(self, block, opindex): + op = block.operations[opindex] argcells = [self.binding(a) for a in op.args] consider_meth = getattr(self,'consider_op_'+op.opname, None) @@ -668,16 +588,18 @@ # boom -- in the assert of setbinding() for arg in argcells: if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op) + raise BlockedInference(self, op, opindex) try: resultcell = consider_meth(*argcells) - except Exception: + except Exception, e: graph = self.bookkeeper.position_key[0] - raise_nicer_exception(op, str(graph)) + e.args = e.args + ( + ErrorWrapper(gather_error(self, graph, block, opindex)),) + raise if resultcell is None: resultcell = self.noreturnvalue(op) elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op) # the operation cannot succeed + raise BlockedInference(self, op, opindex) # the operation cannot succeed assert isinstance(resultcell, annmodel.SomeObject) assert isinstance(op.result, Variable) self.setbinding(op.result, resultcell) # bind resultcell to op.result @@ -728,13 +650,14 @@ """This exception signals the type inference engine that the situation is currently blocked, and that it should try to progress elsewhere.""" - def __init__(self, annotator, op): + def __init__(self, annotator, op, opindex): self.annotator = annotator try: self.break_at = annotator.bookkeeper.position_key except AttributeError: self.break_at = None self.op = op + self.opindex = opindex def __repr__(self): if not self.break_at: diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,32 +29,23 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', - 'truediv', 'floordiv', 'divmod', 'pow', + 'truediv', 'floordiv', 'divmod', 'and_', 'or_', 'xor', 'lshift', 'rshift', 'getitem', 'setitem', 'delitem', 'getitem_idx', 'getitem_key', 'getitem_idx_key', 'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv', 'inplace_floordiv', 'inplace_div', - 'inplace_mod', 'inplace_pow', + 'inplace_mod', 'inplace_lshift', 'inplace_rshift', 'inplace_and', 'inplace_or', 'inplace_xor', 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'is_', 'cmp', 'coerce', ] +[opname+'_ovf' for opname in - """add sub mul floordiv div mod pow lshift + """add sub mul floordiv div mod lshift """.split() ]) @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -102,7 +65,6 @@ def inplace_floordiv((obj1, obj2)): return pair(obj1, obj2).floordiv() def inplace_div((obj1, obj2)): return pair(obj1, obj2).div() def inplace_mod((obj1, obj2)): return pair(obj1, obj2).mod() - def inplace_pow((obj1, obj2)): return pair(obj1, obj2).pow(s_None) def inplace_lshift((obj1, obj2)): return pair(obj1, obj2).lshift() def inplace_rshift((obj1, obj2)): return pair(obj1, obj2).rshift() def inplace_and((obj1, obj2)): return pair(obj1, obj2).and_() @@ -238,7 +200,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -315,19 +300,6 @@ return SomeInteger(nonneg=int1.nonneg, knowntype=int1.knowntype) rshift.can_only_throw = [] - def pow((int1, int2), obj3): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - pow.can_only_throw = [ZeroDivisionError] - pow_ovf = _clone(pow, [ZeroDivisionError, OverflowError]) - - def inplace_pow((int1, int2)): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - inplace_pow.can_only_throw = [ZeroDivisionError] - def _compare_helper((int1, int2), opname, operation): r = SomeBool() if int1.is_immutable_constant() and int2.is_immutable_constant(): @@ -514,9 +486,6 @@ div.can_only_throw = [] truediv = div - def pow((flt1, flt2), obj3): - raise NotImplementedError("float power not supported, use math.pow") - # repeat these in order to copy the 'can_only_throw' attribute inplace_div = div inplace_truediv = truediv @@ -564,14 +533,30 @@ def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): - return SomeObject() + raise UnionError("cannot take the union of a tuple of length %d " + "and a tuple of length %d" % (len(tup1.items), + len(tup2.items))) else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): return SomeTuple(items = tup1.items + tup2.items) + def eq(tup1tup2): + tup1tup2.union() + return s_Bool + ne = eq + + def lt((tup1, tup2)): + raise Exception("unsupported: (...) < (...)") + def le((tup1, tup2)): + raise Exception("unsupported: (...) <= (...)") + def gt((tup1, tup2)): + raise Exception("unsupported: (...) > (...)") + def ge((tup1, tup2)): + raise Exception("unsupported: (...) >= (...)") + class __extend__(pairtype(SomeDict, SomeDict)): @@ -723,8 +708,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -764,7 +748,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -778,7 +762,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -806,7 +790,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,13 +10,13 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef from pypy.annotation import description from pypy.annotation.signature import annotationoftype -from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.rlib.objectmodel import r_dict, Symbolic from pypy.tool.algo.unionfind import UnionFind from pypy.rpython.lltypesystem import lltype, llmemory @@ -101,7 +101,7 @@ def consider_list_delitem(self, idx): return self.indexrepr(idx) - + def consider_str_join(self, s): if s.is_constant(): return repr(s.const) @@ -148,7 +148,6 @@ self.descs = {} # map Python objects to their XxxDesc wrappers self.methoddescs = {} # map (funcdesc, classdef) to the MethodDesc self.classdefs = [] # list of all ClassDefs - self.pbctypes = {} self.seen_mutable = {} self.listdefs = {} # map position_keys to ListDefs self.dictdefs = {} # map position_keys to DictDefs @@ -167,9 +166,6 @@ self.stats = Stats(self) - # used in SomeObject.__new__ for keeping debugging info - self._isomeobject_coming_from = identity_dict() - delayed_imports() def count(self, category, *args): @@ -228,7 +224,7 @@ check_no_flags(s_value_or_def.listdef.listitem) elif isinstance(s_value_or_def, SomeDict): check_no_flags(s_value_or_def.dictdef.dictkey) - check_no_flags(s_value_or_def.dictdef.dictvalue) + check_no_flags(s_value_or_def.dictdef.dictvalue) elif isinstance(s_value_or_def, SomeTuple): for s_item in s_value_or_def.items: check_no_flags(s_item) @@ -242,9 +238,9 @@ elif isinstance(s_value_or_def, ListItem): if s_value_or_def in seen: return - seen.add(s_value_or_def) + seen.add(s_value_or_def) check_no_flags(s_value_or_def.s_value) - + for clsdef in self.classdefs: check_no_flags(clsdef) @@ -275,8 +271,7 @@ """Get the ClassDef associated with the given user cls. Avoid using this! It breaks for classes that must be specialized. """ - if cls is object: - return None + assert cls is not object desc = self.getdesc(cls) return desc.getuniqueclassdef() @@ -325,8 +320,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -373,14 +366,14 @@ listdef = ListDef(self, s_ImpossibleValue) for e in x: listdef.generalize(self.immutablevalue(e, False)) - result = SomeList(listdef) + result = SomeList(listdef) elif tp is dict or tp is r_dict: if need_const: key = Constant(x) try: return self.immutable_cache[key] except KeyError: - result = SomeDict(DictDef(self, + result = SomeDict(DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict)) @@ -403,7 +396,7 @@ result.const_box = key return result else: - dictdef = DictDef(self, + dictdef = DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict) @@ -445,6 +438,12 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if (x is type(None) or # add cases here if needed + x.__module__ == 'pypy.rpython.lltypesystem.lltype'): + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) 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 @@ -455,20 +454,13 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) - elif hasattr(x, '_freeze_') and x._freeze_(): + result = SomePBC([self.getdesc(x)]) + elif hasattr(x, '_freeze_'): + assert x._freeze_() is True # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method # returns True, the instance is considered immutable and becomes @@ -476,16 +468,18 @@ result = SomePBC([self.getdesc(x)]) elif hasattr(x, '__class__') \ and x.__class__.__module__ != '__builtin__': + if hasattr(x, '_cleanup_'): + x._cleanup_() self.see_mutable(x) result = SomeInstance(self.getuniqueclassdef(x.__class__)) elif x is None: return s_None else: - result = SomeObject() + raise Exception("Don't know how to represent %r" % (x,)) if need_const: result.const = x return result - + def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: @@ -509,8 +503,10 @@ elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) - elif (hasattr(pyobj.im_self, '_freeze_') and - pyobj.im_self._freeze_()): # method of frozen + if hasattr(pyobj.im_self, '_cleanup_'): + pyobj.im_self._cleanup_() + if hasattr(pyobj.im_self, '_freeze_'): # method of frozen + assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc(self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc @@ -529,9 +525,9 @@ name) else: # must be a frozen pre-built constant, but let's check - try: - assert pyobj._freeze_() - except AttributeError: + if hasattr(pyobj, '_freeze_'): + assert pyobj._freeze_() is True + else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: @@ -549,13 +545,9 @@ return True else: return False - + def getfrozen(self, pyobj): - result = description.FrozenDesc(self, pyobj) - cls = result.knowntype - if cls not in self.pbctypes: - self.pbctypes[cls] = True - return result + return description.FrozenDesc(self, pyobj) def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, flags={}): @@ -574,7 +566,7 @@ key = (x.__class__, x) if key in self.seen_mutable: return - clsdef = self.getuniqueclassdef(x.__class__) + clsdef = self.getuniqueclassdef(x.__class__) self.seen_mutable[key] = True self.event('mutable', x) source = InstanceSource(self, x) @@ -594,7 +586,7 @@ except KeyError: access_sets = map[attrname] = UnionFind(description.ClassAttrFamily) return access_sets - + def pbc_getattr(self, pbc, s_attr): assert s_attr.is_constant() attr = s_attr.const @@ -606,7 +598,7 @@ first = descs[0] if len(descs) == 1: return first.s_read_attribute(attr) - + change = first.mergeattrfamilies(descs[1:], attr) attrfamily = first.getattrfamily(attr) @@ -708,7 +700,7 @@ def ondegenerated(self, what, s_value, where=None, called_from_graph=None): self.annotator.ondegenerated(what, s_value, where=where, called_from_graph=called_from_graph) - + def whereami(self): return self.annotator.whereami(self.position_key) diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -150,7 +150,7 @@ def builtin_isinstance(s_obj, s_type, variables=None): - r = SomeBool() + r = SomeBool() if s_type.is_constant(): typ = s_type.const if issubclass(typ, pypy.rlib.rarithmetic.base_int): @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,8 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + + if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r @@ -329,10 +323,12 @@ def robjmodel_hlinvoke(s_repr, s_llcallable, *args_s): from pypy.rpython import rmodel - assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr),"hlinvoke expects a constant repr as first argument" - r_func, nimplicitarg = s_repr.const.get_r_implfunc() + from pypy.rpython.error import TyperError - nbargs = len(args_s) + nimplicitarg + assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr), "hlinvoke expects a constant repr as first argument" + r_func, nimplicitarg = s_repr.const.get_r_implfunc() + + nbargs = len(args_s) + nimplicitarg s_sigs = r_func.get_s_signatures((nbargs, (), False, False)) if len(s_sigs) != 1: raise TyperError("cannot hlinvoke callable %r with not uniform" @@ -343,6 +339,7 @@ return lltype_to_annotation(rresult.lowleveltype) + def robjmodel_keepalive_until_here(*args_s): return immutablevalue(None) @@ -410,7 +407,10 @@ BUILTIN_ANALYZERS[unicodedata.decimal] = unicodedata_decimal # xxx # object - just ignore object.__init__ -BUILTIN_ANALYZERS[object.__init__] = object_init +if hasattr(object.__init__, 'im_func'): + BUILTIN_ANALYZERS[object.__init__.im_func] = object_init +else: + BUILTIN_ANALYZERS[object.__init__] = object_init # import BUILTIN_ANALYZERS[__import__] = import_func diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -1,8 +1,7 @@ import types, py from pypy.objspace.flow.model import Constant, FunctionGraph -from pypy.interpreter.pycode import cpython_code_signature -from pypy.interpreter.argument import rawshape -from pypy.interpreter.argument import ArgErr +from pypy.objspace.flow.bytecode import cpython_code_signature +from pypy.objspace.flow.argument import rawshape, ArgErr from pypy.tool.sourcetools import valid_identifier from pypy.tool.pairtype import extendabletype @@ -181,7 +180,7 @@ name = pyobj.func_name if signature is None: if hasattr(pyobj, '_generator_next_method_of_'): - from pypy.interpreter.argument import Signature + from pypy.objspace.flow.argument import Signature signature = Signature(['entry']) # haaaaaack defaults = () else: @@ -247,17 +246,20 @@ defs_s = [] if graph is None: signature = self.signature - defaults = self.defaults + defaults = self.defaults else: signature = graph.signature - defaults = graph.defaults + defaults = graph.defaults if defaults: for x in defaults: - defs_s.append(self.bookkeeper.immutablevalue(x)) + if x is NODEFAULT: + defs_s.append(None) + else: + defs_s.append(self.bookkeeper.immutablevalue(x)) try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: - raise TypeError("signature mismatch: %s() %s" % + raise TypeError("signature mismatch: %s() %s" % (self.name, e.getmsg())) return inputcells diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,8 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype + immutable = False knowntype = object - immutable = False + + def __init__(self): + assert type(self) is not SomeObject def __eq__(self, other): return (self.__class__ is other.__class__ and @@ -105,60 +106,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: From noreply at buildbot.pypy.org Fri Oct 26 23:05:15 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 23:05:15 +0200 (CEST) Subject: [pypy-commit] pypy default: mark this as unroll safe - it's going to be almost always constant-folded away Message-ID: <20121026210515.6F0491C1E05@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58482:22ec69c6b15d Date: 2012-10-26 22:50 +0200 http://bitbucket.org/pypy/pypy/changeset/22ec69c6b15d/ Log: mark this as unroll safe - it's going to be almost always constant- folded away 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 @@ -413,6 +413,7 @@ return interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] + at jit.unroll_safe def find_unaryop_result_dtype(space, dt, promote_to_float=False, promote_bools=False, promote_to_largest=False, allow_complex=True): if promote_bools and (dt.kind == interp_dtype.BOOLLTR): From noreply at buildbot.pypy.org Fri Oct 26 23:05:16 2012 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 26 Oct 2012 23:05:16 +0200 (CEST) Subject: [pypy-commit] pypy default: merge Message-ID: <20121026210516.9D7B01C1E05@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58483:0fe28351555a Date: 2012-10-26 23:04 +0200 http://bitbucket.org/pypy/pypy/changeset/0fe28351555a/ Log: merge diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,9 +4,8 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi, rposix +from pypy.rlib import jit, clibffi, jit_libffi from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -152,9 +151,6 @@ if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') - elif flag == 2: - file = rffi.cast(rffi.CCHARPP, data)[0] - rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -169,27 +165,6 @@ assert isinstance(abi, int) return space.wrap(abi) -rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) - -def prepare_file_call_argument(fileobj): - import os - space = fileobj.space - fileobj.direct_flush() - fd = fileobj.direct_fileno() - if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file has no OS file descriptor")) - try: - fd2 = os.dup(fd) - f = rffi_fdopen(fd2, fileobj.mode) - if not f: - os.close(fd2) - raise OSError(rposix.get_errno(), "fdopen failed") - except OSError, e: - raise wrap_oserror(space, e) - return f - # ____________________________________________________________ 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 @@ -3,9 +3,11 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.rarithmetic import ovfcheck +from pypy.rlib import rposix from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend import cdataobj, misc, ctypeprim @@ -236,6 +238,22 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) + def cast(self, w_ob): + if self.is_file: + value = self.prepare_file(w_ob) + if value: + return cdataobj.W_CData(self.space, value, self) + return W_CTypePtrBase.cast(self, w_ob) + + def prepare_file(self, w_ob): + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = self.space.interpclass_w(w_ob) + if isinstance(ob, W_File): + return prepare_file_argument(self.space, ob) + else: + return lltype.nullptr(rffi.CCHARP.TO) + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or @@ -245,11 +263,8 @@ # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 elif self.is_file: - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc - ob = space.interpclass_w(w_init) - if isinstance(ob, W_File): - result = ctypefunc.prepare_file_call_argument(ob) + result = self.prepare_file(w_init) + if result: rffi.cast(rffi.CCHARPP, cdata)[0] = result return 2 return 0 @@ -303,3 +318,31 @@ else: raise OperationError(space.w_TypeError, space.wrap("expected a 'cdata struct-or-union' object")) + +# ____________________________________________________________ + + +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +class CffiFileObj(object): + _immutable_ = True + def __init__(self, fd, mode): + self.llf = rffi_fdopen(fd, mode) + if not self.llf: + raise OSError(rposix.get_errno(), "fdopen failed") + def close(self): + rffi_fclose(self.llf) + +def prepare_file_argument(space, fileobj): + fileobj.direct_flush() + if fileobj.cffi_fileobj is None: + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + except OSError, e: + raise wrap_oserror(space, e) + return fileobj.cffi_fileobj.llf diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -2264,3 +2264,35 @@ e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " "be a cdata pointer, not file") + +def test_FILE_object(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP,), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fileno = ll.load_function(BFunc2, "fileno") + # + import posix + fdr, fdw = posix.pipe() + fw1 = posix.fdopen(fdw, 'wb', 256) + # + fw1p = cast(BFILEP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p) + assert res >= 0 + res = fileno(fw1p) + assert res == fdw + fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,8 +1,21 @@ from pypy.objspace.fake.checkmodule import checkmodule +from pypy.module._cffi_backend import ctypeptr +from pypy.rpython.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - checkmodule('_cffi_backend') + # prepare_file_argument() is not working without translating the _file + # module too + def dummy_prepare_file_argument(space, fileobj): + return lltype.nullptr(rffi.CCHARP.TO) + old = ctypeptr.prepare_file_argument + try: + ctypeptr.prepare_file_argument = dummy_prepare_file_argument + # + checkmodule('_cffi_backend') + # + finally: + ctypeptr.prepare_file_argument = old diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -32,6 +32,7 @@ encoding = None errors = None fd = -1 + cffi_fileobj = None # pypy/module/_cffi_backend newlines = 0 # Updated when the stream is closed @@ -148,7 +149,14 @@ del openstreams[stream] except KeyError: pass - stream.close() + # close the stream. If cffi_fileobj is None, we close the + # underlying fileno too. Otherwise, we leave that to + # cffi_fileobj.close(). + cffifo = self.cffi_fileobj + self.cffi_fileobj = None + stream.close1(cffifo is None) + if cffifo is not None: + cffifo.close() def direct_fileno(self): self.getstream() # check if the file is still open diff --git a/pypy/rlib/streamio.py b/pypy/rlib/streamio.py --- a/pypy/rlib/streamio.py +++ b/pypy/rlib/streamio.py @@ -268,6 +268,9 @@ return False def close(self): + self.close1(True) + + def close1(self, closefileno): pass def peek(self): @@ -333,8 +336,9 @@ else: data = data[n:] - def close(self): - os.close(self.fd) + def close1(self, closefileno): + if closefileno: + os.close(self.fd) if sys.platform == "win32": def truncate(self, size): @@ -375,9 +379,10 @@ size = os.fstat(self.fd).st_size self.mm = mmap.mmap(self.fd, size, access=self.access) - def close(self): + def close1(self, closefileno): self.mm.close() - os.close(self.fd) + if closefileno: + os.close(self.fd) def tell(self): return self.pos @@ -470,7 +475,7 @@ ("truncate", [r_longlong]), ("flush", []), ("flushable", []), - ("close", []), + ("close1", [int]), ("peek", []), ("try_to_find_file_descriptor", []), ("getnewlines", []), @@ -715,7 +720,7 @@ truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=True) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -770,7 +775,7 @@ seek = PassThrough("seek", flush_buffers=True) truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=True) - close = PassThrough("close", flush_buffers=True) + close1 = PassThrough("close1", flush_buffers=True) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -838,7 +843,7 @@ flush = PassThrough("flush", flush_buffers=False) flushable= PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -907,7 +912,7 @@ truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=False) flushable= PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1041,7 +1046,7 @@ truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=True) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1067,7 +1072,7 @@ truncate = PassThrough("truncate", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1091,7 +1096,7 @@ peek = PassThrough("peek", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) write = PassThrough("write", flush_buffers=False) truncate = PassThrough("truncate", flush_buffers=False) getnewlines= PassThrough("getnewlines",flush_buffers=False) @@ -1144,7 +1149,7 @@ truncate = PassThrough("truncate", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1172,6 +1177,6 @@ truncate = PassThrough("truncate", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) From noreply at buildbot.pypy.org Sat Oct 27 00:06:48 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 00:06:48 +0200 (CEST) Subject: [pypy-commit] pypy missing-ndarray-attributes: shuffle stuff around and pass argsort tests Message-ID: <20121026220648.838BB1C1E04@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58484:4b874f254549 Date: 2012-10-27 00:06 +0200 http://bitbucket.org/pypy/pypy/changeset/4b874f254549/ Log: shuffle stuff around and pass argsort tests diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,6 +1,6 @@ from pypy.module.micronumpy.arrayimpl import base -from pypy.module.micronumpy import support, loop +from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException from pypy.module.micronumpy.strides import calc_new_strides, shape_agreement,\ @@ -12,152 +12,6 @@ from pypy.rlib.rawstorage import free_raw_storage from pypy.module.micronumpy.arrayimpl.sort import argsort_array -class ConcreteArrayIterator(base.BaseArrayIterator): - def __init__(self, array): - self.array = array - self.offset = 0 - self.dtype = array.dtype - self.skip = self.dtype.itemtype.get_element_size() - self.size = array.size - - def setitem(self, elem): - self.array.setitem(self.offset, elem) - - def getitem(self): - return self.array.getitem(self.offset) - - def getitem_bool(self): - return self.dtype.getitem_bool(self.array, self.offset) - - def next(self): - self.offset += self.skip - - def next_skip_x(self, x): - self.offset += self.skip * x - - def done(self): - return self.offset >= self.size - - def reset(self): - self.offset %= self.size - -class OneDimViewIterator(ConcreteArrayIterator): - def __init__(self, array): - self.array = array - self.offset = array.start - self.skip = array.strides[0] - self.dtype = array.dtype - self.index = 0 - self.size = array.shape[0] - - def next(self): - self.offset += self.skip - self.index += 1 - - def next_skip_x(self, x): - self.offset += self.skip * x - self.index += x - - def done(self): - return self.index >= self.size - - def reset(self): - self.offset %= self.size - -class MultiDimViewIterator(ConcreteArrayIterator): - def __init__(self, array, start, strides, backstrides, shape): - self.indexes = [0] * len(shape) - self.array = array - self.shape = shape - self.offset = start - self.shapelen = len(shape) - self._done = False - self.strides = strides - self.backstrides = backstrides - self.size = array.size - - @jit.unroll_safe - def next(self): - offset = self.offset - for i in range(self.shapelen - 1, -1, -1): - if self.indexes[i] < self.shape[i] - 1: - self.indexes[i] += 1 - offset += self.strides[i] - break - else: - self.indexes[i] = 0 - offset -= self.backstrides[i] - else: - self._done = True - self.offset = offset - - @jit.unroll_safe - def next_skip_x(self, step): - for i in range(len(self.shape) - 1, -1, -1): - if self.indexes[i] < self.shape[i] - step: - self.indexes[i] += step - self.offset += self.strides[i] * step - break - else: - remaining_step = (self.indexes[i] + step) // self.shape[i] - this_i_step = step - remaining_step * self.shape[i] - self.offset += self.strides[i] * this_i_step - self.indexes[i] = self.indexes[i] + this_i_step - step = remaining_step - else: - self._done = True - - def done(self): - return self._done - - def reset(self): - self.offset %= self.size - -class AxisIterator(base.BaseArrayIterator): - def __init__(self, array, shape, dim): - self.shape = shape - strides = array.strides - backstrides = array.backstrides - if len(shape) == len(strides): - # keepdims = True - self.strides = strides[:dim] + [0] + strides[dim + 1:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:] - else: - self.strides = strides[:dim] + [0] + strides[dim:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim:] - self.first_line = True - self.indices = [0] * len(shape) - self._done = False - self.offset = array.start - self.dim = dim - self.array = array - - def setitem(self, elem): - self.array.setitem(self.offset, elem) - - def getitem(self): - return self.array.getitem(self.offset) - - @jit.unroll_safe - def next(self): - for i in range(len(self.shape) - 1, -1, -1): - if self.indices[i] < self.shape[i] - 1: - if i == self.dim: - self.first_line = False - self.indices[i] += 1 - self.offset += self.strides[i] - break - else: - if i == self.dim: - self.first_line = True - self.indices[i] = 0 - self.offset -= self.backstrides[i] - else: - self._done = True - - def done(self): - return self._done - def int_w(space, w_obj): try: return space.int_w(space.index(w_obj)) @@ -354,12 +208,12 @@ return loop.setslice(self.shape, impl, self) def create_axis_iter(self, shape, dim): - return AxisIterator(self, shape, dim) + return iter.AxisIterator(self, shape, dim) def create_dot_iter(self, shape, skip): r = calculate_dot_strides(self.strides, self.backstrides, shape, skip) - return MultiDimViewIterator(self, self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.start, r[0], r[1], shape) def swapaxes(self, axis1, axis2): shape = self.shape[:] @@ -389,10 +243,10 @@ def create_iter(self, shape): if shape == self.shape: - return ConcreteArrayIterator(self) + return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.strides, self.backstrides, self.shape, shape) - return MultiDimViewIterator(self, 0, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, 0, r[0], r[1], shape) def fill(self, box): self.dtype.fill(self.storage, box, 0, self.size) @@ -431,12 +285,12 @@ if shape != self.shape: r = calculate_broadcast_strides(self.strides, self.backstrides, self.shape, shape) - return MultiDimViewIterator(self.parent, + return iter.MultiDimViewIterator(self.parent, self.start, r[0], r[1], shape) if len(self.shape) == 1: - return OneDimViewIterator(self) - return MultiDimViewIterator(self.parent, self.start, self.strides, - self.backstrides, self.shape) + return iter.OneDimViewIterator(self) + return iter.MultiDimViewIterator(self.parent, self.start, self.strides, + self.backstrides, self.shape) def set_shape(self, space, new_shape): if len(self.shape) < 2 or self.size == 0: diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -11,6 +11,7 @@ from pypy.interpreter.error import OperationError from pypy.module.micronumpy.base import W_NDimArray from pypy.module.micronumpy import interp_dtype, types +from pypy.module.micronumpy.iter import AxisIterator INT_SIZE = rffi.sizeof(lltype.Signed) @@ -19,22 +20,30 @@ TP = itemtype.T class ArgArrayRepresentation(object): - def __init__(self, itemsize, size, values, indexes): - self.itemsize = itemsize + def __init__(self, index_stride_size, stride_size, size, values, + indexes, index_start, start): + self.index_stride_size = index_stride_size + self.stride_size = stride_size + self.index_start = index_start + self.start = start self.size = size self.values = values self.indexes = indexes + self.start = start def getitem(self, item): - v = raw_storage_getitem(TP, self.values, item * self.itemsize) + v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start) v = itemtype.for_computation(v) return (v, raw_storage_getitem(lltype.Signed, self.indexes, - item * INT_SIZE)) + item * self.index_stride_size + + self.index_start)) def setitem(self, idx, item): - raw_storage_setitem(self.values, idx * self.itemsize, - rffi.cast(TP, item[0])) - raw_storage_setitem(self.indexes, idx * INT_SIZE, item[1]) + raw_storage_setitem(self.values, idx * self.stride_size + + self.start, rffi.cast(TP, item[0])) + raw_storage_setitem(self.indexes, idx * self.index_stride_size + + self.index_start, item[1]) def arg_getitem(lst, item): return lst.getitem(item) @@ -73,15 +82,36 @@ itemsize = itemtype.get_element_size() # create array of indexes dtype = interp_dtype.get_dtype_cache(space).w_longdtype - indexes = W_NDimArray.from_shape(arr.get_shape(), dtype) + index_arr = W_NDimArray.from_shape(arr.get_shape(), dtype) + storage = index_arr.implementation.get_storage() if len(arr.get_shape()) == 1: - storage = indexes.implementation.get_storage() for i in range(arr.get_size()): raw_storage_setitem(storage, i * INT_SIZE, i) Repr, Sort = make_sort_classes(space, itemtype) - r = Repr(itemsize, arr.get_size(), arr.get_storage(), - indexes.implementation.get_storage()) + r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), + storage, 0, arr.start) Sort(r).sort() else: - xxx - return indexes + shape = arr.get_shape() + if axis < 0: + axis = len(shape) + axis - 1 + if axis < 0 or axis > len(shape): + raise OperationError(space.w_IndexError("Wrong axis %d" % axis)) + iterable_shape = shape[:axis] + [0] + shape[axis + 1:] + iter = AxisIterator(arr, iterable_shape, axis) + index_impl = index_arr.implementation + index_iter = AxisIterator(index_impl, iterable_shape, axis) + stride_size = arr.strides[axis] + index_stride_size = index_impl.strides[axis] + axis_size = arr.shape[axis] + Repr, Sort = make_sort_classes(space, itemtype) + while not iter.done(): + for i in range(axis_size): + raw_storage_setitem(storage, i * index_stride_size + + index_iter.offset, i) + r = Repr(index_stride_size, stride_size, axis_size, + arr.get_storage(), storage, index_iter.offset, iter.offset) + Sort(r).sort() + iter.next() + index_iter.next() + return index_arr 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 @@ -45,6 +45,7 @@ from pypy.module.micronumpy.strides import enumerate_chunks,\ calculate_slice_strides from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.arrayimpl import base from pypy.rlib import jit # structures to describe slicing @@ -121,3 +122,181 @@ class BroadcastTransform(BaseTransform): def __init__(self, res_shape): self.res_shape = res_shape + +class PureShapeIterator(object): + def __init__(self, shape, idx_w): + self.shape = shape + self.shapelen = len(shape) + self.indexes = [0] * len(shape) + self._done = False + self.idx_w = [None] * len(idx_w) + for i, w_idx in enumerate(idx_w): + if isinstance(w_idx, W_NDimArray): + self.idx_w[i] = w_idx.create_iter(shape) + + def done(self): + return self._done + + @jit.unroll_safe + def next(self): + for w_idx in self.idx_w: + if w_idx is not None: + w_idx.next() + for i in range(self.shapelen - 1, -1, -1): + if self.indexes[i] < self.shape[i] - 1: + self.indexes[i] += 1 + break + else: + self.indexes[i] = 0 + else: + self._done = True + + @jit.unroll_safe + def get_index(self, space, shapelen): + return [space.wrap(self.indexes[i]) for i in range(shapelen)] + +class ConcreteArrayIterator(base.BaseArrayIterator): + def __init__(self, array): + self.array = array + self.offset = 0 + self.dtype = array.dtype + self.skip = self.dtype.itemtype.get_element_size() + self.size = array.size + + def setitem(self, elem): + self.array.setitem(self.offset, elem) + + def getitem(self): + return self.array.getitem(self.offset) + + def getitem_bool(self): + return self.dtype.getitem_bool(self.array, self.offset) + + def next(self): + self.offset += self.skip + + def next_skip_x(self, x): + self.offset += self.skip * x + + def done(self): + return self.offset >= self.size + + def reset(self): + self.offset %= self.size + +class OneDimViewIterator(ConcreteArrayIterator): + def __init__(self, array): + self.array = array + self.offset = array.start + self.skip = array.strides[0] + self.dtype = array.dtype + self.index = 0 + self.size = array.shape[0] + + def next(self): + self.offset += self.skip + self.index += 1 + + def next_skip_x(self, x): + self.offset += self.skip * x + self.index += x + + def done(self): + return self.index >= self.size + + def reset(self): + self.offset %= self.size + +class MultiDimViewIterator(ConcreteArrayIterator): + def __init__(self, array, start, strides, backstrides, shape): + self.indexes = [0] * len(shape) + self.array = array + self.shape = shape + self.offset = start + self.shapelen = len(shape) + self._done = False + self.strides = strides + self.backstrides = backstrides + self.size = array.size + + @jit.unroll_safe + def next(self): + offset = self.offset + for i in range(self.shapelen - 1, -1, -1): + if self.indexes[i] < self.shape[i] - 1: + self.indexes[i] += 1 + offset += self.strides[i] + break + else: + self.indexes[i] = 0 + offset -= self.backstrides[i] + else: + self._done = True + self.offset = offset + + @jit.unroll_safe + def next_skip_x(self, step): + for i in range(len(self.shape) - 1, -1, -1): + if self.indexes[i] < self.shape[i] - step: + self.indexes[i] += step + self.offset += self.strides[i] * step + break + else: + remaining_step = (self.indexes[i] + step) // self.shape[i] + this_i_step = step - remaining_step * self.shape[i] + self.offset += self.strides[i] * this_i_step + self.indexes[i] = self.indexes[i] + this_i_step + step = remaining_step + else: + self._done = True + + def done(self): + return self._done + + def reset(self): + self.offset %= self.size + +class AxisIterator(base.BaseArrayIterator): + def __init__(self, array, shape, dim): + self.shape = shape + strides = array.strides + backstrides = array.backstrides + if len(shape) == len(strides): + # keepdims = True + self.strides = strides[:dim] + [0] + strides[dim + 1:] + self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:] + else: + self.strides = strides[:dim] + [0] + strides[dim:] + self.backstrides = backstrides[:dim] + [0] + backstrides[dim:] + self.first_line = True + self.indices = [0] * len(shape) + self._done = False + self.offset = array.start + self.dim = dim + self.array = array + + def setitem(self, elem): + self.array.setitem(self.offset, elem) + + def getitem(self): + return self.array.getitem(self.offset) + + @jit.unroll_safe + def next(self): + for i in range(len(self.shape) - 1, -1, -1): + if self.indices[i] < self.shape[i] - 1: + if i == self.dim: + self.first_line = False + self.indices[i] += 1 + self.offset += self.strides[i] + break + else: + if i == self.dim: + self.first_line = True + self.indices[i] = 0 + self.offset -= self.backstrides[i] + else: + self._done = True + + def done(self): + return self._done 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 @@ -8,6 +8,7 @@ from pypy.rlib import jit from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.iter import PureShapeIterator call2_driver = jit.JitDriver(name='numpy_call2', greens = ['shapelen', 'func', 'calc_dtype', @@ -395,38 +396,6 @@ iter.next() return builder.build() -class PureShapeIterator(object): - def __init__(self, shape, idx_w): - self.shape = shape - self.shapelen = len(shape) - self.indexes = [0] * len(shape) - self._done = False - self.idx_w = [None] * len(idx_w) - for i, w_idx in enumerate(idx_w): - if isinstance(w_idx, W_NDimArray): - self.idx_w[i] = w_idx.create_iter(shape) - - def done(self): - return self._done - - @jit.unroll_safe - def next(self): - for w_idx in self.idx_w: - if w_idx is not None: - w_idx.next() - for i in range(self.shapelen - 1, -1, -1): - if self.indexes[i] < self.shape[i] - 1: - self.indexes[i] += 1 - break - else: - self.indexes[i] = 0 - else: - self._done = True - - @jit.unroll_safe - def get_index(self, space, shapelen): - return [space.wrap(self.indexes[i]) for i in range(shapelen)] - getitem_int_driver = jit.JitDriver(name = 'numpy_getitem_int', greens = ['shapelen', 'indexlen', 'prefixlen', 'dtype'], From noreply at buildbot.pypy.org Sat Oct 27 00:09:31 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 00:09:31 +0200 (CEST) Subject: [pypy-commit] pypy missing-ndarray-attributes: mention why we do that Message-ID: <20121026220931.9C52D1C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58485:c1bd1b306ef7 Date: 2012-10-27 00:09 +0200 http://bitbucket.org/pypy/pypy/changeset/c1bd1b306ef7/ Log: mention why we do that 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 @@ -379,6 +379,8 @@ def descr_argsort(self, space, w_axis=None, w_kind=None, w_order=None): # happily ignore the kind # create a contiguous copy of the array + # we must do that, because we need a working set. otherwise + # we would modify the array in-place contig = self.descr_copy(space) return contig.implementation.argsort(space, w_axis) From noreply at buildbot.pypy.org Sat Oct 27 00:41:19 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 00:41:19 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: guard class removal Message-ID: <20121026224119.4ACEA1C1DE9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58486:0ed7c47bcde4 Date: 2012-10-27 00:40 +0200 http://bitbucket.org/pypy/pypy/changeset/0ed7c47bcde4/ Log: guard class removal diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -195,17 +195,17 @@ self.emit_operation(op) def optimize_INT_ADD_OVF(self, op): - v1 = self.getvalue(op.getarg(0)) - v2 = self.getvalue(op.getarg(1)) + op = self.getforwarded(op) + v1 = self.getforwarded(op.getarg(0)) + v2 = self.getforwarded(op.getarg(1)) resbound = v1.getintbound().add_bound(v2.getintbound()) if resbound.bounded(): # Transform into INT_ADD. The following guard will be killed # by optimize_GUARD_NO_OVERFLOW; if we see instead an # optimize_GUARD_OVERFLOW, then InvalidLoop. - op = self.optimizer.copy_and_change(op, rop.INT_ADD) - self.emit_operation(op) # emit the op - r = self.getvalue(op) - r.getintbound().intersect(resbound) + op = op.make_forwarded_copy(rop.INT_ADD) + op.getintbound().intersect(resbound) + return op def optimize_INT_SUB_OVF(self, op): v1 = self.getvalue(op.getarg(0)) diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -165,16 +165,6 @@ return self.box.same_constant(other.box) return self is other - def get_constant_class(self, cpu): - xxx - level = self.level - if level == LEVEL_KNOWNCLASS: - return self.known_class - elif level == LEVEL_CONSTANT: - return cpu.ts.cls_of_box(self.op) - else: - return None - def make_constant_class(self, classbox, guardop, index): assert self.level < LEVEL_KNOWNCLASS self.known_class = classbox @@ -464,6 +454,11 @@ if isinstance(op, Const): return op + def get_constant_class(self, op): + if op.is_constant(): + xxx + return op.getknownclass() + def get_newoperations(self): self.flush() return self._newoperations diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -210,7 +210,10 @@ self.postprocess_guard(op, CONST_1) def postprocess_GUARD_FALSE(self, op): - self.postprocess_guard(op, CONST_0) + self.postprocess_guard(op, CONST_0) + + def postprocess_GUARD_NO_OVERFLOW(self, op): + pass # to be killed def postprocess_default(self, op): if op.is_guard(): @@ -237,7 +240,7 @@ def optimize_GUARD_VALUE(self, op): value = self.getforwarded(op.getarg(0)) - if value.getlastguard(): + if value.getlastguardpos() != -1: xxx # there already has been a guard_nonnull or guard_class or # guard_nonnull_class on this value, which is rather silly. @@ -286,7 +289,7 @@ value = self.getvalue(op.getarg(0)) expectedclassbox = op.getarg(1) assert isinstance(expectedclassbox, Const) - realclassbox = value.get_constant_class(self.optimizer.cpu) + realclassbox = self.optimizer.get_constant_class(value) if realclassbox is not None: assert realclassbox.same_constant(expectedclassbox) return @@ -294,16 +297,16 @@ self.optimizer.get_pos()) def optimize_GUARD_CLASS(self, op): - value = self.getvalue(op.getarg(0)) + value = self.getforwarded(op.getarg(0)) expectedclassbox = op.getarg(1) assert isinstance(expectedclassbox, Const) - realclassbox = value.get_constant_class(self.optimizer.cpu) + realclassbox = self.optimizer.get_constant_class(value) if realclassbox is not None: if realclassbox.same_constant(expectedclassbox): return raise InvalidLoop('A GUARD_CLASS was proven to always fail') - emit_operation = True - if value.last_guard: + if value.getlastguardpos() != -1: + xxx # there already has been a guard_nonnull or guard_class or # guard_nonnull_class on this value. old_guard_op = value.last_guard @@ -320,14 +323,17 @@ new_op.set_extra("failargs", old_guard_op.get_extra("failargs")) self.optimizer.replace_op(value, new_op) op = new_op - emit_operation = False + return value.last_guard = None - pos = value.last_guard_pos else: - pos = self.optimizer.get_pos() - if emit_operation: - self.emit_operation(op) - value.make_constant_class(expectedclassbox, op, pos) + value.setlastguardpos(self.optimizer.get_pos()) + return op + + def postprocess_GUARD_CLASS(self, op): + value = self.getforwarded(op.getarg(0)) + expectedclassbox = op.getarg(1) + assert isinstance(expectedclassbox, Const) + value.setknownclass(expectedclassbox) def optimize_GUARD_NONNULL_CLASS(self, op): value = self.getvalue(op.getarg(0)) diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -167,19 +167,19 @@ def test_constant_propagate_ovf(self): ops = """ [i] - guard_value(i, 2) [] + guard_value(i, 2) i0 = int_add_ovf(i, 3) - guard_no_overflow() [] + guard_no_overflow() i1 = int_is_true(i0) - guard_true(i1) [] + guard_true(i1) i2 = int_is_zero(i1) - guard_false(i2) [] - guard_value(i0, 5) [] + guard_false(i2) + guard_value(i0, 5) jump(i) """ expected = """ [i] - guard_value(i, 2) [] + guard_value(i, 2) jump(2) """ self.optimize_loop(ops, expected) @@ -224,13 +224,13 @@ def test_remove_guard_class_1(self): ops = """ [p0] - guard_class(p0, ConstClass(node_vtable)) [] - guard_class(p0, ConstClass(node_vtable)) [] + guard_class(p0, ConstClass(node_vtable)) + guard_class(p0, ConstClass(node_vtable)) jump(p0) """ expected = """ [p0] - guard_class(p0, ConstClass(node_vtable)) [] + guard_class(p0, ConstClass(node_vtable)) jump(p0) """ self.optimize_loop(ops, expected) diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -4,7 +4,7 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable, rop,\ - INT, ConstInt, Const + INT, REF, ConstInt, Const from pypy.jit.metainterp.optimizeopt.intutils import ImmutableIntUnbounded,\ ConstantIntBound @@ -16,8 +16,8 @@ return False # for optimization class __extend__(Const): - def getlastguard(self): - return None + def getlastguardpos(self): + return -1 def create_mutable_subclasses(): def addattr(cls, attr, default_value=None): @@ -34,7 +34,7 @@ def _copy_extra_attrs(self, new): paren_cls._copy_extra_attrs(self, new) for attr in cls.attributes_to_copy: - setattr(new, getattr(self, attr)) + setattr(new, attr, getattr(self, attr)) cls._copy_extra_attrs = _copy_extra_attrs imm_int_unbound = ImmutableIntUnbounded() @@ -53,9 +53,10 @@ # all the integers have bounds addattr(Mutable, 'intbound', imm_int_unbound) addattr(Mutable, 'boolbox', False) + elif cls.type == REF: + addattr(Mutable, 'knownclass', None) # for tracking last guard and merging GUARD_VALUE with # GUARD_NONNULL etc - addattr(Mutable, 'lastguard', None) addattr(Mutable, 'lastguardpos', -1) Mutable.__name__ = cls.__name__ + '_mutable' if Mutable.attributes_to_copy: diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -1043,9 +1043,6 @@ arg1 or self._arg1, descr or self.getdescr(), mutable=True) - if self.is_guard(): - res.set_rd_frame_info_list(self.get_rd_frame_info_list()) - res.set_rd_snapshot(self.get_rd_snapshot()) assert not self._forwarded self._forwarded = res self._copy_extra_attrs(res) From noreply at buildbot.pypy.org Sat Oct 27 00:58:53 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 00:58:53 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: one more test_guard_class Message-ID: <20121026225853.9D3EC1C1E03@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58487:c9dbbd6d9b9d Date: 2012-10-27 00:56 +0200 http://bitbucket.org/pypy/pypy/changeset/c9dbbd6d9b9d/ Log: one more test_guard_class diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -300,9 +300,6 @@ def make_constant_int(self, box, intconst): return self.optimizer.make_constant_int(box, intconst) - def replace(self, box, value): - return self.optimizer.replace(box, value) - def get_constant_op(self, op): return self.optimizer.get_constant_op(op) @@ -357,7 +354,7 @@ self.optimizer.forget_numberings(box) -class Optimizer(Optimization): +class Optimizer(object): def __init__(self, jitdriver_sd, metainterp_sd, loop, optimizations=None): self.jitdriver_sd = jitdriver_sd @@ -379,7 +376,6 @@ self.optimizations = optimizations for opt in optimizations: opt.optimizer = self - self.setup() def force_at_end_of_preamble(self): for o in self.optimizations: @@ -424,11 +420,8 @@ return op return op.getforwarded() - def setvalue(self, box, value): - xxx - assert not box.is_constant() - assert not box.has_extra("optimize_value") - box.set_extra("optimize_value", value) + def replace(self, op, with_): + self.getforwarded(op)._forwarded = with_ def copy_op_if_modified_by_optimization(self, op): xxxx @@ -456,7 +449,7 @@ def get_constant_class(self, op): if op.is_constant(): - xxx + return self.cpu.ts.cls_of_box(op) return op.getknownclass() def get_newoperations(self): @@ -564,7 +557,7 @@ op = self.store_final_boxes_in_guard(op) assert op is not None for i in range(op.numargs()): - op.setarg(i, self.getforwarded(op.getarg(i))) + op.setarg(i, self.getforwarded(op.getarg(i)).force(self)) self._newoperations.append(op) def store_final_boxes_in_guard(self, op): diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -331,6 +331,8 @@ def postprocess_GUARD_CLASS(self, op): value = self.getforwarded(op.getarg(0)) + if value.is_constant(): + return expectedclassbox = op.getarg(1) assert isinstance(expectedclassbox, Const) value.setknownclass(expectedclassbox) @@ -538,7 +540,7 @@ self.emit_operation(op) def optimize_SAME_AS_i(self, op): - self.replace(op, op.getarg(0)) + self.optimizer.replace(op, op.getarg(0)) optimize_SAME_AS_r = optimize_SAME_AS_i optimize_SAME_AS_f = optimize_SAME_AS_i diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -240,7 +240,7 @@ [i0] p0 = new_with_vtable(ConstClass(node_vtable)) escape(p0) - guard_class(p0, ConstClass(node_vtable)) [] + guard_class(p0, ConstClass(node_vtable)) jump(i0) """ expected = """ @@ -255,7 +255,7 @@ ops = """ [i0] p0 = same_as_r(ConstPtr(myptr)) - guard_class(p0, ConstClass(node_vtable)) [] + guard_class(p0, ConstClass(node_vtable)) jump(i0) """ expected = """ diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py --- a/pypy/jit/metainterp/optimizeopt/virtualize.py +++ b/pypy/jit/metainterp/optimizeopt/virtualize.py @@ -358,11 +358,6 @@ def new(self): return OptVirtualize() - def make_virtual(self, known_class, op): - vvalue = VirtualValue(self.optimizer.cpu, known_class, op) - self.setvalue(op, vvalue) - return vvalue - def make_varray(self, arraydescr, size, op): if arraydescr.is_array_of_structs(): vvalue = VArrayStructValue(arraydescr, size, op) @@ -468,7 +463,8 @@ self.emit_operation(op) def optimize_NEW_WITH_VTABLE(self, op): - self.make_virtual(op.getarg(0), op) + value = self.getforwarded(op) + value.setknownclass(op.getarg(0)) def optimize_NEW(self, op): self.make_vstruct(op.getdescr(), op) diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -19,6 +19,9 @@ def getlastguardpos(self): return -1 + def force(self, _): + return self + def create_mutable_subclasses(): def addattr(cls, attr, default_value=None): cls.attributes_to_copy.append('_' + attr) @@ -45,6 +48,14 @@ class Mutable(cls): is_mutable = True attributes_to_copy = [] + + if cls.getopnum() in (rop.NEW_WITH_VTABLE, rop.NEW): + def force(self, optimizer): + optimizer.emit_operation(self) + return self + else: + def force(self, _): + return self if cls.is_guard() or cls.getopnum() == rop.FINISH: addattr(Mutable, 'failargs') if cls.is_guard(): From noreply at buildbot.pypy.org Sat Oct 27 09:38:03 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 09:38:03 +0200 (CEST) Subject: [pypy-commit] pypy default: Merge change bf651562fa0c from pyrepl: Message-ID: <20121027073803.6F9A21C0250@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58488:43d0a2bd9ab1 Date: 2012-10-27 09:37 +0200 http://bitbucket.org/pypy/pypy/changeset/43d0a2bd9ab1/ Log: Merge change bf651562fa0c from pyrepl: - When the history file contains non-utf8 character sequences, don't crash but just replace them with the "unknown" unicode char. - When writing out text to the terminal, use "?" instead of crashing when the text cannot be encoded. 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 @@ -233,7 +233,7 @@ try: return unicode(line, ENCODING) except UnicodeDecodeError: # bah, silently fall back... - return unicode(line, 'utf-8') + return unicode(line, 'utf-8', 'replace') def get_history_length(self): return self.saved_history_length diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -496,7 +496,7 @@ if iscode: self.__tputs(text) else: - os.write(self.output_fd, text.encode(self.encoding)) + os.write(self.output_fd, text.encode(self.encoding, 'replace')) del self.__buffer[:] def __tputs(self, fmt, prog=delayprog): From noreply at buildbot.pypy.org Sat Oct 27 09:44:37 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 09:44:37 +0200 (CEST) Subject: [pypy-commit] pypy default: Oups, my fault for leaving the option "--jit-backend=llvm" around Message-ID: <20121027074437.7F43A1C0250@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58489:f0d036cd3b7b Date: 2012-10-27 09:44 +0200 http://bitbucket.org/pypy/pypy/changeset/f0d036cd3b7b/ Log: Oups, my fault for leaving the option "--jit-backend=llvm" around when the llvm jit backend was removed long ago. diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -118,7 +118,7 @@ ("translation.gcrootfinder", DEFL_ROOTFINDER_WITHJIT), ("translation.list_comprehension_operations", True)]), ChoiceOption("jit_backend", "choose the backend for the JIT", - ["auto", "x86", "x86-without-sse2", "llvm", 'arm'], + ["auto", "x86", "x86-without-sse2", 'arm'], default="auto", cmdline="--jit-backend"), ChoiceOption("jit_profiler", "integrate profiler support into the JIT", ["off", "oprofile"], From noreply at buildbot.pypy.org Sat Oct 27 09:37:57 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 09:37:57 +0200 (CEST) Subject: [pypy-commit] pyrepl default: - When the history file contains non-utf8 character sequences, Message-ID: <20121027073757.71FF31C01E7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r202:bf651562fa0c Date: 2012-10-27 09:37 +0200 http://bitbucket.org/pypy/pyrepl/changeset/bf651562fa0c/ Log: - When the history file contains non-utf8 character sequences, don't crash but just replace them with the "unknown" unicode char. - When writing out text to the terminal, use "?" instead of crashing when the text cannot be encoded. diff --git a/pyrepl/readline.py b/pyrepl/readline.py --- a/pyrepl/readline.py +++ b/pyrepl/readline.py @@ -235,7 +235,7 @@ try: return unicode(line, ENCODING) except UnicodeDecodeError: # bah, silently fall back... - return unicode(line, 'utf-8') + return unicode(line, 'utf-8', 'replace') def get_history_length(self): return self.saved_history_length diff --git a/pyrepl/unix_console.py b/pyrepl/unix_console.py --- a/pyrepl/unix_console.py +++ b/pyrepl/unix_console.py @@ -477,7 +477,7 @@ if iscode: self.__tputs(text) else: - os.write(self.output_fd, text.encode(self.encoding)) + os.write(self.output_fd, text.encode(self.encoding, 'replace')) del self.__buffer[:] def __tputs(self, fmt, prog=delayprog): From noreply at buildbot.pypy.org Sat Oct 27 09:46:38 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 09:46:38 +0200 (CEST) Subject: [pypy-commit] pypy default: Kill these lines too. Message-ID: <20121027074638.2AFEB1C0250@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58490:ed43c2dc0a42 Date: 2012-10-27 09:46 +0200 http://bitbucket.org/pypy/pypy/changeset/ed43c2dc0a42/ Log: Kill these lines too. diff --git a/pypy/jit/backend/detect_cpu.py b/pypy/jit/backend/detect_cpu.py --- a/pypy/jit/backend/detect_cpu.py +++ b/pypy/jit/backend/detect_cpu.py @@ -77,8 +77,6 @@ return "pypy.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "pypy.jit.backend.cli.runner", "CliCPU" - elif backend_name == 'llvm': - return "pypy.jit.backend.llvm.runner", "LLVMCPU" elif backend_name == 'arm': return "pypy.jit.backend.arm.runner", "CPU_ARM" elif backend_name == 'armhf': From noreply at buildbot.pypy.org Sat Oct 27 10:54:38 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 10:54:38 +0200 (CEST) Subject: [pypy-commit] pypy default: Don't write directly to "SomeBool().knowntypedata"; instead use a setter. Message-ID: <20121027085438.CD0601C01E7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58491:28ae0f0e0b79 Date: 2012-10-27 10:54 +0200 http://bitbucket.org/pypy/pypy/changeset/28ae0f0e0b79/ Log: Don't write directly to "SomeBool().knowntypedata"; instead use a setter. This lets us do more checking, and fixes a hard-to- reproduce-in-a-small-test issue whereby sometimes an empty knowntypedata attribute gets attached, confusing contains(). diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -548,7 +548,7 @@ if cell.is_constant(): newcell.const = cell.const cell = newcell - cell.knowntypedata = renamed_knowntypedata + cell.set_knowntypedata(renamed_knowntypedata) cells.append(cell) diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -144,7 +144,7 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key annotator = bk.annotator @@ -168,6 +168,7 @@ bind(obj2, obj1, 0) bind(obj1, obj2, 1) + r.set_knowntypedata(knowntypedata) return r @@ -337,8 +338,7 @@ case = opname in ('gt', 'ge', 'eq') add_knowntypedata(knowntypedata, case, [op.args[0]], SomeInteger(nonneg=True, knowntype=tointtype(int1))) - if knowntypedata: - r.knowntypedata = knowntypedata + r.set_knowntypedata(knowntypedata) # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) @@ -369,8 +369,7 @@ if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) - if ktd: - s.knowntypedata = ktd + s.set_knowntypedata(ktd) return s def and_((boo1, boo2)): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -188,10 +188,10 @@ variables = [op.args[1]] for variable in variables: assert bk.annotator.binding(variable) == s_obj - r.knowntypedata = {} - + knowntypedata = {} if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): - add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) + add_knowntypedata(knowntypedata, True, variables, bk.valueoftype(typ)) + r.set_knowntypedata(knowntypedata) return r # note that this one either needs to be constant, or we will create SomeObject diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -195,6 +195,10 @@ unsigned = False def __init__(self): pass + def set_knowntypedata(self, knowntypedata): + assert not hasattr(self, 'knowntypedata') + if knowntypedata: + self.knowntypedata = knowntypedata class SomeStringOrUnicode(SomeObject): immutable = True diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -76,7 +76,7 @@ s_obj.is_true_behavior(r) bk = getbookkeeper() - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key op = block.operations[i] assert op.opname == "is_true" or op.opname == "nonzero" @@ -86,8 +86,8 @@ if s_obj.can_be_none(): s_nonnone_obj = s_obj.nonnoneify() add_knowntypedata(knowntypedata, True, [arg], s_nonnone_obj) + r.set_knowntypedata(knowntypedata) return r - def nonzero(obj): return obj.is_true() From noreply at buildbot.pypy.org Sat Oct 27 11:28:22 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 11:28:22 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: make yet another test pass Message-ID: <20121027092822.D1DC41C01E7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58492:3945cce69723 Date: 2012-10-27 11:20 +0200 http://bitbucket.org/pypy/pypy/changeset/3945cce69723/ Log: make yet another test pass diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -228,14 +228,14 @@ r.getintbound().intersect(resbound) def optimize_INT_LT(self, op): - v1 = self.getvalue(op.getarg(0)) - v2 = self.getvalue(op.getarg(1)) + v1 = self.getforwarded(op.getarg(0)) + v2 = self.getforwarded(op.getarg(1)) if v1.getintbound().known_lt(v2.getintbound()): self.make_constant_int(op, 1) elif v1.getintbound().known_ge(v2.getintbound()) or v1 is v2: self.make_constant_int(op, 0) else: - self.emit_operation(op) + return op def optimize_INT_GT(self, op): v1 = self.getvalue(op.getarg(0)) @@ -255,17 +255,17 @@ elif v1.getintbound().known_gt(v2.getintbound()): self.make_constant_int(op, 0) else: - self.emit_operation(op) + return op def optimize_INT_GE(self, op): - v1 = self.getvalue(op.getarg(0)) - v2 = self.getvalue(op.getarg(1)) + v1 = self.getforwarded(op.getarg(0)) + v2 = self.getforwarded(op.getarg(1)) if v1.getintbound().known_ge(v2.getintbound()) or v1 is v2: self.make_constant_int(op, 1) elif v1.getintbound().known_lt(v2.getintbound()): self.make_constant_int(op, 0) else: - self.emit_operation(op) + return op def optimize_INT_EQ(self, op): v1 = self.getvalue(op.getarg(0)) @@ -326,13 +326,13 @@ v1 = self.getvalue(op) v1.getintbound().make_ge(IntLowerBound(0)) - def make_int_lt(self, box1, box2): - v1 = self.getvalue(box1) - v2 = self.getvalue(box2) + def make_int_lt(self, op1, op2): + v1 = self.getforwarded(op1) + v2 = self.getforwarded(op2) if v1.getintbound().make_lt(v2.getintbound()): - self.propagate_bounds_backward(box1) + self.propagate_bounds_backward(op1) if v2.getintbound().make_gt(v1.getintbound()): - self.propagate_bounds_backward(box2) + self.propagate_bounds_backward(op2) def make_int_le(self, box1, box2): v1 = self.getvalue(box1) @@ -349,17 +349,17 @@ self.make_int_le(box2, box1) def propagate_bounds_INT_LT(self, op): - r = self.getvalue(op) + r = self.getforwarded(op) if r.is_constant(): - if r.op.same_constant(CONST_1): + if r.same_constant(CONST_1): self.make_int_lt(op.getarg(0), op.getarg(1)) else: self.make_int_ge(op.getarg(0), op.getarg(1)) def propagate_bounds_INT_GT(self, op): - r = self.getvalue(op) + r = self.getforwarded(op) if r.is_constant(): - if r.op.same_constant(CONST_1): + if r.same_constant(CONST_1): self.make_int_gt(op.getarg(0), op.getarg(1)) else: self.make_int_le(op.getarg(0), op.getarg(1)) @@ -373,9 +373,9 @@ self.make_int_gt(op.getarg(0), op.getarg(1)) def propagate_bounds_INT_GE(self, op): - r = self.getvalue(op) + r = self.getforwarded(op) if r.is_constant(): - if r.op.same_constant(CONST_1): + if r.same_constant(CONST_1): self.make_int_ge(op.getarg(0), op.getarg(1)) else: self.make_int_lt(op.getarg(0), op.getarg(1)) diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -460,11 +460,14 @@ self._newoperations = [] def make_constant(self, op, constbox): + op = self.getforwarded(op) if not op.is_constant(): - self.getforwarded(op)._forwarded = constbox + op._forwarded = constbox - def make_constant_int(self, box, intvalue): - self.getvalue(box).make_constant(ConstInt(intvalue)) + def make_constant_int(self, op, intvalue): + op = self.getforwarded(op) + if not op.is_constant(): + op._forwarded = ConstInt(intvalue) def new_ptr_box(self): return self.cpu.ts.BoxRef() @@ -536,13 +539,6 @@ dispatch_opt(self, op) def emit_operation(self, op): - if op.returns_bool_result(): - xxxx - self.getvalue(op).is_bool_box = True - self._emit_operation(op) - - @specialize.argtype(0) - def _emit_operation(self, op): assert op.getopnum() not in opgroups.CALL_PURE assert not op._forwarded if isinstance(op, Const): diff --git a/pypy/jit/metainterp/optimizeopt/pure.py b/pypy/jit/metainterp/optimizeopt/pure.py --- a/pypy/jit/metainterp/optimizeopt/pure.py +++ b/pypy/jit/metainterp/optimizeopt/pure.py @@ -12,6 +12,7 @@ self.emitted_pure_operations = [] def optimize_default(self, op): + op = self.getforwarded(op) canfold = op.is_always_pure() if op.is_ovf(): self.posponedop = op @@ -24,7 +25,6 @@ else: nextop = None - newop = self.getforwarded(op) if canfold: for i in range(op.numargs()): if self.get_constant_op(op.getarg(i)) is None: @@ -38,20 +38,18 @@ return # did we do the exact same operation already? - oldop = self.pure_operations.get(newop) + oldop = self.pure_operations.get(op) if oldop is not None: self.replace(op, oldop) return else: - self.pure_operations.set(newop, op) + self.pure_operations.set(op, op) self.remember_emitting_pure(op) # otherwise, the operation remains - if newop.returns_bool_result(): - newop.setboolbox(True) if nextop: - self.emit_operation(nextop) - return newop + return nextop + return op def _new_optimize_call_pure(opnum): def optimize_CALL_PURE(self, op): diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -280,10 +280,10 @@ return self.optimize_guard(op, constbox, emit_operation=emit_operation) def optimize_GUARD_TRUE(self, op): - self.optimize_guard(op, CONST_1) + return self.optimize_guard(op, CONST_1) def optimize_GUARD_FALSE(self, op): - self.optimize_guard(op, CONST_0) + return self.optimize_guard(op, CONST_0) def optimize_RECORD_KNOWN_CLASS(self, op): value = self.getvalue(op.getarg(0)) @@ -380,8 +380,7 @@ self.emit_operation(op) def optimize_INT_IS_TRUE(self, op): - value = self.getforwarded(op.getarg(0)) - if value.getboolbox(): + if op.getarg(0).returns_bool_result(): self.replace(op, op.getarg(0)) return return self._optimize_nullness(op, op.getarg(0), True) diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -268,15 +268,15 @@ ops = """ [i0] i1 = int_lt(i0, 0) - guard_true(i1) [] + guard_true(i1) i2 = int_ge(i0, 0) - guard_false(i2) [] + guard_false(i2) jump(i0) """ expected = """ [i0] i1 = int_lt(i0, 0) - guard_true(i1) [] + guard_true(i1) jump(i0) """ self.optimize_loop(ops, expected) diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -12,7 +12,7 @@ def getintbound(self): return ConstantIntBound(self.getint()) - def getboolbox(self): + def getboolres(self): return False # for optimization class __extend__(Const): @@ -63,7 +63,7 @@ if cls.type == INT: # all the integers have bounds addattr(Mutable, 'intbound', imm_int_unbound) - addattr(Mutable, 'boolbox', False) + addattr(Mutable, 'boolres', False) elif cls.type == REF: addattr(Mutable, 'knownclass', None) # for tracking last guard and merging GUARD_VALUE with diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -650,8 +650,6 @@ opnum = cls.getopnum() if we_are_translated(): assert opnum >= 0 - elif opnum < 0: - return False # for tests return opboolresult[opnum] def _copy_extra_attrs(self, new): From noreply at buildbot.pypy.org Sat Oct 27 11:28:24 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 11:28:24 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: pass next test Message-ID: <20121027092824.624F31C01E7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58493:9961edc33b94 Date: 2012-10-27 11:25 +0200 http://bitbucket.org/pypy/pypy/changeset/9961edc33b94/ Log: pass next test diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -369,15 +369,14 @@ optimize_CALL_LOOPINVARIANT_f = _new_optimize_call_loopinvariant(rop.CALL_f) optimize_CALL_LOOPINVARIANT_v = _new_optimize_call_loopinvariant(rop.CALL_v) - def _optimize_nullness(self, op, box, expect_nonnull): - return op - value = self.getvalue(box) - if value.is_nonnull(): + def _optimize_nullness(self, op, arg, expect_nonnull): + value = self.getforwarded(arg) + if value.nonnull(): self.make_constant_int(op, expect_nonnull) - elif value.is_null(): + elif not value.nonnull(): self.make_constant_int(op, not expect_nonnull) else: - self.emit_operation(op) + return op def optimize_INT_IS_TRUE(self, op): if op.getarg(0).returns_bool_result(): From noreply at buildbot.pypy.org Sat Oct 27 11:28:25 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 11:28:25 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: hooray 11 tests passing Message-ID: <20121027092825.9001A1C01E7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58494:4db10840977e Date: 2012-10-27 11:28 +0200 http://bitbucket.org/pypy/pypy/changeset/4db10840977e/ Log: hooray 11 tests passing diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -238,18 +238,18 @@ return op def optimize_INT_GT(self, op): - v1 = self.getvalue(op.getarg(0)) - v2 = self.getvalue(op.getarg(1)) + v1 = self.getforwarded(op.getarg(0)) + v2 = self.getforwarded(op.getarg(1)) if v1.getintbound().known_gt(v2.getintbound()): self.make_constant_int(op, 1) elif v1.getintbound().known_le(v2.getintbound()) or v1 is v2: self.make_constant_int(op, 0) else: - self.emit_operation(op) + return op def optimize_INT_LE(self, op): - v1 = self.getvalue(op.getarg(0)) - v2 = self.getvalue(op.getarg(1)) + v1 = self.getforwarded(op.getarg(0)) + v2 = self.getforwarded(op.getarg(1)) if v1.getintbound().known_le(v2.getintbound()) or v1 is v2: self.make_constant_int(op, 1) elif v1.getintbound().known_gt(v2.getintbound()): @@ -365,9 +365,9 @@ self.make_int_le(op.getarg(0), op.getarg(1)) def propagate_bounds_INT_LE(self, op): - r = self.getvalue(op) + r = self.getforwarded(op) if r.is_constant(): - if r.op.same_constant(CONST_1): + if r.same_constant(CONST_1): self.make_int_le(op.getarg(0), op.getarg(1)) else: self.make_int_gt(op.getarg(0), op.getarg(1)) diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -285,15 +285,15 @@ ops = """ [i0] i1 = int_gt(i0, 0) - guard_true(i1) [] + guard_true(i1) i2 = int_le(i0, 0) - guard_false(i2) [] + guard_false(i2) jump(i0) """ expected = """ [i0] i1 = int_gt(i0, 0) - guard_true(i1) [] + guard_true(i1) jump(i0) """ self.optimize_loop(ops, expected) @@ -302,15 +302,15 @@ ops = """ [i0] i1 = int_gt(i0, 0) - guard_true(i1) [] + guard_true(i1) i2 = int_lt(0, i0) - guard_true(i2) [] + guard_true(i2) jump(i0) """ expected = """ [i0] i1 = int_gt(i0, 0) - guard_true(i1) [] + guard_true(i1) jump(i0) """ self.optimize_loop(ops, expected) @@ -319,15 +319,15 @@ ops = """ [i0] i1 = int_gt(i0, 0) - guard_true(i1) [] + guard_true(i1) i2 = int_ge(0, i0) - guard_false(i2) [] + guard_false(i2) jump(i0) """ expected = """ [i0] i1 = int_gt(i0, 0) - guard_true(i1) [] + guard_true(i1) jump(i0) """ self.optimize_loop(ops, expected) @@ -335,16 +335,16 @@ def test_remove_consecutive_guard_value_constfold(self): ops = """ [i0] - guard_value(i0, 0) [] + guard_value(i0, 0) i1 = int_add(i0, 1) - guard_value(i1, 1) [] + guard_value(i1, 1) i2 = int_add(i1, 2) escape(i2) jump(i0) """ expected = """ [i0] - guard_value(i0, 0) [] + guard_value(i0, 0) escape(3) jump(0) """ @@ -353,7 +353,7 @@ def test_remove_guard_value_if_constant(self): ops = """ [p1] - guard_value(p1, ConstPtr(myptr)) [] + guard_value(p1, ConstPtr(myptr)) jump(ConstPtr(myptr)) """ expected = """ From noreply at buildbot.pypy.org Sat Oct 27 12:05:37 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 12:05:37 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: fix fix fix Message-ID: <20121027100537.9CE801C01E7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58495:04f3b0fce078 Date: 2012-10-27 11:43 +0200 http://bitbucket.org/pypy/pypy/changeset/04f3b0fce078/ Log: fix fix fix diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -52,7 +52,7 @@ arg1=op.getarg(0)) oldop = self.get_pure_result(key_op) if oldop is not None and oldop.getdescr() is op.getdescr(): - self.replace(op, oldop) + self.optimizer.replace(op, oldop) return True oldopnum = opboolinvers[opboolreflex[op.getopnum()]] @@ -76,16 +76,16 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) if v1.is_null(): - self.replace(op, op.getarg(1)) + self.optimizer.replace(op, op.getarg(1)) elif v2.is_null(): - self.replace(op, op.getarg(0)) + self.optimizer.replace(op, op.getarg(0)) else: self.emit_operation(op) def optimize_INT_SUB(self, op): v2 = self.getforwarded(op.getarg(1)) if v2.is_constant() and v2.getint() == 0: - self.replace(op, op.getarg(0)) + self.optimizer.replace(op, op.getarg(0)) else: # Synthesize the reverse ops for optimize_default to reuse self.pure(op.getarg(0), rop.INT_ADD, op.getarg(1), op) @@ -101,9 +101,9 @@ # If one side of the op is 0 the result is the other side. if v1.is_constant() and v1.getint() == 0: - self.replace(op, arg2) + self.optimizer.replace(op, arg2) elif v2.is_constant() and v2.getint() == 0: - self.replace(op, arg1) + self.optimizer.replace(op, arg1) else: # Synthesize the reverse op for optimize_default to reuse self.pure(op.getarg(0), rop.INT_SUB, op, op.getarg(1)) @@ -172,11 +172,11 @@ if v1.is_constant(): if v1.op.getfloat() == 1.0: - self.replace(op, rhs) + self.optimizer.replace(op, rhs) return elif v1.op.getfloat() == -1.0: new_op = create_resop_1(rop.FLOAT_NEG, 0.0, rhs) - self.replace(op, new_op) + self.optimizer.replace(op, new_op) self.emit_operation(new_op) return self.emit_operation(op) @@ -354,7 +354,7 @@ resop = self.loop_invariant_results.get(key, None) if resop is not None: - self.replace(op, resop) + self.optimizer.replace(op, resop) self.last_emitted_operation = REMOVED return # change the op to be a normal call, from the backend's point of view @@ -380,7 +380,7 @@ def optimize_INT_IS_TRUE(self, op): if op.getarg(0).returns_bool_result(): - self.replace(op, op.getarg(0)) + self.optimizer.replace(op, op.getarg(0)) return return self._optimize_nullness(op, op.getarg(0), True) diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -366,13 +366,13 @@ def test_ooisnull_oononnull_1(self): ops = """ [p0] - guard_class(p0, ConstClass(node_vtable)) [] - guard_nonnull(p0) [] + guard_class(p0, ConstClass(node_vtable)) + guard_nonnull(p0) jump(p0) """ expected = """ [p0] - guard_class(p0, ConstClass(node_vtable)) [] + guard_class(p0, ConstClass(node_vtable)) jump(p0) """ self.optimize_loop(ops, expected) From noreply at buildbot.pypy.org Sat Oct 27 12:05:39 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 12:05:39 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: remove a test that was specializing on constant - not being run for years Message-ID: <20121027100539.0560F1C01E7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58496:3bd494f17512 Date: 2012-10-27 11:43 +0200 http://bitbucket.org/pypy/pypy/changeset/3bd494f17512/ Log: remove a test that was specializing on constant - not being run for years diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -350,19 +350,6 @@ """ self.optimize_loop(ops, expected) - def test_remove_guard_value_if_constant(self): - ops = """ - [p1] - guard_value(p1, ConstPtr(myptr)) - jump(ConstPtr(myptr)) - """ - expected = """ - [] - jump() - """ - py.test.skip("XXX") - self.optimize_loop(ops, 'Constant(myptr)', expected) - def test_ooisnull_oononnull_1(self): ops = """ [p0] From noreply at buildbot.pypy.org Sat Oct 27 12:05:40 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 12:05:40 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: figure out isnull/isnonnull Message-ID: <20121027100540.226801C01E7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58497:eacd35d4d91a Date: 2012-10-27 11:54 +0200 http://bitbucket.org/pypy/pypy/changeset/eacd35d4d91a/ Log: figure out isnull/isnonnull diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -212,13 +212,6 @@ def postprocess_GUARD_FALSE(self, op): self.postprocess_guard(op, CONST_0) - def postprocess_GUARD_NO_OVERFLOW(self, op): - pass # to be killed - - def postprocess_default(self, op): - if op.is_guard(): - xxx - def optimize_GUARD_ISNULL(self, op): value = self.getvalue(op.getarg(0)) if value.is_null(): @@ -229,14 +222,14 @@ value.make_constant(self.optimizer.cpu.ts.CONST_NULL) def optimize_GUARD_NONNULL(self, op): - value = self.getvalue(op.getarg(0)) + value = self.getforwarded(op.getarg(0)) if value.is_nonnull(): return elif value.is_null(): raise InvalidLoop('A GUARD_NONNULL was proven to always fail') - pos = self.optimizer.get_pos() - self.emit_operation(op) - value.make_nonnull(op, pos) + value.setknownnonnull(True) + value.setlastguardpos(self.optimizer.getpos()) + return op def optimize_GUARD_VALUE(self, op): value = self.getforwarded(op.getarg(0)) @@ -371,9 +364,9 @@ def _optimize_nullness(self, op, arg, expect_nonnull): value = self.getforwarded(arg) - if value.nonnull(): + if value.is_nonnull(): self.make_constant_int(op, expect_nonnull) - elif not value.nonnull(): + elif value.is_null(): self.make_constant_int(op, not expect_nonnull) else: return op diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -22,6 +22,12 @@ def force(self, _): return self + def is_nonnull(self): + return self.nonnull() + + def is_null(self): + return not self.nonnull() + def create_mutable_subclasses(): def addattr(cls, attr, default_value=None): cls.attributes_to_copy.append('_' + attr) @@ -40,6 +46,18 @@ setattr(new, attr, getattr(self, attr)) cls._copy_extra_attrs = _copy_extra_attrs + def int_is_null(self): + return False + + def int_is_nonnull(self): + xxx + + def ref_is_null(self): + return False + + def ref_is_nonnull(self): + return self.getknownclass() is not None or self.getknownnonnull() + imm_int_unbound = ImmutableIntUnbounded() for i, cls in enumerate(opclasses): if cls is None: @@ -64,8 +82,13 @@ # all the integers have bounds addattr(Mutable, 'intbound', imm_int_unbound) addattr(Mutable, 'boolres', False) + Mutable.is_nonnull = int_is_nonnull + Mutable.is_null = int_is_null elif cls.type == REF: addattr(Mutable, 'knownclass', None) + addattr(Mutable, 'knownnonnull', False) + Mutable.is_nonnull = ref_is_nonnull + Mutable.is_null = ref_is_null # for tracking last guard and merging GUARD_VALUE with # GUARD_NONNULL etc addattr(Mutable, 'lastguardpos', -1) From noreply at buildbot.pypy.org Sat Oct 27 12:05:41 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 12:05:41 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: fix hashing Message-ID: <20121027100541.4452E1C01E7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58498:026b0ffa02fa Date: 2012-10-27 11:57 +0200 http://bitbucket.org/pypy/pypy/changeset/026b0ffa02fa/ Log: fix hashing diff --git a/pypy/jit/metainterp/optimizeopt/pure.py b/pypy/jit/metainterp/optimizeopt/pure.py --- a/pypy/jit/metainterp/optimizeopt/pure.py +++ b/pypy/jit/metainterp/optimizeopt/pure.py @@ -12,6 +12,7 @@ self.emitted_pure_operations = [] def optimize_default(self, op): + orig_op = op op = self.getforwarded(op) canfold = op.is_always_pure() if op.is_ovf(): @@ -38,12 +39,12 @@ return # did we do the exact same operation already? - oldop = self.pure_operations.get(op) + oldop = self.pure_operations.get(orig_op) if oldop is not None: - self.replace(op, oldop) + self.optimizer.replace(op, oldop) return else: - self.pure_operations.set(op, op) + self.pure_operations.set(orig_op, op) self.remember_emitting_pure(op) # otherwise, the operation remains diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -368,15 +368,15 @@ ops = """ [i0] i1 = int_is_true(i0) - guard_true(i1) [] + guard_true(i1) i2 = int_is_true(i0) - guard_true(i2) [] + guard_true(i2) jump(i0) """ expected = """ [i0] i1 = int_is_true(i0) - guard_true(i1) [] + guard_true(i1) jump(i0) """ self.optimize_loop(ops, expected) diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -6,7 +6,7 @@ from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable, rop,\ INT, REF, ConstInt, Const from pypy.jit.metainterp.optimizeopt.intutils import ImmutableIntUnbounded,\ - ConstantIntBound + ConstantIntBound, IntBound class __extend__(ConstInt): def getintbound(self): @@ -50,7 +50,13 @@ return False def int_is_nonnull(self): - xxx + intbound = self.getintbound() + if intbound is not None: + if intbound.known_gt(IntBound(0, 0)) or \ + intbound.known_lt(IntBound(0, 0)): + return True + return False + return False def ref_is_null(self): return False From noreply at buildbot.pypy.org Sat Oct 27 12:05:42 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 12:05:42 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: oops Message-ID: <20121027100542.7B6511C01E7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58499:66cc988427fe Date: 2012-10-27 11:59 +0200 http://bitbucket.org/pypy/pypy/changeset/66cc988427fe/ Log: oops diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -378,7 +378,7 @@ return self._optimize_nullness(op, op.getarg(0), True) def optimize_INT_IS_ZERO(self, op): - self._optimize_nullness(op, op.getarg(0), False) + return self._optimize_nullness(op, op.getarg(0), False) def _optimize_oois_ooisnot(self, op, expect_isnot, instance): value0 = self.getvalue(op.getarg(0)) diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -403,15 +403,15 @@ ops = """ [i0] i1 = int_is_zero(i0) - guard_true(i1) [] + guard_true(i1) i2 = int_is_true(i0) - guard_false(i2) [] + guard_false(i2) jump(i0) """ expected = """ [i0] i1 = int_is_zero(i0) - guard_true(i1) [] + guard_true(i1) jump(0) """ self.optimize_loop(ops, expected) @@ -419,13 +419,13 @@ def test_ooisnull_oononnull_2(self): ops = """ [p0] - guard_nonnull(p0) [] - guard_nonnull(p0) [] + guard_nonnull(p0) + guard_nonnull(p0) jump(p0) """ expected = """ [p0] - guard_nonnull(p0) [] + guard_nonnull(p0) jump(p0) """ self.optimize_loop(ops, expected) From noreply at buildbot.pypy.org Sat Oct 27 12:05:44 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 12:05:44 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: stop just short of starting to implement virtuals Message-ID: <20121027100544.46A1C1C01E7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58500:b3ef852cc2fa Date: 2012-10-27 12:05 +0200 http://bitbucket.org/pypy/pypy/changeset/b3ef852cc2fa/ Log: stop just short of starting to implement virtuals diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -213,13 +213,16 @@ self.postprocess_guard(op, CONST_0) def optimize_GUARD_ISNULL(self, op): - value = self.getvalue(op.getarg(0)) + value = self.getforwarded(op.getarg(0)) if value.is_null(): return elif value.is_nonnull(): raise InvalidLoop('A GUARD_ISNULL was proven to always fail') - self.emit_operation(op) - value.make_constant(self.optimizer.cpu.ts.CONST_NULL) + return op + + def postprocess_GUARD_ISNULL(self, op): + self.optimizer.make_constant(op.getarg(0), + self.optimizer.cpu.ts.CONST_NULL) def optimize_GUARD_NONNULL(self, op): value = self.getforwarded(op.getarg(0)) @@ -228,7 +231,7 @@ elif value.is_null(): raise InvalidLoop('A GUARD_NONNULL was proven to always fail') value.setknownnonnull(True) - value.setlastguardpos(self.optimizer.getpos()) + value.setlastguardpos(self.optimizer.get_pos()) return op def optimize_GUARD_VALUE(self, op): diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -433,13 +433,13 @@ def test_ooisnull_on_null_ptr_1(self): ops = """ [p0, p1] - guard_isnull(p0) [] - guard_isnull(p0) [] + guard_isnull(p0) + guard_isnull(p0) jump(p1, p1) """ expected = """ [p0, p1] - guard_isnull(p0) [] + guard_isnull(p0) jump(p1, p1) """ self.optimize_loop(ops, expected) @@ -449,14 +449,14 @@ [p0] pv = new_with_vtable(ConstClass(node_vtable)) setfield_gc(pv, p0, descr=valuedescr) - guard_nonnull(p0) [] + guard_nonnull(p0) p1 = getfield_gc_r(pv, descr=valuedescr) - guard_nonnull(p1) [] + guard_nonnull(p1) jump(p0) """ expected = """ [p0] - guard_nonnull(p0) [] + guard_nonnull(p0) jump(p0) """ self.optimize_loop(ops, expected) diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py --- a/pypy/jit/metainterp/optimizeopt/virtualize.py +++ b/pypy/jit/metainterp/optimizeopt/virtualize.py @@ -453,14 +453,16 @@ optimize_GETFIELD_GC_PURE_f = optimize_GETFIELD_GC_i def optimize_SETFIELD_GC(self, op): - value = self.getvalue(op.getarg(0)) + value = self.getforwarded(op.getarg(0)) if value.is_virtual(): - fieldvalue = self.getvalue(op.getarg(1)) + fieldvalue = self.getforwarded(op.getarg(1)) + xxx value.setfield(op.getdescr(), fieldvalue) else: + xxx value.ensure_nonnull() - self.emit_operation(op) + return op def optimize_NEW_WITH_VTABLE(self, op): value = self.getforwarded(op) diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -75,11 +75,17 @@ if cls.getopnum() in (rop.NEW_WITH_VTABLE, rop.NEW): def force(self, optimizer): - optimizer.emit_operation(self) + if not self._isforced: + optimizer.emit_operation(self) + self._isforced = True return self + def is_virtual(self): + return not self._isforced else: def force(self, _): return self + def is_virtual(self): + return False if cls.is_guard() or cls.getopnum() == rop.FINISH: addattr(Mutable, 'failargs') if cls.is_guard(): @@ -95,6 +101,8 @@ addattr(Mutable, 'knownnonnull', False) Mutable.is_nonnull = ref_is_nonnull Mutable.is_null = ref_is_null + if cls.getopnum() in (rop.NEW_WITH_VTABLE, rop.NEW): + addattr(Mutable, 'isforced', False) # for tracking last guard and merging GUARD_VALUE with # GUARD_NONNULL etc addattr(Mutable, 'lastguardpos', -1) From noreply at buildbot.pypy.org Sat Oct 27 17:15:28 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 17:15:28 +0200 (CEST) Subject: [pypy-commit] pypy no-failargs: Another branch off result-in-resops: remove 'failargs' from the ResOperations. Message-ID: <20121027151528.D9FC21C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58501:15c4240c5c4a Date: 2012-10-27 14:34 +0200 http://bitbucket.org/pypy/pypy/changeset/15c4240c5c4a/ Log: Another branch off result-in-resops: remove 'failargs' from the ResOperations. diff --git a/pypy/jit/backend/llsupport/jitframe.py b/pypy/jit/backend/llsupport/jitframe.py --- a/pypy/jit/backend/llsupport/jitframe.py +++ b/pypy/jit/backend/llsupport/jitframe.py @@ -1,18 +1,17 @@ +from pypy.rpython.lltypesystem import lltype, llmemory -_LONGLONGARRAY = lltype.GcArray(lltype.SignedLongLong) - JITFRAME = lltype.GcStruct( 'JITFRAME', # Once the execute_token() returns, the field 'jf_descr' stores the # descr of the last executed operation (either a GUARD, or FINISH). + # This field is also set immediately before doing CALL_MAY_FORCE. ('jf_descr', llmemory.GCREF), # For the front-end: a GCREF for the savedata ('jf_savedata', llmemory.GCREF), # XXX - ('jf_nongcvalues', lltype.Ptr(_LONGLONGARRAY)), - ('jf_gcvalues', lltype.Array(llmemory.GCREF))) + ('jf_values', lltype.Array(llmemory.Address))) JITFRAMEPTR = lltype.Ptr(JITFRAME) From noreply at buildbot.pypy.org Sat Oct 27 17:15:30 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 17:15:30 +0200 (CEST) Subject: [pypy-commit] pypy no-failargs: in-progress Message-ID: <20121027151530.6B0111C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58502:432e12af25ca Date: 2012-10-27 15:44 +0200 http://bitbucket.org/pypy/pypy/changeset/432e12af25ca/ Log: in-progress diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -3,7 +3,7 @@ from pypy.jit.backend.llgraph import support from pypy.jit.metainterp.history import AbstractDescr from pypy.jit.metainterp.resoperation import Const, getkind -from pypy.jit.metainterp.resoperation import INT, REF, FLOAT, VOID +from pypy.jit.metainterp.resoperation import INT, REF, FLOAT, VOID, FLOAT_SIZE from pypy.jit.metainterp.resoperation import rop from pypy.jit.codewriter import longlong, heaptracker from pypy.jit.codewriter.effectinfo import EffectInfo @@ -47,8 +47,6 @@ map(mapping, op.getarglist()), mapping(op.result), newdescr) - if op.getfailargs() is not None: - newop.setfailargs(map(mapping, op.getfailargs())) self.operations.append(newop) class WeakrefDescr(AbstractDescr): @@ -56,15 +54,13 @@ self.realdescrref = weakref.ref(realdescr) class GuardFailed(Exception): - def __init__(self, failargs, descr): - self.failargs = failargs + def __init__(self, descr): self.descr = descr class ExecutionFinished(Exception): - def __init__(self, descr, arg, failargs): + def __init__(self, descr, arg): self.descr = descr self.arg = arg - self.failargs = failargs class Jump(Exception): def __init__(self, descr, args): @@ -261,22 +257,17 @@ assert False except ExecutionFinished, e: frame.finish_value = e.arg - frame.latest_values = e.failargs frame.latest_descr = e.descr frame._execution_finished_normally = e.descr.fast_path_done return frame except GuardFailed, e: - frame.latest_values = e.failargs frame.latest_descr = e.descr return frame - def get_latest_value_int(self, frame, index): - return frame.latest_values[index] - get_latest_value_float = get_latest_value_int - get_latest_value_ref = get_latest_value_int - - def get_latest_value_count(self, frame): - return len(frame.latest_values) + def get_frame_value_int(self, frame, index): + return frame.framecontent[index] + get_frame_value_float = get_frame_value_int + get_frame_value_ref = get_frame_value_int def get_latest_descr(self, frame): return frame.latest_descr @@ -635,17 +626,26 @@ def __init__(self, cpu, argboxes, args): self.env = {} + self.framecontent = {} self.cpu = cpu assert len(argboxes) == len(args) for box, arg in zip(argboxes, args): - self.env[box] = arg + self.setenv(box, arg) self.overflow_flag = False self.last_exception = None + def setenv(self, box, arg): + self.env[box] = arg + self.framecontent[box.getvarindex()] = arg + if box.type == FLOAT and FLOAT_SIZE > 1: + self.framecontent[box.getvarindex() + 1] = '2nd float word' + def lookup(self, arg): if isinstance(arg, Const): return arg.value - return self.env[arg] + result = self.env[arg] + assert result is self.framecontent[arg.getvarindex()] + return result def execute(self, lltrace): self.lltrace = lltrace @@ -670,9 +670,8 @@ if hasattr(gf.descr, '_llgraph_bridge'): i = 0 self.lltrace = gf.descr._llgraph_bridge - newargs = [self.env[arg] for arg in - self.current_op.getfailargs() if arg is not None] - self.do_renaming(self.lltrace.inputargs, newargs) + newvals = [self.env[arg] for arg in self.lltrace.inputargs] + self.do_renaming(self.lltrace.inputargs, newvals) continue raise if op.type == INT: @@ -687,43 +686,27 @@ else: assert op.type == VOID assert resval is None - self.env[op] = resval + if op.type != VOID: + self.setenv(op, resval) i += 1 - def _getfailargs(self, op=None, skip=None): - if op is None: - op = self.current_op - r = [] - for arg in op.getfailargs(): - if arg is None: - r.append(None) - elif arg is skip: - r.append(_example_res[skip.type]) - else: - r.append(self.env[arg]) - return r - - def do_renaming(self, newargs, oldargs): - assert len(newargs) == len(oldargs) - newenv = {} - for new, old in zip(newargs, oldargs): - newenv[new] = old - self.env = newenv + def do_renaming(self, newargs, newvalues): + assert len(newargs) == len(newvalues) + self.env = {} + self.framecontent = {} + for new, newvalue in zip(newargs, newvalues): + self.setenv(new, newvalue) # ----------------------------------------------------- def fail_guard(self, descr): - raise GuardFailed(self._getfailargs(), descr) + raise GuardFailed(descr) def execute_force_spill(self, _, arg): pass def execute_finish(self, descr, arg=None): - if self.current_op.getfailargs() is not None: - failargs = self._getfailargs() - else: - failargs = None # compatibility - raise ExecutionFinished(descr, arg, failargs) + raise ExecutionFinished(descr, arg) def execute_label(self, descr, *args): argboxes = self.current_op.getarglist() @@ -864,6 +847,7 @@ call_op = self.lltrace.operations[self.current_index] guard_op = self.lltrace.operations[self.current_index + 1] assert guard_op.getopnum() == rop.GUARD_NOT_FORCED + XXX self.latest_values = self._getfailargs(guard_op, skip=call_op) self.latest_descr = _getdescr(guard_op) res = self.execute_call(calldescr, func, *args) @@ -890,6 +874,7 @@ call_op = self.lltrace.operations[self.current_index] guard_op = self.lltrace.operations[self.current_index + 1] assert guard_op.getopnum() == rop.GUARD_NOT_FORCED + XXX self.latest_values = self._getfailargs(guard_op, skip=call_op) self.latest_descr = _getdescr(guard_op) # diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -106,7 +106,7 @@ Execute the generated code referenced by the looptoken. It runs it until either a guard fails, or until we reach the FINISH operation. It returns the "jit frame" object - which should be inspected with the get_latest_xyz() methods. + which should be inspected with the get_frame_value_xyz() methods. """ argtypes = [lltype.typeOf(x) for x in args] execute = self.make_execute_token(*argtypes) @@ -123,24 +123,19 @@ jitframe.""" raise NotImplementedError - def get_latest_value_int(self, jitframe, index): - """Returns the value for the index'th 'fail_args' of the - last executed operation. Returns an int.""" + def get_frame_value_int(self, jitframe, index): + """Returns the value for the index'th value in the frame. + Returns an int.""" raise NotImplementedError - def get_latest_value_float(self, jitframe, index): - """Returns the value for the index'th 'fail_args' of the - last executed operation. Returns a FLOATSTORAGE.""" + def get_frame_value_float(self, jitframe, index): + """Returns the value for the index'th value in the frame. + Returns a FLOATSTORAGE.""" raise NotImplementedError - def get_latest_value_ref(self, jitframe, index): - """Returns the value for the index'th 'fail_args' of the - last executed operation. Returns a GCREF.""" - raise NotImplementedError - - def get_latest_value_count(self, jitframe): - """Return how many values are ready to be returned by - get_latest_value_xxx().""" + def get_frame_value_ref(self, jitframe, index): + """Returns the value for the index'th value in the frame. + Returns a GCREF.""" raise NotImplementedError def get_finish_value_int(self, jitframe): diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -95,7 +95,7 @@ avoid_instances = False - def parse(self, s, namespace): + def parse(self, s, namespace, invent_varindex=True): if namespace is None: namespace = {} else: @@ -112,15 +112,28 @@ namespace['faildescr3'] = BasicFailDescr(3) if 'faildescr4' not in namespace: namespace['faildescr4'] = BasicFailDescr(4) - loop = oparser.parse(s, namespace=namespace, guards_with_failargs=True) + loop = oparser.parse(s, namespace=namespace, mutable=True, + vars=getattr(self, 'original_vars', {})) + self.original_vars = loop.original_vars return loop.inputargs, loop.operations, JitCellToken() + def get_frame_value(self, frame, varname): + op = self.original_vars[varname] + index = op.getvarindex() + if varname.startswith('i'): + return self.cpu.get_frame_value_int(frame, index) + if varname.startswith('p'): + return self.cpu.get_frame_value_ref(frame, index) + if varname.startswith('f'): + return self.cpu.get_frame_value_float(frame, index) + raise ValueError(varname) + def test_compile_linear_loop(self): faildescr = BasicFailDescr(1) inputargs, ops, token = self.parse(""" [i0] i1 = int_add(i0, 1) - finish(i1, descr=faildescr) [] + finish(i1, descr=faildescr) """, namespace=locals()) self.cpu.compile_loop(inputargs, ops, token) frame = self.cpu.execute_token(token, 2) @@ -133,7 +146,7 @@ inputargs, ops, token = self.parse(""" [f0] f1 = float_add(f0, 1.) - finish(f1, descr=faildescr) [] + finish(f1, descr=faildescr) """, namespace=locals()) self.cpu.compile_loop(inputargs, ops, token) frame = self.cpu.execute_token(token, longlong.getfloatstorage(2.8)) @@ -149,16 +162,16 @@ label(i0, descr=targettoken) i1 = int_add(i0, 1) i2 = int_le(i1, 9) - guard_true(i2, descr=faildescr) [i1] + guard_true(i2, descr=faildescr) jump(i1, descr=targettoken) ''', namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 2) assert self.cpu.get_latest_descr(frame).identifier == 2 - res = self.cpu.get_latest_value_int(frame, 0) + res = self.get_frame_value(frame, 'i1') assert res == 10 - def test_compile_with_holes_in_fail_args(self): + def test_compile_loop_2(self): faildescr3 = BasicFailDescr(3) targettoken = TargetToken() inputargs, operations, looptoken = self.parse(""" @@ -167,14 +180,14 @@ label(i0, descr=targettoken) i1 = int_add(i0, 1) i2 = int_le(i1, 9) - guard_true(i2, descr=faildescr3) [None, None, i1, None] + guard_true(i2, descr=faildescr3) jump(i1, descr=targettoken) """, namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 44) assert self.cpu.get_latest_descr(frame).identifier == 3 - res = self.cpu.get_latest_value_int(frame, 2) + res = self.get_frame_value(frame, 'i1') assert res == 10 def test_backends_dont_keep_loops_alive(self): @@ -185,7 +198,7 @@ label(i0, descr=targettoken) i1 = int_add(i0, 1) i2 = int_le(i1, 9) - guard_true(i2, descr=faildescr) [i1] + guard_true(i2, descr=faildescr) jump(i1, descr=targettoken) """, namespace={'targettoken': TargetToken()}) i1 = inputargs[0] @@ -210,17 +223,17 @@ label(i0, descr=targettoken) i1 = int_add(i0, 1) i2 = int_le(i1, 9) - guard_true(i2, descr=faildescr) [i1] + guard_true(i2, descr=faildescr) jump(i1, descr=targettoken) """, namespace={'faildescr': faildescr4, 'targettoken': targettoken}) self.cpu.compile_loop(inputargs, operations, looptoken) inputargs, bridge_ops, _ = self.parse(""" - [i1b] - i3 = int_le(i1b, 19) - guard_true(i3, descr=faildescr5) [i1b] - jump(i1b, descr=targettoken) + [i1] + i3 = int_le(i1, 19) + guard_true(i3, descr=faildescr5) + jump(i1, descr=targettoken) """, namespace={'faildescr5': BasicFailDescr(5), 'targettoken': targettoken}) self.cpu.compile_bridge(faildescr4, diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -4,7 +4,7 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable, rop,\ - INT, REF, ConstInt, Const + VOID, INT, REF, ConstInt, Const from pypy.jit.metainterp.optimizeopt.intutils import ImmutableIntUnbounded,\ ConstantIntBound @@ -56,8 +56,10 @@ else: def force(self, _): return self - if cls.is_guard() or cls.getopnum() == rop.FINISH: - addattr(Mutable, 'failargs') + if cls.type != VOID: + addattr(Mutable, 'varindex', -1) + #if cls.type == REF: + # addattr(Mutable, 'varrange', sys.maxint // 2) if cls.is_guard(): addattr(Mutable, 'descr') # mutable guards have descrs if cls.type == INT: diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -12,6 +12,7 @@ """ +import sys from pypy.jit.codewriter import longlong from pypy.jit.codewriter import heaptracker from pypy.rpython.lltypesystem import lltype, llmemory, rffi @@ -28,6 +29,12 @@ VOID = 'v' HOLE = '_' +if sys.maxint == 2**31 - 1: + FLOAT_SIZE = 2 # a FLOAT variable uses two INT or REF positions +else: + FLOAT_SIZE = 1 # FLOAT is the same size as INT and REF + + def create_resop_dispatch(opnum, result, args, descr=None, mutable=False): """ NOT_RPYTHON this is for tests only! """ @@ -555,10 +562,15 @@ t = 'i' elif self.type == FLOAT: t = 'f' + elif self.type == REF: + t = 'p' else: - t = 'p' - self._str = '%s%d' % (t, AbstractResOp._counter) - AbstractResOp._counter += 1 + t = '?' + if not hasattr(self, '_varindex'): + self._str = '%s%d' % (t, AbstractResOp._counter) + AbstractResOp._counter += 1 + else: + self._str = '%s%s' % (t.upper(), self._varindex) return self._str def repr(self, graytext=False): diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -20,22 +20,17 @@ use_mock_model = False def __init__(self, input, cpu, namespace, type_system, - invent_fail_descr=True, results=None, - guards_with_failargs=False): + invent_fail_descr=True, results=None, mutable=False, vars={}): self.input = input - self.vars = {} + self.vars = vars.copy() self.cpu = cpu self._consts = namespace self.type_system = type_system - self.guards_with_failargs = guards_with_failargs - if namespace is not None: - self._cache = namespace.setdefault('_CACHE_', {}) - else: - self._cache = {} self.invent_fail_descr = invent_fail_descr self.model = get_model(self.use_mock_model) self.original_jitcell_token = self.model.JitCellToken() self.results = results + self.mutable = mutable def get_const(self, name, typ): if self._consts is None: @@ -70,24 +65,6 @@ return tt raise - def box_for_var(self, elem): - try: - return self._cache[self.type_system, elem] - except KeyError: - pass - if elem[0] in 'ifp': - if elem[0] == 'p': - p = 'r' - else: - p = elem[0] - opnum = getattr(rop, 'INPUT_' + p) - box = create_resop_0(opnum, example_for_opnum(opnum)) - else: - raise ParseError("Unknown variable type: %s" % elem) - self._cache[self.type_system, elem] = box - box._str = elem - return box - def parse_header_line(self, line): elements = line.split(",") vars = [] @@ -97,9 +74,26 @@ return vars def newvar(self, elem): - box = self.box_for_var(elem) - self.vars[elem] = box - return box + if elem not in self.vars: + if elem[0] in 'ifp': + if elem[0] == 'p': + p = 'r' + else: + p = elem[0] + opnum = getattr(rop, 'INPUT_' + p) + box = create_resop_0(opnum, example_for_opnum(opnum), + mutable=self.mutable) + else: + raise ParseError("Unknown variable type: %s" % elem) + self.setstr(box, elem) + self.vars[elem] = box + return self.vars[elem] + + def setstr(self, op, text): + if hasattr(op, 'setvarindex') and text[1:].isdigit(): + op.setvarindex(int(text[1:])) + else: + op._res = text def is_float(self, arg): try: @@ -185,44 +179,15 @@ endnum = line.rfind(')') if endnum == -1: raise ParseError("invalid line: %s" % line) + if line.find('[', endnum) >= 0: + raise ParseError("fail_args should be removed: %s" % line) args, descr = self.parse_args(opname, line[num + 1:endnum]) - fail_args = None - if rop._GUARD_FIRST <= opnum <= rop._GUARD_LAST or opnum == rop.FINISH: - i = line.find('[', endnum) + 1 - j = line.find(']', i) - if i <= 0 or j <= 0: - if self.guards_with_failargs and opnum != rop.FINISH: - raise ParseError("missing fail_args for guard operation") - fail_args = None - else: - if not self.guards_with_failargs: - raise ParseError("fail_args should be NULL") - fail_args = [] - if i < j: - for arg in line[i:j].split(','): - arg = arg.strip() - if arg == 'None': - fail_arg = None - else: - try: - fail_arg = self.vars[arg] - except KeyError: - raise ParseError( - "Unknown var in fail_args: %s" % arg) - fail_args.append(fail_arg) - else: - if opnum == rop.FINISH: - if descr is None and self.invent_fail_descr: - descr = self.invent_fail_descr(self.model, fail_args) - elif opnum == rop.JUMP: - if descr is None and self.invent_fail_descr: - descr = self.original_jitcell_token - - return opnum, args, descr, fail_args + if descr is None and opnum == rop.JUMP: + descr = self.original_jitcell_token + return opnum, args, descr def create_op(self, opnum, result, args, descr): - r = create_resop_dispatch(opnum, result, args, - mutable=self.guards_with_failargs) + r = create_resop_dispatch(opnum, result, args, mutable=self.mutable) if descr is not None: r.setdescr(descr) return r @@ -231,7 +196,7 @@ res, op = line.split("=", 1) res = res.strip() op = op.strip() - opnum, args, descr, fail_args = self.parse_op(op) + opnum, args, descr = self.parse_op(op) if res in self.vars: raise ParseError("Double assign to var %s in line: %s" % (res, line)) if self.results is None: @@ -239,16 +204,13 @@ else: result = self.results[num] opres = self.create_op(opnum, result, args, descr) + self.setstr(opres, res) self.vars[res] = opres - if fail_args is not None: - opres.setfailargs(fail_args) return opres def parse_op_no_result(self, line): - opnum, args, descr, fail_args = self.parse_op(line) + opnum, args, descr = self.parse_op(line) res = self.create_op(opnum, None, args, descr) - if fail_args is not None: - res.setfailargs(fail_args) return res def parse_next_op(self, line, num): @@ -287,6 +249,7 @@ loop.operations = ops loop.inputargs = inpargs loop.last_offset = last_offset + loop.original_vars = self.vars return loop def parse_ops(self, indent, lines, start): @@ -344,11 +307,11 @@ def parse(input, cpu=None, namespace=DEFAULT, type_system='lltype', invent_fail_descr=True, OpParser=OpParser, - results=None, guards_with_failargs=False): + results=None, mutable=False, vars={}): if namespace is DEFAULT: namespace = {} return OpParser(input, cpu, namespace, type_system, - invent_fail_descr, results, guards_with_failargs).parse() + invent_fail_descr, results, mutable, vars).parse() def pure_parse(*args, **kwds): kwds['invent_fail_descr'] = False From noreply at buildbot.pypy.org Sat Oct 27 17:15:31 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 17:15:31 +0200 (CEST) Subject: [pypy-commit] pypy no-failargs: fix fix fix Message-ID: <20121027151531.A64A51C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58503:82348e42f0e3 Date: 2012-10-27 16:06 +0200 http://bitbucket.org/pypy/pypy/changeset/82348e42f0e3/ Log: fix fix fix diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -635,6 +635,7 @@ self.last_exception = None def setenv(self, box, arg): + assert box.getvarindex() >= 0 self.env[box] = arg self.framecontent[box.getvarindex()] = arg if box.type == FLOAT and FLOAT_SIZE > 1: @@ -644,7 +645,7 @@ if isinstance(arg, Const): return arg.value result = self.env[arg] - assert result is self.framecontent[arg.getvarindex()] + assert result == self.framecontent[arg.getvarindex()] return result def execute(self, lltrace): diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -5,7 +5,8 @@ JitCellToken, TargetToken) from pypy.jit.metainterp.resoperation import rop, create_resop_dispatch,\ create_resop, ConstInt, ConstPtr, ConstFloat, create_resop_2,\ - create_resop_1, create_resop_0, INT, REF, FLOAT, example_for_opnum + create_resop_1, create_resop_0, INT, REF, FLOAT, example_for_opnum,\ + AbstractResOp from pypy.jit.metainterp.test.support import boxint, boxfloat,\ boxlonglong_on_32bit, boxptr, constfloat from pypy.jit.metainterp.typesystem import deref @@ -23,8 +24,24 @@ add_loop_instruction = ['overload for a specific cpu'] bridge_loop_instruction = ['overload for a specific cpu'] + _nextvarindex = 0 + + def _prepare_valuebox(self, box): + if isinstance(box, AbstractResOp): + box = box.getforwarded() + if getattr(box, '_varindex', 42) < 0: + while self._nextvarindex in self._seen_varindex: + self._nextvarindex += 1 + box.setvarindex(self._nextvarindex) + self._nextvarindex += 1 + return box + + def _fetch_varindex(self, box): + return getattr(box, '_varindex', -1) def execute_operation(self, opname, valueboxes, result_type, descr=None): + self._seen_varindex = set(map(self._fetch_varindex, valueboxes)) + valueboxes = map(self._prepare_valuebox, valueboxes) inputargs, operations = self._get_single_operation_list(opname, result_type, valueboxes, @@ -79,11 +96,11 @@ if result is None: results = [] else: + op0 = self._prepare_valuebox(op0) results = [op0] op1 = create_resop(rop.FINISH, None, results, descr=BasicFailDescr(0), mutable=True) if op0.is_guard(): - op0.setfailargs([]) if not descr: descr = BasicFailDescr(1) if descr is not None: @@ -241,47 +258,19 @@ frame = self.cpu.execute_token(looptoken, 2) assert self.cpu.get_latest_descr(frame).identifier == 5 - res = self.cpu.get_latest_value_int(frame, 0) + res = self.get_frame_value(frame, 'i1') assert res == 20 assert self.cpu.total_compiled_loops == 1 assert self.cpu.total_compiled_bridges == 1 return looptoken - def test_compile_bridge_with_holes(self): - faildescr1 = BasicFailDescr(1) - faildescr2 = BasicFailDescr(2) - targettoken = TargetToken() - inputargs, operations, looptoken = self.parse(""" - [i3] - i0 = int_sub(i3, 42) - label(i0, descr=targettoken) - i1 = int_add(i0, 1) - i2 = int_le(i1, 9) - guard_true(i2, descr=faildescr1) [None, i1, None] - jump(i1, descr=targettoken) - """, namespace=locals()) - self.cpu.compile_loop(inputargs, operations, looptoken) - - inputargs, bridge_ops, _ = self.parse(""" - [i1b] - i3 = int_le(i1b, 19) - guard_true(i3, descr=faildescr2) [i1b] - jump(i1b, descr=targettoken) - """, namespace=locals()) - self.cpu.compile_bridge(faildescr1, inputargs, bridge_ops, looptoken) - - frame = self.cpu.execute_token(looptoken, 2) - assert self.cpu.get_latest_descr(frame).identifier == 2 - res = self.cpu.get_latest_value_int(frame, 0) - assert res == 20 - def test_compile_big_bridge_out_of_small_loop(self): faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) inputargs, operations, looptoken = self.parse(""" [i0] - guard_false(i0, descr=faildescr1) [i0] + guard_false(i0, descr=faildescr1) finish(descr=faildescr3) """, namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) @@ -289,8 +278,7 @@ bridge_source = ["[i0]"] for i in range(1000): bridge_source.append("i%d = int_add(i%d, 1)" % (i + 1, i)) - failargs = ",".join(["i%d" % i for i in range(1000)]) - bridge_source.append("guard_false(i0, descr=faildescr2) [%s]" % failargs) + bridge_source.append("guard_false(i0, descr=faildescr2)") bridge_source.append("finish(descr=faildescr4)") inputargs, bridge, _ = self.parse("\n".join(bridge_source), namespace=locals()) @@ -298,30 +286,9 @@ frame = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_latest_descr(frame).identifier == 2 - for i in range(1000): - res = self.cpu.get_latest_value_int(frame, i) - assert res == 1 + i - - def test_get_latest_value_count(self): - faildescr1 = BasicFailDescr(1) - targettoken = TargetToken() - inputargs, operations, looptoken = self.parse(""" - [i0] - label(i0, descr=targettoken) - i1 = int_add(i0, 1) - i2 = int_le(i1, 9) - guard_true(i2, descr=faildescr1) [None, i1, None] - jump(i1, descr=targettoken) - """, namespace=locals()) - self.cpu.compile_loop(inputargs, operations, looptoken) - - frame = self.cpu.execute_token(looptoken, 2) - assert self.cpu.get_latest_descr(frame) is faildescr1 - - count = self.cpu.get_latest_value_count(frame) - assert count == 3 - assert self.cpu.get_latest_value_int(frame, 1) == 10 - assert self.cpu.get_latest_value_int(frame, 1) == 10 # multiple reads ok + for i in range(1001): + res = self.get_frame_value(frame, 'i%d' % i) + assert res == i or 1 def test_finish(self): class UntouchableFailDescr(AbstractFailDescr): @@ -384,18 +351,18 @@ def test_execute_operations_in_env(self): cpu = self.cpu inputargs, operations, looptoken = self.parse(""" - [ix, iy] - label(iy, ix, descr=targettoken) - iz = int_add(ix, iy) - it = int_sub(iy, 1) - iu = int_eq(it, 0) - guard_false(iu, descr=faildescr) [it, iz] - jump(it, iz, descr=targettoken) + [i0, i2] + label(i2, i0, descr=targettoken) + i5 = int_add(i0, i2) + i1 = int_sub(i2, 1) + i4 = int_eq(i1, 0) + guard_false(i4, descr=faildescr) + jump(i1, i5, descr=targettoken) """, None) cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 0, 10) - assert self.cpu.get_latest_value_int(frame, 0) == 0 - assert self.cpu.get_latest_value_int(frame, 1) == 55 + assert self.get_frame_value(frame, 'i1') == 0 + assert self.get_frame_value(frame, 'i5') == 55 def test_int_operations(self): from pypy.jit.metainterp.test.test_executor import get_int_tests diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -566,7 +566,7 @@ t = 'p' else: t = '?' - if not hasattr(self, '_varindex'): + if getattr(self, '_varindex', -1) < 0: self._str = '%s%d' % (t, AbstractResOp._counter) AbstractResOp._counter += 1 else: From noreply at buildbot.pypy.org Sat Oct 27 17:15:33 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 17:15:33 +0200 (CEST) Subject: [pypy-commit] pypy no-failargs: fix fix Message-ID: <20121027151533.01C5F1C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58504:db55cdd71296 Date: 2012-10-27 16:11 +0200 http://bitbucket.org/pypy/pypy/changeset/db55cdd71296/ Log: fix fix diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -130,7 +130,7 @@ if 'faildescr4' not in namespace: namespace['faildescr4'] = BasicFailDescr(4) loop = oparser.parse(s, namespace=namespace, mutable=True, - vars=getattr(self, 'original_vars', {})) + oldvars=getattr(self, 'original_vars', {})) self.original_vars = loop.original_vars return loop.inputargs, loop.operations, JitCellToken() @@ -393,16 +393,16 @@ if not reversed: inputargs, operations, looptoken = self.parse(""" [i1, i2] - ires = %s(i1, i2) - guard_no_overflow(descr=faildescr1) [] - finish(ires, descr=faildescr2) + i3 = %s(i1, i2) + guard_no_overflow(descr=faildescr1) + finish(i3, descr=faildescr2) """ % op, namespace={'faildescr1': BasicFailDescr(1), 'faildescr2': BasicFailDescr(2)}) else: inputargs, operations, looptoken = self.parse(""" [i1, i2] - ires = %s(i1, i2) - guard_overflow(descr=faildescr1) [ires] + i3 = %s(i1, i2) + guard_overflow(descr=faildescr1) finish(descr=faildescr2) """ % op, namespace={'faildescr1': BasicFailDescr(1), 'faildescr2': BasicFailDescr(2)}) @@ -418,7 +418,7 @@ if not reversed: assert self.cpu.get_finish_value_int(frame) == z else: - assert self.cpu.get_latest_value_int(frame, 0) == z + assert self.get_frame_value(frame, 'i3') == z def test_ovf_operations_reversed(self): self.test_ovf_operations(reversed=True) diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -20,9 +20,11 @@ use_mock_model = False def __init__(self, input, cpu, namespace, type_system, - invent_fail_descr=True, results=None, mutable=False, vars={}): + invent_fail_descr=True, results=None, mutable=False, + oldvars={}): self.input = input - self.vars = vars.copy() + self.oldvars = oldvars + self.vars = {} self.cpu = cpu self._consts = namespace self.type_system = type_system @@ -75,17 +77,20 @@ def newvar(self, elem): if elem not in self.vars: - if elem[0] in 'ifp': - if elem[0] == 'p': - p = 'r' + if elem not in self.oldvars: + if elem[0] in 'ifp': + if elem[0] == 'p': + p = 'r' + else: + p = elem[0] + opnum = getattr(rop, 'INPUT_' + p) + box = create_resop_0(opnum, example_for_opnum(opnum), + mutable=self.mutable) else: - p = elem[0] - opnum = getattr(rop, 'INPUT_' + p) - box = create_resop_0(opnum, example_for_opnum(opnum), - mutable=self.mutable) + raise ParseError("Unknown variable type: %s" % elem) + self.setstr(box, elem) else: - raise ParseError("Unknown variable type: %s" % elem) - self.setstr(box, elem) + box = self.oldvars[elem] self.vars[elem] = box return self.vars[elem] @@ -307,11 +312,11 @@ def parse(input, cpu=None, namespace=DEFAULT, type_system='lltype', invent_fail_descr=True, OpParser=OpParser, - results=None, mutable=False, vars={}): + results=None, mutable=False, oldvars={}): if namespace is DEFAULT: namespace = {} return OpParser(input, cpu, namespace, type_system, - invent_fail_descr, results, mutable, vars).parse() + invent_fail_descr, results, mutable, oldvars).parse() def pure_parse(*args, **kwds): kwds['invent_fail_descr'] = False From noreply at buildbot.pypy.org Sat Oct 27 18:30:00 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 27 Oct 2012 18:30:00 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: a bit of progress all over Message-ID: <20121027163000.7366E1C0257@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: result-in-resops Changeset: r58505:c3e20e9919f9 Date: 2012-10-27 09:29 -0700 http://bitbucket.org/pypy/pypy/changeset/c3e20e9919f9/ Log: a bit of progress all over diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -384,8 +384,8 @@ return self._optimize_nullness(op, op.getarg(0), False) def _optimize_oois_ooisnot(self, op, expect_isnot, instance): - value0 = self.getvalue(op.getarg(0)) - value1 = self.getvalue(op.getarg(1)) + value0 = self.getforwarded(op.getarg(0)) + value1 = self.getforwarded(op.getarg(1)) if value0.is_virtual(): if value1.is_virtual(): intres = (value0 is value1) ^ expect_isnot @@ -445,7 +445,7 @@ if oopspecindex == EffectInfo.OS_ARRAYCOPY: if self._optimize_CALL_ARRAYCOPY(op): return - self.emit_operation(op) + return op optimize_CALL_p = optimize_CALL_i optimize_CALL_f = optimize_CALL_i optimize_CALL_v = optimize_CALL_i @@ -486,14 +486,14 @@ # it's being done by someone else) for i in range(op.numargs()): arg = op.getarg(i) - const = self.get_constant_box(arg) + const = self.get_constant_op(arg) if const is None or not const.eq_value(arg): break else: self.make_constant(op, op.constbox()) self.last_emitted_operation = REMOVED return - self.emit_operation(op) + return op optimize_CALL_PURE_f = optimize_CALL_PURE_i optimize_CALL_PURE_p = optimize_CALL_PURE_i optimize_CALL_PURE_v = optimize_CALL_PURE_i diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -464,20 +464,20 @@ def test_oois_1(self): ops = """ [p0] - guard_class(p0, ConstClass(node_vtable)) [] + guard_class(p0, ConstClass(node_vtable)) i0 = instance_ptr_ne(p0, NULL) - guard_true(i0) [] + guard_true(i0) i1 = instance_ptr_eq(p0, NULL) - guard_false(i1) [] + guard_false(i1) i2 = instance_ptr_ne(NULL, p0) - guard_true(i0) [] + guard_true(i0) i3 = instance_ptr_eq(NULL, p0) - guard_false(i1) [] + guard_false(i1) jump(p0) """ expected = """ [p0] - guard_class(p0, ConstClass(node_vtable)) [] + guard_class(p0, ConstClass(node_vtable)) jump(p0) """ self.optimize_loop(ops, expected) @@ -487,14 +487,14 @@ [p0] setfield_gc(p0, 5, descr=valuedescr) # forces p0 != NULL i0 = ptr_ne(p0, NULL) - guard_true(i0) [] + guard_true(i0) i1 = ptr_eq(p0, NULL) - guard_false(i1) [] + guard_false(i1) i2 = ptr_ne(NULL, p0) - guard_true(i0) [] + guard_true(i0) i3 = ptr_eq(NULL, p0) - guard_false(i1) [] - guard_nonnull(p0) [] + guard_false(i1) + guard_nonnull(p0) jump(p0) """ expected = """ @@ -507,14 +507,14 @@ def test_const_guard_value(self): ops = """ [i0] - guard_value(i0, 2) [] + guard_value(i0, 2) i = int_add(5, i0) - guard_value(i, 7) [] + guard_value(i, 7) jump(i0) """ expected = """ [i0] - guard_value(i0, 2) [] + guard_value(i0, 2) jump(2) """ self.optimize_loop(ops, expected) @@ -522,12 +522,12 @@ def test_constptr_guard_value(self): ops = """ [p1] - guard_value(p1, ConstPtr(myptr)) [] + guard_value(p1, ConstPtr(myptr)) jump(p1) """ expected = """ [p1] - guard_value(p1, ConstPtr(myptr)) [] + guard_value(p1, ConstPtr(myptr)) jump(ConstPtr(myptr)) """ self.optimize_loop(ops, expected) @@ -536,13 +536,13 @@ ops = """ [i] i1 = int_lt(i, 3) - guard_value(i1, 1) [i] + guard_value(i1, 1) jump(i) """ expected = """ [i] i1 = int_lt(i, 3) - guard_true(i1) [i] + guard_true(i1) jump(i) """ self.optimize_loop(ops, expected) @@ -551,13 +551,13 @@ ops = """ [i] i1 = int_is_true(i) - guard_value(i1, 0) [i] + guard_value(i1, 0) jump(i) """ expected = """ [i] i1 = int_is_true(i) - guard_false(i1) [i] + guard_false(i1) jump(i) """ self.optimize_loop(ops, expected) @@ -566,13 +566,13 @@ ops = """ [i] i1 = int_add(i, 3) - guard_value(i1, 0) [i] + guard_value(i1, 0) jump(i) """ expected = """ [i] i1 = int_add(i, 3) - guard_value(i1, 0) [i] + guard_value(i1, 0) jump(-3) """ self.optimize_loop(ops, expected) @@ -583,20 +583,17 @@ i2 = int_gt(i0, i1) i3 = int_is_true(i2) i4 = int_is_true(i3) - guard_value(i4, 0) [i0, i1] + guard_value(i4, 0) jump(i0, i1) """ expected = """ [i0, i1] i2 = int_gt(i0, i1) - guard_false(i2) [i0, i1] + guard_false(i2) jump(i0, i1) """ self.optimize_loop(ops, expected) - - - def test_p123_simple(self): ops = """ [i1, p2, p3] @@ -647,7 +644,7 @@ ops = """ [i1] i2 = call_i(i1, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() jump(i2) """ self.optimize_loop(ops, ops) @@ -656,13 +653,13 @@ ops = """ [i1] i2 = call_pure_i(123456, i1, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() jump(i2) """ expected = """ [i1] i2 = call_i(123456, i1, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() jump(i2) """ self.optimize_loop(ops, expected) @@ -672,7 +669,7 @@ [i1] i3 = same_as_i(81) i2 = call_pure_i(123456, i3, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() jump(i2) """ expected = """ @@ -685,15 +682,15 @@ ops = """ [i1] i2 = call_pure_i(123456, i1, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() i3 = call_pure_i(123456, i1, descr=nonwritedescr) - guard_no_exception() [i1, i2, i3] + guard_no_exception() jump(i3) """ expected = """ [i1] i2 = call_i(123456, i1, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() jump(i2) """ self.optimize_loop(ops, expected) @@ -704,26 +701,25 @@ ops = """ [i1] i2 = call_loopinvariant_i(1, i1, descr=nonwritedescr) - guard_no_exception() [] - guard_value(i2, 1) [] + guard_no_exception() + guard_value(i2, 1) i3 = call_loopinvariant_i(1, i1, descr=nonwritedescr) - guard_no_exception() [] - guard_value(i3, 1) [] + guard_no_exception() + guard_value(i3, 1) i4 = call_loopinvariant_i(1, i1, descr=nonwritedescr) - guard_no_exception() [] - guard_value(i4, 1) [] + guard_no_exception() + guard_value(i4, 1) jump(i1) """ expected = """ [i1] i2 = call_i(1, i1, descr=nonwritedescr) - guard_no_exception() [] - guard_value(i2, 1) [] + guard_no_exception() + guard_value(i2, 1) jump(i1) """ self.optimize_loop(ops, expected) - # ---------- def test_virtual_1(self): @@ -1089,13 +1085,13 @@ def test_getfield_gc_pure_2(self): ops = """ [p0, i] - guard_value(p0, ConstPtr(myptr)) [] + guard_value(p0, ConstPtr(myptr)) i1 = getfield_gc_pure_i(p0, descr=valuedescr) jump(p0, i1) """ expected = """ [p0, i] - guard_value(p0, ConstPtr(myptr)) [] + guard_value(p0, ConstPtr(myptr)) jump(ConstPtr(myptr), 5) """ self.node.value = 5 @@ -1115,7 +1111,7 @@ [i1] p1 = new_array(3, descr=arraydescr) i3 = arraylen_gc(p1, descr=arraydescr) - guard_value(i3, 3) [] + guard_value(i3, 3) setarrayitem_gc(p1, 1, i1, descr=arraydescr) setarrayitem_gc(p1, 0, 25, descr=arraydescr) i2 = getarrayitem_gc_i(p1, 1, descr=arraydescr) @@ -1146,7 +1142,7 @@ [f1] p1 = new_array(3, descr=floatarraydescr) i3 = arraylen_gc(p1, descr=floatarraydescr) - guard_value(i3, 3) [] + guard_value(i3, 3) setarrayitem_gc(p1, 1, f1, descr=floatarraydescr) setarrayitem_gc(p1, 0, 3.5, descr=floatarraydescr) f2 = getarrayitem_gc_f(p1, 1, descr=floatarraydescr) diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py --- a/pypy/jit/metainterp/optimizeopt/virtualize.py +++ b/pypy/jit/metainterp/optimizeopt/virtualize.py @@ -425,7 +425,7 @@ # was already forced). def optimize_GETFIELD_GC_i(self, op): - value = self.getvalue(op.getarg(0)) + value = self.getforwarded(op.getarg(0)) # If this is an immutable field (as indicated by op.is_always_pure()) # then it's safe to reuse the virtual's field, even if it has been # forced, because it should never be written to again. @@ -472,7 +472,7 @@ self.make_vstruct(op.getdescr(), op) def optimize_NEW_ARRAY(self, op): - sizebox = self.get_constant_box(op.getarg(0)) + sizebox = self.get_constant_op(op.getarg(0)) if sizebox is not None: # if the original 'op' did not have a ConstInt as argument, # build a new one with the ConstInt argument diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -538,7 +538,7 @@ if oopspecindex == EffectInfo.OS_STR2UNICODE: if self.opt_call_str_STR2UNICODE(op): return - self.emit_operation(op) + return op optimize_CALL_f = optimize_CALL_i optimize_CALL_r = optimize_CALL_i optimize_CALL_v = optimize_CALL_i From noreply at buildbot.pypy.org Sat Oct 27 18:41:39 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 18:41:39 +0200 (CEST) Subject: [pypy-commit] pypy no-failargs: More fix fix. Sanitize runner_test, at least when compared to the Message-ID: <20121027164139.4FEF51C01E7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58506:2b24249e63c9 Date: 2012-10-27 18:41 +0200 http://bitbucket.org/pypy/pypy/changeset/2b24249e63c9/ Log: More fix fix. Sanitize runner_test, at least when compared to the previous situation. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -645,7 +645,9 @@ if isinstance(arg, Const): return arg.value result = self.env[arg] - assert result == self.framecontent[arg.getvarindex()] + assert result is self.framecontent[arg.getvarindex()] + if arg.type == FLOAT and FLOAT_SIZE > 1: + assert self.framecontent[arg.getvarindex() + 1] == '2nd float word' return result def execute(self, lltrace): diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -5,7 +5,7 @@ JitCellToken, TargetToken) from pypy.jit.metainterp.resoperation import rop, create_resop_dispatch,\ create_resop, ConstInt, ConstPtr, ConstFloat, create_resop_2,\ - create_resop_1, create_resop_0, INT, REF, FLOAT, example_for_opnum,\ + create_resop_1, create_resop_0, INT, REF, FLOAT, VOID, example_for_opnum,\ AbstractResOp from pypy.jit.metainterp.test.support import boxint, boxfloat,\ boxlonglong_on_32bit, boxptr, constfloat @@ -26,26 +26,49 @@ bridge_loop_instruction = ['overload for a specific cpu'] _nextvarindex = 0 - def _prepare_valuebox(self, box): - if isinstance(box, AbstractResOp): - box = box.getforwarded() - if getattr(box, '_varindex', 42) < 0: - while self._nextvarindex in self._seen_varindex: - self._nextvarindex += 1 - box.setvarindex(self._nextvarindex) - self._nextvarindex += 1 - return box + def update_varindexes(self, newtext2op): + # 'self.text2op' is a dict mapping variable names (as present in + # the oparser source) to the corresponding ResOp. This function + # updates it with 'newtext2op', then assigns '_varindex' to all + # the new ResOps. The choice of '_varindex' is done automatically + # to avoid conflicts, but existing '_varindex' are not changed. + # If 'newtext2op' is not a dict but a list, comes up with names + # as per str(op). + if isinstance(newtext2op, list): + newtext2op = dict([(str(op), op) for op in newtext2op]) + try: + text2op = self.text2op + except AttributeError: + text2op = self.text2op = {} + text2op.update(newtext2op) + if newtext2op: + # update 'self._nextvarindex' to a value higher than any seen + # in newtext2op. Pick two more rather than one more just in + # case the highest so far was a FLOAT. + newops = newtext2op.values() + random.shuffle(newops) + maximum = max([getattr(op, '_varindex', -2) for op in newops]) + self._nextvarindex = max(self._nextvarindex, maximum + 2) + for op in newops: + self.assign_varindex(op) - def _fetch_varindex(self, box): - return getattr(box, '_varindex', -1) + def assign_varindex(self, op): + if (isinstance(op, AbstractResOp) and op.type != VOID and + getattr(op, '_varindex', -1) == -1): + op._varindex = self._nextvarindex + if hasattr(op, '_str'): + del op._str # recompute it + # this op consumes either one or two numbers, depending on its + # type as a non-FLOAT or FLOAT. We don't care too much about + # being on 32-bit vs 64-bit here. + self._nextvarindex += 1 + (op.type == FLOAT) def execute_operation(self, opname, valueboxes, result_type, descr=None): - self._seen_varindex = set(map(self._fetch_varindex, valueboxes)) - valueboxes = map(self._prepare_valuebox, valueboxes) inputargs, operations = self._get_single_operation_list(opname, result_type, valueboxes, descr) + self.update_varindexes(inputargs + operations) looptoken = JitCellToken() self.cpu.compile_loop(inputargs, operations, looptoken) args = [] @@ -96,7 +119,6 @@ if result is None: results = [] else: - op0 = self._prepare_valuebox(op0) results = [op0] op1 = create_resop(rop.FINISH, None, results, descr=BasicFailDescr(0), mutable=True) @@ -130,12 +152,12 @@ if 'faildescr4' not in namespace: namespace['faildescr4'] = BasicFailDescr(4) loop = oparser.parse(s, namespace=namespace, mutable=True, - oldvars=getattr(self, 'original_vars', {})) - self.original_vars = loop.original_vars + oldvars=getattr(self, 'text2op', {})) + self.update_varindexes(loop.text2op) return loop.inputargs, loop.operations, JitCellToken() def get_frame_value(self, frame, varname): - op = self.original_vars[varname] + op = self.text2op[varname] index = op.getvarindex() if varname.startswith('i'): return self.cpu.get_frame_value_int(frame, index) @@ -1082,6 +1104,7 @@ for nb_args in range(50): print 'Passing %d arguments to execute_token...' % nb_args # + text2op = {} inputargs = [] values = [] for k in range(nb_args): @@ -1089,18 +1112,19 @@ if kind == 0: inputargs.append(boxint()) values.append(r.randrange(-100000, 100000)) + text2op['ii%d' % k] = inputargs[-1] else: inputargs.append(boxfloat()) values.append(longlong.getfloatstorage(r.random())) + text2op['fi%d' % k] = inputargs[-1] # looptoken = JitCellToken() faildescr = BasicFailDescr(42) operations = [] - retboxes = [] - retvalues = [] # ks = range(nb_args) random.shuffle(ks) + retvalues = [] for k in ks: if inputargs[k].type == INT: x = r.randrange(-100000, 100000) @@ -1108,6 +1132,7 @@ create_resop_2(rop.INT_ADD, 0, inputargs[k], ConstInt(x)) ) + text2op['io%d' % k] = operations[-1] y = values[k] + x else: x = r.random() @@ -1115,17 +1140,16 @@ create_resop_2(rop.FLOAT_ADD, 0.0, inputargs[k], constfloat(x)) ) + text2op['fo%d' % k] = operations[-1] y = longlong.getrealfloat(values[k]) + x y = longlong.getfloatstorage(y) - kk = r.randrange(0, len(retboxes)+1) - retboxes.insert(kk, operations[-1]) - retvalues.insert(kk, y) + retvalues.append(y) # operations.append( create_resop(rop.FINISH, None, [], descr=faildescr, mutable=True) ) - operations[-1].setfailargs(retboxes) + self.update_varindexes(text2op) print inputargs for op in operations: print op @@ -1134,12 +1158,12 @@ frame = self.cpu.execute_token(looptoken, *values) assert self.cpu.get_latest_descr(frame).identifier == 42 # - for k in range(len(retvalues)): - if retboxes[k].type == 'i': - got = self.cpu.get_latest_value_int(frame, k) + for k, expected in zip(ks, retvalues): + if 'io%d' % k in text2op: + got = self.get_frame_value(frame, 'io%d' % k) else: - got = self.cpu.get_latest_value_float(frame, k) - assert got == retvalues[k] + got = self.get_frame_value(frame, 'fo%d' % k) + assert got == expected def test_jump(self): # this test generates small loops where the JUMP passes many diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -660,13 +660,22 @@ @classmethod def returns_bool_result(cls): opnum = cls.getopnum() - if we_are_translated(): - assert opnum >= 0 + if opnum < 0: + return False return opboolresult[opnum] def _copy_extra_attrs(self, new): pass - + + def getvarindex(self): + # for testing only: even non-mutable ResOperations have a + # getvarindex() that works by reading '_varindex'. This + # is convenient for runner_test.py. + if we_are_translated(): + raise NotImplementedError + assert self._varindex >= 0 # and hasattr(self, '_varindex') + return self._varindex + # some debugging help def __setattr__(self, attr, val): diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -88,18 +88,12 @@ mutable=self.mutable) else: raise ParseError("Unknown variable type: %s" % elem) - self.setstr(box, elem) + box._str = elem else: box = self.oldvars[elem] self.vars[elem] = box return self.vars[elem] - def setstr(self, op, text): - if hasattr(op, 'setvarindex') and text[1:].isdigit(): - op.setvarindex(int(text[1:])) - else: - op._res = text - def is_float(self, arg): try: float(arg) @@ -209,7 +203,7 @@ else: result = self.results[num] opres = self.create_op(opnum, result, args, descr) - self.setstr(opres, res) + opres._str = res self.vars[res] = opres return opres @@ -254,7 +248,7 @@ loop.operations = ops loop.inputargs = inpargs loop.last_offset = last_offset - loop.original_vars = self.vars + loop.text2op = self.vars return loop def parse_ops(self, indent, lines, start): From noreply at buildbot.pypy.org Sat Oct 27 18:50:59 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 18:50:59 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: (agaynor, fijal) fish the types Message-ID: <20121027165059.169241C01E7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58507:6cb7afbf9931 Date: 2012-10-27 18:51 +0200 http://bitbucket.org/pypy/pypy/changeset/6cb7afbf9931/ Log: (agaynor, fijal) fish the types diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -185,7 +185,7 @@ self.optimize_loop(ops, expected) def test_constfold_all(self): - from pypy.jit.backend.llgraph.llimpl import TYPES # xxx fish + from pypy.jit.metainterp.optimizeopt.test.types import TYPES # xxx fish from pypy.jit.metainterp.executor import execute_nonspec import random for opnum in [rop._ALWAYS_PURE_FIRST, rop._ALWAYS_PURE_NO_PTR_LAST]: diff --git a/pypy/jit/metainterp/optimizeopt/test/types.py b/pypy/jit/metainterp/optimizeopt/test/types.py new file mode 100644 --- /dev/null +++ b/pypy/jit/metainterp/optimizeopt/test/types.py @@ -0,0 +1,105 @@ +TYPES = { + 'int_add' : (('int', 'int'), 'int'), + 'int_sub' : (('int', 'int'), 'int'), + 'int_mul' : (('int', 'int'), 'int'), + 'int_floordiv' : (('int', 'int'), 'int'), + 'int_mod' : (('int', 'int'), 'int'), + 'int_and' : (('int', 'int'), 'int'), + 'int_or' : (('int', 'int'), 'int'), + 'int_xor' : (('int', 'int'), 'int'), + 'int_lshift' : (('int', 'int'), 'int'), + 'int_rshift' : (('int', 'int'), 'int'), + 'int_lt' : (('int', 'int'), 'bool'), + 'int_gt' : (('int', 'int'), 'bool'), + 'int_ge' : (('int', 'int'), 'bool'), + 'int_le' : (('int', 'int'), 'bool'), + 'int_eq' : (('int', 'int'), 'bool'), + 'int_ne' : (('int', 'int'), 'bool'), + 'int_is_true' : (('int',), 'bool'), + 'int_is_zero' : (('int',), 'bool'), + 'int_neg' : (('int',), 'int'), + 'int_invert' : (('int',), 'int'), + 'int_add_ovf' : (('int', 'int'), 'int'), + 'int_sub_ovf' : (('int', 'int'), 'int'), + 'int_mul_ovf' : (('int', 'int'), 'int'), + 'int_force_ge_zero':(('int',), 'int'), + 'uint_add' : (('int', 'int'), 'int'), + 'uint_sub' : (('int', 'int'), 'int'), + 'uint_mul' : (('int', 'int'), 'int'), + 'uint_lt' : (('int', 'int'), 'bool'), + 'uint_le' : (('int', 'int'), 'bool'), + 'uint_eq' : (('int', 'int'), 'bool'), + 'uint_ne' : (('int', 'int'), 'bool'), + 'uint_gt' : (('int', 'int'), 'bool'), + 'uint_ge' : (('int', 'int'), 'bool'), + 'uint_xor' : (('int', 'int'), 'int'), + 'uint_rshift' : (('int', 'int'), 'int'), + 'uint_floordiv' : (('int', 'int'), 'int'), + 'float_add' : (('float', 'float'), 'float'), + 'float_sub' : (('float', 'float'), 'float'), + 'float_mul' : (('float', 'float'), 'float'), + 'float_truediv' : (('float', 'float'), 'float'), + 'float_lt' : (('float', 'float'), 'bool'), + 'float_le' : (('float', 'float'), 'bool'), + 'float_eq' : (('float', 'float'), 'bool'), + 'float_ne' : (('float', 'float'), 'bool'), + 'float_gt' : (('float', 'float'), 'bool'), + 'float_ge' : (('float', 'float'), 'bool'), + 'float_neg' : (('float',), 'float'), + 'float_abs' : (('float',), 'float'), + 'cast_float_to_int':(('float',), 'int'), + 'cast_int_to_float':(('int',), 'float'), + 'same_as' : (('int',), 'int'), # could also be ptr=>ptr + 'new_with_vtable' : (('ref',), 'ref'), + 'new' : ((), 'ref'), + 'new_array' : (('int',), 'ref'), + 'oois' : (('ref', 'ref'), 'bool'), + 'ooisnot' : (('ref', 'ref'), 'bool'), + 'instanceof' : (('ref',), 'bool'), + 'subclassof' : (('ref', 'ref'), 'bool'), + 'runtimenew' : (('ref',), 'ref'), + 'setfield_gc' : (('ref', 'intorptr'), None), + 'getfield_gc' : (('ref',), 'intorptr'), + 'getfield_gc_pure': (('ref',), 'intorptr'), + 'setfield_raw' : (('ref', 'intorptr'), None), + 'getfield_raw' : (('ref',), 'intorptr'), + 'getfield_raw_pure': (('ref',), 'intorptr'), + 'setarrayitem_gc' : (('ref', 'int', 'intorptr'), None), + 'getarrayitem_gc' : (('ref', 'int'), 'intorptr'), + 'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'), + 'setarrayitem_raw' : (('ref', 'int', 'intorptr'), None), + 'getarrayitem_raw' : (('ref', 'int'), 'intorptr'), + 'getarrayitem_raw_pure' : (('ref', 'int'), 'intorptr'), + 'arraylen_gc' : (('ref',), 'int'), + 'call' : (('ref', 'varargs'), 'intorptr'), + 'call_assembler' : (('varargs',), 'intorptr'), + 'cond_call_gc_wb' : (('ptr', 'ptr'), None), + 'cond_call_gc_wb_array': (('ptr', 'int', 'ptr'), None), + 'oosend' : (('varargs',), 'intorptr'), + 'oosend_pure' : (('varargs',), 'intorptr'), + 'guard_true' : (('bool',), None), + 'guard_false' : (('bool',), None), + 'guard_value' : (('int', 'int'), None), + 'guard_class' : (('ref', 'ref'), None), + 'guard_no_exception' : ((), None), + 'guard_exception' : (('ref',), 'ref'), + 'guard_no_overflow' : ((), None), + 'guard_overflow' : ((), None), + 'guard_nonnull' : (('ref',), None), + 'guard_isnull' : (('ref',), None), + 'guard_nonnull_class' : (('ref', 'ref'), None), + 'newstr' : (('int',), 'ref'), + 'strlen' : (('ref',), 'int'), + 'strgetitem' : (('ref', 'int'), 'int'), + 'strsetitem' : (('ref', 'int', 'int'), None), + 'newunicode' : (('int',), 'ref'), + 'unicodelen' : (('ref',), 'int'), + 'unicodegetitem' : (('ref', 'int'), 'int'), + 'unicodesetitem' : (('ref', 'int', 'int'), 'int'), + 'cast_ptr_to_int' : (('ref',), 'int'), + 'cast_int_to_ptr' : (('int',), 'ref'), + 'debug_merge_point': (('ref', 'int', 'int'), None), + 'force_token' : ((), 'int'), + 'call_may_force' : (('int', 'varargs'), 'intorptr'), + 'guard_not_forced': ((), None), +} From noreply at buildbot.pypy.org Sat Oct 27 18:53:32 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 27 Oct 2012 18:53:32 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: small cleanup Message-ID: <20121027165332.B15401C01E7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: result-in-resops Changeset: r58508:0e131b57a8eb Date: 2012-10-27 09:53 -0700 http://bitbucket.org/pypy/pypy/changeset/0e131b57a8eb/ Log: small cleanup diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -1,4 +1,7 @@ +import random + import py + from pypy.rlib.objectmodel import instantiate from pypy.jit.metainterp.optimizeopt.test.test_util import ( LLtypeMixin, BaseTest, FakeMetaInterpStaticData, convert_old_style_to_targets) @@ -13,6 +16,7 @@ from pypy.jit.metainterp.test.support import boxint from pypy.rlib.rarithmetic import LONG_BIT + def test_store_final_boxes_in_guard(): from pypy.jit.metainterp.resume import tag, TAGBOX b0 = boxint() @@ -185,9 +189,9 @@ self.optimize_loop(ops, expected) def test_constfold_all(self): - from pypy.jit.metainterp.optimizeopt.test.types import TYPES # xxx fish + from pypy.jit.metainterp.optimizeopt.test.types import TYPES from pypy.jit.metainterp.executor import execute_nonspec - import random + for opnum in [rop._ALWAYS_PURE_FIRST, rop._ALWAYS_PURE_NO_PTR_LAST]: try: op = opname[opnum] @@ -195,8 +199,6 @@ continue if op.startswith('_'): continue - if 'FLOAT' in op: - continue argtypes, restype = TYPES[op.lower()] args = [] for argtype in argtypes: From noreply at buildbot.pypy.org Sat Oct 27 19:29:45 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 27 Oct 2012 19:29:45 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: merge default into branch Message-ID: <20121027172945.5205D1C0558@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-problems Changeset: r58509:7be0c69a3026 Date: 2012-10-27 19:24 +0200 http://bitbucket.org/pypy/pypy/changeset/7be0c69a3026/ Log: merge default into branch 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 @@ -233,7 +233,7 @@ try: return unicode(line, ENCODING) except UnicodeDecodeError: # bah, silently fall back... - return unicode(line, 'utf-8') + return unicode(line, 'utf-8', 'replace') def get_history_length(self): return self.saved_history_length diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -496,7 +496,7 @@ if iscode: self.__tputs(text) else: - os.write(self.output_fd, text.encode(self.encoding)) + os.write(self.output_fd, text.encode(self.encoding, 'replace')) del self.__buffer[:] def __tputs(self, fmt, prog=delayprog): diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -548,7 +548,7 @@ if cell.is_constant(): newcell.const = cell.const cell = newcell - cell.knowntypedata = renamed_knowntypedata + cell.set_knowntypedata(renamed_knowntypedata) cells.append(cell) diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -144,7 +144,7 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key annotator = bk.annotator @@ -168,6 +168,7 @@ bind(obj2, obj1, 0) bind(obj1, obj2, 1) + r.set_knowntypedata(knowntypedata) return r @@ -337,8 +338,7 @@ case = opname in ('gt', 'ge', 'eq') add_knowntypedata(knowntypedata, case, [op.args[0]], SomeInteger(nonneg=True, knowntype=tointtype(int1))) - if knowntypedata: - r.knowntypedata = knowntypedata + r.set_knowntypedata(knowntypedata) # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) @@ -369,8 +369,7 @@ if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) - if ktd: - s.knowntypedata = ktd + s.set_knowntypedata(ktd) return s def and_((boo1, boo2)): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -188,10 +188,10 @@ variables = [op.args[1]] for variable in variables: assert bk.annotator.binding(variable) == s_obj - r.knowntypedata = {} - + knowntypedata = {} if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): - add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) + add_knowntypedata(knowntypedata, True, variables, bk.valueoftype(typ)) + r.set_knowntypedata(knowntypedata) return r # note that this one either needs to be constant, or we will create SomeObject diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -195,6 +195,10 @@ unsigned = False def __init__(self): pass + def set_knowntypedata(self, knowntypedata): + assert not hasattr(self, 'knowntypedata') + if knowntypedata: + self.knowntypedata = knowntypedata class SomeStringOrUnicode(SomeObject): immutable = True diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -76,7 +76,7 @@ s_obj.is_true_behavior(r) bk = getbookkeeper() - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key op = block.operations[i] assert op.opname == "is_true" or op.opname == "nonzero" @@ -86,8 +86,8 @@ if s_obj.can_be_none(): s_nonnone_obj = s_obj.nonnoneify() add_knowntypedata(knowntypedata, True, [arg], s_nonnone_obj) + r.set_knowntypedata(knowntypedata) return r - def nonzero(obj): return obj.is_true() diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -118,7 +118,7 @@ ("translation.gcrootfinder", DEFL_ROOTFINDER_WITHJIT), ("translation.list_comprehension_operations", True)]), ChoiceOption("jit_backend", "choose the backend for the JIT", - ["auto", "x86", "x86-without-sse2", "llvm", 'arm'], + ["auto", "x86", "x86-without-sse2", 'arm'], default="auto", cmdline="--jit-backend"), ChoiceOption("jit_profiler", "integrate profiler support into the JIT", ["off", "oprofile"], diff --git a/pypy/jit/backend/detect_cpu.py b/pypy/jit/backend/detect_cpu.py --- a/pypy/jit/backend/detect_cpu.py +++ b/pypy/jit/backend/detect_cpu.py @@ -77,8 +77,6 @@ return "pypy.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "pypy.jit.backend.cli.runner", "CliCPU" - elif backend_name == 'llvm': - return "pypy.jit.backend.llvm.runner", "LLVMCPU" elif backend_name == 'arm': return "pypy.jit.backend.arm.runner", "CPU_ARM" elif backend_name == 'armhf': diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,9 +4,8 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi, rposix +from pypy.rlib import jit, clibffi, jit_libffi from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -152,9 +151,6 @@ if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') - elif flag == 2: - file = rffi.cast(rffi.CCHARPP, data)[0] - rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -169,27 +165,6 @@ assert isinstance(abi, int) return space.wrap(abi) -rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) - -def prepare_file_call_argument(fileobj): - import os - space = fileobj.space - fileobj.direct_flush() - fd = fileobj.direct_fileno() - if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file has no OS file descriptor")) - try: - fd2 = os.dup(fd) - f = rffi_fdopen(fd2, fileobj.mode) - if not f: - os.close(fd2) - raise OSError(rposix.get_errno(), "fdopen failed") - except OSError, e: - raise wrap_oserror(space, e) - return f - # ____________________________________________________________ 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 @@ -3,9 +3,11 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.rarithmetic import ovfcheck +from pypy.rlib import rposix from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend import cdataobj, misc, ctypeprim @@ -236,6 +238,22 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) + def cast(self, w_ob): + if self.is_file: + value = self.prepare_file(w_ob) + if value: + return cdataobj.W_CData(self.space, value, self) + return W_CTypePtrBase.cast(self, w_ob) + + def prepare_file(self, w_ob): + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = self.space.interpclass_w(w_ob) + if isinstance(ob, W_File): + return prepare_file_argument(self.space, ob) + else: + return lltype.nullptr(rffi.CCHARP.TO) + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or @@ -245,11 +263,8 @@ # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 elif self.is_file: - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc - ob = space.interpclass_w(w_init) - if isinstance(ob, W_File): - result = ctypefunc.prepare_file_call_argument(ob) + result = self.prepare_file(w_init) + if result: rffi.cast(rffi.CCHARPP, cdata)[0] = result return 2 return 0 @@ -303,3 +318,31 @@ else: raise OperationError(space.w_TypeError, space.wrap("expected a 'cdata struct-or-union' object")) + +# ____________________________________________________________ + + +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +class CffiFileObj(object): + _immutable_ = True + def __init__(self, fd, mode): + self.llf = rffi_fdopen(fd, mode) + if not self.llf: + raise OSError(rposix.get_errno(), "fdopen failed") + def close(self): + rffi_fclose(self.llf) + +def prepare_file_argument(space, fileobj): + fileobj.direct_flush() + if fileobj.cffi_fileobj is None: + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + except OSError, e: + raise wrap_oserror(space, e) + return fileobj.cffi_fileobj.llf diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -2264,3 +2264,35 @@ e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " "be a cdata pointer, not file") + +def test_FILE_object(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP,), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fileno = ll.load_function(BFunc2, "fileno") + # + import posix + fdr, fdw = posix.pipe() + fw1 = posix.fdopen(fdw, 'wb', 256) + # + fw1p = cast(BFILEP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p) + assert res >= 0 + res = fileno(fw1p) + assert res == fdw + fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,8 +1,21 @@ from pypy.objspace.fake.checkmodule import checkmodule +from pypy.module._cffi_backend import ctypeptr +from pypy.rpython.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - checkmodule('_cffi_backend') + # prepare_file_argument() is not working without translating the _file + # module too + def dummy_prepare_file_argument(space, fileobj): + return lltype.nullptr(rffi.CCHARP.TO) + old = ctypeptr.prepare_file_argument + try: + ctypeptr.prepare_file_argument = dummy_prepare_file_argument + # + checkmodule('_cffi_backend') + # + finally: + ctypeptr.prepare_file_argument = old diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -32,6 +32,7 @@ encoding = None errors = None fd = -1 + cffi_fileobj = None # pypy/module/_cffi_backend newlines = 0 # Updated when the stream is closed @@ -148,7 +149,14 @@ del openstreams[stream] except KeyError: pass - stream.close() + # close the stream. If cffi_fileobj is None, we close the + # underlying fileno too. Otherwise, we leave that to + # cffi_fileobj.close(). + cffifo = self.cffi_fileobj + self.cffi_fileobj = None + stream.close1(cffifo is None) + if cffifo is not None: + cffifo.close() def direct_fileno(self): self.getstream() # check if the file is still open 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 @@ -423,6 +423,7 @@ return interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] + at jit.unroll_safe def find_unaryop_result_dtype(space, dt, promote_to_float=False, promote_bools=False, promote_to_largest=False, allow_complex=True): if promote_bools and (dt.kind == interp_dtype.BOOLLTR): diff --git a/pypy/rlib/streamio.py b/pypy/rlib/streamio.py --- a/pypy/rlib/streamio.py +++ b/pypy/rlib/streamio.py @@ -268,6 +268,9 @@ return False def close(self): + self.close1(True) + + def close1(self, closefileno): pass def peek(self): @@ -333,8 +336,9 @@ else: data = data[n:] - def close(self): - os.close(self.fd) + def close1(self, closefileno): + if closefileno: + os.close(self.fd) if sys.platform == "win32": def truncate(self, size): @@ -375,9 +379,10 @@ size = os.fstat(self.fd).st_size self.mm = mmap.mmap(self.fd, size, access=self.access) - def close(self): + def close1(self, closefileno): self.mm.close() - os.close(self.fd) + if closefileno: + os.close(self.fd) def tell(self): return self.pos @@ -470,7 +475,7 @@ ("truncate", [r_longlong]), ("flush", []), ("flushable", []), - ("close", []), + ("close1", [int]), ("peek", []), ("try_to_find_file_descriptor", []), ("getnewlines", []), @@ -715,7 +720,7 @@ truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=True) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -770,7 +775,7 @@ seek = PassThrough("seek", flush_buffers=True) truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=True) - close = PassThrough("close", flush_buffers=True) + close1 = PassThrough("close1", flush_buffers=True) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -838,7 +843,7 @@ flush = PassThrough("flush", flush_buffers=False) flushable= PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -907,7 +912,7 @@ truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=False) flushable= PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1041,7 +1046,7 @@ truncate = PassThrough("truncate", flush_buffers=True) flush = PassThrough("flush", flush_buffers=True) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1067,7 +1072,7 @@ truncate = PassThrough("truncate", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1091,7 +1096,7 @@ peek = PassThrough("peek", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) write = PassThrough("write", flush_buffers=False) truncate = PassThrough("truncate", flush_buffers=False) getnewlines= PassThrough("getnewlines",flush_buffers=False) @@ -1144,7 +1149,7 @@ truncate = PassThrough("truncate", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) @@ -1172,6 +1177,6 @@ truncate = PassThrough("truncate", flush_buffers=False) flush = PassThrough("flush", flush_buffers=False) flushable = PassThrough("flushable", flush_buffers=False) - close = PassThrough("close", flush_buffers=False) + close1 = PassThrough("close1", flush_buffers=False) try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor", flush_buffers=False) From noreply at buildbot.pypy.org Sat Oct 27 19:29:46 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 27 Oct 2012 19:29:46 +0200 (CEST) Subject: [pypy-commit] pypy numpypy-problems: close branch about to be merged Message-ID: <20121027172946.77E571C0558@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-problems Changeset: r58510:0033c3f2423f Date: 2012-10-27 19:28 +0200 http://bitbucket.org/pypy/pypy/changeset/0033c3f2423f/ Log: close branch about to be merged From noreply at buildbot.pypy.org Sat Oct 27 19:29:48 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 27 Oct 2012 19:29:48 +0200 (CEST) Subject: [pypy-commit] pypy default: merge branch into default Message-ID: <20121027172948.0F2431C0558@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r58511:d503178b639c Date: 2012-10-27 19:28 +0200 http://bitbucket.org/pypy/pypy/changeset/d503178b639c/ Log: merge branch into default diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,5 +1,5 @@ -from _numpypy import array, ndarray, int_, float_, bool_ #, complex_# , longlong +from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math @@ -200,7 +200,7 @@ typename = "'%s'" % typename lf = '' - if 0: # or issubclass(arr.dtype.type, flexible): + if issubclass(arr.dtype.type, flexible): if arr.dtype.names: typename = "%s" % str(arr.dtype) else: 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 @@ -38,6 +38,8 @@ .. branch: numpypy-complex2 Complex dtype support for numpy +.. branch: numpypy-problems +Improve dtypes intp, uintp, void, string and record .. branch: kill-someobject major cleanups including killing some object support diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -62,6 +62,7 @@ 'flexible': 'interp_boxes.W_FlexibleBox', 'character': 'interp_boxes.W_CharacterBox', 'str_': 'interp_boxes.W_StringBox', + 'string_': 'interp_boxes.W_StringBox', 'unicode_': 'interp_boxes.W_UnicodeBox', 'void': 'interp_boxes.W_VoidBox', 'complexfloating': 'interp_boxes.W_ComplexFloatingBox', diff --git a/pypy/module/micronumpy/arrayimpl/voidbox.py b/pypy/module/micronumpy/arrayimpl/voidbox.py --- a/pypy/module/micronumpy/arrayimpl/voidbox.py +++ b/pypy/module/micronumpy/arrayimpl/voidbox.py @@ -6,6 +6,7 @@ def __init__(self, size, dtype): self.storage = alloc_raw_storage(size) self.dtype = dtype + self.size = size def __del__(self): free_raw_storage(self.storage) 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 @@ -246,7 +246,11 @@ except KeyError: raise OperationError(space.w_IndexError, space.wrap("Field %s does not exist" % item)) - return dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + if isinstance (read_val, W_StringBox): + # StringType returns a str + return space.wrap(dtype.itemtype.to_str(read_val)) + return read_val @unwrap_spec(item=str) def descr_setitem(self, space, item, w_value): @@ -271,6 +275,13 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) + # Running entire test suite needs this function to succeed, + # running single test_stringarray succeeds without it. + # With convert_to() test_ztranslation fails since + # W_CharacterBox is not a W_GenericBox. + # Why is it needed for multiple tests? + #def convert_to(self, dtype): + # xxx class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -474,6 +485,7 @@ W_VoidBox.typedef = TypeDef("void", W_FlexibleBox.typedef, __module__ = "numpypy", + __new__ = interp2app(W_VoidBox.descr__new__.im_func), __getitem__ = interp2app(W_VoidBox.descr_getitem), __setitem__ = interp2app(W_VoidBox.descr_setitem), ) 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 @@ -8,6 +8,7 @@ from pypy.module.micronumpy import types, interp_boxes from pypy.rlib.objectmodel import specialize from pypy.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong +from pypy.rpython.lltypesystem import rffi UNSIGNEDLTR = "u" @@ -17,6 +18,8 @@ VOIDLTR = 'V' STRINGLTR = 'S' UNICODELTR = 'U' +INTPLTR = 'p' +UINTPLTR = 'P' def decode_w_dtype(space, w_dtype): if space.is_none(w_dtype): @@ -66,11 +69,16 @@ def fill(self, storage, box, start, stop): self.itemtype.fill(storage, self.get_size(), box, start, stop, 0) + def get_name(self): + if self.char == 'S': + return '|S' + str(self.get_size()) + return self.name + def descr_str(self, space): - return space.wrap(self.name) + return space.wrap(self.get_name()) def descr_repr(self, space): - return space.wrap("dtype('%s')" % self.name) + return space.wrap("dtype('%s')" % self.get_name()) def descr_get_itemsize(self, space): return space.wrap(self.itemtype.get_element_size()) @@ -135,6 +143,9 @@ def is_record_type(self): return self.fields is not None + def is_flexible_type(self): + return (self.num == 18 or self.num == 19 or self.num == 20) + def __repr__(self): if self.fields is not None: return '' % self.fields @@ -454,6 +465,35 @@ #alternate_constructors=[space.w_buffer], # XXX no buffer in space ) + ptr_size = rffi.sizeof(rffi.CCHARP) + if ptr_size == 4: + intp_box = interp_boxes.W_Int32Box + intp_type = types.Int32() + uintp_box = interp_boxes.W_UInt32Box + uintp_type = types.UInt32() + elif ptr_size == 8: + intp_box = interp_boxes.W_Int64Box + intp_type = types.Int64() + uintp_box = interp_boxes.W_UInt64Box + uintp_type = types.UInt64() + else: + raise ValueError('unknown point size %d' % ptr_size) + self.w_intpdtype = W_Dtype( + intp_type, + num=5, + kind=INTPLTR, + name='intp', + char=INTPLTR, + w_box_type = space.gettypefor(intp_box), + ) + self.w_uintpdtype = W_Dtype( + uintp_type, + num=6, + kind=UINTPLTR, + name='uintp', + char=UINTPLTR, + w_box_type = space.gettypefor(uintp_box), + ) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, @@ -462,7 +502,7 @@ self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, self.w_complex128dtype, self.w_stringdtype, self.w_unicodedtype, - self.w_voiddtype, + self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) @@ -504,7 +544,8 @@ #'CDOUBLE', #'DATETIME', 'UINT': self.w_uint32dtype, - 'INTP': self.w_longdtype, + 'INTP': self.w_intpdtype, + 'UINTP': self.w_uintpdtype, #'HALF', 'BYTE': self.w_int8dtype, #'CFLOAT': , 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 @@ -150,6 +150,9 @@ "supported for binary functions")) assert isinstance(self, W_Ufunc2) obj = convert_to_array(space, w_obj) + if obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('cannot perform reduce for flexible type')) obj_shape = obj.get_shape() if obj.is_scalar(): return obj.get_scalar_value() @@ -235,6 +238,9 @@ if space.is_w(out, space.w_None): out = None w_obj = convert_to_array(space, w_obj) + if w_obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('Not implemented for this type')) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -301,6 +307,10 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) + if w_lhs.get_dtype().is_flexible_type() or \ + w_rhs.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('unsupported operand types')) calc_dtype = find_binop_result_dtype(space, w_lhs.get_dtype(), w_rhs.get_dtype(), int_only=self.int_only, @@ -447,6 +457,7 @@ int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype complex_type = interp_dtype.get_dtype_cache(space).w_complex128dtype float_type = interp_dtype.get_dtype_cache(space).w_float64dtype + str_dtype = interp_dtype.get_dtype_cache(space).w_stringdtype if isinstance(w_obj, interp_boxes.W_GenericBox): dtype = w_obj.get_dtype(space) if current_guess is None: @@ -473,6 +484,15 @@ current_guess is complex_type or current_guess is float_type): return complex_type return current_guess + elif space.isinstance_w(w_obj, space.w_str): + if (current_guess is None): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + elif current_guess.num ==18: + if current_guess.itemtype.get_size() < space.len_w(w_obj): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + return current_guess if current_guess is complex_type: return complex_type return interp_dtype.get_dtype_cache(space).w_float64dtype diff --git a/pypy/module/micronumpy/stdobjspace.py b/pypy/module/micronumpy/stdobjspace.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/stdobjspace.py @@ -0,0 +1,11 @@ + +from pypy.objspace.std import stringobject +from pypy.module.micronumpy import interp_boxes + +def delegate_stringbox2stringobj(space, w_box): + return space.wrap(w_box.dtype.itemtype.to_str(w_box)) + +def register_delegates(typeorder): + typeorder[interp_boxes.W_StringBox] = [ + (stringobject.W_StringObject, delegate_stringbox2stringobj), + ] diff --git a/pypy/module/micronumpy/test/test_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 @@ -31,6 +31,8 @@ from _numpypy import dtype assert dtype(bool).num == 0 + assert dtype('intp').num == 5 + assert dtype('uintp').num == 6 assert dtype(int).num == 7 assert dtype(long).num == 9 assert dtype(float).num == 12 @@ -176,10 +178,15 @@ def test_cant_subclass(self): from _numpypy import dtype - # You can't subclass dtype raises(TypeError, type, "Foo", (dtype,), {}) + def test_can_subclass(self): + import _numpypy + class xyz(_numpypy.void): + pass + assert True + def test_aliases(self): from _numpypy import dtype @@ -228,6 +235,17 @@ class AppTestTypes(BaseNumpyAppTest): + def setup_class(cls): + BaseNumpyAppTest.setup_class.im_func(cls) + if option.runappdirect: + import platform + bits, linkage = platform.architecture() + ptr_size = int(bits[:-3]) // 8 + else: + from pypy.rpython.lltypesystem import rffi + ptr_size = rffi.sizeof(rffi.CCHARP) + cls.w_ptr_size = cls.space.wrap(ptr_size) + def test_abstract_types(self): import _numpypy as numpy raises(TypeError, numpy.generic, 0) @@ -269,7 +287,9 @@ def test_int8(self): import _numpypy as numpy - assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, object] a = numpy.array([1, 2, 3], numpy.int8) assert type(a[1]) is numpy.int8 @@ -291,7 +311,9 @@ def test_uint8(self): import _numpypy as numpy - assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, + numpy.integer, numpy.number, + numpy.generic, object] a = numpy.array([1, 2, 3], numpy.uint8) assert type(a[1]) is numpy.uint8 @@ -361,16 +383,22 @@ import _numpypy as numpy assert numpy.int_ is numpy.dtype(int).type - assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, int, object] + assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, int, object] def test_int64(self): import sys import _numpypy as numpy if sys.maxint == 2 ** 63 -1: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, int, object] + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, int, object] else: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, object] assert numpy.dtype(numpy.int64).type is numpy.int64 assert numpy.int64(3) == 3 @@ -385,7 +413,9 @@ import sys import _numpypy as numpy - assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, + numpy.integer, numpy.number, + numpy.generic, object] assert numpy.dtype(numpy.uint64).type is numpy.uint64 skip("see comment") @@ -400,7 +430,9 @@ def test_float32(self): import _numpypy as numpy - assert numpy.float32.mro() == [numpy.float32, numpy.floating, numpy.inexact, numpy.number, numpy.generic, object] + assert numpy.float32.mro() == [numpy.float32, numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, object] assert numpy.float32(12) == numpy.float64(12) assert numpy.float32('23.4') == numpy.float32(23.4) @@ -409,7 +441,9 @@ def test_float64(self): import _numpypy as numpy - assert numpy.float64.mro() == [numpy.float64, numpy.floating, numpy.inexact, numpy.number, numpy.generic, float, object] + assert numpy.float64.mro() == [numpy.float64, numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, float, object] a = numpy.array([1, 2, 3], numpy.float64) assert type(a[1]) is numpy.float64 @@ -508,15 +542,16 @@ def test_various_types(self): import _numpypy as numpy - import sys assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte assert numpy.bool_ is numpy.bool8 - if sys.maxint == (1 << 63) - 1: - assert '%r' % numpy.intp == '%r' % numpy.int64 - else: - assert '%r' % numpy.intp == '%r' % numpy.int32 + if self.ptr_size == 4: + assert numpy.intp is numpy.int32 + assert numpy.uintp is numpy.uint32 + elif self.ptr_size == 8: + assert numpy.intp is numpy.int64 + assert numpy.uintp is numpy.uint64 def test_mro(self): import _numpypy as numpy @@ -562,6 +597,11 @@ assert dtype('=i8').byteorder == '=' assert dtype(byteorder + 'i8').byteorder == '=' + def test_intp(self): + from _numpypy import dtype + assert dtype('p') == dtype('intp') + assert dtype('P') == dtype('uintp') + def test_alignment(self): from _numpypy import dtype assert dtype('i4').alignment == 4 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 @@ -2238,7 +2238,49 @@ assert arr[1]['y']['y'] == 3.5 assert arr[1]['y']['x'] == 0.0 assert arr[1]['x'] == 15 - + + def test_string_record(self): + from _numpypy import dtype, array + d = dtype([('x', str), ('y', 'int32')]) + assert d.fields['x'] == (dtype(str), 0) + assert d.fields['y'] == (dtype('int32'), 1) + d = dtype([('x', 'S1'), ('y', 'int32')]) + assert d.fields['x'] == (dtype(str), 0) + assert d.fields['y'] == (dtype('int32'), 1) + a = array([('a', 2), ('c', 1)], dtype=d) + assert a[1]['y'] == 1 + assert a[0]['x'] == 'a' + + def test_stringarray(self): + from _numpypy import array, flexible + a = array(['abc'],'S3') + assert str(a.dtype) == '|S3' + a = array(['abc']) + assert str(a.dtype) == '|S3' + a = array(['abc','defg','ab']) + assert str(a.dtype) == '|S4' + assert a[0] == 'abc' + assert a[1] == 'defg' + assert a[2] == 'ab' + raises(TypeError, a, 'sum') + raises(TypeError, 'a+a') + + def test_flexible_repr(self): + # import overrides str(), repr() for array + from numpypy.core import arrayprint + from _numpypy import array + a = array(['abc'],'S3') + s = repr(a) + # simplify test for \n in repr + assert s.replace('\n', '') == "array(['abc'], dtype='|S3')" + # but make sure it exists + assert s.find('\n') == 15 + a = array(['abc','defg','ab']) + s = repr(a) + assert s.replace('\n', '') == \ + "array(['abc', 'defg', 'ab'], dtype='|S4')" + + class AppTestPyPy(BaseNumpyAppTest): def setup_class(cls): if option.runappdirect and '__pypy__' not in sys.builtin_module_names: 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 @@ -16,6 +16,7 @@ from pypy.rlib.rstruct.runpack import runpack from pypy.tool.sourcetools import func_with_new_name from pypy.rlib import jit +from pypy.rlib.rstring import StringBuilder degToRad = math.pi / 180.0 @@ -1464,9 +1465,53 @@ def get_element_size(self): return self.size * rffi.sizeof(self.T) + def get_size(self): + return self.size + class StringType(BaseType, BaseStringType): T = lltype.Char + @jit.unroll_safe + def coerce(self, space, dtype, w_item): + from pypy.module.micronumpy.interp_dtype import new_string_dtype + arg = space.str_w(space.str(w_item)) + arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) + for i in range(len(arg)): + arr.storage[i] = arg[i] + return interp_boxes.W_StringBox(arr, 0, None) + + @jit.unroll_safe + def store(self, arr, i, offset, box): + assert isinstance(box, interp_boxes.W_StringBox) + for k in range(min(self.size, box.arr.size-offset)): + arr.storage[k + i] = box.arr.storage[k + offset] + + def read(self, arr, i, offset, dtype=None): + if dtype is None: + dtype = arr.dtype + return interp_boxes.W_StringBox(arr, i + offset, dtype) + + @jit.unroll_safe + def to_str(self, item): + builder = StringBuilder() + assert isinstance(item, interp_boxes.W_StringBox) + i = item.ofs + end = i+self.size + while i < end: + assert isinstance(item.arr.storage[i], str) + if item.arr.storage[i] == '\x00': + break + builder.append(item.arr.storage[i]) + i += 1 + return builder.build() + + def str_format(self, item): + builder = StringBuilder() + builder.append("'") + builder.append(self.to_str(item)) + builder.append("'") + return builder.build() + class VoidType(BaseType, BaseStringType): T = lltype.Char 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 @@ -182,6 +182,10 @@ (complexobject.W_ComplexObject, smallintobject.delegate_SmallInt2Complex), ] + if config.objspace.usemodules.micronumpy: + from pypy.module.micronumpy.stdobjspace import register_delegates + register_delegates(self.typeorder) + self.typeorder[boolobject.W_BoolObject] += [ (intobject.W_IntObject, boolobject.delegate_Bool2IntObject), (floatobject.W_FloatObject, floatobject.delegate_Bool2Float), From noreply at buildbot.pypy.org Sat Oct 27 20:17:10 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 20:17:10 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: (agaynor, fijal) in-progress Message-ID: <20121027181710.75F131C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58512:9967bfdae13e Date: 2012-10-27 20:14 +0200 http://bitbucket.org/pypy/pypy/changeset/9967bfdae13e/ Log: (agaynor, fijal) in-progress diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -7,6 +7,7 @@ INT, REF, ConstInt, Const from pypy.jit.metainterp.optimizeopt.intutils import ImmutableIntUnbounded,\ ConstantIntBound, IntBound +from pypy.jit.metainterp.virtualmodel import declare_virtual class __extend__(ConstInt): def getintbound(self): @@ -73,19 +74,12 @@ is_mutable = True attributes_to_copy = [] - if cls.getopnum() in (rop.NEW_WITH_VTABLE, rop.NEW): - def force(self, optimizer): - if not self._isforced: - optimizer.emit_operation(self) - self._isforced = True - return self - def is_virtual(self): - return not self._isforced - else: - def force(self, _): - return self - def is_virtual(self): - return False + def force(self, _): + return self + def is_virtual(self): + return False + if op.getopnum() == rop.NEW_WITH_VTABLE: + Mutable = declare_virtual(Mutable) if cls.is_guard() or cls.getopnum() == rop.FINISH: addattr(Mutable, 'failargs') if cls.is_guard(): diff --git a/pypy/jit/metainterp/virtualmodel.py b/pypy/jit/metainterp/virtualmodel.py new file mode 100644 --- /dev/null +++ b/pypy/jit/metainterp/virtualmodel.py @@ -0,0 +1,12 @@ + +def declare_virtual(cls): + class Virtual(cls): + def force(self, optimizer): + if not self._isforced: + optimizer.emit_operation(self) + self._isforced = True + return self + + def is_virtual(self): + return not self._isforced + return Virtual From noreply at buildbot.pypy.org Sat Oct 27 20:17:11 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 20:17:11 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: imerged upstream Message-ID: <20121027181711.C11F31C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58513:914ee3eb41e9 Date: 2012-10-27 20:17 +0200 http://bitbucket.org/pypy/pypy/changeset/914ee3eb41e9/ Log: imerged upstream diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -1,4 +1,7 @@ +import random + import py + from pypy.rlib.objectmodel import instantiate from pypy.jit.metainterp.optimizeopt.test.test_util import ( LLtypeMixin, BaseTest, FakeMetaInterpStaticData, convert_old_style_to_targets) @@ -13,6 +16,7 @@ from pypy.jit.metainterp.test.support import boxint from pypy.rlib.rarithmetic import LONG_BIT + def test_store_final_boxes_in_guard(): from pypy.jit.metainterp.resume import tag, TAGBOX b0 = boxint() @@ -185,9 +189,9 @@ self.optimize_loop(ops, expected) def test_constfold_all(self): - from pypy.jit.metainterp.optimizeopt.test.types import TYPES # xxx fish + from pypy.jit.metainterp.optimizeopt.test.types import TYPES from pypy.jit.metainterp.executor import execute_nonspec - import random + for opnum in [rop._ALWAYS_PURE_FIRST, rop._ALWAYS_PURE_NO_PTR_LAST]: try: op = opname[opnum] @@ -195,8 +199,6 @@ continue if op.startswith('_'): continue - if 'FLOAT' in op: - continue argtypes, restype = TYPES[op.lower()] args = [] for argtype in argtypes: From noreply at buildbot.pypy.org Sat Oct 27 20:33:08 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 20:33:08 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: start porting virtuals Message-ID: <20121027183309.0039C1C05ED@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58514:677f50b5f832 Date: 2012-10-27 20:32 +0200 http://bitbucket.org/pypy/pypy/changeset/677f50b5f832/ Log: start porting virtuals diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py --- a/pypy/jit/metainterp/optimizeopt/virtualize.py +++ b/pypy/jit/metainterp/optimizeopt/virtualize.py @@ -435,11 +435,10 @@ self.replace(op, fieldvalue.op) return if value.is_virtual(): - assert isinstance(value, AbstractVirtualValue) fieldvalue = value.getfield(op.getdescr(), None) if fieldvalue is None: fieldvalue = self.optimizer.new_const(op.getdescr()) - self.replace(op, fieldvalue.op) + self.optimizer.replace(op, fieldvalue) else: value.ensure_nonnull() self.emit_operation(op) @@ -457,7 +456,6 @@ if value.is_virtual(): fieldvalue = self.getforwarded(op.getarg(1)) - xxx value.setfield(op.getdescr(), fieldvalue) else: xxx @@ -465,8 +463,7 @@ return op def optimize_NEW_WITH_VTABLE(self, op): - value = self.getforwarded(op) - value.setknownclass(op.getarg(0)) + pass def optimize_NEW(self, op): self.make_vstruct(op.getdescr(), op) diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -4,10 +4,10 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable, rop,\ - INT, REF, ConstInt, Const + INT, REF, ConstInt, Const, ConstPtr from pypy.jit.metainterp.optimizeopt.intutils import ImmutableIntUnbounded,\ ConstantIntBound, IntBound -from pypy.jit.metainterp.virtualmodel import declare_virtual +from pypy.jit.metainterp.virtualmodel import Virtual class __extend__(ConstInt): def getintbound(self): @@ -16,6 +16,13 @@ def getboolres(self): return False # for optimization +class __extend__(ConstPtr): + def is_virtual(self): + return False + + def is_forced_virtual(self): + return False + class __extend__(Const): def getlastguardpos(self): return -1 @@ -29,9 +36,12 @@ def is_null(self): return not self.nonnull() +opclasses_mutable[rop.NEW_WITH_VTABLE] = Virtual + def create_mutable_subclasses(): def addattr(cls, attr, default_value=None): - cls.attributes_to_copy.append('_' + attr) + if hasattr(cls, 'attributes_to_copy'): + cls.attributes_to_copy.append('_' + attr) def getter(self): return getattr(self, '_' + attr) def setter(self, value): @@ -68,7 +78,10 @@ imm_int_unbound = ImmutableIntUnbounded() for i, cls in enumerate(opclasses): if cls is None: - Mutable = None + continue + elif opclasses_mutable[cls.getopnum()] is not None: + addattr(opclasses_mutable[cls.getopnum()], 'lastguardpos') + continue else: class Mutable(cls): is_mutable = True @@ -78,8 +91,9 @@ return self def is_virtual(self): return False - if op.getopnum() == rop.NEW_WITH_VTABLE: - Mutable = declare_virtual(Mutable) + def is_forced_virtual(self): + return False + if cls.is_guard() or cls.getopnum() == rop.FINISH: addattr(Mutable, 'failargs') if cls.is_guard(): @@ -95,16 +109,12 @@ addattr(Mutable, 'knownnonnull', False) Mutable.is_nonnull = ref_is_nonnull Mutable.is_null = ref_is_null - if cls.getopnum() in (rop.NEW_WITH_VTABLE, rop.NEW): - addattr(Mutable, 'isforced', False) # for tracking last guard and merging GUARD_VALUE with # GUARD_NONNULL etc addattr(Mutable, 'lastguardpos', -1) Mutable.__name__ = cls.__name__ + '_mutable' if Mutable.attributes_to_copy: make_new_copy_function(Mutable, cls) - assert len(opclasses_mutable) == i - opclasses_mutable.append(Mutable) - assert len(opclasses) == len(opclasses_mutable) + opclasses_mutable[i] = Mutable create_mutable_subclasses() diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -1404,6 +1404,8 @@ pass def setup(debug_print=False): + global opclasses_mutable + i = 0 for basename in _oplist: if '/' in basename: @@ -1446,6 +1448,7 @@ if k.startswith('CALL'): ALLCALLS.append(v) opgroups.ALLCALLS = tuple(ALLCALLS) + opclasses_mutable = [None] * len(opclasses) def get_base_class(mixin, tpmixin, base): try: diff --git a/pypy/jit/metainterp/virtualmodel.py b/pypy/jit/metainterp/virtualmodel.py --- a/pypy/jit/metainterp/virtualmodel.py +++ b/pypy/jit/metainterp/virtualmodel.py @@ -1,12 +1,45 @@ -def declare_virtual(cls): - class Virtual(cls): - def force(self, optimizer): - if not self._isforced: - optimizer.emit_operation(self) - self._isforced = True - return self - - def is_virtual(self): - return not self._isforced - return Virtual +from pypy.jit.metainterp.resoperation import rop, opclasses + +NEW_WITH_VTABLE = opclasses[rop.NEW_WITH_VTABLE] + +class Virtual(NEW_WITH_VTABLE): + is_mutable = True + + def __init__(self, pval): + NEW_WITH_VTABLE.__init__(self, pval) + self._fields = {} # XXX convert from dict to a list + self._is_forced = False + + def getfield(self, ofs, default): + return self._fields.get(ofs, default) + + def setfield(self, ofs, fieldvalue): + self._fields[ofs] = fieldvalue + + def getknownclass(self): + return self.getarg(0) + + def setknownclass(self, cls): + pass # ignore + + def is_nonnull(self): + return True + + def is_null(self): + return False + + def _copy_extra_attrs(self, new): + raise Exception("Virtual should not be forwarded") + + def force(self, optimizer): + if not self._is_forced: + optimizer.emit_operation(self) + self._is_forced = True + return self + + def is_virtual(self): + return not self._is_forced + + def is_forced_virtual(self): + return self._is_forced From noreply at buildbot.pypy.org Sat Oct 27 21:33:46 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 21:33:46 +0200 (CEST) Subject: [pypy-commit] pypy default: a passing test Message-ID: <20121027193347.000E11C0257@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58515:26b36d793c7e Date: 2012-10-27 21:32 +0200 http://bitbucket.org/pypy/pypy/changeset/26b36d793c7e/ Log: a passing test diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -344,6 +344,13 @@ assert a[-1] == 8 raises(IndexError, "a[-6]") + def test_getitem_float(self): + from _numpypy import array + a = array([1, 2, 3, 4]) + assert a[1.2] == 2 + assert a[1.6] == 2 + assert a[-1.2] == 4 + def test_getitem_tuple(self): from _numpypy import array a = array(range(5)) From noreply at buildbot.pypy.org Sat Oct 27 21:33:48 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 21:33:48 +0200 (CEST) Subject: [pypy-commit] pypy default: merge Message-ID: <20121027193348.91FCA1C0257@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58516:8a98d2b926ad Date: 2012-10-27 21:33 +0200 http://bitbucket.org/pypy/pypy/changeset/8a98d2b926ad/ Log: merge diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,5 +1,5 @@ -from _numpypy import array, ndarray, int_, float_, bool_ #, complex_# , longlong +from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math @@ -200,7 +200,7 @@ typename = "'%s'" % typename lf = '' - if 0: # or issubclass(arr.dtype.type, flexible): + if issubclass(arr.dtype.type, flexible): if arr.dtype.names: typename = "%s" % str(arr.dtype) else: 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 @@ -233,7 +233,7 @@ try: return unicode(line, ENCODING) except UnicodeDecodeError: # bah, silently fall back... - return unicode(line, 'utf-8') + return unicode(line, 'utf-8', 'replace') def get_history_length(self): return self.saved_history_length diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -496,7 +496,7 @@ if iscode: self.__tputs(text) else: - os.write(self.output_fd, text.encode(self.encoding)) + os.write(self.output_fd, text.encode(self.encoding, 'replace')) del self.__buffer[:] def __tputs(self, fmt, prog=delayprog): diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -548,7 +548,7 @@ if cell.is_constant(): newcell.const = cell.const cell = newcell - cell.knowntypedata = renamed_knowntypedata + cell.set_knowntypedata(renamed_knowntypedata) cells.append(cell) diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -144,7 +144,7 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key annotator = bk.annotator @@ -168,6 +168,7 @@ bind(obj2, obj1, 0) bind(obj1, obj2, 1) + r.set_knowntypedata(knowntypedata) return r @@ -337,8 +338,7 @@ case = opname in ('gt', 'ge', 'eq') add_knowntypedata(knowntypedata, case, [op.args[0]], SomeInteger(nonneg=True, knowntype=tointtype(int1))) - if knowntypedata: - r.knowntypedata = knowntypedata + r.set_knowntypedata(knowntypedata) # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) @@ -369,8 +369,7 @@ if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) - if ktd: - s.knowntypedata = ktd + s.set_knowntypedata(ktd) return s def and_((boo1, boo2)): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -188,10 +188,10 @@ variables = [op.args[1]] for variable in variables: assert bk.annotator.binding(variable) == s_obj - r.knowntypedata = {} - + knowntypedata = {} if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): - add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) + add_knowntypedata(knowntypedata, True, variables, bk.valueoftype(typ)) + r.set_knowntypedata(knowntypedata) return r # note that this one either needs to be constant, or we will create SomeObject diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -195,6 +195,10 @@ unsigned = False def __init__(self): pass + def set_knowntypedata(self, knowntypedata): + assert not hasattr(self, 'knowntypedata') + if knowntypedata: + self.knowntypedata = knowntypedata class SomeStringOrUnicode(SomeObject): immutable = True diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -76,7 +76,7 @@ s_obj.is_true_behavior(r) bk = getbookkeeper() - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key op = block.operations[i] assert op.opname == "is_true" or op.opname == "nonzero" @@ -86,8 +86,8 @@ if s_obj.can_be_none(): s_nonnone_obj = s_obj.nonnoneify() add_knowntypedata(knowntypedata, True, [arg], s_nonnone_obj) + r.set_knowntypedata(knowntypedata) return r - def nonzero(obj): return obj.is_true() diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -118,7 +118,7 @@ ("translation.gcrootfinder", DEFL_ROOTFINDER_WITHJIT), ("translation.list_comprehension_operations", True)]), ChoiceOption("jit_backend", "choose the backend for the JIT", - ["auto", "x86", "x86-without-sse2", "llvm", 'arm'], + ["auto", "x86", "x86-without-sse2", 'arm'], default="auto", cmdline="--jit-backend"), ChoiceOption("jit_profiler", "integrate profiler support into the JIT", ["off", "oprofile"], 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 @@ -38,6 +38,8 @@ .. branch: numpypy-complex2 Complex dtype support for numpy +.. branch: numpypy-problems +Improve dtypes intp, uintp, void, string and record .. branch: kill-someobject major cleanups including killing some object support diff --git a/pypy/jit/backend/detect_cpu.py b/pypy/jit/backend/detect_cpu.py --- a/pypy/jit/backend/detect_cpu.py +++ b/pypy/jit/backend/detect_cpu.py @@ -77,8 +77,6 @@ return "pypy.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "pypy.jit.backend.cli.runner", "CliCPU" - elif backend_name == 'llvm': - return "pypy.jit.backend.llvm.runner", "LLVMCPU" elif backend_name == 'arm': return "pypy.jit.backend.arm.runner", "CPU_ARM" elif backend_name == 'armhf': diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -62,6 +62,7 @@ 'flexible': 'interp_boxes.W_FlexibleBox', 'character': 'interp_boxes.W_CharacterBox', 'str_': 'interp_boxes.W_StringBox', + 'string_': 'interp_boxes.W_StringBox', 'unicode_': 'interp_boxes.W_UnicodeBox', 'void': 'interp_boxes.W_VoidBox', 'complexfloating': 'interp_boxes.W_ComplexFloatingBox', diff --git a/pypy/module/micronumpy/arrayimpl/voidbox.py b/pypy/module/micronumpy/arrayimpl/voidbox.py --- a/pypy/module/micronumpy/arrayimpl/voidbox.py +++ b/pypy/module/micronumpy/arrayimpl/voidbox.py @@ -6,6 +6,7 @@ def __init__(self, size, dtype): self.storage = alloc_raw_storage(size) self.dtype = dtype + self.size = size def __del__(self): free_raw_storage(self.storage) 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 @@ -246,7 +246,11 @@ except KeyError: raise OperationError(space.w_IndexError, space.wrap("Field %s does not exist" % item)) - return dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + if isinstance (read_val, W_StringBox): + # StringType returns a str + return space.wrap(dtype.itemtype.to_str(read_val)) + return read_val @unwrap_spec(item=str) def descr_setitem(self, space, item, w_value): @@ -271,6 +275,13 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) + # Running entire test suite needs this function to succeed, + # running single test_stringarray succeeds without it. + # With convert_to() test_ztranslation fails since + # W_CharacterBox is not a W_GenericBox. + # Why is it needed for multiple tests? + #def convert_to(self, dtype): + # xxx class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -474,6 +485,7 @@ W_VoidBox.typedef = TypeDef("void", W_FlexibleBox.typedef, __module__ = "numpypy", + __new__ = interp2app(W_VoidBox.descr__new__.im_func), __getitem__ = interp2app(W_VoidBox.descr_getitem), __setitem__ = interp2app(W_VoidBox.descr_setitem), ) 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 @@ -8,6 +8,7 @@ from pypy.module.micronumpy import types, interp_boxes from pypy.rlib.objectmodel import specialize from pypy.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong +from pypy.rpython.lltypesystem import rffi UNSIGNEDLTR = "u" @@ -17,6 +18,8 @@ VOIDLTR = 'V' STRINGLTR = 'S' UNICODELTR = 'U' +INTPLTR = 'p' +UINTPLTR = 'P' def decode_w_dtype(space, w_dtype): if space.is_none(w_dtype): @@ -66,11 +69,16 @@ def fill(self, storage, box, start, stop): self.itemtype.fill(storage, self.get_size(), box, start, stop, 0) + def get_name(self): + if self.char == 'S': + return '|S' + str(self.get_size()) + return self.name + def descr_str(self, space): - return space.wrap(self.name) + return space.wrap(self.get_name()) def descr_repr(self, space): - return space.wrap("dtype('%s')" % self.name) + return space.wrap("dtype('%s')" % self.get_name()) def descr_get_itemsize(self, space): return space.wrap(self.itemtype.get_element_size()) @@ -135,6 +143,9 @@ def is_record_type(self): return self.fields is not None + def is_flexible_type(self): + return (self.num == 18 or self.num == 19 or self.num == 20) + def __repr__(self): if self.fields is not None: return '' % self.fields @@ -454,6 +465,35 @@ #alternate_constructors=[space.w_buffer], # XXX no buffer in space ) + ptr_size = rffi.sizeof(rffi.CCHARP) + if ptr_size == 4: + intp_box = interp_boxes.W_Int32Box + intp_type = types.Int32() + uintp_box = interp_boxes.W_UInt32Box + uintp_type = types.UInt32() + elif ptr_size == 8: + intp_box = interp_boxes.W_Int64Box + intp_type = types.Int64() + uintp_box = interp_boxes.W_UInt64Box + uintp_type = types.UInt64() + else: + raise ValueError('unknown point size %d' % ptr_size) + self.w_intpdtype = W_Dtype( + intp_type, + num=5, + kind=INTPLTR, + name='intp', + char=INTPLTR, + w_box_type = space.gettypefor(intp_box), + ) + self.w_uintpdtype = W_Dtype( + uintp_type, + num=6, + kind=UINTPLTR, + name='uintp', + char=UINTPLTR, + w_box_type = space.gettypefor(uintp_box), + ) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, @@ -462,7 +502,7 @@ self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, self.w_complex128dtype, self.w_stringdtype, self.w_unicodedtype, - self.w_voiddtype, + self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) @@ -504,7 +544,8 @@ #'CDOUBLE', #'DATETIME', 'UINT': self.w_uint32dtype, - 'INTP': self.w_longdtype, + 'INTP': self.w_intpdtype, + 'UINTP': self.w_uintpdtype, #'HALF', 'BYTE': self.w_int8dtype, #'CFLOAT': , 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 @@ -150,6 +150,9 @@ "supported for binary functions")) assert isinstance(self, W_Ufunc2) obj = convert_to_array(space, w_obj) + if obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('cannot perform reduce for flexible type')) obj_shape = obj.get_shape() if obj.is_scalar(): return obj.get_scalar_value() @@ -235,6 +238,9 @@ if space.is_w(out, space.w_None): out = None w_obj = convert_to_array(space, w_obj) + if w_obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('Not implemented for this type')) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -301,6 +307,10 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) + if w_lhs.get_dtype().is_flexible_type() or \ + w_rhs.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('unsupported operand types')) calc_dtype = find_binop_result_dtype(space, w_lhs.get_dtype(), w_rhs.get_dtype(), int_only=self.int_only, @@ -447,6 +457,7 @@ int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype complex_type = interp_dtype.get_dtype_cache(space).w_complex128dtype float_type = interp_dtype.get_dtype_cache(space).w_float64dtype + str_dtype = interp_dtype.get_dtype_cache(space).w_stringdtype if isinstance(w_obj, interp_boxes.W_GenericBox): dtype = w_obj.get_dtype(space) if current_guess is None: @@ -473,6 +484,15 @@ current_guess is complex_type or current_guess is float_type): return complex_type return current_guess + elif space.isinstance_w(w_obj, space.w_str): + if (current_guess is None): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + elif current_guess.num ==18: + if current_guess.itemtype.get_size() < space.len_w(w_obj): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + return current_guess if current_guess is complex_type: return complex_type return interp_dtype.get_dtype_cache(space).w_float64dtype diff --git a/pypy/module/micronumpy/stdobjspace.py b/pypy/module/micronumpy/stdobjspace.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/stdobjspace.py @@ -0,0 +1,11 @@ + +from pypy.objspace.std import stringobject +from pypy.module.micronumpy import interp_boxes + +def delegate_stringbox2stringobj(space, w_box): + return space.wrap(w_box.dtype.itemtype.to_str(w_box)) + +def register_delegates(typeorder): + typeorder[interp_boxes.W_StringBox] = [ + (stringobject.W_StringObject, delegate_stringbox2stringobj), + ] diff --git a/pypy/module/micronumpy/test/test_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 @@ -31,6 +31,8 @@ from _numpypy import dtype assert dtype(bool).num == 0 + assert dtype('intp').num == 5 + assert dtype('uintp').num == 6 assert dtype(int).num == 7 assert dtype(long).num == 9 assert dtype(float).num == 12 @@ -176,10 +178,15 @@ def test_cant_subclass(self): from _numpypy import dtype - # You can't subclass dtype raises(TypeError, type, "Foo", (dtype,), {}) + def test_can_subclass(self): + import _numpypy + class xyz(_numpypy.void): + pass + assert True + def test_aliases(self): from _numpypy import dtype @@ -228,6 +235,17 @@ class AppTestTypes(BaseNumpyAppTest): + def setup_class(cls): + BaseNumpyAppTest.setup_class.im_func(cls) + if option.runappdirect: + import platform + bits, linkage = platform.architecture() + ptr_size = int(bits[:-3]) // 8 + else: + from pypy.rpython.lltypesystem import rffi + ptr_size = rffi.sizeof(rffi.CCHARP) + cls.w_ptr_size = cls.space.wrap(ptr_size) + def test_abstract_types(self): import _numpypy as numpy raises(TypeError, numpy.generic, 0) @@ -269,7 +287,9 @@ def test_int8(self): import _numpypy as numpy - assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, object] a = numpy.array([1, 2, 3], numpy.int8) assert type(a[1]) is numpy.int8 @@ -291,7 +311,9 @@ def test_uint8(self): import _numpypy as numpy - assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, + numpy.integer, numpy.number, + numpy.generic, object] a = numpy.array([1, 2, 3], numpy.uint8) assert type(a[1]) is numpy.uint8 @@ -361,16 +383,22 @@ import _numpypy as numpy assert numpy.int_ is numpy.dtype(int).type - assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, int, object] + assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, int, object] def test_int64(self): import sys import _numpypy as numpy if sys.maxint == 2 ** 63 -1: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, int, object] + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, int, object] else: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, object] assert numpy.dtype(numpy.int64).type is numpy.int64 assert numpy.int64(3) == 3 @@ -385,7 +413,9 @@ import sys import _numpypy as numpy - assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, + numpy.integer, numpy.number, + numpy.generic, object] assert numpy.dtype(numpy.uint64).type is numpy.uint64 skip("see comment") @@ -400,7 +430,9 @@ def test_float32(self): import _numpypy as numpy - assert numpy.float32.mro() == [numpy.float32, numpy.floating, numpy.inexact, numpy.number, numpy.generic, object] + assert numpy.float32.mro() == [numpy.float32, numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, object] assert numpy.float32(12) == numpy.float64(12) assert numpy.float32('23.4') == numpy.float32(23.4) @@ -409,7 +441,9 @@ def test_float64(self): import _numpypy as numpy - assert numpy.float64.mro() == [numpy.float64, numpy.floating, numpy.inexact, numpy.number, numpy.generic, float, object] + assert numpy.float64.mro() == [numpy.float64, numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, float, object] a = numpy.array([1, 2, 3], numpy.float64) assert type(a[1]) is numpy.float64 @@ -508,15 +542,16 @@ def test_various_types(self): import _numpypy as numpy - import sys assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte assert numpy.bool_ is numpy.bool8 - if sys.maxint == (1 << 63) - 1: - assert '%r' % numpy.intp == '%r' % numpy.int64 - else: - assert '%r' % numpy.intp == '%r' % numpy.int32 + if self.ptr_size == 4: + assert numpy.intp is numpy.int32 + assert numpy.uintp is numpy.uint32 + elif self.ptr_size == 8: + assert numpy.intp is numpy.int64 + assert numpy.uintp is numpy.uint64 def test_mro(self): import _numpypy as numpy @@ -562,6 +597,11 @@ assert dtype('=i8').byteorder == '=' assert dtype(byteorder + 'i8').byteorder == '=' + def test_intp(self): + from _numpypy import dtype + assert dtype('p') == dtype('intp') + assert dtype('P') == dtype('uintp') + def test_alignment(self): from _numpypy import dtype assert dtype('i4').alignment == 4 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 @@ -2245,7 +2245,49 @@ assert arr[1]['y']['y'] == 3.5 assert arr[1]['y']['x'] == 0.0 assert arr[1]['x'] == 15 - + + def test_string_record(self): + from _numpypy import dtype, array + d = dtype([('x', str), ('y', 'int32')]) + assert d.fields['x'] == (dtype(str), 0) + assert d.fields['y'] == (dtype('int32'), 1) + d = dtype([('x', 'S1'), ('y', 'int32')]) + assert d.fields['x'] == (dtype(str), 0) + assert d.fields['y'] == (dtype('int32'), 1) + a = array([('a', 2), ('c', 1)], dtype=d) + assert a[1]['y'] == 1 + assert a[0]['x'] == 'a' + + def test_stringarray(self): + from _numpypy import array, flexible + a = array(['abc'],'S3') + assert str(a.dtype) == '|S3' + a = array(['abc']) + assert str(a.dtype) == '|S3' + a = array(['abc','defg','ab']) + assert str(a.dtype) == '|S4' + assert a[0] == 'abc' + assert a[1] == 'defg' + assert a[2] == 'ab' + raises(TypeError, a, 'sum') + raises(TypeError, 'a+a') + + def test_flexible_repr(self): + # import overrides str(), repr() for array + from numpypy.core import arrayprint + from _numpypy import array + a = array(['abc'],'S3') + s = repr(a) + # simplify test for \n in repr + assert s.replace('\n', '') == "array(['abc'], dtype='|S3')" + # but make sure it exists + assert s.find('\n') == 15 + a = array(['abc','defg','ab']) + s = repr(a) + assert s.replace('\n', '') == \ + "array(['abc', 'defg', 'ab'], dtype='|S4')" + + class AppTestPyPy(BaseNumpyAppTest): def setup_class(cls): if option.runappdirect and '__pypy__' not in sys.builtin_module_names: 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 @@ -16,6 +16,7 @@ from pypy.rlib.rstruct.runpack import runpack from pypy.tool.sourcetools import func_with_new_name from pypy.rlib import jit +from pypy.rlib.rstring import StringBuilder degToRad = math.pi / 180.0 @@ -1464,9 +1465,53 @@ def get_element_size(self): return self.size * rffi.sizeof(self.T) + def get_size(self): + return self.size + class StringType(BaseType, BaseStringType): T = lltype.Char + @jit.unroll_safe + def coerce(self, space, dtype, w_item): + from pypy.module.micronumpy.interp_dtype import new_string_dtype + arg = space.str_w(space.str(w_item)) + arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) + for i in range(len(arg)): + arr.storage[i] = arg[i] + return interp_boxes.W_StringBox(arr, 0, None) + + @jit.unroll_safe + def store(self, arr, i, offset, box): + assert isinstance(box, interp_boxes.W_StringBox) + for k in range(min(self.size, box.arr.size-offset)): + arr.storage[k + i] = box.arr.storage[k + offset] + + def read(self, arr, i, offset, dtype=None): + if dtype is None: + dtype = arr.dtype + return interp_boxes.W_StringBox(arr, i + offset, dtype) + + @jit.unroll_safe + def to_str(self, item): + builder = StringBuilder() + assert isinstance(item, interp_boxes.W_StringBox) + i = item.ofs + end = i+self.size + while i < end: + assert isinstance(item.arr.storage[i], str) + if item.arr.storage[i] == '\x00': + break + builder.append(item.arr.storage[i]) + i += 1 + return builder.build() + + def str_format(self, item): + builder = StringBuilder() + builder.append("'") + builder.append(self.to_str(item)) + builder.append("'") + return builder.build() + class VoidType(BaseType, BaseStringType): T = lltype.Char 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 @@ -182,6 +182,10 @@ (complexobject.W_ComplexObject, smallintobject.delegate_SmallInt2Complex), ] + if config.objspace.usemodules.micronumpy: + from pypy.module.micronumpy.stdobjspace import register_delegates + register_delegates(self.typeorder) + self.typeorder[boolobject.W_BoolObject] += [ (intobject.W_IntObject, boolobject.delegate_Bool2IntObject), (floatobject.W_FloatObject, floatobject.delegate_Bool2Float), From noreply at buildbot.pypy.org Sat Oct 27 21:40:10 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 21:40:10 +0200 (CEST) Subject: [pypy-commit] pypy default: promote shape a bit everywhere Message-ID: <20121027194010.5C5141C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58517:f23ed5302cee Date: 2012-10-27 21:37 +0200 http://bitbucket.org/pypy/pypy/changeset/f23ed5302cee/ Log: promote shape a bit everywhere diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -47,7 +47,7 @@ self.skip = array.strides[0] self.dtype = array.dtype self.index = 0 - self.size = array.shape[0] + self.size = array.get_shape()[0] def next(self): self.offset += self.skip @@ -168,7 +168,9 @@ parent = None def get_shape(self): - return self.shape + shape = self.shape + jit.hint(shape, promote=True) + return shape def getitem(self, index): return self.dtype.getitem(self, index) @@ -181,7 +183,7 @@ if impl.is_scalar(): self.fill(impl.get_scalar_value()) return - shape = shape_agreement(space, self.shape, arr) + shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: impl = impl.copy() loop.setslice(shape, self, impl) @@ -193,7 +195,7 @@ # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: - new_strides = calc_new_strides(new_shape, self.shape, + new_strides = calc_new_strides(new_shape, self.get_shape(), self.strides, self.order) if new_strides: # We can create a view, strides somehow match up. @@ -216,10 +218,10 @@ raise IndexError idx = int_w(space, w_index) if idx < 0: - idx = self.shape[i] + idx - if idx < 0 or idx >= self.shape[i]: + idx = self.get_shape()[i] + idx + if idx < 0 or idx >= self.get_shape()[i]: raise operationerrfmt(space.w_IndexError, - "index (%d) out of range (0<=index<%d", i, self.shape[i], + "index (%d) out of range (0<=index<%d", i, self.get_shape()[i], ) item += idx * self.strides[i] return item @@ -227,13 +229,14 @@ @jit.unroll_safe def _lookup_by_unwrapped_index(self, space, lst): item = self.start - assert len(lst) == len(self.shape) + shape = self.get_shape() + assert len(lst) == len(shape) for i, idx in enumerate(lst): if idx < 0: - idx = self.shape[i] + idx - if idx < 0 or idx >= self.shape[i]: + idx = shape[i] + idx + if idx < 0 or idx >= shape[i]: raise operationerrfmt(space.w_IndexError, - "index (%d) out of range (0<=index<%d", i, self.shape[i], + "index (%d) out of range (0<=index<%d", i, shape[i], ) item += idx * self.strides[i] return item @@ -255,7 +258,8 @@ raise IndexError if isinstance(w_idx, W_NDimArray): raise ArrayArgumentException - shape_len = len(self.shape) + shape = self.get_shape() + shape_len = len(shape) if shape_len == 0: raise OperationError(space.w_IndexError, space.wrap( "0-d arrays can't be indexed")) @@ -299,7 +303,7 @@ return RecordChunk(idx) if (space.isinstance_w(w_idx, space.w_int) or space.isinstance_w(w_idx, space.w_slice)): - return Chunks([Chunk(*space.decode_index4(w_idx, self.shape[0]))]) + return Chunks([Chunk(*space.decode_index4(w_idx, self.get_shape()[0]))]) elif space.is_w(w_idx, space.w_None): return Chunks([NewAxisChunk()]) result = [] @@ -309,7 +313,7 @@ result.append(NewAxisChunk()) else: result.append(Chunk(*space.decode_index4(w_item, - self.shape[i]))) + self.get_shape()[i]))) i += 1 return Chunks(result) @@ -333,24 +337,24 @@ view.implementation.setslice(space, w_value) def transpose(self): - if len(self.shape) < 2: + if len(self.get_shape()) < 2: return self strides = [] backstrides = [] shape = [] - for i in range(len(self.shape) - 1, -1, -1): + for i in range(len(self.get_shape()) - 1, -1, -1): strides.append(self.strides[i]) backstrides.append(self.backstrides[i]) - shape.append(self.shape[i]) + shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, backstrides, shape, self) def copy(self): - strides, backstrides = support.calc_strides(self.shape, self.dtype, + strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) - impl = ConcreteArray(self.shape, self.dtype, self.order, strides, + impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(self.shape, impl, self) + return loop.setslice(self.get_shape(), impl, self) def create_axis_iter(self, shape, dim): return AxisIterator(self, shape, dim) @@ -361,7 +365,7 @@ return MultiDimViewIterator(self, self.start, r[0], r[1], shape) def swapaxes(self, axis1, axis2): - shape = self.shape[:] + shape = self.get_shape()[:] strides = self.strides[:] backstrides = self.backstrides[:] shape[axis1], shape[axis2] = shape[axis2], shape[axis1] @@ -384,10 +388,10 @@ self.backstrides = backstrides def create_iter(self, shape): - if shape == self.shape: + if shape == self.get_shape(): return ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.strides, self.backstrides, - self.shape, shape) + self.get_shape(), shape) return MultiDimViewIterator(self, 0, r[0], r[1], shape) def fill(self, box): @@ -421,18 +425,18 @@ loop.fill(self, box.convert_to(self.dtype)) def create_iter(self, shape): - if shape != self.shape: + if shape != self.get_shape(): r = calculate_broadcast_strides(self.strides, self.backstrides, - self.shape, shape) + self.get_shape(), shape) return MultiDimViewIterator(self.parent, self.start, r[0], r[1], shape) - if len(self.shape) == 1: + if len(self.get_shape()) == 1: return OneDimViewIterator(self) return MultiDimViewIterator(self.parent, self.start, self.strides, - self.backstrides, self.shape) + self.backstrides, self.get_shape()) def set_shape(self, space, new_shape): - if len(self.shape) < 2 or self.size == 0: + if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor strides = [] @@ -451,7 +455,7 @@ new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, self) - new_strides = calc_new_strides(new_shape, self.shape, self.strides, + new_strides = calc_new_strides(new_shape, self.get_shape(), self.strides, self.order) if new_strides is None: raise OperationError(space.w_AttributeError, space.wrap( From noreply at buildbot.pypy.org Sat Oct 27 21:40:11 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 21:40:11 +0200 (CEST) Subject: [pypy-commit] pypy default: promote the LENGTH of shape, not the pointer to shape Message-ID: <20121027194011.ABC111C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58518:410ef836304c Date: 2012-10-27 21:37 +0200 http://bitbucket.org/pypy/pypy/changeset/410ef836304c/ Log: promote the LENGTH of shape, not the pointer to shape 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 @@ -169,7 +169,7 @@ def get_shape(self): shape = self.shape - jit.hint(shape, promote=True) + jit.hint(len(shape), promote=True) return shape def getitem(self, index): From noreply at buildbot.pypy.org Sat Oct 27 22:34:40 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 27 Oct 2012 22:34:40 +0200 (CEST) Subject: [pypy-commit] pypy default: Skip this test when running on a version of Python where Message-ID: <20121027203440.A26A61C0250@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58519:3e170e65982c Date: 2012-10-27 22:34 +0200 http://bitbucket.org/pypy/pypy/changeset/3e170e65982c/ Log: Skip this test when running on a version of Python where a "python -S" cannot import extension modules, like a non-installed version on Posix. (See the bug report.) diff --git a/pypy/translator/goal/test2/test_app_main.py b/pypy/translator/goal/test2/test_app_main.py --- a/pypy/translator/goal/test2/test_app_main.py +++ b/pypy/translator/goal/test2/test_app_main.py @@ -689,6 +689,10 @@ child_out_err.close() def test_proper_sys_path(self, tmpdir): + data = self.run('-c "import _ctypes"', python_flags='-S') + if data.startswith('Traceback'): + py.test.skip("'python -S' cannot import extension modules: " + "see probably http://bugs.python.org/issue586680") @contextmanager def chdir_and_unset_pythonpath(new_cwd): From noreply at buildbot.pypy.org Sat Oct 27 23:15:52 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 27 Oct 2012 23:15:52 +0200 (CEST) Subject: [pypy-commit] pypy numpypy.float16: start numpypy.float16 to implement float16 dtype on numpypy Message-ID: <20121027211552.1B21B1C01E7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy.float16 Changeset: r58520:7487b384ef10 Date: 2012-10-26 16:56 +0200 http://bitbucket.org/pypy/pypy/changeset/7487b384ef10/ Log: start numpypy.float16 to implement float16 dtype on numpypy From noreply at buildbot.pypy.org Sat Oct 27 23:15:53 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 27 Oct 2012 23:15:53 +0200 (CEST) Subject: [pypy-commit] pypy numpypy.float16: float16 is a container for floats Message-ID: <20121027211553.772401C01E7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy.float16 Changeset: r58521:dcccbf6334a8 Date: 2012-10-26 16:56 +0200 http://bitbucket.org/pypy/pypy/changeset/dcccbf6334a8/ Log: float16 is a container for floats 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 @@ -217,6 +217,9 @@ class W_FloatingBox(W_InexactBox): _attrs_ = () +class W_Float16Box(W_FloatingBox, PrimitiveBox): + descr__new__, _get_dtype = new_dtype_getter("float16") + class W_Float32Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float32") @@ -466,6 +469,12 @@ __module__ = "numpypy", ) +W_Float16Box.typedef = TypeDef("float16", W_FloatingBox.typedef, + __module__ = "numpypy", + + __new__ = interp2app(W_Float16Box.descr__new__.im_func), +) + W_Float32Box.typedef = TypeDef("float32", W_FloatingBox.typedef, __module__ = "numpypy", diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -465,6 +465,14 @@ #alternate_constructors=[space.w_buffer], # XXX no buffer in space ) + self.w_float16dtype = W_Dtype( + types.Float16(), + num=11, + kind=FLOATINGLTR, + name="float16", + char="e", + w_box_type=space.gettypefor(interp_boxes.W_Float16Box), + ) ptr_size = rffi.sizeof(rffi.CCHARP) if ptr_size == 4: intp_box = interp_boxes.W_Int32Box @@ -499,14 +507,14 @@ self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype, self.w_int64dtype, self.w_uint64dtype, - self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, + self.w_float12type, self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, self.w_complex128dtype, self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) - for dtype in [self.w_float32dtype, self.w_float64dtype] + for dtype in [self.w_float16type, self.w_float32dtype, self.w_float64dtype] ) self.dtypes_by_name = {} # we reverse, so the stuff with lower numbers override stuff with 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 @@ -228,6 +228,7 @@ (numpy.int16, 5), (numpy.uint32, 7), (numpy.int64, 3), + (numpy.float16, 3.14156), (numpy.float32, 2.0), (numpy.float64, 4.32), ]: @@ -427,6 +428,17 @@ assert numpy.uint64(18446744073709551615) == 18446744073709551615 raises(OverflowError, numpy.uint64(18446744073709551616)) + def test_float16(self): + import _numpypy as numpy + assert numpy.float16.mro() == [numpy.float16, numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, object] + + assert numpy.float16(12) == numpy.float64(12) + assert numpy.float16('23.4') == numpy.float16(23.4) + raises(ValueError, numpy.float16, '23.2df') + + def test_float32(self): import _numpypy as numpy diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2038,6 +2038,7 @@ BaseNumpyAppTest.setup_class.im_func(cls) cls.w_data = cls.space.wrap(struct.pack('dddd', 1, 2, 3, 4)) cls.w_fdata = cls.space.wrap(struct.pack('f', 2.3)) + cls.w_float16val = cls.space.wrap(struct.pack('e', 5.2)) cls.w_float32val = cls.space.wrap(struct.pack('f', 5.2)) cls.w_float64val = cls.space.wrap(struct.pack('d', 300.4)) cls.w_ulongval = cls.space.wrap(struct.pack('L', 12)) @@ -2109,7 +2110,7 @@ def test_fromstring_types(self): from _numpypy import (fromstring, int8, int16, int32, int64, uint8, - uint16, uint32, float32, float64) + uint16, uint32, float16, float32, float64) a = fromstring('\xFF', dtype=int8) assert a[0] == -1 @@ -2125,6 +2126,8 @@ assert repr(f[0]) == '4294967295' g = fromstring('\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF', dtype=int64) assert g[0] == -1 + h = fromstring(self.float16val, dtype=float16) + assert h[0] == float16(5.2) h = fromstring(self.float32val, dtype=float32) assert h[0] == float32(5.2) i = fromstring(self.float64val, dtype=float64) 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 @@ -919,6 +919,20 @@ return struct.pack(self.format_code, self.unbox(box)) +class Float16(BaseType, Float): + _attrs_ = () + + T = rffi.FLOAT + BoxType = interp_boxes.W_Float16Box + format_code = "e" + +class NonNativeFloat16(BaseType, NonNativeFloat): + _attrs_ = () + + T = rffi.FLOAT + BoxType = interp_boxes.W_Float16Box + format_code = "e" + class Float32(BaseType, Float): _attrs_ = () From noreply at buildbot.pypy.org Sat Oct 27 23:15:54 2012 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 27 Oct 2012 23:15:54 +0200 (CEST) Subject: [pypy-commit] pypy numpypy.float16: basic tests and framework in place, start to implement Message-ID: <20121027211554.A86841C01E7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy.float16 Changeset: r58522:4eac89c2ad82 Date: 2012-10-27 23:14 +0200 http://bitbucket.org/pypy/pypy/changeset/4eac89c2ad82/ Log: basic tests and framework in place, start to implement diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -55,6 +55,7 @@ 'inexact': 'interp_boxes.W_InexactBox', 'floating': 'interp_boxes.W_FloatingBox', 'float_': 'interp_boxes.W_Float64Box', + 'float16': 'interp_boxes.W_Float16Box', 'float32': 'interp_boxes.W_Float32Box', 'float64': 'interp_boxes.W_Float64Box', 'intp': 'types.IntP.BoxType', 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 @@ -507,14 +507,14 @@ self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype, self.w_int64dtype, self.w_uint64dtype, - self.w_float12type, self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, + self.w_float16dtype, self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, self.w_complex128dtype, self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) - for dtype in [self.w_float16type, self.w_float32dtype, self.w_float64dtype] + for dtype in [self.w_float16dtype, self.w_float32dtype, self.w_float64dtype] ) self.dtypes_by_name = {} # we reverse, so the stuff with lower numbers override stuff with 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 @@ -933,6 +933,15 @@ BoxType = interp_boxes.W_Float16Box format_code = "e" +class Float16(BaseType, Float): + _attrs_ = () + + def get_element_size(self): + return 16 + + BoxType = interp_boxes.W_Float16Box + format_code = "e" + class Float32(BaseType, Float): _attrs_ = () From noreply at buildbot.pypy.org Sat Oct 27 23:49:47 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 23:49:47 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: flush operations before jump or finish. not completely sure how it was done Message-ID: <20121027214947.656BB1C1DE0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58523:30128f37f1fe Date: 2012-10-27 23:48 +0200 http://bitbucket.org/pypy/pypy/changeset/30128f37f1fe/ Log: flush operations before jump or finish. not completely sure how it was done before diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py --- a/pypy/jit/metainterp/optimizeopt/heap.py +++ b/pypy/jit/metainterp/optimizeopt/heap.py @@ -25,6 +25,8 @@ # value pending in the ResOperation is *not* visible in # 'cached_fields'. # + + # XXXX kill dicts here self._cached_fields = {} self._cached_fields_getfield_op = {} self._lazy_setfield = None @@ -32,8 +34,8 @@ def do_setfield(self, optheap, op): # Update the state with the SETFIELD_GC/SETARRAYITEM_GC operation 'op'. - structvalue = optheap.getvalue(op.getarg(0)) - fieldvalue = optheap.getvalue(op.getarglist()[-1]) + structvalue = optheap.getforwarded(op.getarg(0)) + fieldvalue = optheap.getforwarded(op.getarglist()[-1]) if self.possible_aliasing(optheap, structvalue): self.force_lazy_setfield(optheap) assert not self.possible_aliasing(optheap, structvalue) @@ -44,7 +46,7 @@ optheap.optimizer.ensure_imported(cached_fieldvalue) cached_fieldvalue = self._cached_fields.get(structvalue, None) - if not fieldvalue.same_value(cached_fieldvalue): + if not optheap.optimizer.same_value(fieldvalue, cached_fieldvalue): # common case: store the 'op' as lazy_setfield, and register # myself in the optheap's _lazy_setfields_and_arrayitems list self._lazy_setfield = op @@ -94,14 +96,15 @@ # possible aliasing). self.clear() self._lazy_setfield = None - optheap.next_optimization.propagate_forward(op) + # XXX should we push it through the optimizer chain? + optheap.optimizer.emit_operation(op) if not can_cache: return # Once it is done, we can put at least one piece of information # back in the cache: the value of this particular structure's # field. - structvalue = optheap.getvalue(op.getarg(0)) - fieldvalue = optheap.getvalue(op.getarglist()[-1]) + structvalue = optheap.getforwarded(op.getarg(0)) + fieldvalue = optheap.getforwarded(op.getarglist()[-1]) self.remember_field_value(structvalue, fieldvalue, op) elif not can_cache: self.clear() @@ -294,7 +297,7 @@ # of virtualref_info and virtualizable_info are not gcptrs. def turned_constant(self, value): - value = self.getforwarded(value) + newvalue = self.getforwarded(value) for cf in self.cached_fields.itervalues(): cf.turned_constant(newvalue, value) for submap in self.cached_arrayitems.itervalues(): @@ -394,6 +397,7 @@ optimize_GETFIELD_GC_PURE_r = optimize_GETFIELD_GC_PURE_i def optimize_SETFIELD_GC(self, op): + # XXX this is just debugging, should we comment it out somehow? if op.type == INT: op_key = create_resop_1(rop.GETFIELD_GC_PURE_i, 0, op.getarg(0), op.getdescr()) diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -158,13 +158,6 @@ return not op.nonnull() return False - def same_value(self, other): - if not other: - return False - if self.is_constant() and other.is_constant(): - return self.box.same_constant(other.box) - return self is other - def make_constant_class(self, classbox, guardop, index): assert self.level < LEVEL_KNOWNCLASS self.known_class = classbox @@ -469,6 +462,15 @@ if not op.is_constant(): op._forwarded = ConstInt(intvalue) + def same_value(self, op1, op2): + if op1 is op2: + return True + if op2 is None: + return False + if op1.is_constant() and op2.is_constant(): + return op1.same_constant(op2) + return False + def new_ptr_box(self): return self.cpu.ts.BoxRef() @@ -539,6 +541,7 @@ dispatch_opt(self, op) def emit_operation(self, op): + op = self.getforwarded(op) assert op.getopnum() not in opgroups.CALL_PURE assert not op._forwarded if isinstance(op, Const): @@ -617,9 +620,6 @@ # self.emit_operation(op) # FIXME: Is this still needed? - def optimize_DEBUG_MERGE_POINT(self, op): - self.emit_operation(op) - def optimize_GETARRAYITEM_GC_PURE_i(self, op): indexvalue = self.getvalue(op.getarg(1)) if indexvalue.is_constant(): diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -538,6 +538,14 @@ optimize_SAME_AS_r = optimize_SAME_AS_i optimize_SAME_AS_f = optimize_SAME_AS_i + def optimize_JUMP(self, op): + self.optimizer.flush() + return op + + def optimize_FINISH(self, op): + self.optimizer.flush() + return op + #dispatch_opt = make_dispatcher_method(OptRewrite, 'optimize_', # default=OptRewrite.emit_operation) #optimize_guards = _findall(OptRewrite, 'optimize_', 'GUARD') diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py --- a/pypy/jit/metainterp/optimizeopt/virtualize.py +++ b/pypy/jit/metainterp/optimizeopt/virtualize.py @@ -458,8 +458,7 @@ fieldvalue = self.getforwarded(op.getarg(1)) value.setfield(op.getdescr(), fieldvalue) else: - xxx - value.ensure_nonnull() + value.setknownnonnull(True) return op def optimize_NEW_WITH_VTABLE(self, op): diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -478,9 +478,9 @@ # XXX this is a hack kill me import sys co_fname = sys._getframe(1).f_code.co_filename - if co_fname.endswith('resume.py') or co_fname.endswith('optimizeopt/util.py') or 'backend/llgraph' in co_fname or 'backend/test' in co_fname or 'test/test_util' in co_fname: + if co_fname.endswith('resume.py') or co_fname.endswith('optimizeopt/util.py') or 'backend/llgraph' in co_fname or 'backend/test' in co_fname or 'test/test_util' in co_fname or co_fname.endswith('heap.py'): return object.__hash__(self) - raise Exception("Should not hash resops, use get/set extra instead") + raise Exception("Should not hash resops") def _get_hash_(self): """ rpython level implementation of hash, cache it because computations From noreply at buildbot.pypy.org Sat Oct 27 23:49:48 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 27 Oct 2012 23:49:48 +0200 (CEST) Subject: [pypy-commit] pypy result-in-resops: only care about bounds when dealing with ints Message-ID: <20121027214948.A105E1C1DE0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58524:0364dd0abcd5 Date: 2012-10-27 23:49 +0200 http://bitbucket.org/pypy/pypy/changeset/0364dd0abcd5/ Log: only care about bounds when dealing with ints diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -36,7 +36,8 @@ dispatch_bounds_ops(self, op) def postprocess_GUARD_TRUE(self, op): - self.propagate_bounds_backward(op.getarg(0)) + if op.getarg(0).type == INT: + self.propagate_bounds_backward(op.getarg(0)) postprocess_GUARD_FALSE = postprocess_GUARD_TRUE postprocess_GUARD_VALUE = postprocess_GUARD_TRUE From noreply at buildbot.pypy.org Sun Oct 28 00:33:28 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 00:33:28 +0200 (CEST) Subject: [pypy-commit] pypy missing-ndarray-attributes: implement astype Message-ID: <20121027223328.193DE1C1E15@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58525:b0e0c785b8dc Date: 2012-10-28 00:05 +0200 http://bitbucket.org/pypy/pypy/changeset/b0e0c785b8dc/ Log: implement astype 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 @@ -262,6 +262,11 @@ def argsort(self, space, w_axis): return argsort_array(self, space, w_axis) + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + class SliceArray(BaseConcreteArray): def __init__(self, start, strides, backstrides, shape, parent, dtype=None): self.strides = strides diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -98,3 +98,6 @@ def argsort(self, space, w_axis): return space.wrap(0) + + def astype(self, space, dtype): + return W_NDimArray.new_scalar(space, dtype, self.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 @@ -384,9 +384,10 @@ contig = self.descr_copy(space) return contig.implementation.argsort(space, w_axis) - def descr_astype(self, space, w_type): - raise OperationError(space.w_NotImplementedError, space.wrap( - "astype not implemented yet")) + def descr_astype(self, space, w_dtype): + dtype = space.interp_w(interp_dtype.W_Dtype, + space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)) + return self.implementation.astype(space, dtype) def descr_base(self, space): raise OperationError(space.w_NotImplementedError, space.wrap( @@ -788,6 +789,7 @@ imag = GetSetProperty(W_NDimArray.descr_get_imag), argsort = interp2app(W_NDimArray.descr_argsort), + astype = interp2app(W_NDimArray.descr_astype), __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) 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 @@ -460,3 +460,16 @@ val_arr.descr_getitem(space, w_idx)) iter.next() +copy_from_to_driver = jit.JitDriver(greens = ['dtype'], + reds = ['from_iter', 'to_iter']) + +def copy_from_to(from_, to, dtype): + from_iter = from_.create_iter(from_.get_shape()) + to_iter = to.create_iter(to.get_shape()) + while not from_iter.done(): + copy_from_to_driver.jit_merge_point(dtype=dtype, from_iter=from_iter, + to_iter=to_iter) + to_iter.setitem(from_iter.getitem().convert_to(dtype)) + to_iter.next() + from_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 @@ -1567,6 +1567,15 @@ a = arange(100) assert (a.argsort() == a).all() + def test_astype(self): + from _numpypy import array + b = array(1).astype(float) + assert b == 1 + assert b.dtype == float + b = array([1, 2]).astype(float) + assert (b == [1, 2]).all() + assert b.dtype == 'float' + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import _numpypy From noreply at buildbot.pypy.org Sun Oct 28 00:33:29 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 00:33:29 +0200 (CEST) Subject: [pypy-commit] pypy default: make sure that shape is nonresizable Message-ID: <20121027223329.471E21C1E15@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58526:184ad638e30d Date: 2012-10-28 00:31 +0200 http://bitbucket.org/pypy/pypy/changeset/184ad638e30d/ Log: make sure that shape is nonresizable 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 @@ -10,6 +10,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rlib import jit from pypy.rlib.rawstorage import free_raw_storage +from pypy.rlib.debug import make_sure_not_resized class ConcreteArrayIterator(base.BaseArrayIterator): def __init__(self, array): @@ -379,6 +380,7 @@ class ConcreteArray(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides): + make_sure_not_resized(shape) self.shape = shape self.size = support.product(shape) * dtype.get_size() self.storage = dtype.itemtype.malloc(self.size) diff --git a/pypy/module/micronumpy/dot.py b/pypy/module/micronumpy/dot.py --- a/pypy/module/micronumpy/dot.py +++ b/pypy/module/micronumpy/dot.py @@ -11,12 +11,12 @@ right_critical_dim = len(right_shape) - 2 right_critical_dim_size = right_shape[right_critical_dim] assert right_critical_dim >= 0 - out_shape += left_shape[:-1] + \ - right_shape[0:right_critical_dim] + \ - right_shape[right_critical_dim + 1:] + out_shape = out_shape + left_shape[:-1] + \ + right_shape[0:right_critical_dim] + \ + right_shape[right_critical_dim + 1:] elif len(right_shape) > 0: #dot does not reduce for scalars - out_shape += left_shape[:-1] + out_shape = out_shape + left_shape[:-1] if my_critical_dim_size != right_critical_dim_size: raise OperationError(space.w_ValueError, space.wrap( "objects are not aligned")) 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 @@ -25,7 +25,7 @@ shape = [] for w_item in space.fixedview(w_size): shape.append(space.int_w(w_item)) - return shape + return shape[:] class __extend__(W_NDimArray): @jit.unroll_safe diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -64,13 +64,13 @@ while True: new_batch = [] if not batch: - return shape, [] + return shape[:], [] if is_single_elem(space, batch[0], is_rec_type): for w_elem in batch: if not is_single_elem(space, w_elem, is_rec_type): raise OperationError(space.w_ValueError, space.wrap( "setting an array element with a sequence")) - return shape, batch + return shape[:], batch size = space.len_w(batch[0]) for w_elem in batch: if (is_single_elem(space, w_elem, is_rec_type) or From noreply at buildbot.pypy.org Sun Oct 28 00:33:30 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 00:33:30 +0200 (CEST) Subject: [pypy-commit] pypy default: merge Message-ID: <20121027223330.7E7501C1E15@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58527:d9b22cb76c40 Date: 2012-10-28 00:33 +0200 http://bitbucket.org/pypy/pypy/changeset/d9b22cb76c40/ Log: merge diff --git a/pypy/translator/goal/test2/test_app_main.py b/pypy/translator/goal/test2/test_app_main.py --- a/pypy/translator/goal/test2/test_app_main.py +++ b/pypy/translator/goal/test2/test_app_main.py @@ -689,6 +689,10 @@ child_out_err.close() def test_proper_sys_path(self, tmpdir): + data = self.run('-c "import _ctypes"', python_flags='-S') + if data.startswith('Traceback'): + py.test.skip("'python -S' cannot import extension modules: " + "see probably http://bugs.python.org/issue586680") @contextmanager def chdir_and_unset_pythonpath(new_cwd): From noreply at buildbot.pypy.org Sun Oct 28 00:45:33 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 00:45:33 +0200 (CEST) Subject: [pypy-commit] pypy missing-ndarray-attributes: A very ugly commit :( Implement base. Unfortunately it means slice has to Message-ID: <20121027224533.52E761C034E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58528:dd59b7d76e43 Date: 2012-10-28 00:45 +0200 http://bitbucket.org/pypy/pypy/changeset/dd59b7d76e43/ Log: A very ugly commit :( Implement base. Unfortunately it means slice has to carry the original array a bit everywhere 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 @@ -44,7 +44,7 @@ def get_size(self): return self.size // self.dtype.itemtype.get_element_size() - def reshape(self, space, new_shape): + def reshape(self, space, orig_array, new_shape): # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: @@ -57,7 +57,7 @@ for nd in range(ndims): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, - new_shape, self) + new_shape, self, orig_array) else: return None @@ -168,26 +168,26 @@ i += 1 return Chunks(result) - def descr_getitem(self, space, w_index): + def descr_getitem(self, space, orig_arr, w_index): try: item = self._single_item_index(space, w_index) return self.getitem(item) except IndexError: # not a single result chunks = self._prepare_slice_args(space, w_index) - return chunks.apply(self) + return chunks.apply(orig_arr) - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_arr, w_index, w_value): try: item = self._single_item_index(space, w_index) self.setitem(item, self.dtype.coerce(space, w_value)) except IndexError: w_value = convert_to_array(space, w_value) chunks = self._prepare_slice_args(space, w_index) - view = chunks.apply(self) + view = chunks.apply(orig_arr) view.implementation.setslice(space, w_value) - def transpose(self): + def transpose(self, orig_array): if len(self.shape) < 2: return self strides = [] @@ -198,7 +198,7 @@ backstrides.append(self.backstrides[i]) shape.append(self.shape[i]) return SliceArray(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_array) def copy(self): strides, backstrides = support.calc_strides(self.shape, self.dtype, @@ -215,7 +215,7 @@ shape, skip) return iter.MultiDimViewIterator(self, self.start, r[0], r[1], shape) - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_arr, axis1, axis2): shape = self.shape[:] strides = self.strides[:] backstrides = self.backstrides[:] @@ -223,7 +223,7 @@ strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] return W_NDimArray.new_slice(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): return rffi.cast(lltype.Signed, self.storage) @@ -254,10 +254,11 @@ def __del__(self): free_raw_storage(self.storage, track_allocation=False) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): strides, backstrides = support.calc_strides(new_shape, self.dtype, self.order) - return SliceArray(0, strides, backstrides, new_shape, self) + return SliceArray(0, strides, backstrides, new_shape, self, + orig_array) def argsort(self, space, w_axis): return argsort_array(self, space, w_axis) @@ -267,8 +268,12 @@ loop.copy_from_to(self, new_arr.implementation, dtype) return new_arr + def base(self): + return None + class SliceArray(BaseConcreteArray): - def __init__(self, start, strides, backstrides, shape, parent, dtype=None): + def __init__(self, start, strides, backstrides, shape, parent, orig_arr, + dtype=None): self.strides = strides self.backstrides = backstrides self.shape = shape @@ -282,6 +287,10 @@ self.dtype = dtype self.size = support.product(shape) * self.dtype.itemtype.get_element_size() self.start = start + self.orig_arr = orig_arr + + def base(self): + return self.orig_arr def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) @@ -297,7 +306,7 @@ return iter.MultiDimViewIterator(self.parent, self.start, self.strides, self.backstrides, self.shape) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if len(self.shape) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor @@ -316,7 +325,7 @@ backstrides.reverse() new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, - self) + self, orig_array) new_strides = calc_new_strides(new_shape, self.shape, self.strides, self.order) if new_strides is None: @@ -326,4 +335,4 @@ for nd in range(len(new_shape)): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, new_shape, - self) + self, orig_array) 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 @@ -51,10 +51,10 @@ def get_size(self): return 1 - def transpose(self): + def transpose(self, _): return self - def descr_getitem(self, space, w_idx): + def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -62,14 +62,14 @@ raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def descr_setitem(self, space, w_idx, w_val): + def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if not new_shape: return self if support.product(new_shape) == 1: @@ -80,8 +80,8 @@ raise OperationError(space.w_ValueError, space.wrap( "total size of the array must be unchanged")) - def reshape(self, space, new_shape): - return self.set_shape(space, new_shape) + def reshape(self, space, orig_array, new_shape): + return self.set_shape(space, orig_array, new_shape) def create_axis_iter(self, shape, dim): raise Exception("axis iter should not happen on scalar") @@ -101,3 +101,6 @@ def astype(self, space, dtype): return W_NDimArray.new_scalar(space, dtype, self.value) + + def base(self): + return None diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -73,7 +73,9 @@ raise OperationError(space.w_NotImplementedError, space.wrap("sorting of non-numeric types is not implemented")) if w_axis is space.w_None: - arr = arr.reshape(space, [arr.get_size()]) + # note that it's fine ot pass None here as we're not going + # to pass the result around (None is the link to base in slices) + arr = arr.reshape(space, None, [arr.get_size()]) axis = 0 elif w_axis is None: axis = -1 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 @@ -23,11 +23,12 @@ return W_NDimArray(impl) @staticmethod - def new_slice(offset, strides, backstrides, shape, parent, dtype=None): + def new_slice(offset, strides, backstrides, shape, parent, orig_arr, + dtype=None): from pypy.module.micronumpy.arrayimpl import concrete impl = concrete.SliceArray(offset, strides, backstrides, shape, parent, - dtype) + orig_arr, dtype) return W_NDimArray(impl) @staticmethod diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -123,7 +123,7 @@ for arr in args_w: chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, arr.get_shape()[axis]) - Chunks(chunks).apply(res.implementation).implementation.setslice(space, arr) + Chunks(chunks).apply(res).implementation.setslice(space, arr) axis_start += arr.get_shape()[axis] return res @@ -137,7 +137,7 @@ res = W_NDimArray.from_shape(shape, arr.get_dtype()) for i in range(repeats): Chunks([Chunk(i, shape[0] - repeats + i, repeats, - orig_size)]).apply(res.implementation).implementation.setslice(space, arr) + orig_size)]).apply(res).implementation.setslice(space, arr) else: axis = space.int_w(w_axis) shape = arr.get_shape()[:] @@ -148,7 +148,7 @@ for i in range(repeats): chunks[axis] = Chunk(i, shape[axis] - repeats + i, repeats, orig_size) - Chunks(chunks).apply(res.implementation).implementation.setslice(space, arr) + Chunks(chunks).apply(res).implementation.setslice(space, arr) return res def count_nonzero(space, w_obj): 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 @@ -232,8 +232,6 @@ return dtype if w_dtype is dtype.w_box_type: return dtype - import pdb - pdb.set_trace() raise OperationError(space.w_TypeError, space.wrap("data type not understood")) W_Dtype.typedef = TypeDef("dtype", 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 @@ -37,7 +37,7 @@ return self.implementation.get_shape() def descr_set_shape(self, space, w_new_shape): - self.implementation = self.implementation.set_shape(space, + self.implementation = self.implementation.set_shape(space, self, get_shape_from_iterable(space, self.get_size(), w_new_shape)) def get_dtype(self): @@ -148,7 +148,7 @@ w_idx.get_dtype().is_bool_type()): return self.getitem_filter(space, w_idx) try: - return self.implementation.descr_getitem(space, w_idx) + return self.implementation.descr_getitem(space, self, w_idx) except ArrayArgumentException: return self.getitem_array_int(space, w_idx) except OperationError: @@ -166,7 +166,7 @@ return self.setitem_filter(space, w_idx, convert_to_array(space, w_value)) try: - self.implementation.descr_setitem(space, w_idx, w_value) + self.implementation.descr_setitem(space, self, w_idx, w_value) except ArrayArgumentException: self.setitem_array_int(space, w_idx, w_value) @@ -254,20 +254,21 @@ else: w_shape = space.newtuple(args_w) new_shape = get_shape_from_iterable(space, self.get_size(), w_shape) - new_impl = self.implementation.reshape(space, new_shape) + new_impl = self.implementation.reshape(space, self, new_shape) if new_impl is not None: return W_NDimArray(new_impl) # Create copy with contiguous data arr = self.descr_copy(space) if arr.get_size() > 0: - arr.implementation = arr.implementation.reshape(space, new_shape) + arr.implementation = arr.implementation.reshape(space, self, + new_shape) assert arr.implementation else: arr.implementation.shape = new_shape return arr def descr_get_transpose(self, space): - return W_NDimArray(self.implementation.transpose()) + return W_NDimArray(self.implementation.transpose(self)) @unwrap_spec(axis1=int, axis2=int) def descr_swapaxes(self, space, axis1, axis2): @@ -283,7 +284,7 @@ """ if self.is_scalar(): return self - return self.implementation.swapaxes(axis1, axis2) + return self.implementation.swapaxes(self, axis1, axis2) def descr_tolist(self, space): if len(self.get_shape()) == 0: @@ -389,9 +390,8 @@ space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)) return self.implementation.astype(space, dtype) - def descr_base(self, space): - raise OperationError(space.w_NotImplementedError, space.wrap( - "base not implemented yet")) + def descr_get_base(self, space): + return self.implementation.base() def descr_byteswap(self, space, w_inplace=False): raise OperationError(space.w_NotImplementedError, space.wrap( @@ -790,6 +790,7 @@ argsort = interp2app(W_NDimArray.descr_argsort), astype = interp2app(W_NDimArray.descr_astype), + base = GetSetProperty(W_NDimArray.descr_get_base), __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) 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 @@ -57,12 +57,13 @@ def __init__(self, name): self.name = name - def apply(self, arr): + def apply(self, orig_arr): + arr = orig_arr.implementation ofs, subdtype = arr.dtype.fields[self.name] # strides backstrides are identical, ofs only changes start return W_NDimArray.new_slice(arr.start + ofs, arr.strides, arr.backstrides, - arr.shape, arr, subdtype) + arr.shape, arr, orig_arr, subdtype) class Chunks(BaseChunk): def __init__(self, l): @@ -79,13 +80,14 @@ assert s >= 0 return shape[:] + old_shape[s:] - def apply(self, arr): + def apply(self, orig_arr): + arr = orig_arr.implementation shape = self.extend_shape(arr.shape) r = calculate_slice_strides(arr.shape, arr.start, arr.strides, arr.backstrides, self.l) _, start, strides, backstrides = r return W_NDimArray.new_slice(start, strides[:], backstrides[:], - shape[:], arr) + shape[:], arr, orig_arr) class Chunk(BaseChunk): diff --git a/pypy/module/micronumpy/test/test_iter.py b/pypy/module/micronumpy/test/test_iter.py --- a/pypy/module/micronumpy/test/test_iter.py +++ b/pypy/module/micronumpy/test/test_iter.py @@ -1,4 +1,4 @@ -from pypy.module.micronumpy.arrayimpl.concrete import MultiDimViewIterator +from pypy.module.micronumpy.iter import MultiDimViewIterator class MockArray(object): size = 1 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 @@ -22,7 +22,7 @@ def create_slice(a, chunks): - return Chunks(chunks).apply(a).implementation + return Chunks(chunks).apply(W_NDimArray(a)).implementation def create_array(*args, **kwargs): return W_NDimArray.from_shape(*args, **kwargs).implementation @@ -1576,6 +1576,14 @@ assert (b == [1, 2]).all() assert b.dtype == 'float' + def test_base(self): + from _numpypy import array + assert array(1).base is None + assert array([1, 2]).base is None + a = array([1, 2, 3, 4]) + b = a[::2] + assert b.base is a + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import _numpypy From noreply at buildbot.pypy.org Sun Oct 28 08:12:09 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 28 Oct 2012 08:12:09 +0100 (CET) Subject: [pypy-commit] pypy default: A bug and fix in the dict insertion code. Interestingly, CPython has Message-ID: <20121028071209.E01F41C0250@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58529:a18b9bbc6530 Date: 2012-10-28 08:11 +0100 http://bitbucket.org/pypy/pypy/changeset/a18b9bbc6530/ Log: A bug and fix in the dict insertion code. Interestingly, CPython has the same bug until changes in 3.3 fixed it. diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py --- a/pypy/rpython/lltypesystem/lltype.py +++ b/pypy/rpython/lltypesystem/lltype.py @@ -1651,10 +1651,7 @@ if n < 0: raise ValueError, "negative array length" _parentable.__init__(self, TYPE) - try: - myrange = range(n) - except OverflowError: - raise MemoryError("definitely too many items") + myrange = self._check_range(n) self.items = [TYPE.OF._allocate(initialization=initialization, parent=self, parentindex=j) for j in myrange] @@ -1664,6 +1661,14 @@ def __repr__(self): return '<%s>' % (self,) + def _check_range(self, n): + # checks that it's ok to make an array of size 'n', and returns + # range(n). Explicitly overridden by some tests. + try: + return range(n) + except OverflowError: + raise MemoryError("definitely too many items") + def _str_item(self, item): if isinstance(item, _uninitialized): return '#' diff --git a/pypy/rpython/lltypesystem/rdict.py b/pypy/rpython/lltypesystem/rdict.py --- a/pypy/rpython/lltypesystem/rdict.py +++ b/pypy/rpython/lltypesystem/rdict.py @@ -4,6 +4,7 @@ rtype_newdict) from pypy.rpython.lltypesystem import lltype from pypy.rlib import objectmodel, jit +from pypy.rlib.debug import ll_assert from pypy.rlib.rarithmetic import r_uint, intmask, LONG_BIT from pypy.rpython import rmodel from pypy.rpython.error import TyperError @@ -462,22 +463,30 @@ def _ll_dict_setitem_lookup_done(d, key, value, hash, i): valid = (i & HIGHEST_BIT) == 0 i = i & MASK - everused = d.entries.everused(i) - # set up the new entry ENTRY = lltype.typeOf(d.entries).TO.OF entry = d.entries[i] - entry.value = value - if valid: - return + if not d.entries.everused(i): + # a new entry that was never used before + ll_assert(not valid, "valid but not everused") + rc = d.resize_counter - 3 + if rc <= 0: # if needed, resize the dict -- before the insertion + ll_dict_resize(d) + i = ll_dict_lookup_clean(d, hash) # then redo the lookup for 'key' + entry = d.entries[i] + rc = d.resize_counter - 3 + ll_assert(rc > 0, "ll_dict_resize failed?") + d.resize_counter = rc + if hasattr(ENTRY, 'f_everused'): entry.f_everused = True + entry.value = value + else: + # override an existing or deleted entry + entry.value = value + if valid: + return entry.key = key if hasattr(ENTRY, 'f_hash'): entry.f_hash = hash if hasattr(ENTRY, 'f_valid'): entry.f_valid = True d.num_items += 1 - if not everused: - if hasattr(ENTRY, 'f_everused'): entry.f_everused = True - d.resize_counter -= 3 - if d.resize_counter <= 0: - ll_dict_resize(d) def ll_dict_insertclean(d, key, value, hash): # Internal routine used by ll_dict_resize() to insert an item which is @@ -534,8 +543,9 @@ # make a 'new_size' estimate and shrink it if there are many # deleted entry markers. See CPython for why it is a good idea to # quadruple the dictionary size as long as it's not too big. - if d.num_items > 50000: new_estimate = d.num_items * 2 - else: new_estimate = d.num_items * 4 + num_items = d.num_items + 1 + if num_items > 50000: new_estimate = num_items * 2 + else: new_estimate = num_items * 4 new_size = DICT_INITSIZE while new_size <= new_estimate: new_size *= 2 diff --git a/pypy/rpython/test/test_rdict.py b/pypy/rpython/test/test_rdict.py --- a/pypy/rpython/test/test_rdict.py +++ b/pypy/rpython/test/test_rdict.py @@ -970,6 +970,39 @@ DICT = lltype.typeOf(llres.item1) assert sorted(DICT.TO.entries.TO.OF._flds) == ['f_hash', 'key', 'value'] + def test_memoryerror_should_not_insert(self): + # This shows a misbehaviour that also exists in CPython 2.7, but not + # any more in CPython 3.3. The behaviour is that even if a dict + # insertion raises MemoryError, the new item is still inserted. + # If we catch the MemoryError, we can keep inserting new items until + # the dict table is completely full. Then the next insertion loops + # forever. This test only checks that after a MemoryError the + # new item was not inserted. + def _check_small_range(self, n): + if n >= 128: + raise MemoryError + return range(n) + original_check_range = lltype._array._check_range + try: + lltype._array._check_range = _check_small_range + # + def do_insert(d, i): + d[i] = i + def func(): + d = {} + i = 0 + while True: + try: + do_insert(d, i) + except MemoryError: + return (i in d) + i += 1 + res = self.interpret(func, []) + assert res == 0 + # + finally: + lltype._array._check_range = original_check_range + # ____________________________________________________________ From noreply at buildbot.pypy.org Sun Oct 28 09:43:10 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 28 Oct 2012 09:43:10 +0100 (CET) Subject: [pypy-commit] cffi default: Allow '[...]' when declaring a global array, and interpret it like '[]'. Message-ID: <20121028084310.D74831C0250@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1013:3bb5d49c0c00 Date: 2012-10-28 09:42 +0100 http://bitbucket.org/cffi/cffi/changeset/3bb5d49c0c00/ Log: Allow '[...]' when declaring a global array, and interpret it like '[]'. diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -162,7 +162,7 @@ decl) # if decl.name: - tp = self._get_type(node) + tp = self._get_type(node, partial_length_ok=True) if self._is_constant_declaration(node): self._declare('constant ' + decl.name, tp) else: diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1275,3 +1275,15 @@ result = posix.read(fdr, 256) posix.close(fdr) assert result == b"Xhello, 42!\n" + +def test_global_array_with_missing_length(): + ffi = FFI() + ffi.cdef("int fooarray[];") + lib = ffi.verify("int fooarray[50];") + assert repr(lib.fooarray).startswith(" Author: Maciej Fijalkowski Branch: Changeset: r58530:a2711f030e6c Date: 2012-10-28 15:24 +0100 http://bitbucket.org/pypy/pypy/changeset/a2711f030e6c/ Log: implement unrolling of arraycopy over non-virtual and small sources diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -426,14 +426,31 @@ source_start_box = self.get_constant_box(op.getarg(3)) dest_start_box = self.get_constant_box(op.getarg(4)) length = self.get_constant_box(op.getarg(5)) - if (source_value.is_virtual() and source_start_box and dest_start_box - and length and (dest_value.is_virtual() or length.getint() <= 8)): + if (source_start_box and dest_start_box + and length and (dest_value.is_virtual() or length.getint() <= 8) and + (source_value.is_virtual() or length.getint() <= 8)): from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue - assert isinstance(source_value, VArrayValue) source_start = source_start_box.getint() dest_start = dest_start_box.getint() for index in range(length.getint()): - val = source_value.getitem(index + source_start) + # XXX fish fish fish + arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] + if source_value.is_virtual(): + assert isinstance(source_value, VArrayValue) + val = source_value.getitem(index + source_start) + else: + if arraydescr.is_array_of_pointers(): + resbox = BoxPtr() + elif arraydescr.is_array_of_floats(): + resbox = BoxFloat() + else: + resbox = BoxInt() + newop = ResOperation(rop.GETARRAYITEM_GC, + [op.getarg(1), + ConstInt(index + source_start)], resbox, + descr=arraydescr) + self.optimizer.propagate_forward(newop) + val = self.getvalue(resbox) if dest_value.is_virtual(): dest_value.setitem(index + dest_start, val) else: @@ -441,7 +458,7 @@ [op.getarg(2), ConstInt(index + dest_start), val.get_key_box()], None, - descr=source_value.arraydescr) + descr=arraydescr) self.emit_operation(newop) return True if length and length.getint() == 0: diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -3239,6 +3239,42 @@ ''' self.optimize_loop(ops, expected) + def test_arraycopy_not_virtual_2(self): + ops = ''' + [p0] + p1 = new_array(3, descr=arraydescr) + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) # removed by the backend + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) # removed by the backend + jump(i0) + ''' + self.optimize_loop(ops, expected) + + def test_arraycopy_not_virtual_3(self): + ops = ''' + [p0, p1] + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0, p1] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) + setarrayitem_gc(p1, 0, i0, descr=arraydescr) + setarrayitem_gc(p1, 1, i1, descr=arraydescr) + setarrayitem_gc(p1, 2, i2, descr=arraydescr) + jump(i0) + ''' + self.optimize_loop(ops, expected) + def test_arraycopy_no_elem(self): """ this was actually observed in the wild """ From noreply at buildbot.pypy.org Sun Oct 28 16:18:39 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 28 Oct 2012 16:18:39 +0100 (CET) Subject: [pypy-commit] cffi default: issue35: meh, Python 2.7 decided to drop complete support for 'buffer' Message-ID: <20121028151840.0131E1C0ECC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1014:14eff35bfad7 Date: 2012-10-28 16:18 +0100 http://bitbucket.org/cffi/cffi/changeset/14eff35bfad7/ Log: issue35: meh, Python 2.7 decided to drop complete support for 'buffer' object at the same time that 'memoryview' was added. Work around. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -4275,7 +4275,7 @@ return NULL; } /*WRITE(cd->c_data, size)*/ -#if PY_MAJOR_VERSION < 3 +#if PY_MAJOR_VERSION < 3 && !defined(PyMemoryView_Check) /* Python 2.6 */ return PyBuffer_FromReadWriteMemory(cd->c_data, size); #else { diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -9,7 +9,7 @@ type_or_class = "type" mandatory_b_prefix = '' mandatory_u_prefix = 'u' - readbuf = str + readbuf = lambda buf: buf[:] bufchar = lambda x: x bytechr = chr class U(object): @@ -1839,7 +1839,7 @@ c[2] = b'-' buf[:2] = b'HI' assert string(c) == b'HI-there' - if sys.version_info < (3,) or sys.version_info >= (3, 3): + if sys.version_info < (2, 7) or sys.version_info >= (3, 3): assert buf[:4:2] == b'H-' if '__pypy__' not in sys.builtin_module_names: # XXX pypy doesn't support the following assignment so far diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py --- a/cffi/backend_ctypes.py +++ b/cffi/backend_ctypes.py @@ -980,7 +980,7 @@ return b._to_string(maxlen) def buffer(self, bptr, size=-1): - if sys.version_info >= (3,): + if sys.version_info >= (2, 7): # buf = bptr._as_ctype_ptr # return memoryview(buf.contents) if isinstance(bptr, CTypesGenericPtr): diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -1074,7 +1074,7 @@ b = ffi.buffer(a) except NotImplementedError as e: py.test.skip(str(e)) - if sys.version < '3': + if sys.version_info < (2, 7): assert type(b) is buffer content = str(b) else: @@ -1098,7 +1098,7 @@ b = ffi.buffer(a) except NotImplementedError as e: py.test.skip(str(e)) - if sys.version < '3': + if sys.version_info < (2, 7): assert type(b) is buffer content = str(b) else: @@ -1120,7 +1120,7 @@ b = ffi.buffer(a, 1) except NotImplementedError as e: py.test.skip(str(e)) - if sys.version < '3': + if sys.version_info < (2, 7): assert type(b) is buffer content = str(b) else: @@ -1144,8 +1144,8 @@ ffi.buffer(a1) except NotImplementedError as e: py.test.skip(str(e)) - if sys.version < '3': - assert str(ffi.buffer(a1)) == str(ffi.buffer(a2, 4*10)) + if sys.version_info < (3,): + assert ffi.buffer(a1)[:] == ffi.buffer(a2, 4*10)[:] else: assert ffi.buffer(a1).tobytes() == ffi.buffer(a2, 4*10).tobytes() @@ -1169,6 +1169,24 @@ f.close() os.unlink(filename) + def test_ffi_buffer_with_io(self): + ffi = FFI(backend=self.Backend()) + import io, array + f = io.BytesIO() + a = ffi.new("int[]", list(range(1005))) + try: + ffi.buffer(a, 512) + except NotImplementedError as e: + py.test.skip(str(e)) + f.write(ffi.buffer(a, 1000 * ffi.sizeof("int"))) + f.seek(0) + assert f.read() == array.array('i', range(1000)).tostring() + f.seek(0) + b = ffi.new("int[]", 1005) + f.readinto(ffi.buffer(b, 1000 * ffi.sizeof("int"))) + assert list(a)[:1000] + [0] * (len(a)-1000) == list(b) + f.close() + def test_array_in_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo_s { int len; short data[5]; };") From noreply at buildbot.pypy.org Sun Oct 28 17:09:56 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 17:09:56 +0100 (CET) Subject: [pypy-commit] pypy result-in-resops: move a hack from store_final_boxes_in_guard Message-ID: <20121028160956.BB1601C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58531:5548cd817164 Date: 2012-10-28 17:04 +0100 http://bitbucket.org/pypy/pypy/changeset/5548cd817164/ Log: move a hack from store_final_boxes_in_guard diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -573,6 +573,7 @@ raise compile.giveup() descr.store_final_boxes(op, newboxes) # + xxx if op.getopnum() == rop.GUARD_VALUE: xxx if self.getvalue(op.getarg(0)).is_bool_box: diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -5,7 +5,8 @@ CONST_0 from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ConstInt, make_hashable_int, - create_resop_2, Const) + create_resop_2, Const, + create_resop_1) from pypy.rlib.rarithmetic import highest_bit @@ -194,7 +195,7 @@ 'always fail') return if emit_operation: - return self.getforwarded(op) + return op def postprocess_guard(self, op, constbox): value = self.getforwarded(op.getarg(0)) @@ -270,6 +271,17 @@ value.last_guard = None emit_operation = False else: + if not value.is_constant() and value.returns_bool_result(): + constvalue = op.getarg(1).getint() + if constvalue == 0: + newop = create_resop_1(rop.GUARD_FALSE, None, + op.getarg(0)) + elif constvalue == 1: + newop = create_resop_1(rop.GUARD_TRUE, None, + op.getarg(0)) + else: + raise AssertionError("uh?") + return newop emit_operation = True constbox = op.getarg(1) assert isinstance(constbox, Const) From noreply at buildbot.pypy.org Sun Oct 28 17:09:58 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 17:09:58 +0100 (CET) Subject: [pypy-commit] pypy default: fix imports Message-ID: <20121028160958.09D6D1C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58532:83532451dc20 Date: 2012-10-28 17:09 +0100 http://bitbucket.org/pypy/pypy/changeset/83532451dc20/ Log: fix imports diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -5,7 +5,7 @@ from pypy.jit.metainterp.optimizeopt.optimizer import * from pypy.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, - ResOperation) + ResOperation, BoxPtr, BoxInt, BoxFloat) from pypy.rlib.rarithmetic import highest_bit From noreply at buildbot.pypy.org Sun Oct 28 17:12:45 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 28 Oct 2012 17:12:45 +0100 (CET) Subject: [pypy-commit] pypy default: remove an import * and fix import locations Message-ID: <20121028161245.D53311C0250@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r58533:b28deb1c63e7 Date: 2012-10-28 09:12 -0700 http://bitbucket.org/pypy/pypy/changeset/b28deb1c63e7/ Log: remove an import * and fix import locations diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -1,17 +1,17 @@ from pypy.jit.metainterp import jitprof, resume, compile from pypy.jit.metainterp.executor import execute_nonspec -from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF, INT +from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF from pypy.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded, \ ImmutableIntUnbounded, \ IntLowerBound, MININT, MAXINT -from pypy.jit.metainterp.optimizeopt.util import (make_dispatcher_method, - args_dict) +from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method from pypy.jit.metainterp.resoperation import rop, ResOperation, AbstractResOp from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.tool.pairtype import extendabletype -from pypy.rlib.debug import debug_start, debug_stop, debug_print +from pypy.rlib.debug import debug_print from pypy.rlib.objectmodel import specialize + LEVEL_UNKNOWN = '\x00' LEVEL_NONNULL = '\x01' LEVEL_KNOWNCLASS = '\x02' # might also mean KNOWNARRAYDESCR, for arrays @@ -20,6 +20,8 @@ MODE_ARRAY = '\x00' MODE_STR = '\x01' MODE_UNICODE = '\x02' + + class LenBound(object): def __init__(self, mode, descr, bound): self.mode = mode diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -1,11 +1,14 @@ from pypy.jit.codewriter.effectinfo import EffectInfo -from pypy.jit.metainterp.history import ConstInt, make_hashable_int +from pypy.jit.metainterp import compile +from pypy.jit.metainterp.history import (Const, ConstInt, BoxInt, BoxFloat, + BoxPtr, make_hashable_int) from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntBound -from pypy.jit.metainterp.optimizeopt.optimizer import * +from pypy.jit.metainterp.optimizeopt.optimizer import (Optimization, REMOVED, + CONST_0, CONST_1) from pypy.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, - ResOperation, BoxPtr, BoxInt, BoxFloat) + ResOperation) from pypy.rlib.rarithmetic import highest_bit From noreply at buildbot.pypy.org Sun Oct 28 17:46:22 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 17:46:22 +0100 (CET) Subject: [pypy-commit] pypy default: fix some imports Message-ID: <20121028164622.6D4DB1C039C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58534:b9840b6692d4 Date: 2012-10-28 17:46 +0100 http://bitbucket.org/pypy/pypy/changeset/b9840b6692d4/ Log: fix some imports diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -4,6 +4,7 @@ from pypy.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken from pypy.jit.metainterp.jitexc import JitException from pypy.jit.metainterp.optimize import InvalidLoop +from pypy.rlib.debug import debug_print, debug_start, debug_stop from pypy.jit.metainterp.optimizeopt.optimizer import * from pypy.jit.metainterp.optimizeopt.generalize import KillHugeIntBounds from pypy.jit.metainterp.inliner import Inliner From noreply at buildbot.pypy.org Sun Oct 28 18:41:43 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 18:41:43 +0100 (CET) Subject: [pypy-commit] pypy result-in-resops: first real virtual test Message-ID: <20121028174143.73C271C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58535:a08cae4bda5b Date: 2012-10-28 18:21 +0100 http://bitbucket.org/pypy/pypy/changeset/a08cae4bda5b/ Log: first real virtual test diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py --- a/pypy/jit/metainterp/optimizeopt/heap.py +++ b/pypy/jit/metainterp/optimizeopt/heap.py @@ -368,21 +368,29 @@ return pendingfields def optimize_GETFIELD_GC_i(self, op): - structvalue = self.getvalue(op.getarg(0)) + structvalue = self.getforwarded(op.getarg(0)) cf = self.field_cache(op.getdescr()) fieldvalue = cf.getfield_from_cache(self, structvalue) if fieldvalue is not None: self.replace(op, fieldvalue.op) return # default case: produce the operation - structvalue.ensure_nonnull() - self.emit_operation(op) - # then remember the result of reading the field - fieldvalue = self.getvalue(op) - cf.remember_field_value(structvalue, fieldvalue, op) + structvalue.setknownnonnull(True) + return op + optimize_GETFIELD_GC_r = optimize_GETFIELD_GC_i optimize_GETFIELD_GC_f = optimize_GETFIELD_GC_i + def postprocess_GETFIELD_GC_i(self, op): + # then remember the result of reading the field + structvalue = self.getforwarded(op.getarg(0)) + fieldvalue = self.getforwarded(op) + cf = self.field_cache(op.getdescr()) + cf.remember_field_value(structvalue, fieldvalue, op) + + postprocess_GETFIELD_GC_r = postprocess_GETFIELD_GC_i + postprocess_GETFIELD_GC_f = postprocess_GETFIELD_GC_i + def optimize_GETFIELD_GC_PURE_i(self, op): structvalue = self.getvalue(op.getarg(0)) cf = self.field_cache(op.getdescr()) diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -561,6 +561,7 @@ def store_final_boxes_in_guard(self, op): return op # XXX we disable it for tests + xxxx assert op.getdescr() is None descr = op.invent_descr(self.jitdriver_sd, self.metainterp_sd) op.setdescr(descr) @@ -573,29 +574,6 @@ raise compile.giveup() descr.store_final_boxes(op, newboxes) # - xxx - if op.getopnum() == rop.GUARD_VALUE: - xxx - if self.getvalue(op.getarg(0)).is_bool_box: - # Hack: turn guard_value(bool) into guard_true/guard_false. - # This is done after the operation is emitted to let - # store_final_boxes_in_guard set the guard_opnum field of the - # descr to the original rop.GUARD_VALUE. - constvalue = op.getarg(1).getint() - if constvalue == 0: - newop = create_resop_1(rop.GUARD_FALSE, None, - op.getarg(0)) - elif constvalue == 1: - newop = create_resop_1(rop.GUARD_TRUE, None, - op.getarg(0)) - else: - raise AssertionError("uh?") - newop.set_extra("failargs", op.get_extra("failargs")) - self.replace(op, newop) - return newop - else: - # a real GUARD_VALUE. Make it use one counter per value. - descr.make_a_counter_per_value(op) return op def optimize_default(self, op): diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py --- a/pypy/jit/metainterp/optimizeopt/virtualize.py +++ b/pypy/jit/metainterp/optimizeopt/virtualize.py @@ -440,8 +440,8 @@ fieldvalue = self.optimizer.new_const(op.getdescr()) self.optimizer.replace(op, fieldvalue) else: - value.ensure_nonnull() - self.emit_operation(op) + value.setknownnonnull(True) + return op optimize_GETFIELD_GC_r = optimize_GETFIELD_GC_i optimize_GETFIELD_GC_f = optimize_GETFIELD_GC_i diff --git a/pypy/jit/metainterp/virtualmodel.py b/pypy/jit/metainterp/virtualmodel.py --- a/pypy/jit/metainterp/virtualmodel.py +++ b/pypy/jit/metainterp/virtualmodel.py @@ -1,5 +1,6 @@ -from pypy.jit.metainterp.resoperation import rop, opclasses +from pypy.jit.metainterp.resoperation import rop, opclasses, create_resop_2 +from pypy.rlib.objectmodel import we_are_translated NEW_WITH_VTABLE = opclasses[rop.NEW_WITH_VTABLE] @@ -34,8 +35,19 @@ def force(self, optimizer): if not self._is_forced: + self._is_forced = True optimizer.emit_operation(self) - self._is_forced = True + iteritems = self._fields.iteritems() + if not we_are_translated(): #random order is fine, except for tests + iteritems = list(iteritems) + iteritems.sort(key = lambda (x,y): x.sort_key()) + for ofs, value in iteritems: + if value.is_null(): + continue + subbox = value.force(optimizer) + op = create_resop_2(rop.SETFIELD_GC, None, self, subbox, + descr=ofs) + optimizer.emit_operation(op) return self def is_virtual(self): From noreply at buildbot.pypy.org Sun Oct 28 18:41:44 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 18:41:44 +0100 (CET) Subject: [pypy-commit] pypy result-in-resops: fix those tests, they're still fine Message-ID: <20121028174144.B7F411C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58536:eb30095a8f30 Date: 2012-10-28 18:25 +0100 http://bitbucket.org/pypy/pypy/changeset/eb30095a8f30/ Log: fix those tests, they're still fine diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -615,9 +615,9 @@ escape(i3) p1 = new_with_vtable(ConstClass(node_vtable)) p1sub = new_with_vtable(ConstClass(node_vtable2)) - setfield_gc(p1, i1, descr=valuedescr) setfield_gc(p1sub, i1, descr=valuedescr) setfield_gc(p1, p1sub, descr=nextdescr) + setfield_gc(p1, i1, descr=valuedescr) jump(i1, p1, p2) """ # The same as test_p123_simple, but with a virtual containing another @@ -630,10 +630,10 @@ p3sub = getfield_gc_r(p3, descr=nextdescr) i3 = getfield_gc_i(p3sub, descr=valuedescr) escape(i3) - p1 = new_with_vtable(ConstClass(node_vtable)) p2sub = new_with_vtable(ConstClass(node_vtable2)) setfield_gc(p2sub, i1, descr=valuedescr) setfield_gc(p2, p2sub, descr=nextdescr) + p1 = new_with_vtable(ConstClass(node_vtable)) jump(i1, p1, p2) """ # The same as test_p123_simple, but in the end the "old" p2 contains From noreply at buildbot.pypy.org Sun Oct 28 18:41:45 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 18:41:45 +0100 (CET) Subject: [pypy-commit] pypy result-in-resops: one more test Message-ID: <20121028174145.D46931C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58537:40876c78ca5b Date: 2012-10-28 18:29 +0100 http://bitbucket.org/pypy/pypy/changeset/40876c78ca5b/ Log: one more test diff --git a/pypy/jit/metainterp/optimizeopt/pure.py b/pypy/jit/metainterp/optimizeopt/pure.py --- a/pypy/jit/metainterp/optimizeopt/pure.py +++ b/pypy/jit/metainterp/optimizeopt/pure.py @@ -63,11 +63,12 @@ self.last_emitted_operation = REMOVED return else: - new_op = op.copy_if_modified_by_optimization(self.optimizer) + new_op = self.optimizer.getforwarded(op) self.pure_operations.set(new_op, op) self.remember_emitting_pure(op) # replace CALL_PURE with just CALL + xxx self.emit_operation(self.optimizer.copy_and_change(op, opnum)) return optimize_CALL_PURE optimize_CALL_PURE_i = _new_optimize_call_pure(rop.CALL_i) @@ -80,7 +81,7 @@ # it was a CALL_PURE that was killed; so we also kill the # following GUARD_NO_EXCEPTION return - self.emit_operation(op) + return op def flush(self): assert self.posponedop is None diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -2,7 +2,7 @@ from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntBound from pypy.jit.metainterp.optimizeopt.optimizer import Optimization, CONST_1,\ - CONST_0 + CONST_0, REMOVED from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ConstInt, make_hashable_int, create_resop_2, Const, @@ -515,7 +515,7 @@ # it was a CALL_PURE or a CALL_LOOPINVARIANT that was killed; # so we also kill the following GUARD_NO_EXCEPTION return - self.emit_operation(op) + return op def optimize_INT_FLOORDIV(self, op): v1 = self.getvalue(op.getarg(0)) diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -551,7 +551,7 @@ def optimize_GUARD_NO_EXCEPTION(self, op): if self.last_emitted_operation is REMOVED: return - self.emit_operation(op) + return op def opt_call_str_STR2UNICODE(self, op): # Constant-fold unicode("constant string"). From noreply at buildbot.pypy.org Sun Oct 28 18:41:46 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 18:41:46 +0100 (CET) Subject: [pypy-commit] pypy default: disable the optimization until we find a better way Message-ID: <20121028174146.EDE0D1C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58538:c7efa45ae2a5 Date: 2012-10-28 18:38 +0100 http://bitbucket.org/pypy/pypy/changeset/c7efa45ae2a5/ Log: disable the optimization until we find a better way diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -431,15 +431,16 @@ length = self.get_constant_box(op.getarg(5)) if (source_start_box and dest_start_box and length and (dest_value.is_virtual() or length.getint() <= 8) and - (source_value.is_virtual() or length.getint() <= 8)): + (source_value.is_virtual())): # or length.getint() <= 8)): from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue source_start = source_start_box.getint() dest_start = dest_start_box.getint() for index in range(length.getint()): # XXX fish fish fish - arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] + #arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] + assert isinstance(source_value, VArrayValue) + arraydescr = source_value.arraydescr if source_value.is_virtual(): - assert isinstance(source_value, VArrayValue) val = source_value.getitem(index + source_start) else: if arraydescr.is_array_of_pointers(): From noreply at buildbot.pypy.org Sun Oct 28 18:41:48 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 18:41:48 +0100 (CET) Subject: [pypy-commit] pypy default: a failing test Message-ID: <20121028174148.2141E1C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58539:d7db0a927f92 Date: 2012-10-28 18:41 +0100 http://bitbucket.org/pypy/pypy/changeset/d7db0a927f92/ Log: a failing test diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py --- a/pypy/jit/metainterp/test/test_list.py +++ b/pypy/jit/metainterp/test/test_list.py @@ -128,6 +128,17 @@ res = self.interp_operations(f, [], listops=True) assert res == 10 + def test_arraycopy_bug(self): + def f(): + l = [1, 2, 3, 4] + l2 = [1, 2, 3, 4] + l[2] = 13 + l2[0:len(l2)] = l[:] + return l2[0] + l2[1] + l2[2] + l2[3] + + res = self.interp_operations(f, [], listops=True) + assert res == 10 + def test_arraycopy_full(self): jitdriver = JitDriver(greens = [], reds = ['n']) def f(n): From noreply at buildbot.pypy.org Sun Oct 28 18:46:12 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 28 Oct 2012 18:46:12 +0100 (CET) Subject: [pypy-commit] pypy default: Tweak ll_arraycopy() to fix again the issue of the missing arraydescr Message-ID: <20121028174613.012251C0250@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58540:a18331247b12 Date: 2012-10-28 18:45 +0100 http://bitbucket.org/pypy/pypy/changeset/a18331247b12/ Log: Tweak ll_arraycopy() to fix again the issue of the missing arraydescr among the calldescr.get_extra_info(). diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py --- a/pypy/rlib/objectmodel.py +++ b/pypy/rlib/objectmodel.py @@ -188,7 +188,7 @@ src = py.code.Source(""" def %(name)s(%(arglist)s): if not we_are_translated(): - typecheck(%(arglist)s) + typecheck(%(arglist)s) # pypy.rlib.objectmodel return %(name)s_original(%(arglist)s) """ % dict(name=f.func_name, arglist=arglist)) # diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py --- a/pypy/rlib/rgc.py +++ b/pypy/rlib/rgc.py @@ -145,8 +145,11 @@ from pypy.rlib.objectmodel import keepalive_until_here # XXX: Hack to ensure that we get a proper effectinfo.write_descrs_arrays - if NonConstant(False): - dest[dest_start] = source[source_start] + # and also, maybe, speed up very small cases + if length <= 1: + if length == 1: + dest[dest_start] = source[source_start] + return # supports non-overlapping copies only if not we_are_translated(): diff --git a/pypy/rlib/test/test_rgc.py b/pypy/rlib/test/test_rgc.py --- a/pypy/rlib/test/test_rgc.py +++ b/pypy/rlib/test/test_rgc.py @@ -134,6 +134,23 @@ assert check.called +def test_ll_arraycopy_small(): + TYPE = lltype.GcArray(lltype.Signed) + for length in range(5): + a1 = lltype.malloc(TYPE, 10) + a2 = lltype.malloc(TYPE, 6) + org1 = range(20, 30) + org2 = range(50, 56) + for i in range(len(a1)): a1[i] = org1[i] + for i in range(len(a2)): a2[i] = org2[i] + rgc.ll_arraycopy(a1, a2, 4, 2, length) + for i in range(10): + assert a1[i] == org1[i] + for i in range(6): + if 2 <= i < 2 + length: + assert a2[i] == a1[i+2] + else: + assert a2[i] == org2[i] def test_ll_shrink_array_1(): From noreply at buildbot.pypy.org Sun Oct 28 18:46:45 2012 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 28 Oct 2012 18:46:45 +0100 (CET) Subject: [pypy-commit] pypy default: Fix the test. Message-ID: <20121028174645.6A7431C0250@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58541:e7004e804a53 Date: 2012-10-28 18:46 +0100 http://bitbucket.org/pypy/pypy/changeset/e7004e804a53/ Log: Fix the test. diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py --- a/pypy/jit/metainterp/test/test_list.py +++ b/pypy/jit/metainterp/test/test_list.py @@ -137,7 +137,7 @@ return l2[0] + l2[1] + l2[2] + l2[3] res = self.interp_operations(f, [], listops=True) - assert res == 10 + assert res == f() def test_arraycopy_full(self): jitdriver = JitDriver(greens = [], reds = ['n']) From noreply at buildbot.pypy.org Sun Oct 28 18:49:04 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 18:49:04 +0100 (CET) Subject: [pypy-commit] pypy default: readd the hack. will find something better Message-ID: <20121028174904.ADE7B1C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58542:8f7faa354ab4 Date: 2012-10-28 18:48 +0100 http://bitbucket.org/pypy/pypy/changeset/8f7faa354ab4/ Log: readd the hack. will find something better diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -431,16 +431,15 @@ length = self.get_constant_box(op.getarg(5)) if (source_start_box and dest_start_box and length and (dest_value.is_virtual() or length.getint() <= 8) and - (source_value.is_virtual())): # or length.getint() <= 8)): + (source_value.is_virtual() or length.getint() <= 8)): from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue source_start = source_start_box.getint() dest_start = dest_start_box.getint() for index in range(length.getint()): # XXX fish fish fish - #arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] - assert isinstance(source_value, VArrayValue) - arraydescr = source_value.arraydescr + arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] if source_value.is_virtual(): + assert isinstance(source_value, VArrayValue) val = source_value.getitem(index + source_start) else: if arraydescr.is_array_of_pointers(): From noreply at buildbot.pypy.org Sun Oct 28 19:22:23 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 19:22:23 +0100 (CET) Subject: [pypy-commit] pypy default: some speedups Message-ID: <20121028182223.A92121C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58543:e5eb07255e76 Date: 2012-10-28 19:22 +0100 http://bitbucket.org/pypy/pypy/changeset/e5eb07255e76/ Log: some speedups 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 @@ -381,6 +381,8 @@ class ConcreteArray(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides): make_sure_not_resized(shape) + make_sure_not_resized(strides) + make_sure_not_resized(backstrides) self.shape = shape self.size = support.product(shape) * dtype.get_size() self.storage = dtype.itemtype.malloc(self.size) @@ -389,8 +391,8 @@ self.strides = strides self.backstrides = backstrides - def create_iter(self, shape): - if shape == self.get_shape(): + def create_iter(self, shape=None): + if shape is None or shape == self.get_shape(): return ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.strides, self.backstrides, self.get_shape(), shape) @@ -426,8 +428,8 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape): - if shape != self.get_shape(): + def create_iter(self, shape=None): + if shape is not None and shape != self.get_shape(): r = calculate_broadcast_strides(self.strides, self.backstrides, self.get_shape(), shape) return MultiDimViewIterator(self.parent, 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 @@ -34,7 +34,7 @@ def get_shape(self): return [] - def create_iter(self, shape): + def create_iter(self, shape=None): return ScalarIterator(self.value) def get_scalar_value(self): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -190,7 +190,7 @@ return space.call_function(cache.w_array_str, self) def dump_data(self): - i = self.create_iter(self.get_shape()) + i = self.create_iter() first = True dtype = self.get_dtype() s = StringBuilder() @@ -206,8 +206,6 @@ return s.build() def create_iter(self, shape=None): - if shape is None: - shape = self.get_shape() return self.implementation.create_iter(shape) def create_axis_iter(self, shape, dim): @@ -396,7 +394,7 @@ 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()")) - iter = self.create_iter(self.get_shape()) + iter = self.create_iter() return space.wrap(space.is_true(iter.getitem())) def _binop_impl(ufunc_name): @@ -681,7 +679,7 @@ if ndmin > len(shape): shape = [1] * (ndmin - len(shape)) + shape arr = W_NDimArray.from_shape(shape, dtype, order=order) - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() for w_elem in elems_w: arr_iter.setitem(dtype.coerce(space, w_elem)) arr_iter.next() 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 @@ -89,7 +89,7 @@ reds = ['obj', 'obj_iter', 'cur_value']) def compute_reduce(obj, calc_dtype, func, done_func, identity): - obj_iter = obj.create_iter(obj.get_shape()) + obj_iter = obj.create_iter() if identity is None: cur_value = obj_iter.getitem().convert_to(calc_dtype) obj_iter.next() @@ -109,7 +109,7 @@ return cur_value def fill(arr, box): - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() while not arr_iter.done(): arr_iter.setitem(box) arr_iter.next() @@ -159,7 +159,7 @@ def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): out_iter = out.create_axis_iter(arr.get_shape(), axis) - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() if identity is not None: identity = identity.convert_to(dtype) shapelen = len(shape) @@ -192,7 +192,7 @@ result = 0 idx = 1 dtype = arr.get_dtype() - iter = arr.create_iter(arr.get_shape()) + iter = arr.create_iter() cur_best = iter.getitem() iter.next() shapelen = len(arr.get_shape()) diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -15,16 +15,22 @@ jit.isconstant(len(chunks)) ) def calculate_slice_strides(shape, start, strides, backstrides, chunks): - rstrides = [] - rbackstrides = [] + size = 0 + for chunk in chunks: + if chunk.step != 0: + size += 1 + rstrides = [0] * size + rbackstrides = [0] * size rstart = start - rshape = [] + rshape = [0] * size i = -1 + j = 0 for i, chunk in enumerate_chunks(chunks): if chunk.step != 0: - rstrides.append(strides[i] * chunk.step) - rbackstrides.append(strides[i] * (chunk.lgt - 1) * chunk.step) - rshape.append(chunk.lgt) + rstrides[j] = strides[i] * chunk.step + rbackstrides[j] = strides[i] * (chunk.lgt - 1) * chunk.step + rshape[j] = chunk.lgt + j += i rstart += strides[i] * chunk.start # add a reminder s = i + 1 @@ -255,19 +261,19 @@ cur_step = steps[oldI] n_old_elems_to_use *= old_shape[oldI] assert len(new_strides) == len(new_shape) - return new_strides + return new_strides[:] def calculate_dot_strides(strides, backstrides, res_shape, skip_dims): - rstrides = [] - rbackstrides = [] - j=0 + rstrides = [0] * len(res_shape) + rbackstrides = [0] * len(res_shape) + j = 0 for i in range(len(res_shape)): if i in skip_dims: - rstrides.append(0) - rbackstrides.append(0) + rstrides[i] = 0 + rbackstrides[i] = 0 else: - rstrides.append(strides[j]) - rbackstrides.append(backstrides[j]) + rstrides[i] = strides[j] + rbackstrides[i] = backstrides[j] j += 1 return rstrides, rbackstrides From noreply at buildbot.pypy.org Sun Oct 28 20:34:28 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 20:34:28 +0100 (CET) Subject: [pypy-commit] pypy result-in-resops: cleanups and pass one more test Message-ID: <20121028193428.13E081C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: result-in-resops Changeset: r58544:d0dcc32ecfe4 Date: 2012-10-28 19:33 +0100 http://bitbucket.org/pypy/pypy/changeset/d0dcc32ecfe4/ Log: cleanups and pass one more test diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -250,13 +250,6 @@ def __init__(self): pass # make rpython happy - #def propagate_forward(self, op): - # raise NotImplementedError - - #def emit_operation(self, op): - # self.last_emitted_operation = op - # self.next_optimization.propagate_forward(op) - def process_inputargs(self, args): pass @@ -416,21 +409,6 @@ def replace(self, op, with_): self.getforwarded(op)._forwarded = with_ - def copy_op_if_modified_by_optimization(self, op): - xxxx - new_op = op.copy_if_modified_by_optimization(self) - if new_op is not op: - self.replace(op, new_op) - return new_op - - # XXX some RPython magic needed - def copy_and_change(self, op, *args, **kwds): - xxx - new_op = op.copy_and_change(*args, **kwds) - if new_op is not op: - self.replace(op, new_op) - return new_op - def ensure_imported(self, value): pass @@ -513,10 +491,11 @@ for opt in self.optimizations: opt.process_inputargs(self.loop.inputargs) while i < len(self.loop.operations): - op = self.loop.operations[i] - orig_op = op + orig_op = self.loop.operations[i] + op = orig_op for opt in self.optimizations: op = opt.optimize_operation(op) + # result can be either None, the same thing or a new operation if op is None: break else: diff --git a/pypy/jit/metainterp/optimizeopt/pure.py b/pypy/jit/metainterp/optimizeopt/pure.py --- a/pypy/jit/metainterp/optimizeopt/pure.py +++ b/pypy/jit/metainterp/optimizeopt/pure.py @@ -46,7 +46,6 @@ else: self.pure_operations.set(orig_op, op) self.remember_emitting_pure(op) - # otherwise, the operation remains if nextop: return nextop @@ -62,14 +61,11 @@ self.replace(op, oldop) self.last_emitted_operation = REMOVED return - else: - new_op = self.optimizer.getforwarded(op) - self.pure_operations.set(new_op, op) - self.remember_emitting_pure(op) - + new_op = self.optimizer.getforwarded(op) + self.pure_operations.set(op, new_op) + self.remember_emitting_pure(new_op) # replace CALL_PURE with just CALL - xxx - self.emit_operation(self.optimizer.copy_and_change(op, opnum)) + return new_op.make_forwarded_copy(opnum) return optimize_CALL_PURE optimize_CALL_PURE_i = _new_optimize_call_pure(rop.CALL_i) optimize_CALL_PURE_f = _new_optimize_call_pure(rop.CALL_f) diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -81,7 +81,7 @@ elif v2.is_null(): self.optimizer.replace(op, op.getarg(0)) else: - self.emit_operation(op) + return op def optimize_INT_SUB(self, op): v2 = self.getforwarded(op.getarg(1)) From noreply at buildbot.pypy.org Sun Oct 28 20:34:29 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 20:34:29 +0100 (CET) Subject: [pypy-commit] pypy default: seems my hacks made assertion worse Message-ID: <20121028193429.416F01C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58545:67c628463599 Date: 2012-10-28 20:27 +0100 http://bitbucket.org/pypy/pypy/changeset/67c628463599/ Log: seems my hacks made assertion worse diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -118,7 +118,7 @@ # 1. find the start of the statement from codeop import compile_command end = None - for start in range(lineno, -1, max(-1, lineno - 10)): + for start in range(lineno, -1, -1): if assertion: line = self.lines[start] # the following lines are not fully tested, change with care @@ -135,9 +135,9 @@ compile_command(trysource) except (SyntaxError, OverflowError, ValueError): continue - + # 2. find the end of the statement - for end in range(lineno+1, min(len(self)+1, lineno + 10)): + for end in range(lineno+1, len(self)+1): trysource = self[start:end] if trysource.isparseable(): return start, end From noreply at buildbot.pypy.org Sun Oct 28 20:34:30 2012 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 28 Oct 2012 20:34:30 +0100 (CET) Subject: [pypy-commit] pypy default: grr, my font sucks Message-ID: <20121028193430.6A7481C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58546:aba6cf7fc006 Date: 2012-10-28 20:34 +0100 http://bitbucket.org/pypy/pypy/changeset/aba6cf7fc006/ Log: grr, my font sucks diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -30,7 +30,7 @@ rstrides[j] = strides[i] * chunk.step rbackstrides[j] = strides[i] * (chunk.lgt - 1) * chunk.step rshape[j] = chunk.lgt - j += i + j += 1 rstart += strides[i] * chunk.start # add a reminder s = i + 1 From noreply at buildbot.pypy.org Sun Oct 28 21:08:05 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Sun, 28 Oct 2012 21:08:05 +0100 (CET) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: hg merge default Message-ID: <20121028200805.E70211C1C59@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r58547:1c6117b14dc2 Date: 2012-10-28 21:07 +0100 http://bitbucket.org/pypy/pypy/changeset/1c6117b14dc2/ Log: hg merge default diff too long, truncating to 2000 out of 24900 lines diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py --- a/lib_pypy/_ctypes/structure.py +++ b/lib_pypy/_ctypes/structure.py @@ -69,7 +69,8 @@ resnames.append(name) names = resnames self._names = names - self.__dict__.update(fields) + for name, field in fields.items(): + setattr(self, name, field) class Field(object): def __init__(self, name, offset, size, ctype, num, is_bitfield): diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py deleted file mode 100644 --- a/lib_pypy/itertools.py +++ /dev/null @@ -1,670 +0,0 @@ -# Note that PyPy contains also a built-in module 'itertools' which will -# hide this one if compiled in. - -"""Functional tools for creating and using iterators. - -Infinite iterators: -count([n]) --> n, n+1, n+2, ... -cycle(p) --> p0, p1, ... plast, p0, p1, ... -repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times - -Iterators terminating on the shortest input sequence: -izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... -ifilter(pred, seq) --> elements of seq where pred(elem) is True -ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False -islice(seq, [start,] stop [, step]) --> elements from - seq[start:stop:step] -imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ... -starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ... -tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n -chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... -takewhile(pred, seq) --> seq[0], seq[1], until pred fails -dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails -groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v) -""" - -__all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', - 'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap', - 'takewhile', 'tee', 'compress', 'product'] - -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f - - -class chain(object): - """Make an iterator that returns elements from the first iterable - until it is exhausted, then proceeds to the next iterable, until - all of the iterables are exhausted. Used for treating consecutive - sequences as a single sequence. - - Equivalent to : - - def chain(*iterables): - for it in iterables: - for element in it: - yield element - """ - def __init__(self, *iterables): - self._iterables_iter = iter(map(iter, iterables)) - # little trick for the first chain.next() call - self._cur_iterable_iter = iter([]) - - def __iter__(self): - return self - - def next(self): - while True: - try: - return self._cur_iterable_iter.next() - except StopIteration: - self._cur_iterable_iter = self._iterables_iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iterable_iter)) - - -class compress(object): - def __init__(self, data, selectors): - self.data = iter(data) - self.selectors = iter(selectors) - - def __iter__(self): - return self - - def next(self): - while True: - next_item = self.data.next() - next_selector = self.selectors.next() - if bool(next_selector): - return next_item - - -class count(object): - """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. - - Equivalent to : - - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) - while True: - yield n - n += 1 - """ - def __init__(self, n=0): - if not isinstance(n, int): - raise TypeError('%s is not a regular integer' % n) - self.times = n-1 - - def __iter__(self): - return self - - def next(self): - self.times += 1 - return self.times - - def __repr__(self): - return 'count(%d)' % (self.times + 1) - - - -class cycle(object): - """Make an iterator returning elements from the iterable and - saving a copy of each. When the iterable is exhausted, return - elements from the saved copy. Repeats indefinitely. - - Equivalent to : - - def cycle(iterable): - saved = [] - for element in iterable: - yield element - saved.append(element) - while saved: - for element in saved: - yield element - """ - def __init__(self, iterable): - self._cur_iter = iter(iterable) - self._saved = [] - self._must_save = True - - def __iter__(self): - return self - - def next(self): - # XXX Could probably be improved - try: - next_elt = self._cur_iter.next() - if self._must_save: - self._saved.append(next_elt) - except StopIteration: - self._cur_iter = iter(self._saved) - next_elt = self._cur_iter.next() - self._must_save = False - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iter)) - return next_elt - - -class dropwhile(object): - """Make an iterator that drops elements from the iterable as long - as the predicate is true; afterwards, returns every - element. Note, the iterator does not produce any output until the - predicate is true, so it may have a lengthy start-up time. - - Equivalent to : - - def dropwhile(predicate, iterable): - iterable = iter(iterable) - for x in iterable: - if not predicate(x): - yield x - break - for x in iterable: - yield x - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - self._dropped = False - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if self._dropped: - return value - while self._predicate(value): - value = self._iter.next() - self._dropped = True - return value - -class groupby(object): - """Make an iterator that returns consecutive keys and groups from the - iterable. The key is a function computing a key value for each - element. If not specified or is None, key defaults to an identity - function and returns the element unchanged. Generally, the - iterable needs to already be sorted on the same key function. - - The returned group is itself an iterator that shares the - underlying iterable with groupby(). Because the source is shared, - when the groupby object is advanced, the previous group is no - longer visible. So, if that data is needed later, it should be - stored as a list: - - groups = [] - uniquekeys = [] - for k, g in groupby(data, keyfunc): - groups.append(list(g)) # Store group iterator as a list - uniquekeys.append(k) - """ - def __init__(self, iterable, key=None): - if key is None: - key = lambda x: x - self.keyfunc = key - self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = xrange(0) - - def __iter__(self): - return self - - def next(self): - while self.currkey == self.tgtkey: - try: - self.currvalue = self.it.next() # Exit on StopIteration - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self.it)) - self.currkey = self.keyfunc(self.currvalue) - self.tgtkey = self.currkey - return (self.currkey, self._grouper(self.tgtkey)) - - def _grouper(self, tgtkey): - while self.currkey == tgtkey: - yield self.currvalue - self.currvalue = self.it.next() # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) - - - -class _ifilter_base(object): - """base class for ifilter and ifilterflase""" - def __init__(self, predicate, iterable): - # Make sure iterable *IS* iterable - self._iter = iter(iterable) - if predicate is None: - self._predicate = bool - else: - self._predicate = predicate - - def __iter__(self): - return self - -class ifilter(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is True. If predicate is - None, return the items that are true. - - Equivalent to : - - def ifilter: - if predicate is None: - predicate = bool - for x in iterable: - if predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - -class ifilterfalse(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is False. If predicate is - None, return the items that are false. - - Equivalent to : - - def ifilterfalse(predicate, iterable): - if predicate is None: - predicate = bool - for x in iterable: - if not predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if not self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - - - - -class imap(object): - """Make an iterator that computes the function using arguments - from each of the iterables. If function is set to None, then - imap() returns the arguments as a tuple. Like map() but stops - when the shortest iterable is exhausted instead of filling in - None for shorter iterables. The reason for the difference is that - infinite iterator arguments are typically an error for map() - (because the output is fully evaluated) but represent a common - and useful way of supplying arguments to imap(). - - Equivalent to : - - def imap(function, *iterables): - iterables = map(iter, iterables) - while True: - args = [i.next() for i in iterables] - if function is None: - yield tuple(args) - else: - yield function(*args) - - """ - def __init__(self, function, iterable, *other_iterables): - self._func = function - self._iters = map(iter, (iterable, ) + other_iterables) - - def __iter__(self): - return self - - def next(self): - try: - args = [it.next() for it in self._iters] - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (it)) - if self._func is None: - return tuple(args) - else: - return self._func(*args) - - - -class islice(object): - """Make an iterator that returns selected elements from the - iterable. If start is non-zero, then elements from the iterable - are skipped until start is reached. Afterward, elements are - returned consecutively unless step is set higher than one which - results in items being skipped. If stop is None, then iteration - continues until the iterator is exhausted, if at all; otherwise, - it stops at the specified position. Unlike regular slicing, - islice() does not support negative values for start, stop, or - step. Can be used to extract related fields from data where the - internal structure has been flattened (for example, a multi-line - report may list a name field on every third line). - """ - def __init__(self, iterable, *args): - s = slice(*args) - self.start, self.stop, self.step = s.start or 0, s.stop, s.step - if not isinstance(self.start, (int, long)): - raise ValueError("Start argument must be an integer") - if self.stop is not None and not isinstance(self.stop, (int,long)): - raise ValueError("Stop argument must be an integer or None") - if self.step is None: - self.step = 1 - if self.start<0 or (self.stop is not None and self.stop<0 - ) or self.step<=0: - raise ValueError, "indices for islice() must be positive" - self.it = iter(iterable) - self.donext = None - self.cnt = 0 - - def __iter__(self): - return self - - def next(self): - if self.donext is None: - try: - self.donext = self.it.next - except AttributeError: - raise TypeError - nextindex = self.start - if self.stop is not None and nextindex >= self.stop: - raise StopIteration - while self.cnt <= nextindex: - nextitem = self.donext() - self.cnt += 1 - self.start += self.step - return nextitem - -class izip(object): - """Make an iterator that aggregates elements from each of the - iterables. Like zip() except that it returns an iterator instead - of a list. Used for lock-step iteration over several iterables at - a time. - - Equivalent to : - - def izip(*iterables): - iterables = map(iter, iterables) - while iterables: - result = [i.next() for i in iterables] - yield tuple(result) - """ - def __init__(self, *iterables): - self._iterators = map(iter, iterables) - self._result = [None] * len(self._iterators) - - def __iter__(self): - return self - - def next(self): - if not self._iterators: - raise StopIteration() - try: - return tuple([i.next() for i in self._iterators]) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (i)) - - -class product(object): - - def __init__(self, *args, **kw): - if len(kw) > 1: - raise TypeError("product() takes at most 1 argument (%d given)" % - len(kw)) - self.repeat = kw.get('repeat', 1) - self.gears = [x for x in args] * self.repeat - self.num_gears = len(self.gears) - # initialization of indicies to loop over - self.indicies = [(0, len(self.gears[x])) - for x in range(0, self.num_gears)] - self.cont = True - - def roll_gears(self): - # Starting from the end of the gear indicies work to the front - # incrementing the gear until the limit is reached. When the limit - # is reached carry operation to the next gear - should_carry = True - for n in range(0, self.num_gears): - nth_gear = self.num_gears - n - 1 - if should_carry: - count, lim = self.indicies[nth_gear] - count += 1 - if count == lim and nth_gear == 0: - self.cont = False - if count == lim: - should_carry = True - count = 0 - else: - should_carry = False - self.indicies[nth_gear] = (count, lim) - else: - break - - def __iter__(self): - return self - - def next(self): - if not self.cont: - raise StopIteration - l = [] - for x in range(0, self.num_gears): - index, limit = self.indicies[x] - l.append(self.gears[x][index]) - self.roll_gears() - return tuple(l) - - -class repeat(object): - """Make an iterator that returns object over and over again. - Runs indefinitely unless the times argument is specified. Used - as argument to imap() for invariant parameters to the called - function. Also used with izip() to create an invariant part of a - tuple record. - - Equivalent to : - - def repeat(object, times=None): - if times is None: - while True: - yield object - else: - for i in xrange(times): - yield object - """ - def __init__(self, obj, times=None): - self._obj = obj - if times is not None: - xrange(times) # Raise a TypeError - if times < 0: - times = 0 - self._times = times - - def __iter__(self): - return self - - def next(self): - # next() *need* to decrement self._times when consumed - if self._times is not None: - if self._times <= 0: - raise StopIteration() - self._times -= 1 - return self._obj - - def __repr__(self): - if self._times is not None: - return 'repeat(%r, %r)' % (self._obj, self._times) - else: - return 'repeat(%r)' % (self._obj,) - - def __len__(self): - if self._times == -1 or self._times is None: - raise TypeError("len() of uniszed object") - return self._times - - -class starmap(object): - """Make an iterator that computes the function using arguments - tuples obtained from the iterable. Used instead of imap() when - argument parameters are already grouped in tuples from a single - iterable (the data has been ``pre-zipped''). The difference - between imap() and starmap() parallels the distinction between - function(a,b) and function(*c). - - Equivalent to : - - def starmap(function, iterable): - iterable = iter(iterable) - while True: - yield function(*iterable.next()) - """ - def __init__(self, function, iterable): - self._func = function - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - # CPython raises a TypeError when the iterator doesn't return a tuple - try: - t = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - if not isinstance(t, tuple): - raise TypeError("iterator must return a tuple") - return self._func(*t) - - - -class takewhile(object): - """Make an iterator that returns elements from the iterable as - long as the predicate is true. - - Equivalent to : - - def takewhile(predicate, iterable): - for x in iterable: - if predicate(x): - yield x - else: - break - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if not self._predicate(value): - raise StopIteration() - return value - - -class TeeData(object): - """Holds cached values for TeeObjects""" - def __init__(self, iterator): - self.data = [] - self._iter = iterator - - def __getitem__(self, i): - # iterates until 'i' if not done yet - while i>= len(self.data): - try: - self.data.append( self._iter.next() ) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - return self.data[i] - - -class TeeObject(object): - """Iterables / Iterators as returned by the tee() function""" - def __init__(self, iterable=None, tee_data=None): - if tee_data: - self.tee_data = tee_data - self.pos = 0 - # <=> Copy constructor - elif isinstance(iterable, TeeObject): - self.tee_data = iterable.tee_data - self.pos = iterable.pos - else: - self.tee_data = TeeData(iter(iterable)) - self.pos = 0 - - def next(self): - data = self.tee_data[self.pos] - self.pos += 1 - return data - - def __iter__(self): - return self - - - at builtinify -def tee(iterable, n=2): - """Return n independent iterators from a single iterable. - Note : once tee() has made a split, the original iterable - should not be used anywhere else; otherwise, the iterable could get - advanced without the tee objects being informed. - - Note : this member of the toolkit may require significant auxiliary - storage (depending on how much temporary data needs to be stored). - In general, if one iterator is going to use most or all of the - data before the other iterator, it is faster to use list() instead - of tee() - - Equivalent to : - - def tee(iterable, n=2): - def gen(next, data={}, cnt=[0]): - for i in count(): - if i == cnt[0]: - item = data[i] = next() - cnt[0] += 1 - else: - item = data.pop(i) - yield item - it = iter(iterable) - return tuple([gen(it.next) for i in range(n)]) - """ - if isinstance(iterable, TeeObject): - # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) - return tuple([iterable] + - [TeeObject(tee_data=iterable.tee_data) for i in xrange(n-1)]) - tee_data = TeeData(iter(iterable)) - return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)]) diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,5 +1,5 @@ -from _numpypy import array, ndarray, int_, float_, bool_ #, complex_# , longlong +from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math @@ -200,7 +200,7 @@ typename = "'%s'" % typename lf = '' - if 0: # or issubclass(arr.dtype.type, flexible): + if issubclass(arr.dtype.type, flexible): if arr.dtype.names: typename = "%s" % str(arr.dtype) else: diff --git a/lib_pypy/pypy_test/test_ctypes_support.py b/lib_pypy/pypy_test/test_ctypes_support.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_ctypes_support.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import absolute_import - -import py -from ctypes import * -try: - from ctypes_support import standard_c_lib, get_errno, set_errno -except ImportError: # on top of cpython - from lib_pypy.ctypes_support import standard_c_lib, get_errno, set_errno - - -def test_stdlib_and_errno(): - py.test.skip("this is expected on top of pypy, we need to fix ctypes in a way that is now in 2.6 in order to make this reliable") - write = standard_c_lib.write - write.argtypes = [c_int, c_char_p, c_size_t] - write.restype = c_size_t - # clear errno first - set_errno(0) - assert get_errno() == 0 - write(-345, "abc", 3) - assert get_errno() != 0 - set_errno(0) - assert get_errno() == 0 - -def test_argument_conversion_and_checks(): - strlen = standard_c_lib.strlen - strlen.argtypes = [c_char_p] - strlen.restype = c_size_t - assert strlen("eggs") == 4 - - # Should raise ArgumentError, not segfault - py.test.raises(ArgumentError, strlen, False) - diff --git a/lib_pypy/pypy_test/test_itertools.py b/lib_pypy/pypy_test/test_itertools.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_itertools.py +++ /dev/null @@ -1,50 +0,0 @@ -from py.test import raises -from lib_pypy import itertools - -class TestItertools(object): - - def test_compress(self): - it = itertools.compress(['a', 'b', 'c'], [0, 1, 0]) - - assert list(it) == ['b'] - - def test_compress_diff_len(self): - it = itertools.compress(['a'], []) - raises(StopIteration, it.next) - - def test_product(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')] - - def test_product_repeat(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m, repeat=2) - ans = [(1, 'a', 1, 'a'), (1, 'a', 1, 'b'), (1, 'a', 2, 'a'), - (1, 'a', 2, 'b'), (1, 'b', 1, 'a'), (1, 'b', 1, 'b'), - (1, 'b', 2, 'a'), (1, 'b', 2, 'b'), (2, 'a', 1, 'a'), - (2, 'a', 1, 'b'), (2, 'a', 2, 'a'), (2, 'a', 2, 'b'), - (2, 'b', 1, 'a'), (2, 'b', 1, 'b'), (2, 'b', 2, 'a'), - (2, 'b', 2, 'b')] - assert list(prodlist) == ans - - def test_product_diff_sizes(self): - l = [1, 2] - m = ['a'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (2, 'a')] - - l = [1] - m = ['a', 'b'] - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b')] - - def test_product_toomany_args(self): - l = [1, 2] - m = ['a'] - raises(TypeError, itertools.product, l, m, repeat=1, foo=2) 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 @@ -233,7 +233,7 @@ try: return unicode(line, ENCODING) except UnicodeDecodeError: # bah, silently fall back... - return unicode(line, 'utf-8') + return unicode(line, 'utf-8', 'replace') def get_history_length(self): return self.saved_history_length diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -496,7 +496,7 @@ if iscode: self.__tputs(text) else: - os.write(self.output_fd, text.encode(self.encoding)) + os.write(self.output_fd, text.encode(self.encoding, 'replace')) del self.__buffer[:] def __tputs(self, fmt, prog=delayprog): diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -548,7 +548,7 @@ if cell.is_constant(): newcell.const = cell.const cell = newcell - cell.knowntypedata = renamed_knowntypedata + cell.set_knowntypedata(renamed_knowntypedata) cells.append(cell) diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -31,21 +31,21 @@ # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', - 'truediv', 'floordiv', 'divmod', 'pow', + 'truediv', 'floordiv', 'divmod', 'and_', 'or_', 'xor', 'lshift', 'rshift', 'getitem', 'setitem', 'delitem', 'getitem_idx', 'getitem_key', 'getitem_idx_key', 'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv', 'inplace_floordiv', 'inplace_div', - 'inplace_mod', 'inplace_pow', + 'inplace_mod', 'inplace_lshift', 'inplace_rshift', 'inplace_and', 'inplace_or', 'inplace_xor', 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'is_', 'cmp', 'coerce', ] +[opname+'_ovf' for opname in - """add sub mul floordiv div mod pow lshift + """add sub mul floordiv div mod lshift """.split() ]) @@ -65,7 +65,6 @@ def inplace_floordiv((obj1, obj2)): return pair(obj1, obj2).floordiv() def inplace_div((obj1, obj2)): return pair(obj1, obj2).div() def inplace_mod((obj1, obj2)): return pair(obj1, obj2).mod() - def inplace_pow((obj1, obj2)): return pair(obj1, obj2).pow(s_None) def inplace_lshift((obj1, obj2)): return pair(obj1, obj2).lshift() def inplace_rshift((obj1, obj2)): return pair(obj1, obj2).rshift() def inplace_and((obj1, obj2)): return pair(obj1, obj2).and_() @@ -145,7 +144,7 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key annotator = bk.annotator @@ -169,6 +168,7 @@ bind(obj2, obj1, 0) bind(obj1, obj2, 1) + r.set_knowntypedata(knowntypedata) return r @@ -301,19 +301,6 @@ return SomeInteger(nonneg=int1.nonneg, knowntype=int1.knowntype) rshift.can_only_throw = [] - def pow((int1, int2), obj3): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - pow.can_only_throw = [ZeroDivisionError] - pow_ovf = _clone(pow, [ZeroDivisionError, OverflowError]) - - def inplace_pow((int1, int2)): - knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype) - return SomeInteger(nonneg = int1.nonneg, - knowntype=knowntype) - inplace_pow.can_only_throw = [ZeroDivisionError] - def _compare_helper((int1, int2), opname, operation): r = SomeBool() if int1.is_immutable_constant() and int2.is_immutable_constant(): @@ -351,8 +338,7 @@ case = opname in ('gt', 'ge', 'eq') add_knowntypedata(knowntypedata, case, [op.args[0]], SomeInteger(nonneg=True, knowntype=tointtype(int1))) - if knowntypedata: - r.knowntypedata = knowntypedata + r.set_knowntypedata(knowntypedata) # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) @@ -383,8 +369,7 @@ if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) - if ktd: - s.knowntypedata = ktd + s.set_knowntypedata(ktd) return s def and_((boo1, boo2)): @@ -500,9 +485,6 @@ div.can_only_throw = [] truediv = div - def pow((flt1, flt2), obj3): - raise NotImplementedError("float power not supported, use math.pow") - # repeat these in order to copy the 'can_only_throw' attribute inplace_div = div inplace_truediv = truediv diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -16,7 +16,7 @@ from pypy.annotation.dictdef import DictDef from pypy.annotation import description from pypy.annotation.signature import annotationoftype -from pypy.interpreter.argument import ArgumentsForTranslation +from pypy.objspace.flow.argument import ArgumentsForTranslation from pypy.rlib.objectmodel import r_dict, Symbolic from pypy.tool.algo.unionfind import UnionFind from pypy.rpython.lltypesystem import lltype, llmemory @@ -101,7 +101,7 @@ def consider_list_delitem(self, idx): return self.indexrepr(idx) - + def consider_str_join(self, s): if s.is_constant(): return repr(s.const) @@ -224,7 +224,7 @@ check_no_flags(s_value_or_def.listdef.listitem) elif isinstance(s_value_or_def, SomeDict): check_no_flags(s_value_or_def.dictdef.dictkey) - check_no_flags(s_value_or_def.dictdef.dictvalue) + check_no_flags(s_value_or_def.dictdef.dictvalue) elif isinstance(s_value_or_def, SomeTuple): for s_item in s_value_or_def.items: check_no_flags(s_item) @@ -238,9 +238,9 @@ elif isinstance(s_value_or_def, ListItem): if s_value_or_def in seen: return - seen.add(s_value_or_def) + seen.add(s_value_or_def) check_no_flags(s_value_or_def.s_value) - + for clsdef in self.classdefs: check_no_flags(clsdef) @@ -366,14 +366,14 @@ listdef = ListDef(self, s_ImpossibleValue) for e in x: listdef.generalize(self.immutablevalue(e, False)) - result = SomeList(listdef) + result = SomeList(listdef) elif tp is dict or tp is r_dict: if need_const: key = Constant(x) try: return self.immutable_cache[key] except KeyError: - result = SomeDict(DictDef(self, + result = SomeDict(DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict)) @@ -396,7 +396,7 @@ result.const_box = key return result else: - dictdef = DictDef(self, + dictdef = DictDef(self, s_ImpossibleValue, s_ImpossibleValue, is_r_dict = tp is r_dict) @@ -545,7 +545,7 @@ return True else: return False - + def getfrozen(self, pyobj): return description.FrozenDesc(self, pyobj) @@ -566,7 +566,7 @@ key = (x.__class__, x) if key in self.seen_mutable: return - clsdef = self.getuniqueclassdef(x.__class__) + clsdef = self.getuniqueclassdef(x.__class__) self.seen_mutable[key] = True self.event('mutable', x) source = InstanceSource(self, x) @@ -586,7 +586,7 @@ except KeyError: access_sets = map[attrname] = UnionFind(description.ClassAttrFamily) return access_sets - + def pbc_getattr(self, pbc, s_attr): assert s_attr.is_constant() attr = s_attr.const @@ -598,7 +598,7 @@ first = descs[0] if len(descs) == 1: return first.s_read_attribute(attr) - + change = first.mergeattrfamilies(descs[1:], attr) attrfamily = first.getattrfamily(attr) @@ -700,7 +700,7 @@ def ondegenerated(self, what, s_value, where=None, called_from_graph=None): self.annotator.ondegenerated(what, s_value, where=where, called_from_graph=called_from_graph) - + def whereami(self): return self.annotator.whereami(self.position_key) diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -188,10 +188,10 @@ variables = [op.args[1]] for variable in variables: assert bk.annotator.binding(variable) == s_obj - r.knowntypedata = {} - + knowntypedata = {} if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): - add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) + add_knowntypedata(knowntypedata, True, variables, bk.valueoftype(typ)) + r.set_knowntypedata(knowntypedata) return r # note that this one either needs to be constant, or we will create SomeObject @@ -323,10 +323,12 @@ def robjmodel_hlinvoke(s_repr, s_llcallable, *args_s): from pypy.rpython import rmodel - assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr),"hlinvoke expects a constant repr as first argument" - r_func, nimplicitarg = s_repr.const.get_r_implfunc() + from pypy.rpython.error import TyperError - nbargs = len(args_s) + nimplicitarg + assert s_repr.is_constant() and isinstance(s_repr.const, rmodel.Repr), "hlinvoke expects a constant repr as first argument" + r_func, nimplicitarg = s_repr.const.get_r_implfunc() + + nbargs = len(args_s) + nimplicitarg s_sigs = r_func.get_s_signatures((nbargs, (), False, False)) if len(s_sigs) != 1: raise TyperError("cannot hlinvoke callable %r with not uniform" @@ -337,6 +339,7 @@ return lltype_to_annotation(rresult.lowleveltype) + def robjmodel_keepalive_until_here(*args_s): return immutablevalue(None) @@ -404,7 +407,10 @@ BUILTIN_ANALYZERS[unicodedata.decimal] = unicodedata_decimal # xxx # object - just ignore object.__init__ -BUILTIN_ANALYZERS[object.__init__] = object_init +if hasattr(object.__init__, 'im_func'): + BUILTIN_ANALYZERS[object.__init__.im_func] = object_init +else: + BUILTIN_ANALYZERS[object.__init__] = object_init # import BUILTIN_ANALYZERS[__import__] = import_func diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py --- a/pypy/annotation/description.py +++ b/pypy/annotation/description.py @@ -1,8 +1,7 @@ import types, py from pypy.objspace.flow.model import Constant, FunctionGraph -from pypy.interpreter.pycode import cpython_code_signature -from pypy.interpreter.argument import rawshape -from pypy.interpreter.argument import ArgErr +from pypy.objspace.flow.bytecode import cpython_code_signature +from pypy.objspace.flow.argument import rawshape, ArgErr from pypy.tool.sourcetools import valid_identifier from pypy.tool.pairtype import extendabletype @@ -181,7 +180,7 @@ name = pyobj.func_name if signature is None: if hasattr(pyobj, '_generator_next_method_of_'): - from pypy.interpreter.argument import Signature + from pypy.objspace.flow.argument import Signature signature = Signature(['entry']) # haaaaaack defaults = () else: @@ -260,7 +259,7 @@ try: inputcells = args.match_signature(signature, defs_s) except ArgErr, e: - raise TypeError("signature mismatch: %s() %s" % + raise TypeError("signature mismatch: %s() %s" % (self.name, e.getmsg())) return inputcells diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -195,6 +195,10 @@ unsigned = False def __init__(self): pass + def set_knowntypedata(self, knowntypedata): + assert not hasattr(self, 'knowntypedata') + if knowntypedata: + self.knowntypedata = knowntypedata class SomeStringOrUnicode(SomeObject): immutable = True diff --git a/pypy/annotation/specialize.py b/pypy/annotation/specialize.py --- a/pypy/annotation/specialize.py +++ b/pypy/annotation/specialize.py @@ -6,7 +6,7 @@ from pypy.objspace.flow.model import Block, Link, Variable, SpaceOperation from pypy.objspace.flow.model import Constant, checkgraph from pypy.annotation import model as annmodel -from pypy.interpreter.argument import Signature +from pypy.objspace.flow.argument import Signature def flatten_star_args(funcdesc, args_s): argnames, vararg, kwarg = funcdesc.signature diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -13,7 +13,7 @@ from pypy.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong from pypy.rlib.rarithmetic import r_singlefloat from pypy.rlib import objectmodel -from pypy.objspace.flow.objspace import FlowObjSpace +from pypy.objspace.flow.objspace import FlowObjSpace, FlowingError from pypy.translator.test import snippet @@ -1431,15 +1431,6 @@ assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_pow(self): - def f(n): - n **= 2 - return 2 ** n - a = self.RPythonAnnotator() - s = a.build_types(f, [int]) - # result should be an integer - assert s.knowntype == int - def test_inplace_div(self): def f(n): n /= 2 @@ -3156,10 +3147,9 @@ x **= y return x ** y a = self.RPythonAnnotator() - s = a.build_types(f, [int, int]) - assert isinstance(s, annmodel.SomeInteger) - a = self.RPythonAnnotator() - py.test.raises(NotImplementedError, a.build_types, f, [float, float]) + py.test.raises(FlowingError, a.build_types, f, [int, int]) + a = self.RPythonAnnotator() + py.test.raises(FlowingError, a.build_types, f, [float, float]) def test_intcmp_bug(self): def g(x, y): @@ -3815,6 +3805,20 @@ s = a.build_types(f, [annmodel.SomeInteger()]) assert isinstance(s, annmodel.SomeBool) + def test_object_init(self): + class A(object): + pass + + class B(A): + def __init__(self): + A.__init__(self) + + def f(): + B() + + a = self.RPythonAnnotator() + a.build_types(f, []) # assert did not explode + def g(n): return [0,1,2,n] diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -76,7 +76,7 @@ s_obj.is_true_behavior(r) bk = getbookkeeper() - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key op = block.operations[i] assert op.opname == "is_true" or op.opname == "nonzero" @@ -86,8 +86,8 @@ if s_obj.can_be_none(): s_nonnone_obj = s_obj.nonnoneify() add_knowntypedata(knowntypedata, True, [arg], s_nonnone_obj) + r.set_knowntypedata(knowntypedata) return r - def nonzero(obj): return obj.is_true() diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -118,7 +118,7 @@ ("translation.gcrootfinder", DEFL_ROOTFINDER_WITHJIT), ("translation.list_comprehension_operations", True)]), ChoiceOption("jit_backend", "choose the backend for the JIT", - ["auto", "x86", "x86-without-sse2", "llvm", 'arm'], + ["auto", "x86", "x86-without-sse2", 'arm'], default="auto", cmdline="--jit-backend"), ChoiceOption("jit_profiler", "integrate profiler support into the JIT", ["off", "oprofile"], diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -285,17 +285,14 @@ Miscellaneous ------------- -* Hash randomization is not supported in PyPy. Passing ``-R`` to the - command line, or setting the ``PYTHONHASHSEED`` environment variable - will display a warning message. +* Hash randomization (``-R``) is ignored in PyPy. As documented in + http://bugs.python.org/issue14621 , some of us believe it has no + purpose in CPython either. -* ``sys.setrecursionlimit()`` is ignored (and not needed) on - PyPy. On CPython it would set the maximum number of nested - calls that can occur before a RuntimeError is raised; on PyPy - overflowing the stack also causes RuntimeErrors, but the limit - is checked at a lower level. (The limit is currently hard-coded - at 768 KB, corresponding to roughly 1480 Python calls on - Linux.) +* ``sys.setrecursionlimit(n)`` sets the limit only approximately, + by setting the usable stack space to ``n * 768`` bytes. On Linux, + depending on the compiler settings, the default of 768KB is enough + for about 1400 calls. * assignment to ``__class__`` is limited to the cases where it works on CPython 2.5. On CPython 2.6 and 2.7 it works in a bit diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -100,7 +100,7 @@ To translate and run for the CLI you must have the SDK installed: Windows users need the `.NET Framework SDK`_, while Linux and Mac users can use Mono_. To translate and run for the JVM you must have a JDK -installed (at least version 5) and ``java``/``javac`` on your path. +installed (at least version 6) and ``java``/``javac`` on your path. A slightly larger example +++++++++++++++++++++++++ diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -17,12 +17,6 @@ projects, or anything else in PyPy, pop up on IRC or write to us on the `mailing list`_. -Make big integers faster -------------------------- - -PyPy's implementation of the Python ``long`` type is slower than CPython's. -Find out why and optimize them. **UPDATE:** this was done (thanks stian). - Make bytearray type fast ------------------------ @@ -81,14 +75,6 @@ * Allow separate compilation of extension modules. -Work on some of other languages -------------------------------- - -There are various languages implemented using the RPython translation toolchain. -One of the most interesting is the `JavaScript implementation`_, but there -are others like scheme or prolog. An interesting project would be to improve -the jittability of those or to experiment with various optimizations. - Various GCs ----------- @@ -144,8 +130,6 @@ * `hg` -* `sympy` - Experiment (again) with LLVM backend for RPython compilation ------------------------------------------------------------ @@ -191,4 +175,3 @@ .. _`issue tracker`: http://bugs.pypy.org .. _`mailing list`: http://mail.python.org/mailman/listinfo/pypy-dev .. _`jitviewer`: http://bitbucket.org/pypy/jitviewer -.. _`JavaScript implementation`: https://bitbucket.org/pypy/lang-js/overview 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 @@ -38,6 +38,8 @@ .. branch: numpypy-complex2 Complex dtype support for numpy +.. branch: numpypy-problems +Improve dtypes intp, uintp, void, string and record .. branch: kill-someobject major cleanups including killing some object support diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -504,149 +504,6 @@ w_key = keyword_names_w[i - limit] space.setitem(w_kwds, w_key, keywords_w[i]) -class ArgumentsForTranslation(Arguments): - def __init__(self, space, args_w, keywords=None, keywords_w=None, - w_stararg=None, w_starstararg=None): - self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False - Arguments.__init__(self, space, args_w, keywords, keywords_w) - - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - - def prepend(self, w_firstarg): # used often - "Return a new Arguments with a new argument inserted first." - return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - def copy(self): - return ArgumentsForTranslation(self.space, self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - - - def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None, - blindargs=0): - self.combine_if_necessary() - # _match_signature is destructive - return Arguments._match_signature( - self, w_firstarg, scope_w, signature, - defaults_w, blindargs) - - def unpack(self): - self.combine_if_necessary() - return Arguments.unpack(self) - - def match_signature(self, signature, defaults_w): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - return self._parse(None, signature, defaults_w) - - def unmatch_signature(self, signature, data_w): - """kind of inverse of match_signature""" - args_w, kwds_w = self.unpack() - need_cnt = len(args_w) - need_kwds = kwds_w.keys() - space = self.space - argnames, varargname, kwargname = signature - cnt = len(argnames) - data_args_w = data_w[:cnt] - if varargname: - data_w_stararg = data_w[cnt] - cnt += 1 - else: - data_w_stararg = space.newtuple([]) - - unfiltered_kwds_w = {} - if kwargname: - data_w_starargarg = data_w[cnt] - for w_key in space.unpackiterable(data_w_starargarg): - key = space.str_w(w_key) - w_value = space.getitem(data_w_starargarg, w_key) - unfiltered_kwds_w[key] = w_value - cnt += 1 - assert len(data_w) == cnt - - ndata_args_w = len(data_args_w) - if ndata_args_w >= need_cnt: - 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) - else: - stararg_w = space.unpackiterable(data_w_stararg) - datalen = len(data_args_w) - args_w = [None] * (datalen + len(stararg_w)) - for i in range(0, datalen): - args_w[i] = data_args_w[i] - for i in range(0, len(stararg_w)): - args_w[i + datalen] = stararg_w[i] - assert len(args_w) == need_cnt - - keywords = [] - keywords_w = [] - for key in need_kwds: - keywords.append(key) - keywords_w.append(unfiltered_kwds_w[key]) - - return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) - - @staticmethod - def frompacked(space, w_args=None, w_kwds=None): - raise NotImplementedError("go away") - - @staticmethod - def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w): - args_w = data_w[:shape_cnt] - p = end_keys = shape_cnt + len(shape_keys) - if shape_star: - w_star = data_w[p] - p += 1 - else: - w_star = None - if shape_stst: - w_starstar = data_w[p] - p += 1 - else: - w_starstar = None - return ArgumentsForTranslation(space, args_w, list(shape_keys), - data_w[shape_cnt:end_keys], w_star, - w_starstar) - - def flatten(self): - """ Argument <-> list of w_objects together with "shape" information """ - shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape() - data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)] - for key in shape_keys] - if shape_star: - data_w.append(self.w_stararg) - if shape_stst: - data_w.append(self.w_starstararg) - return (shape_cnt, shape_keys, shape_star, shape_stst), data_w - - def _rawshape(self, nextra=0): - assert not self.combine_has_happened - shape_cnt = len(self.arguments_w)+nextra # Number of positional args - if self.keywords: - shape_keys = self.keywords[:] # List of keywords (strings) - shape_keys.sort() - else: - shape_keys = [] - shape_star = self.w_stararg is not None # Flag: presence of *arg - shape_stst = self.w_starstararg is not None # Flag: presence of **kwds - return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted - -def rawshape(args, nextra=0): - return args._rawshape(nextra) - - # # ArgErr family of exceptions raised in case of argument mismatch. # We try to give error messages following CPython's, which are very informative. diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py --- a/pypy/interpreter/astcompiler/consts.py +++ b/pypy/interpreter/astcompiler/consts.py @@ -9,13 +9,14 @@ CO_NESTED = 0x0010 CO_GENERATOR = 0x0020 CO_NOFREE = 0x0040 -CO_CONTAINSGLOBALS = 0x0800 CO_GENERATOR_ALLOWED = 0x1000 CO_FUTURE_DIVISION = 0x2000 CO_FUTURE_ABSOLUTE_IMPORT = 0x4000 CO_FUTURE_WITH_STATEMENT = 0x8000 CO_FUTURE_PRINT_FUNCTION = 0x10000 CO_FUTURE_UNICODE_LITERALS = 0x20000 +CO_CONTAINSGLOBALS = 0x80000 # pypy-specific: need to check that it's not used + # by any other flag PyCF_SOURCE_IS_UTF8 = 0x0100 PyCF_DONT_IMPLY_DEDENT = 0x0200 diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -415,6 +415,7 @@ raise operationerrfmt(space.w_ValueError, "%s() requires a code object with %d free vars, not %d", self.name, closure_len, len(code.co_freevars)) + self.fget_func_doc(space) # see test_issue1293 self.code = code def fget_func_closure(self, space): 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 @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- import py -from pypy.interpreter.argument import (Arguments, ArgumentsForTranslation, - ArgErr, ArgErrUnknownKwds, ArgErrMultipleValues, ArgErrCount, rawshape, - Signature) +from pypy.interpreter.argument import (Arguments, ArgErr, ArgErrUnknownKwds, + ArgErrMultipleValues, ArgErrCount, Signature) from pypy.interpreter.error import OperationError @@ -687,206 +686,3 @@ def f(x): pass e = raises(TypeError, "f(**{u'ü' : 19})") assert "?" in str(e.value) - -def make_arguments_for_translation(space, args_w, keywords_w={}, - w_stararg=None, w_starstararg=None): - return ArgumentsForTranslation(space, args_w, keywords_w.keys(), - keywords_w.values(), w_stararg, - w_starstararg) - -class TestArgumentsForTranslation(object): - - def test_prepend(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ["0"]) - args1 = args.prepend("thingy") - assert args1 is not args - assert args1.arguments_w == ["thingy", "0"] - assert args1.keywords is args.keywords - assert args1.keywords_w is args.keywords_w - - def test_unmatch_signature(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - sig = Signature(['a', 'b', 'c'], 'r', None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], 'r', 'kw') - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - def test_rawshape(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert rawshape(args) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1]) - assert rawshape(args, 2) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert rawshape(args) == (5, (), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert rawshape(args) == (1, ('b', 'c'), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert rawshape(args) == (1, ('c', ), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert rawshape(args) == (1, ('c', 'd'), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert rawshape(args) == (5, ('d', 'e'), False, False) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert rawshape(args) == (0, (), True, True) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert rawshape(args) == (2, ('g', ), True, True) - - def test_copy_and_shape(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ['a'], ['x'], [1], - ['w1'], {'y': 'w2'}) - args1 = args.copy() - args.combine_if_necessary() - assert rawshape(args1) == (1, ('x',), True, True) - - - def test_flatten(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert args.flatten() == ((3, (), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1]) - assert args.flatten() == ((1, (), False, False), [1]) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert args.flatten() == ((5, (), False, False), [1,2,3,4,5]) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert args.flatten() == ((1, ('c', ), False, False), [1, 5]) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7]) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert args.flatten() == ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert args.flatten() == ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - - def test_stararg_flowspace_variable(self): - space = DummySpace() - var = object() - shape = ((2, ('g', ), True, False), [1, 2, 9, var]) - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=var) - assert args.flatten() == shape - - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - - def test_fromshape(self): - space = DummySpace() - shape = ((3, (), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, (), False, False), [1]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, (), False, False), [1,2,3,4,5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('b', 'c'), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', ), False, False), [1, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', 'd'), False, False), [1, 5, 7]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - diff --git a/pypy/interpreter/test/test_code.py b/pypy/interpreter/test/test_code.py --- a/pypy/interpreter/test/test_code.py +++ b/pypy/interpreter/test/test_code.py @@ -1,5 +1,6 @@ from pypy.conftest import gettestobjspace from pypy.interpreter import gateway +from pypy.interpreter.astcompiler import consts import py class AppTestCodeIntrospection: @@ -11,6 +12,7 @@ filename = filename[:-1] cls.w_file = space.wrap(filename) + cls.w_CO_CONTAINSGLOBALS = space.wrap(consts.CO_CONTAINSGLOBALS) def test_attributes(self): def f(): pass @@ -185,7 +187,7 @@ assert f(4).func_code.co_flags & 0x10 assert f.func_code.co_flags & 0x10 == 0 # check for CO_CONTAINSGLOBALS - assert not f.func_code.co_flags & 0x0800 + assert not f.func_code.co_flags & self.CO_CONTAINSGLOBALS exec """if 1: @@ -197,8 +199,8 @@ """ # check for CO_CONTAINSGLOBALS - assert f.func_code.co_flags & 0x0800 - assert not g.func_code.co_flags & 0x0800 + assert f.func_code.co_flags & self.CO_CONTAINSGLOBALS + assert not g.func_code.co_flags & self.CO_CONTAINSGLOBALS exec """if 1: b = 2 @@ -207,4 +209,4 @@ return a + b + x """ # check for CO_CONTAINSGLOBALS - assert f.func_code.co_flags & 0x0800 + assert f.func_code.co_flags & self.CO_CONTAINSGLOBALS diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py --- a/pypy/interpreter/test/test_function.py +++ b/pypy/interpreter/test/test_function.py @@ -299,6 +299,12 @@ assert f.__doc__ == u"hi" assert type(f.__doc__) is unicode + def test_issue1293(self): + def f1(): "doc f1" + def f2(): "doc f2" + f1.func_code = f2.func_code + assert f1.__doc__ == "doc f1" + def test_subclassing(self): # cannot subclass 'function' or 'builtin_function' def f(): diff --git a/pypy/jit/backend/detect_cpu.py b/pypy/jit/backend/detect_cpu.py --- a/pypy/jit/backend/detect_cpu.py +++ b/pypy/jit/backend/detect_cpu.py @@ -77,8 +77,6 @@ return "pypy.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "pypy.jit.backend.cli.runner", "CliCPU" - elif backend_name == 'llvm': - return "pypy.jit.backend.llvm.runner", "LLVMCPU" elif backend_name == 'arm': return "pypy.jit.backend.arm.runner", "CPU_ARM" elif backend_name == 'armhf': diff --git a/pypy/jit/backend/llvm/__init__.py b/pypy/jit/backend/llvm/__init__.py deleted file mode 100644 diff --git a/pypy/jit/backend/llvm/compile.py b/pypy/jit/backend/llvm/compile.py deleted file mode 100644 --- a/pypy/jit/backend/llvm/compile.py +++ /dev/null @@ -1,732 +0,0 @@ -import py -from pypy.rpython.lltypesystem import lltype, rffi -from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp.history import Const, INT -from pypy.jit.backend.llvm import llvm_rffi -from pypy.jit.metainterp import resoperation -from pypy.jit.metainterp.resoperation import rop -from pypy.jit.backend.llsupport import symbolic -from pypy.jit.backend.llvm.runner import SizeDescr, CallDescr -from pypy.jit.backend.llvm.runner import FieldDescr, ArrayDescr - -# ____________________________________________________________ - -class LLVMJITCompiler(object): - FUNC = lltype.FuncType([], lltype.Signed) - lastovf = lltype.nullptr(llvm_rffi.LLVMValueRef.TO) - - def __init__(self, cpu, loop): - self.cpu = cpu - self.loop = loop - - def compile(self): - self.start_generating_function() - self.generate_initial_arguments_load() - self.generate_loop_body() - self.close_phi_nodes() - self.done_generating_function() - - def start_generating_function(self): - func = llvm_rffi.LLVMAddFunction(self.cpu.module, "", self.cpu.ty_func) - self.compiling_func = func - self.builder = llvm_rffi.LLVMCreateBuilder() - self.vars = {} - - def generate_initial_arguments_load(self): - loop = self.loop - func = self.compiling_func - bb_entry = llvm_rffi.LLVMAppendBasicBlock(func, "entry") - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_entry) - self.cpu._ensure_in_args(len(loop.inputargs)) - self.phi_incoming_blocks = [bb_entry] - self.phi_incoming_values = [] - for i in range(len(loop.inputargs)): - ty = self.cpu._get_pointer_type(loop.inputargs[i]) - llvmconstptr = self.cpu._make_const(self.cpu.in_out_args[i], ty) - res = llvm_rffi.LLVMBuildLoad(self.builder, llvmconstptr, "") - self.phi_incoming_values.append([res]) - self.bb_start = llvm_rffi.LLVMAppendBasicBlock(func, "") - llvm_rffi.LLVMBuildBr(self.builder, self.bb_start) - # - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, self.bb_start) - for v in loop.inputargs: - ty = self.cpu._get_var_type(v) - phi = llvm_rffi.LLVMBuildPhi(self.builder, ty, "") - self.vars[v] = phi - - def generate_loop_body(self): - func = self.compiling_func - self.pending_blocks = [(self.loop.operations, self.bb_start, False)] - while self.pending_blocks: - operations, bb, exc = self.pending_blocks.pop() - self._generate_branch(operations, bb, exc) - self.bb_start = lltype.nullptr(llvm_rffi.LLVMBasicBlockRef.TO) - - def close_phi_nodes(self): - incoming_blocks = lltype.malloc( - rffi.CArray(llvm_rffi.LLVMBasicBlockRef), - len(self.phi_incoming_blocks), flavor='raw') - incoming_values = lltype.malloc( - rffi.CArray(llvm_rffi.LLVMValueRef), - len(self.phi_incoming_blocks), flavor='raw') - for j in range(len(self.phi_incoming_blocks)): - incoming_blocks[j] = self.phi_incoming_blocks[j] - loop = self.loop - for i in range(len(loop.inputargs)): - phi = self.vars[loop.inputargs[i]] - incoming = self.phi_incoming_values[i] - for j in range(len(self.phi_incoming_blocks)): - incoming_values[j] = incoming[j] - llvm_rffi.LLVMAddIncoming(phi, incoming_values, incoming_blocks, - len(self.phi_incoming_blocks)) - lltype.free(incoming_values, flavor='raw') - lltype.free(incoming_blocks, flavor='raw') - - def done_generating_function(self): - llvm_rffi.LLVMDisposeBuilder(self.builder) - llvm_rffi.LLVMDumpValue(self.compiling_func) # xxx for debugging - # - func_addr = llvm_rffi.LLVM_EE_getPointerToFunction(self.cpu.ee, - self.compiling_func) - if not we_are_translated(): - print '--- function is at %r ---' % (func_addr,) - # - func_ptr = rffi.cast(lltype.Ptr(self.FUNC), func_addr) - index = self.loop._llvm_compiled_index - if index < 0: - self.loop._llvm_compiled_index = len(self.cpu.compiled_functions) - self.cpu.compiled_functions.append(func_ptr) - else: - self.cpu.compiled_functions[index] = func_ptr - - def _generate_branch(self, operations, basicblock, exc): - llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, basicblock) - # The flag 'exc' is set to True if we are a branch handling a - # GUARD_EXCEPTION or GUARD_NO_EXCEPTION. In this case, we have to - # store away the exception into self.backup_exc_xxx, *unless* the - # branch starts with a further GUARD_EXCEPTION/GUARD_NO_EXCEPTION. - if exc: - opnum = operations[0].getopnum() - if opnum not in (rop.GUARD_EXCEPTION, rop.GUARD_NO_EXCEPTION): - self._store_away_exception() - # Normal handling of the operations follows. - for op in operations: - self._generate_op(op) - - def _generate_op(self, op): - opnum = op.getopnum() - for i, name in all_operations: - if opnum == i: - meth = getattr(self, name) - meth(op) - return - else: - raise MissingOperation(resoperation.opname[opnum]) - - def _store_away_exception(self): - # etype, evalue: ty_char_ptr - etype = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_type, "") - llvm_rffi.LLVMBuildStore(self.builder, - self.cpu.const_null_charptr, - self.cpu.const_exc_type) - llvm_rffi.LLVMBuildStore(self.builder, - etype, - self.cpu.const_backup_exc_type) - evalue = llvm_rffi.LLVMBuildLoad(self.builder, - self.cpu.const_exc_value, "") - llvm_rffi.LLVMBuildStore(self.builder, - self.cpu.const_null_charptr, - self.cpu.const_exc_value) - llvm_rffi.LLVMBuildStore(self.builder, - evalue, - self.cpu.const_backup_exc_value) - - def getintarg(self, v): - try: - value_ref = self.vars[v] - except KeyError: - assert isinstance(v, Const) - return self.cpu._make_const_int(v.getint()) - else: - return self._cast_to_int(value_ref) - - def _cast_to_int(self, value_ref): - ty = llvm_rffi.LLVMTypeOf(value_ref) - if ty == self.cpu.ty_int: - return value_ref - else: - return llvm_rffi.LLVMBuildZExt(self.builder, value_ref, - self.cpu.ty_int, "") From noreply at buildbot.pypy.org Sun Oct 28 23:16:06 2012 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 28 Oct 2012 23:16:06 +0100 (CET) Subject: [pypy-commit] pypy default: make it possible to compare rbigints with == and != for testing Message-ID: <20121028221606.2555A1C039C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r58548:12f7aa38e6e2 Date: 2012-10-28 15:15 -0700 http://bitbucket.org/pypy/pypy/changeset/12f7aa38e6e2/ Log: make it possible to compare rbigints with == and != for testing diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -119,6 +119,17 @@ self.size = size or len(digits) self.sign = sign + # __eq__ and __ne__ method exist for testingl only, they are not RPython! + def __eq__(self, other): + # NOT_RPYTHON + if not isinstance(other, rbigint): + return NotImplemented + return self.eq(other) + + def __ne__(self, other): + # NOT_RPYTHON + return not (self == other) + def digit(self, x): """Return the x'th digit, as an int.""" return self._digits[x] diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -1,14 +1,19 @@ from __future__ import division + +import operator +import sys +from random import random, randint, sample + import py -import operator, sys, array -from random import random, randint, sample -from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF -from pypy.rlib.rbigint import _store_digit, _mask_digit -from pypy.rlib.rfloat import NAN + from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask +from pypy.rlib.rbigint import (rbigint, SHIFT, MASK, KARATSUBA_CUTOFF, + _store_digit, _mask_digit) +from pypy.rlib.rfloat import NAN from pypy.rpython.test.test_llinterp import interpret + class TestRLong(object): def test_simple(self): for op1 in [-2, -1, 0, 1, 2, 50]: @@ -112,6 +117,17 @@ rl = rbigint.fromint(sys.maxint).add(rbigint.fromint(42)) assert rl.touint() == result + def test_eq_ne_operators(self): + a1 = rbigint.fromint(12) + a2 = rbigint.fromint(12) + a3 = rbigint.fromint(123) + + assert a1 == a2 + assert a1 != a3 + assert not (a1 != a2) + assert not (a1 == a3) + + def gen_signs(l): for s in l: if s == 0: From noreply at buildbot.pypy.org Mon Oct 29 05:05:09 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 29 Oct 2012 05:05:09 +0100 (CET) Subject: [pypy-commit] pypy numpypy.float16: work in progress Message-ID: <20121029040509.8D3F41C0ECC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy.float16 Changeset: r58549:919585f4f4a8 Date: 2012-10-28 19:45 +0200 http://bitbucket.org/pypy/pypy/changeset/919585f4f4a8/ Log: work in progress 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 @@ -921,24 +921,31 @@ class Float16(BaseType, Float): _attrs_ = () + T = rffi.USHORT - T = rffi.FLOAT BoxType = interp_boxes.W_Float16Box format_code = "e" + def _coerce(self, space, w_item): + return self.box(space.float_w(space.call_function(space.w_float, w_item))) + + def str_format(self, box): + return float2string(self.for_computation(self.unbox(box)), "g", + rfloat.DTSF_STR_PRECISION) + + def for_computation(self, v): + return float(v) + + def default_fromstring(self, space): + return self.box(-1.0) + + @specialize.argtype(1) + def box(self, value): + xxx + class NonNativeFloat16(BaseType, NonNativeFloat): _attrs_ = () - T = rffi.FLOAT - BoxType = interp_boxes.W_Float16Box - format_code = "e" - -class Float16(BaseType, Float): - _attrs_ = () - - def get_element_size(self): - return 16 - BoxType = interp_boxes.W_Float16Box format_code = "e" From noreply at buildbot.pypy.org Mon Oct 29 05:05:11 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 29 Oct 2012 05:05:11 +0100 (CET) Subject: [pypy-commit] pypy numpypy.float16: merge default into branch Message-ID: <20121029040511.4E4011C0ECC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy.float16 Changeset: r58550:0a4fa60c1207 Date: 2012-10-28 23:26 +0200 http://bitbucket.org/pypy/pypy/changeset/0a4fa60c1207/ Log: merge default into branch diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -118,7 +118,7 @@ # 1. find the start of the statement from codeop import compile_command end = None - for start in range(lineno, -1, max(-1, lineno - 10)): + for start in range(lineno, -1, -1): if assertion: line = self.lines[start] # the following lines are not fully tested, change with care @@ -135,9 +135,9 @@ compile_command(trysource) except (SyntaxError, OverflowError, ValueError): continue - + # 2. find the end of the statement - for end in range(lineno+1, min(len(self)+1, lineno + 10)): + for end in range(lineno+1, len(self)+1): trysource = self[start:end] if trysource.isparseable(): return start, end diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -1,17 +1,17 @@ from pypy.jit.metainterp import jitprof, resume, compile from pypy.jit.metainterp.executor import execute_nonspec -from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF, INT +from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF from pypy.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded, \ ImmutableIntUnbounded, \ IntLowerBound, MININT, MAXINT -from pypy.jit.metainterp.optimizeopt.util import (make_dispatcher_method, - args_dict) +from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method from pypy.jit.metainterp.resoperation import rop, ResOperation, AbstractResOp from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.tool.pairtype import extendabletype -from pypy.rlib.debug import debug_start, debug_stop, debug_print +from pypy.rlib.debug import debug_print from pypy.rlib.objectmodel import specialize + LEVEL_UNKNOWN = '\x00' LEVEL_NONNULL = '\x01' LEVEL_KNOWNCLASS = '\x02' # might also mean KNOWNARRAYDESCR, for arrays @@ -20,6 +20,8 @@ MODE_ARRAY = '\x00' MODE_STR = '\x01' MODE_UNICODE = '\x02' + + class LenBound(object): def __init__(self, mode, descr, bound): self.mode = mode diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -1,8 +1,11 @@ from pypy.jit.codewriter.effectinfo import EffectInfo -from pypy.jit.metainterp.history import ConstInt, make_hashable_int +from pypy.jit.metainterp import compile +from pypy.jit.metainterp.history import (Const, ConstInt, BoxInt, BoxFloat, + BoxPtr, make_hashable_int) from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntBound -from pypy.jit.metainterp.optimizeopt.optimizer import * +from pypy.jit.metainterp.optimizeopt.optimizer import (Optimization, REMOVED, + CONST_0, CONST_1) from pypy.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ResOperation) @@ -426,14 +429,31 @@ source_start_box = self.get_constant_box(op.getarg(3)) dest_start_box = self.get_constant_box(op.getarg(4)) length = self.get_constant_box(op.getarg(5)) - if (source_value.is_virtual() and source_start_box and dest_start_box - and length and (dest_value.is_virtual() or length.getint() <= 8)): + if (source_start_box and dest_start_box + and length and (dest_value.is_virtual() or length.getint() <= 8) and + (source_value.is_virtual() or length.getint() <= 8)): from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue - assert isinstance(source_value, VArrayValue) source_start = source_start_box.getint() dest_start = dest_start_box.getint() for index in range(length.getint()): - val = source_value.getitem(index + source_start) + # XXX fish fish fish + arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] + if source_value.is_virtual(): + assert isinstance(source_value, VArrayValue) + val = source_value.getitem(index + source_start) + else: + if arraydescr.is_array_of_pointers(): + resbox = BoxPtr() + elif arraydescr.is_array_of_floats(): + resbox = BoxFloat() + else: + resbox = BoxInt() + newop = ResOperation(rop.GETARRAYITEM_GC, + [op.getarg(1), + ConstInt(index + source_start)], resbox, + descr=arraydescr) + self.optimizer.propagate_forward(newop) + val = self.getvalue(resbox) if dest_value.is_virtual(): dest_value.setitem(index + dest_start, val) else: @@ -441,7 +461,7 @@ [op.getarg(2), ConstInt(index + dest_start), val.get_key_box()], None, - descr=source_value.arraydescr) + descr=arraydescr) self.emit_operation(newop) return True if length and length.getint() == 0: diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -3239,6 +3239,42 @@ ''' self.optimize_loop(ops, expected) + def test_arraycopy_not_virtual_2(self): + ops = ''' + [p0] + p1 = new_array(3, descr=arraydescr) + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) # removed by the backend + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) # removed by the backend + jump(i0) + ''' + self.optimize_loop(ops, expected) + + def test_arraycopy_not_virtual_3(self): + ops = ''' + [p0, p1] + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0, p1] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) + setarrayitem_gc(p1, 0, i0, descr=arraydescr) + setarrayitem_gc(p1, 1, i1, descr=arraydescr) + setarrayitem_gc(p1, 2, i2, descr=arraydescr) + jump(i0) + ''' + self.optimize_loop(ops, expected) + def test_arraycopy_no_elem(self): """ this was actually observed in the wild """ diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -4,6 +4,7 @@ from pypy.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken from pypy.jit.metainterp.jitexc import JitException from pypy.jit.metainterp.optimize import InvalidLoop +from pypy.rlib.debug import debug_print, debug_start, debug_stop from pypy.jit.metainterp.optimizeopt.optimizer import * from pypy.jit.metainterp.optimizeopt.generalize import KillHugeIntBounds from pypy.jit.metainterp.inliner import Inliner diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py --- a/pypy/jit/metainterp/test/test_list.py +++ b/pypy/jit/metainterp/test/test_list.py @@ -128,6 +128,17 @@ res = self.interp_operations(f, [], listops=True) assert res == 10 + def test_arraycopy_bug(self): + def f(): + l = [1, 2, 3, 4] + l2 = [1, 2, 3, 4] + l[2] = 13 + l2[0:len(l2)] = l[:] + return l2[0] + l2[1] + l2[2] + l2[3] + + res = self.interp_operations(f, [], listops=True) + assert res == f() + def test_arraycopy_full(self): jitdriver = JitDriver(greens = [], reds = ['n']) def f(n): 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 @@ -10,6 +10,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rlib import jit from pypy.rlib.rawstorage import free_raw_storage +from pypy.rlib.debug import make_sure_not_resized class ConcreteArrayIterator(base.BaseArrayIterator): def __init__(self, array): @@ -379,6 +380,9 @@ class ConcreteArray(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides): + make_sure_not_resized(shape) + make_sure_not_resized(strides) + make_sure_not_resized(backstrides) self.shape = shape self.size = support.product(shape) * dtype.get_size() self.storage = dtype.itemtype.malloc(self.size) @@ -387,8 +391,8 @@ self.strides = strides self.backstrides = backstrides - def create_iter(self, shape): - if shape == self.get_shape(): + def create_iter(self, shape=None): + if shape is None or shape == self.get_shape(): return ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.strides, self.backstrides, self.get_shape(), shape) @@ -424,8 +428,8 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape): - if shape != self.get_shape(): + def create_iter(self, shape=None): + if shape is not None and shape != self.get_shape(): r = calculate_broadcast_strides(self.strides, self.backstrides, self.get_shape(), shape) return MultiDimViewIterator(self.parent, 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 @@ -34,7 +34,7 @@ def get_shape(self): return [] - def create_iter(self, shape): + def create_iter(self, shape=None): return ScalarIterator(self.value) def get_scalar_value(self): diff --git a/pypy/module/micronumpy/dot.py b/pypy/module/micronumpy/dot.py --- a/pypy/module/micronumpy/dot.py +++ b/pypy/module/micronumpy/dot.py @@ -11,12 +11,12 @@ right_critical_dim = len(right_shape) - 2 right_critical_dim_size = right_shape[right_critical_dim] assert right_critical_dim >= 0 - out_shape += left_shape[:-1] + \ - right_shape[0:right_critical_dim] + \ - right_shape[right_critical_dim + 1:] + out_shape = out_shape + left_shape[:-1] + \ + right_shape[0:right_critical_dim] + \ + right_shape[right_critical_dim + 1:] elif len(right_shape) > 0: #dot does not reduce for scalars - out_shape += left_shape[:-1] + out_shape = out_shape + left_shape[:-1] if my_critical_dim_size != right_critical_dim_size: raise OperationError(space.w_ValueError, space.wrap( "objects are not aligned")) 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 @@ -25,7 +25,7 @@ shape = [] for w_item in space.fixedview(w_size): shape.append(space.int_w(w_item)) - return shape + return shape[:] class __extend__(W_NDimArray): @jit.unroll_safe @@ -190,7 +190,7 @@ return space.call_function(cache.w_array_str, self) def dump_data(self): - i = self.create_iter(self.get_shape()) + i = self.create_iter() first = True dtype = self.get_dtype() s = StringBuilder() @@ -206,8 +206,6 @@ return s.build() def create_iter(self, shape=None): - if shape is None: - shape = self.get_shape() return self.implementation.create_iter(shape) def create_axis_iter(self, shape, dim): @@ -396,7 +394,7 @@ 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()")) - iter = self.create_iter(self.get_shape()) + iter = self.create_iter() return space.wrap(space.is_true(iter.getitem())) def _binop_impl(ufunc_name): @@ -681,7 +679,7 @@ if ndmin > len(shape): shape = [1] * (ndmin - len(shape)) + shape arr = W_NDimArray.from_shape(shape, dtype, order=order) - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() for w_elem in elems_w: arr_iter.setitem(dtype.coerce(space, w_elem)) arr_iter.next() 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 @@ -89,7 +89,7 @@ reds = ['obj', 'obj_iter', 'cur_value']) def compute_reduce(obj, calc_dtype, func, done_func, identity): - obj_iter = obj.create_iter(obj.get_shape()) + obj_iter = obj.create_iter() if identity is None: cur_value = obj_iter.getitem().convert_to(calc_dtype) obj_iter.next() @@ -109,7 +109,7 @@ return cur_value def fill(arr, box): - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() while not arr_iter.done(): arr_iter.setitem(box) arr_iter.next() @@ -159,7 +159,7 @@ def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): out_iter = out.create_axis_iter(arr.get_shape(), axis) - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() if identity is not None: identity = identity.convert_to(dtype) shapelen = len(shape) @@ -192,7 +192,7 @@ result = 0 idx = 1 dtype = arr.get_dtype() - iter = arr.create_iter(arr.get_shape()) + iter = arr.create_iter() cur_best = iter.getitem() iter.next() shapelen = len(arr.get_shape()) diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -15,16 +15,22 @@ jit.isconstant(len(chunks)) ) def calculate_slice_strides(shape, start, strides, backstrides, chunks): - rstrides = [] - rbackstrides = [] + size = 0 + for chunk in chunks: + if chunk.step != 0: + size += 1 + rstrides = [0] * size + rbackstrides = [0] * size rstart = start - rshape = [] + rshape = [0] * size i = -1 + j = 0 for i, chunk in enumerate_chunks(chunks): if chunk.step != 0: - rstrides.append(strides[i] * chunk.step) - rbackstrides.append(strides[i] * (chunk.lgt - 1) * chunk.step) - rshape.append(chunk.lgt) + rstrides[j] = strides[i] * chunk.step + rbackstrides[j] = strides[i] * (chunk.lgt - 1) * chunk.step + rshape[j] = chunk.lgt + j += 1 rstart += strides[i] * chunk.start # add a reminder s = i + 1 @@ -64,13 +70,13 @@ while True: new_batch = [] if not batch: - return shape, [] + return shape[:], [] if is_single_elem(space, batch[0], is_rec_type): for w_elem in batch: if not is_single_elem(space, w_elem, is_rec_type): raise OperationError(space.w_ValueError, space.wrap( "setting an array element with a sequence")) - return shape, batch + return shape[:], batch size = space.len_w(batch[0]) for w_elem in batch: if (is_single_elem(space, w_elem, is_rec_type) or @@ -255,19 +261,19 @@ cur_step = steps[oldI] n_old_elems_to_use *= old_shape[oldI] assert len(new_strides) == len(new_shape) - return new_strides + return new_strides[:] def calculate_dot_strides(strides, backstrides, res_shape, skip_dims): - rstrides = [] - rbackstrides = [] - j=0 + rstrides = [0] * len(res_shape) + rbackstrides = [0] * len(res_shape) + j = 0 for i in range(len(res_shape)): if i in skip_dims: - rstrides.append(0) - rbackstrides.append(0) + rstrides[i] = 0 + rbackstrides[i] = 0 else: - rstrides.append(strides[j]) - rbackstrides.append(backstrides[j]) + rstrides[i] = strides[j] + rbackstrides[i] = backstrides[j] j += 1 return rstrides, rbackstrides diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py --- a/pypy/rlib/objectmodel.py +++ b/pypy/rlib/objectmodel.py @@ -188,7 +188,7 @@ src = py.code.Source(""" def %(name)s(%(arglist)s): if not we_are_translated(): - typecheck(%(arglist)s) + typecheck(%(arglist)s) # pypy.rlib.objectmodel return %(name)s_original(%(arglist)s) """ % dict(name=f.func_name, arglist=arglist)) # diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py --- a/pypy/rlib/rgc.py +++ b/pypy/rlib/rgc.py @@ -145,8 +145,11 @@ from pypy.rlib.objectmodel import keepalive_until_here # XXX: Hack to ensure that we get a proper effectinfo.write_descrs_arrays - if NonConstant(False): - dest[dest_start] = source[source_start] + # and also, maybe, speed up very small cases + if length <= 1: + if length == 1: + dest[dest_start] = source[source_start] + return # supports non-overlapping copies only if not we_are_translated(): diff --git a/pypy/rlib/test/test_rgc.py b/pypy/rlib/test/test_rgc.py --- a/pypy/rlib/test/test_rgc.py +++ b/pypy/rlib/test/test_rgc.py @@ -134,6 +134,23 @@ assert check.called +def test_ll_arraycopy_small(): + TYPE = lltype.GcArray(lltype.Signed) + for length in range(5): + a1 = lltype.malloc(TYPE, 10) + a2 = lltype.malloc(TYPE, 6) + org1 = range(20, 30) + org2 = range(50, 56) + for i in range(len(a1)): a1[i] = org1[i] + for i in range(len(a2)): a2[i] = org2[i] + rgc.ll_arraycopy(a1, a2, 4, 2, length) + for i in range(10): + assert a1[i] == org1[i] + for i in range(6): + if 2 <= i < 2 + length: + assert a2[i] == a1[i+2] + else: + assert a2[i] == org2[i] def test_ll_shrink_array_1(): diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py --- a/pypy/rpython/lltypesystem/lltype.py +++ b/pypy/rpython/lltypesystem/lltype.py @@ -1651,10 +1651,7 @@ if n < 0: raise ValueError, "negative array length" _parentable.__init__(self, TYPE) - try: - myrange = range(n) - except OverflowError: - raise MemoryError("definitely too many items") + myrange = self._check_range(n) self.items = [TYPE.OF._allocate(initialization=initialization, parent=self, parentindex=j) for j in myrange] @@ -1664,6 +1661,14 @@ def __repr__(self): return '<%s>' % (self,) + def _check_range(self, n): + # checks that it's ok to make an array of size 'n', and returns + # range(n). Explicitly overridden by some tests. + try: + return range(n) + except OverflowError: + raise MemoryError("definitely too many items") + def _str_item(self, item): if isinstance(item, _uninitialized): return '#' diff --git a/pypy/rpython/lltypesystem/rdict.py b/pypy/rpython/lltypesystem/rdict.py --- a/pypy/rpython/lltypesystem/rdict.py +++ b/pypy/rpython/lltypesystem/rdict.py @@ -4,6 +4,7 @@ rtype_newdict) from pypy.rpython.lltypesystem import lltype from pypy.rlib import objectmodel, jit +from pypy.rlib.debug import ll_assert from pypy.rlib.rarithmetic import r_uint, intmask, LONG_BIT from pypy.rpython import rmodel from pypy.rpython.error import TyperError @@ -462,22 +463,30 @@ def _ll_dict_setitem_lookup_done(d, key, value, hash, i): valid = (i & HIGHEST_BIT) == 0 i = i & MASK - everused = d.entries.everused(i) - # set up the new entry ENTRY = lltype.typeOf(d.entries).TO.OF entry = d.entries[i] - entry.value = value - if valid: - return + if not d.entries.everused(i): + # a new entry that was never used before + ll_assert(not valid, "valid but not everused") + rc = d.resize_counter - 3 + if rc <= 0: # if needed, resize the dict -- before the insertion + ll_dict_resize(d) + i = ll_dict_lookup_clean(d, hash) # then redo the lookup for 'key' + entry = d.entries[i] + rc = d.resize_counter - 3 + ll_assert(rc > 0, "ll_dict_resize failed?") + d.resize_counter = rc + if hasattr(ENTRY, 'f_everused'): entry.f_everused = True + entry.value = value + else: + # override an existing or deleted entry + entry.value = value + if valid: + return entry.key = key if hasattr(ENTRY, 'f_hash'): entry.f_hash = hash if hasattr(ENTRY, 'f_valid'): entry.f_valid = True d.num_items += 1 - if not everused: - if hasattr(ENTRY, 'f_everused'): entry.f_everused = True - d.resize_counter -= 3 - if d.resize_counter <= 0: - ll_dict_resize(d) def ll_dict_insertclean(d, key, value, hash): # Internal routine used by ll_dict_resize() to insert an item which is @@ -534,8 +543,9 @@ # make a 'new_size' estimate and shrink it if there are many # deleted entry markers. See CPython for why it is a good idea to # quadruple the dictionary size as long as it's not too big. - if d.num_items > 50000: new_estimate = d.num_items * 2 - else: new_estimate = d.num_items * 4 + num_items = d.num_items + 1 + if num_items > 50000: new_estimate = num_items * 2 + else: new_estimate = num_items * 4 new_size = DICT_INITSIZE while new_size <= new_estimate: new_size *= 2 diff --git a/pypy/rpython/test/test_rdict.py b/pypy/rpython/test/test_rdict.py --- a/pypy/rpython/test/test_rdict.py +++ b/pypy/rpython/test/test_rdict.py @@ -970,6 +970,39 @@ DICT = lltype.typeOf(llres.item1) assert sorted(DICT.TO.entries.TO.OF._flds) == ['f_hash', 'key', 'value'] + def test_memoryerror_should_not_insert(self): + # This shows a misbehaviour that also exists in CPython 2.7, but not + # any more in CPython 3.3. The behaviour is that even if a dict + # insertion raises MemoryError, the new item is still inserted. + # If we catch the MemoryError, we can keep inserting new items until + # the dict table is completely full. Then the next insertion loops + # forever. This test only checks that after a MemoryError the + # new item was not inserted. + def _check_small_range(self, n): + if n >= 128: + raise MemoryError + return range(n) + original_check_range = lltype._array._check_range + try: + lltype._array._check_range = _check_small_range + # + def do_insert(d, i): + d[i] = i + def func(): + d = {} + i = 0 + while True: + try: + do_insert(d, i) + except MemoryError: + return (i in d) + i += 1 + res = self.interpret(func, []) + assert res == 0 + # + finally: + lltype._array._check_range = original_check_range + # ____________________________________________________________ diff --git a/pypy/translator/goal/test2/test_app_main.py b/pypy/translator/goal/test2/test_app_main.py --- a/pypy/translator/goal/test2/test_app_main.py +++ b/pypy/translator/goal/test2/test_app_main.py @@ -689,6 +689,10 @@ child_out_err.close() def test_proper_sys_path(self, tmpdir): + data = self.run('-c "import _ctypes"', python_flags='-S') + if data.startswith('Traceback'): + py.test.skip("'python -S' cannot import extension modules: " + "see probably http://bugs.python.org/issue586680") @contextmanager def chdir_and_unset_pythonpath(new_cwd): From noreply at buildbot.pypy.org Mon Oct 29 05:05:12 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 29 Oct 2012 05:05:12 +0100 (CET) Subject: [pypy-commit] pypy numpypy.float16: fix promotion of UInt64 -> Float64, obscure use of indexes in builtin_types Message-ID: <20121029040512.90AA51C0ECC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy.float16 Changeset: r58551:935d79f359c2 Date: 2012-10-29 05:40 +0200 http://bitbucket.org/pypy/pypy/changeset/935d79f359c2/ Log: fix promotion of UInt64 -> Float64, obscure use of indexes in builtin_types 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 @@ -407,7 +407,7 @@ dtypenum = dt2.num + 1 # UInt64 + signed = Float64 if dt2.num == 10: - dtypenum += 1 + dtypenum += 2 newdtype = interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] if (newdtype.itemtype.get_element_size() > dt2.itemtype.get_element_size() or From noreply at buildbot.pypy.org Mon Oct 29 05:05:13 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 29 Oct 2012 05:05:13 +0100 (CET) Subject: [pypy-commit] pypy numpypy.float16: flesh out Float16 type Message-ID: <20121029040513.C0F091C0ECC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy.float16 Changeset: r58552:7bfd4719be6c Date: 2012-10-29 05:56 +0200 http://bitbucket.org/pypy/pypy/changeset/7bfd4719be6c/ Log: flesh out Float16 type 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 @@ -922,13 +922,11 @@ class Float16(BaseType, Float): _attrs_ = () T = rffi.USHORT + _COMPUTATION_T = rffi.FLOAT BoxType = interp_boxes.W_Float16Box format_code = "e" - def _coerce(self, space, w_item): - return self.box(space.float_w(space.call_function(space.w_float, w_item))) - def str_format(self, box): return float2string(self.for_computation(self.unbox(box)), "g", rfloat.DTSF_STR_PRECISION) @@ -941,7 +939,24 @@ @specialize.argtype(1) def box(self, value): - xxx + return self.BoxType( + rffi.cast(self._COMPUTATION_T, value)) + + def unbox(self, box): + assert isinstance(box, self.BoxType) + return box.tofloat() + + def store(self, arr, i, offset, box): + raw_storage_setitem(arr.storage, i+offset, box.tobytes()) + + def _read(self, storage, i, offset): + byte_rep = raw_storage_getitem(self.T, storage, i + offset) + return self.BoxType.val_to_float(byte_rep) + + def read(self, arr, i, offset, dtype=None): + val = self._read(arr.storage, i, offset) + return self.BoxType(val) + class NonNativeFloat16(BaseType, NonNativeFloat): _attrs_ = () From noreply at buildbot.pypy.org Mon Oct 29 05:05:14 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 29 Oct 2012 05:05:14 +0100 (CET) Subject: [pypy-commit] pypy default: remove old cruft Message-ID: <20121029040514.EA66B1C0ECC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r58553:a11f3b7e7b8e Date: 2012-10-29 05:58 +0200 http://bitbucket.org/pypy/pypy/changeset/a11f3b7e7b8e/ Log: remove old cruft 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 @@ -275,14 +275,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - # Running entire test suite needs this function to succeed, - # running single test_stringarray succeeds without it. - # With convert_to() test_ztranslation fails since - # W_CharacterBox is not a W_GenericBox. - # Why is it needed for multiple tests? - #def convert_to(self, dtype): - # xxx - class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): from pypy.module.micronumpy.interp_dtype import new_unicode_dtype From noreply at buildbot.pypy.org Mon Oct 29 05:05:16 2012 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 29 Oct 2012 05:05:16 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121029040516.25CE91C0ECC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r58554:0856e88f3e3e Date: 2012-10-29 06:03 +0200 http://bitbucket.org/pypy/pypy/changeset/0856e88f3e3e/ Log: merge heads diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -119,6 +119,17 @@ self.size = size or len(digits) self.sign = sign + # __eq__ and __ne__ method exist for testingl only, they are not RPython! + def __eq__(self, other): + # NOT_RPYTHON + if not isinstance(other, rbigint): + return NotImplemented + return self.eq(other) + + def __ne__(self, other): + # NOT_RPYTHON + return not (self == other) + def digit(self, x): """Return the x'th digit, as an int.""" return self._digits[x] diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -1,14 +1,19 @@ from __future__ import division + +import operator +import sys +from random import random, randint, sample + import py -import operator, sys, array -from random import random, randint, sample -from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF -from pypy.rlib.rbigint import _store_digit, _mask_digit -from pypy.rlib.rfloat import NAN + from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask +from pypy.rlib.rbigint import (rbigint, SHIFT, MASK, KARATSUBA_CUTOFF, + _store_digit, _mask_digit) +from pypy.rlib.rfloat import NAN from pypy.rpython.test.test_llinterp import interpret + class TestRLong(object): def test_simple(self): for op1 in [-2, -1, 0, 1, 2, 50]: @@ -112,6 +117,17 @@ rl = rbigint.fromint(sys.maxint).add(rbigint.fromint(42)) assert rl.touint() == result + def test_eq_ne_operators(self): + a1 = rbigint.fromint(12) + a2 = rbigint.fromint(12) + a3 = rbigint.fromint(123) + + assert a1 == a2 + assert a1 != a3 + assert not (a1 != a2) + assert not (a1 == a3) + + def gen_signs(l): for s in l: if s == 0: From noreply at buildbot.pypy.org Mon Oct 29 09:20:36 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 09:20:36 +0100 (CET) Subject: [pypy-commit] cffi default: Give up trying to reuse one of CPython's buffer or memoryview classes. Message-ID: <20121029082036.51DE01C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1015:f93cc8e8f97b Date: 2012-10-29 08:58 +0100 http://bitbucket.org/cffi/cffi/changeset/f93cc8e8f97b/ Log: Give up trying to reuse one of CPython's buffer or memoryview classes. Write our own simple class. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -205,6 +205,8 @@ # define restore_errno_only restore_errno #endif +#include "minibuffer.h" + #ifdef HAVE_WCHAR_H # include "wchar_helper.h" #endif @@ -4275,17 +4277,7 @@ return NULL; } /*WRITE(cd->c_data, size)*/ -#if PY_MAJOR_VERSION < 3 && !defined(PyMemoryView_Check) /* Python 2.6 */ - return PyBuffer_FromReadWriteMemory(cd->c_data, size); -#else - { - Py_buffer view; - if (PyBuffer_FillInfo(&view, NULL, cd->c_data, size, - /*readonly=*/0, PyBUF_CONTIG | PyBUF_FORMAT) < 0) - return NULL; - return PyMemoryView_FromBuffer(&view); - } -#endif + return minibuffer_new(cd->c_data, size); } static PyObject *b_get_errno(PyObject *self, PyObject *noarg) @@ -4760,6 +4752,8 @@ INITERROR; if (PyType_Ready(&CDataIter_Type) < 0) INITERROR; + if (PyType_Ready(&MiniBuffer_Type) < 0) + INITERROR; v = PyCapsule_New((void *)cffi_exports, "cffi", NULL); if (v == NULL || PyModule_AddObject(m, "_C_API", v) < 0) diff --git a/c/minibuffer.h b/c/minibuffer.h new file mode 100644 --- /dev/null +++ b/c/minibuffer.h @@ -0,0 +1,151 @@ + +/* Implementation of a C object with the 'buffer' or 'memoryview' + * interface at C-level (as approriate for the version of Python we're + * compiling for), but only a minimal but *consistent* part of the + * 'buffer' interface at application level. + */ + +typedef struct { + PyObject_HEAD + char *mb_data; + Py_ssize_t mb_size; +} MiniBufferObj; + +static Py_ssize_t mb_length(MiniBufferObj *self) +{ + return self->mb_size; +} + +static PyObject *mb_item(MiniBufferObj *self, Py_ssize_t idx) +{ + if (idx < 0 || idx >= self->mb_size ) { + PyErr_SetString(PyExc_IndexError, "buffer index out of range"); + return NULL; + } + return PyBytes_FromStringAndSize(self->mb_data + idx, 1); +} + +static PyObject *mb_slice(MiniBufferObj *self, + Py_ssize_t left, Py_ssize_t right) +{ + Py_ssize_t size = self->mb_size; + if (left < 0) left = 0; + if (right > size) right = size; + if (left > right) left = right; + return PyString_FromStringAndSize(self->mb_data + left, right - left); +} + +static int mb_ass_item(MiniBufferObj *self, Py_ssize_t idx, PyObject *other) +{ + if (idx < 0 || idx >= self->mb_size) { + PyErr_SetString(PyExc_IndexError, + "buffer assignment index out of range"); + return -1; + } + if (PyBytes_Check(other) && PyBytes_GET_SIZE(other) == 1) { + self->mb_data[idx] = PyBytes_AS_STRING(other)[0]; + return 0; + } + else { + PyErr_Format(PyExc_TypeError, + "must assign a "STR_OR_BYTES + " of length 1, not %.200s", Py_TYPE(other)->tp_name); + return -1; + } +} + +static int mb_ass_slice(MiniBufferObj *self, + Py_ssize_t left, Py_ssize_t right, PyObject *other) +{ + const void *buffer; + Py_ssize_t buffer_len, count; + Py_ssize_t size = self->mb_size; + + if (PyObject_AsReadBuffer(other, &buffer, &buffer_len) < 0) + return -1; + + if (left < 0) left = 0; + if (right > size) right = size; + if (left > right) left = right; + + count = right - left; + if (count != buffer_len) { + PyErr_SetString(PyExc_TypeError, + "right operand length must match slice length"); + return -1; + } + memcpy(self->mb_data + left, buffer, count); + return 0; +} + +static Py_ssize_t mb_getdata(MiniBufferObj *self, Py_ssize_t idx, void **pp) +{ + *pp = self->mb_data; + return self->mb_size; +} + +static Py_ssize_t mb_getsegcount(MiniBufferObj *self, Py_ssize_t *lenp) +{ + if (lenp) + *lenp = self->mb_size; + return 1; +} + +static int mb_getbuf(MiniBufferObj *self, Py_buffer *view, int flags) +{ + return PyBuffer_FillInfo(view, NULL, self->mb_data, self->mb_size, + /*readonly=*/0, PyBUF_CONTIG | PyBUF_FORMAT); +} + +static PySequenceMethods mb_as_sequence = { + (lenfunc)mb_length, /*sq_length*/ + (binaryfunc)0, /*sq_concat*/ + (ssizeargfunc)0, /*sq_repeat*/ + (ssizeargfunc)mb_item, /*sq_item*/ + (ssizessizeargfunc)mb_slice, /*sq_slice*/ + (ssizeobjargproc)mb_ass_item, /*sq_ass_item*/ + (ssizessizeobjargproc)mb_ass_slice, /*sq_ass_slice*/ +}; + +static PyBufferProcs mb_as_buffer = { + (readbufferproc)mb_getdata, + (writebufferproc)mb_getdata, + (segcountproc)mb_getsegcount, + (charbufferproc)mb_getdata, + (getbufferproc)mb_getbuf, + (releasebufferproc)0, +}; + +static PyTypeObject MiniBuffer_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_cffi_backend.buffer", + sizeof(MiniBufferObj), + 0, + (destructor)PyObject_Del, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &mb_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + &mb_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | + Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */ +}; + +static PyObject *minibuffer_new(char *data, Py_ssize_t size) +{ + MiniBufferObj *ob = PyObject_New(MiniBufferObj, &MiniBuffer_Type); + if (ob != NULL) { + ob->mb_data = data; + ob->mb_size = size; + } + return (PyObject *)ob; +} diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -9,8 +9,6 @@ type_or_class = "type" mandatory_b_prefix = '' mandatory_u_prefix = 'u' - readbuf = lambda buf: buf[:] - bufchar = lambda x: x bytechr = chr class U(object): def __add__(self, other): @@ -24,11 +22,6 @@ unichr = chr mandatory_b_prefix = 'b' mandatory_u_prefix = '' - readbuf = lambda buf: buf.tobytes() - if sys.version_info < (3, 3): - bufchar = lambda x: bytes([ord(x)]) - else: - bufchar = ord bytechr = lambda n: bytes([n]) u = "" @@ -1815,36 +1808,76 @@ assert (p < s) ^ (p > s) def test_buffer(): + import __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() assert sizeof(BShort) == 2 - assert len(readbuf(buffer(s))) == 2 + assert len(buffer(s)) == 2 # BChar = new_primitive_type("char") BCharArray = new_array_type(new_pointer_type(BChar), None) c = newp(BCharArray, b"hi there") + # buf = buffer(c) - assert readbuf(buf) == b"hi there\x00" + assert str(buf).startswith('<_cffi_backend.buffer object at 0x') + # --mb_length-- assert len(buf) == len(b"hi there\x00") - assert buf[0] == bufchar('h') - assert buf[2] == bufchar(' ') - assert list(buf) == list(map(bufchar, "hi there\x00")) - buf[2] = bufchar('-') - assert c[2] == b'-' - assert readbuf(buf) == b"hi-there\x00" - c[2] = b'!' - assert buf[2] == bufchar('!') - assert readbuf(buf) == b"hi!there\x00" - c[2] = b'-' - buf[:2] = b'HI' - assert string(c) == b'HI-there' - if sys.version_info < (2, 7) or sys.version_info >= (3, 3): - assert buf[:4:2] == b'H-' - if '__pypy__' not in sys.builtin_module_names: - # XXX pypy doesn't support the following assignment so far - buf[:4:2] = b'XY' - assert string(c) == b'XIYthere' + # --mb_item-- + for i in range(-12, 12): + try: + expected = b"hi there\x00"[i] + except IndexError: + py.test.raises(IndexError, "buf[i]") + else: + assert buf[i] == expected + # --mb_slice-- + assert buf[:] == b"hi there\x00" + for i in range(-12, 12): + assert buf[i:] == b"hi there\x00"[i:] + assert buf[:i] == b"hi there\x00"[:i] + for j in range(-12, 12): + assert buf[i:j] == b"hi there\x00"[i:j] + # --misc-- + assert list(buf) == list(b"hi there\x00") + # --mb_as_buffer-- + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 + py.test.raises(TypeError, memoryview, c) + mv1 = memoryview(buf) + assert len(mv1) == len(buf) and mv1[3] == "t" + # --mb_ass_item-- + expected = list(b"hi there\x00") + for i in range(-12, 12): + try: + expected[i] = chr(i & 0xff) + except IndexError: + py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + else: + buf[i] = chr(i & 0xff) + assert list(buf) == expected + # --mb_ass_slice-- + buf[:] = b"hi there\x00" + assert list(buf) == list(c) == list(b"hi there\x00") + py.test.raises(TypeError, 'buf[:] = b"shorter"') + py.test.raises(TypeError, 'buf[:] = b"this is much too long!"') + buf[4:2] = b"" # no effect, but should work + assert buf[:] == b"hi there\x00" + expected = list(b"hi there\x00") + x = 0 + for i in range(-12, 12): + for j in range(-12, 12): + start = i if i >= 0 else i + len(buf) + stop = j if j >= 0 else j + len(buf) + start = max(0, min(len(buf), start)) + stop = max(0, min(len(buf), stop)) + sample = chr(x & 0xff) * (stop - start) + x += 1 + buf[i:j] = sample + expected[i:j] = sample + assert list(buf) == expected def test_getcname(): BUChar = new_primitive_type("unsigned char") From noreply at buildbot.pypy.org Mon Oct 29 09:20:37 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 09:20:37 +0100 (CET) Subject: [pypy-commit] cffi default: Fix the documentation. Message-ID: <20121029082037.6E8181C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1016:81e1b38d5e2f Date: 2012-10-29 09:14 +0100 http://bitbucket.org/cffi/cffi/changeset/81e1b38d5e2f/ Log: Fix the documentation. diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -208,8 +208,13 @@ def buffer(self, cdata, size=-1): """Return a read-write buffer object that references the raw C data pointed to by the given 'cdata'. The 'cdata' must be a pointer or - an array. To get a copy of it in a regular string, call str() on - the result. + an array. Can be passed to functions expecting a buffer, or directly + manipulated with: + + buf[:] get a copy of it in a regular string, or + buf[idx] as a single character + buf[:] = ... + buf[idx] = ... change the content """ return self._backend.buffer(cdata, size) diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -996,20 +996,33 @@ - If 'cdata' is an enum, returns the value of the enumerator as a string, or ``#NUMBER`` if the value is out of range. -``ffi.buffer(pointer, [size])``: return a read-write buffer object that -references the raw C data pointed to by the given 'cdata', of 'size' -bytes. The 'cdata' must be a pointer or an array. To get a copy of it -in a regular string, use ``ffi.buffer(..)[:]`` in Python 2 and -``ffi.buffer(..).tobytes()`` in Python 3. To change the content, -use ``ffi.buffer(..)[:] = new_string_of_bytes``. If unspecified, the -default size of the buffer is ``sizeof(*pointer)`` or the whole size of -the array. Getting a buffer is useful because you can read from it + +``ffi.buffer(cdata, [size])``: return a buffer object that references +the raw C data pointed to by the given 'cdata', of 'size' bytes. The +'cdata' must be a pointer or an array. If unspecified, the size of the +buffer is either the size of what ``cdata`` points to, or the whole size +of the array. Getting a buffer is useful because you can read from it without an extra copy, or write into it to change the original value; you can use for example ``file.write()`` and ``file.readinto()`` with such a buffer (for files opened in binary mode). (Remember that like in C, you use ``array + index`` to get the pointer to the index'th item of an array.) +.. versionchanged:: 0.4 + The returned object is not a built-in buffer nor memoryview object, + because these objects' API changes too much across Python versions. + Instead it has the following Python API (a subset of ``buffer``): + +- ``buf[:]``: fetch a copy as a regular byte string (or + ``buf[start:end]`` for a part) + +- ``buf[:] = newstr``: change the original content (or ``buf[start:end] + = newstr``) + +- ``len(buf), buf[index], buf[index] = newchar``: access as a sequence + of characters. + + ``ffi.typeof("C type" or cdata object)``: return an object of type ```` corresponding to the parsed string, or to the C type of the cdata instance. Usually you don't need to call this function or to From noreply at buildbot.pypy.org Mon Oct 29 09:20:38 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 09:20:38 +0100 (CET) Subject: [pypy-commit] cffi default: Fix the tests and kill support in the ctypes backend. Message-ID: <20121029082038.687B21C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1017:f5ee4b029afc Date: 2012-10-29 09:17 +0100 http://bitbucket.org/cffi/cffi/changeset/f5ee4b029afc/ Log: Fix the tests and kill support in the ctypes backend. diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py --- a/cffi/backend_ctypes.py +++ b/cffi/backend_ctypes.py @@ -980,48 +980,7 @@ return b._to_string(maxlen) def buffer(self, bptr, size=-1): - if sys.version_info >= (2, 7): - # buf = bptr._as_ctype_ptr - # return memoryview(buf.contents) - if isinstance(bptr, CTypesGenericPtr): - buf = bptr._as_ctype_ptr - val = buf.contents - elif isinstance(bptr, CTypesGenericArray): - buf = bptr._blob - val = bptr._blob - else: - raise TypeError(bptr) - class Hack(ctypes.Union): - _fields_ = [('stupid', type(val))] - ptr = ctypes.cast(buf, ctypes.POINTER(Hack)) - view = memoryview(ptr.contents) - try: - view = view.cast('B') - except AttributeError: - raise NotImplementedError("buffer() with ctypes backend " - "in Python < 3.3") - if size >= 0: - view = view[:size] - return view - - # haaaaaaaaaaaack - if '__pypy__' in sys.builtin_module_names: - raise NotImplementedError("PyPy: ffi.buffer() with ctypes backend") - call = ctypes.pythonapi.PyBuffer_FromReadWriteMemory - call.argtypes = (ctypes.c_void_p, ctypes.c_size_t) - call.restype = ctypes.py_object - # - if isinstance(bptr, CTypesGenericPtr): - if size < 0: - size = bptr._bitem_size - return call(bptr._as_ctype_ptr, size) - elif isinstance(bptr, CTypesGenericArray): - if size < 0: - size = ctypes.sizeof(bptr._blob) - return call(ctypes.pointer(bptr._blob), size) - else: - raise TypeError("pointer or array argument expected, got %r" % - (type(bptr).__name__,)) + raise NotImplementedError("buffer() with ctypes backend") def sizeof(self, cdata_or_BType): if isinstance(cdata_or_BType, CTypesData): diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -1074,13 +1074,8 @@ b = ffi.buffer(a) except NotImplementedError as e: py.test.skip(str(e)) - if sys.version_info < (2, 7): - assert type(b) is buffer - content = str(b) - else: - assert type(b) is memoryview - content = b.tobytes() - assert len(content) == 2 + content = b[:] + assert len(content) == len(b) == 2 if sys.byteorder == 'little': assert content == b'\x64\x00' assert b[0] == bufitem(b'\x64') @@ -1098,12 +1093,7 @@ b = ffi.buffer(a) except NotImplementedError as e: py.test.skip(str(e)) - if sys.version_info < (2, 7): - assert type(b) is buffer - content = str(b) - else: - assert type(b) is memoryview - content = b.tobytes() + content = b[:] if sys.byteorder == 'little': assert content.startswith(b'\x64\x00\x00\x00\x65\x00\x00\x00') b[4] = bufitem(b'\x45') @@ -1120,12 +1110,7 @@ b = ffi.buffer(a, 1) except NotImplementedError as e: py.test.skip(str(e)) - if sys.version_info < (2, 7): - assert type(b) is buffer - content = str(b) - else: - assert type(b) is memoryview - content = b.tobytes() + content = b[:] assert len(content) == 1 if sys.byteorder == 'little': assert content == b'\x43' @@ -1144,10 +1129,7 @@ ffi.buffer(a1) except NotImplementedError as e: py.test.skip(str(e)) - if sys.version_info < (3,): - assert ffi.buffer(a1)[:] == ffi.buffer(a2, 4*10)[:] - else: - assert ffi.buffer(a1).tobytes() == ffi.buffer(a2, 4*10).tobytes() + assert ffi.buffer(a1)[:] == ffi.buffer(a2, 4*10)[:] def test_ffi_buffer_with_file(self): ffi = FFI(backend=self.Backend()) From noreply at buildbot.pypy.org Mon Oct 29 09:30:28 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 09:30:28 +0100 (CET) Subject: [pypy-commit] cffi default: Giving a TypeError doesn't make much sense here, even though Message-ID: <20121029083028.AE7AC1C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1018:15e763a4ae27 Date: 2012-10-29 09:29 +0100 http://bitbucket.org/cffi/cffi/changeset/15e763a4ae27/ Log: Giving a TypeError doesn't make much sense here, even though CPython's buffer type does it. diff --git a/c/minibuffer.h b/c/minibuffer.h --- a/c/minibuffer.h +++ b/c/minibuffer.h @@ -70,7 +70,7 @@ count = right - left; if (count != buffer_len) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "right operand length must match slice length"); return -1; } diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1861,8 +1861,8 @@ # --mb_ass_slice-- buf[:] = b"hi there\x00" assert list(buf) == list(c) == list(b"hi there\x00") - py.test.raises(TypeError, 'buf[:] = b"shorter"') - py.test.raises(TypeError, 'buf[:] = b"this is much too long!"') + py.test.raises(ValueError, 'buf[:] = b"shorter"') + py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" expected = list(b"hi there\x00") From noreply at buildbot.pypy.org Mon Oct 29 09:36:19 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 09:36:19 +0100 (CET) Subject: [pypy-commit] pypy default: Test and fix. Message-ID: <20121029083619.A10451C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58555:e2b412fbfe09 Date: 2012-10-29 09:34 +0100 http://bitbucket.org/pypy/pypy/changeset/e2b412fbfe09/ Log: Test and fix. diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -74,8 +74,11 @@ elif step == 1: length = stop - start if length != len(newstring): - msg = "buffer slice assignment is wrong size" - raise OperationError(space.w_ValueError, space.wrap(msg)) + if length < 0 and len(newstring) == 0: + pass # ok anyway + else: + msg = "right operand length must match slice length" + raise OperationError(space.w_ValueError, space.wrap(msg)) self.setslice(start, newstring) else: raise OperationError(space.w_ValueError, diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -117,6 +117,8 @@ b[:] = '12345' assert a.tostring() == 'hello 12345' raises(IndexError, 'b[5] = "."') + b[4:2] = '' + assert a.tostring() == 'hello 12345' b = buffer(b, 2) assert len(b) == 3 From noreply at buildbot.pypy.org Mon Oct 29 09:36:20 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 09:36:20 +0100 (CET) Subject: [pypy-commit] pypy default: Update to cffi/15e763a4ae27. Message-ID: <20121029083620.D12C91C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58556:410126277756 Date: 2012-10-29 09:35 +0100 http://bitbucket.org/pypy/pypy/changeset/410126277756/ Log: Update to cffi/15e763a4ae27. diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,6 +1,7 @@ from pypy.interpreter.error import operationerrfmt from pypy.interpreter.buffer import RWBuffer -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.interpreter.typedef import TypeDef from pypy.rpython.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -34,6 +35,16 @@ for i in range(len(string)): raw_cdata[i] = string[i] +LLBuffer.typedef = TypeDef( + "buffer", + __module__ = "_cffi_backend", + __len__ = interp2app(RWBuffer.descr_len), + __getitem__ = interp2app(RWBuffer.descr_getitem), + __setitem__ = interp2app(RWBuffer.descr_setitem), + __buffer__ = interp2app(RWBuffer.descr__buffer__), + ) +LLBuffer.typedef.acceptable_as_base_class = False + @unwrap_spec(cdata=cdataobj.W_CData, size=int) def buffer(space, cdata, size=-1): 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 @@ -5,8 +5,6 @@ type_or_class = "type" mandatory_b_prefix = '' mandatory_u_prefix = 'u' - readbuf = str - bufchar = lambda x: x bytechr = chr class U(object): def __add__(self, other): @@ -20,11 +18,6 @@ unichr = chr mandatory_b_prefix = 'b' mandatory_u_prefix = '' - readbuf = lambda buf: buf.tobytes() - if sys.version_info < (3, 3): - bufchar = lambda x: bytes([ord(x)]) - else: - bufchar = ord bytechr = lambda n: bytes([n]) u = "" @@ -1811,36 +1804,76 @@ assert (p < s) ^ (p > s) def test_buffer(): + import __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() assert sizeof(BShort) == 2 - assert len(readbuf(buffer(s))) == 2 + assert len(buffer(s)) == 2 # BChar = new_primitive_type("char") BCharArray = new_array_type(new_pointer_type(BChar), None) c = newp(BCharArray, b"hi there") + # buf = buffer(c) - assert readbuf(buf) == b"hi there\x00" + assert str(buf).startswith('<_cffi_backend.buffer object at 0x') + # --mb_length-- assert len(buf) == len(b"hi there\x00") - assert buf[0] == bufchar('h') - assert buf[2] == bufchar(' ') - assert list(buf) == list(map(bufchar, "hi there\x00")) - buf[2] = bufchar('-') - assert c[2] == b'-' - assert readbuf(buf) == b"hi-there\x00" - c[2] = b'!' - assert buf[2] == bufchar('!') - assert readbuf(buf) == b"hi!there\x00" - c[2] = b'-' - buf[:2] = b'HI' - assert string(c) == b'HI-there' - if sys.version_info < (3,) or sys.version_info >= (3, 3): - assert buf[:4:2] == b'H-' - if '__pypy__' not in sys.builtin_module_names: - # XXX pypy doesn't support the following assignment so far - buf[:4:2] = b'XY' - assert string(c) == b'XIYthere' + # --mb_item-- + for i in range(-12, 12): + try: + expected = b"hi there\x00"[i] + except IndexError: + py.test.raises(IndexError, "buf[i]") + else: + assert buf[i] == expected + # --mb_slice-- + assert buf[:] == b"hi there\x00" + for i in range(-12, 12): + assert buf[i:] == b"hi there\x00"[i:] + assert buf[:i] == b"hi there\x00"[:i] + for j in range(-12, 12): + assert buf[i:j] == b"hi there\x00"[i:j] + # --misc-- + assert list(buf) == list(b"hi there\x00") + # --mb_as_buffer-- + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 + py.test.raises(TypeError, memoryview, c) + mv1 = memoryview(buf) + assert len(mv1) == len(buf) and mv1[3] == "t" + # --mb_ass_item-- + expected = list(b"hi there\x00") + for i in range(-12, 12): + try: + expected[i] = chr(i & 0xff) + except IndexError: + py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + else: + buf[i] = chr(i & 0xff) + assert list(buf) == expected + # --mb_ass_slice-- + buf[:] = b"hi there\x00" + assert list(buf) == list(c) == list(b"hi there\x00") + py.test.raises(ValueError, 'buf[:] = b"shorter"') + py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + buf[4:2] = b"" # no effect, but should work + assert buf[:] == b"hi there\x00" + expected = list(b"hi there\x00") + x = 0 + for i in range(-12, 12): + for j in range(-12, 12): + start = i if i >= 0 else i + len(buf) + stop = j if j >= 0 else j + len(buf) + start = max(0, min(len(buf), start)) + stop = max(0, min(len(buf), stop)) + sample = chr(x & 0xff) * (stop - start) + x += 1 + buf[i:j] = sample + expected[i:j] = sample + assert list(buf) == expected def test_getcname(): BUChar = new_primitive_type("unsigned char") From noreply at buildbot.pypy.org Mon Oct 29 09:36:22 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 09:36:22 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121029083622.1A4821C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58557:3c48814f0da0 Date: 2012-10-29 09:36 +0100 http://bitbucket.org/pypy/pypy/changeset/3c48814f0da0/ Log: merge heads 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 @@ -275,14 +275,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - # Running entire test suite needs this function to succeed, - # running single test_stringarray succeeds without it. - # With convert_to() test_ztranslation fails since - # W_CharacterBox is not a W_GenericBox. - # Why is it needed for multiple tests? - #def convert_to(self, dtype): - # xxx - class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): from pypy.module.micronumpy.interp_dtype import new_unicode_dtype diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -119,6 +119,17 @@ self.size = size or len(digits) self.sign = sign + # __eq__ and __ne__ method exist for testingl only, they are not RPython! + def __eq__(self, other): + # NOT_RPYTHON + if not isinstance(other, rbigint): + return NotImplemented + return self.eq(other) + + def __ne__(self, other): + # NOT_RPYTHON + return not (self == other) + def digit(self, x): """Return the x'th digit, as an int.""" return self._digits[x] diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -1,14 +1,19 @@ from __future__ import division + +import operator +import sys +from random import random, randint, sample + import py -import operator, sys, array -from random import random, randint, sample -from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF -from pypy.rlib.rbigint import _store_digit, _mask_digit -from pypy.rlib.rfloat import NAN + from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask +from pypy.rlib.rbigint import (rbigint, SHIFT, MASK, KARATSUBA_CUTOFF, + _store_digit, _mask_digit) +from pypy.rlib.rfloat import NAN from pypy.rpython.test.test_llinterp import interpret + class TestRLong(object): def test_simple(self): for op1 in [-2, -1, 0, 1, 2, 50]: @@ -112,6 +117,17 @@ rl = rbigint.fromint(sys.maxint).add(rbigint.fromint(42)) assert rl.touint() == result + def test_eq_ne_operators(self): + a1 = rbigint.fromint(12) + a2 = rbigint.fromint(12) + a3 = rbigint.fromint(123) + + assert a1 == a2 + assert a1 != a3 + assert not (a1 != a2) + assert not (a1 == a3) + + def gen_signs(l): for s in l: if s == 0: From noreply at buildbot.pypy.org Mon Oct 29 10:11:08 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 10:11:08 +0100 (CET) Subject: [pypy-commit] pypy default: Add a sanity check and fix test_ztranslation. Message-ID: <20121029091108.CFCB21C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58558:3397c6918695 Date: 2012-10-29 10:10 +0100 http://bitbucket.org/pypy/pypy/changeset/3397c6918695/ Log: Add a sanity check and fix test_ztranslation. diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -429,15 +429,17 @@ source_start_box = self.get_constant_box(op.getarg(3)) dest_start_box = self.get_constant_box(op.getarg(4)) length = self.get_constant_box(op.getarg(5)) + extrainfo = op.getdescr().get_extra_info() if (source_start_box and dest_start_box and length and (dest_value.is_virtual() or length.getint() <= 8) and - (source_value.is_virtual() or length.getint() <= 8)): + (source_value.is_virtual() or length.getint() <= 8) and + len(extrainfo.write_descrs_arrays) == 1): # <-sanity check from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue source_start = source_start_box.getint() dest_start = dest_start_box.getint() + # XXX fish fish fish + arraydescr = extrainfo.write_descrs_arrays[0] for index in range(length.getint()): - # XXX fish fish fish - arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] if source_value.is_virtual(): assert isinstance(source_value, VArrayValue) val = source_value.getitem(index + source_start) From noreply at buildbot.pypy.org Mon Oct 29 10:41:33 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 10:41:33 +0100 (CET) Subject: [pypy-commit] pypy default: Fix. Message-ID: <20121029094133.C08731C0250@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58559:c792e6da2776 Date: 2012-10-29 10:40 +0100 http://bitbucket.org/pypy/pypy/changeset/c792e6da2776/ Log: Fix. 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 @@ -357,8 +357,8 @@ buffering = 1024 # minimum amount of compressed data read at once self.buffering = buffering - def close(self): - self.stream.close() + def close1(self, closefileno): + self.stream.close1(closefileno) def tell(self): return self.readlength @@ -479,9 +479,9 @@ self.compressor = W_BZ2Compressor(space, compresslevel) self.writtenlength = 0 - def close(self): + def close1(self, closefileno): self.stream.write(self.space.str_w(self.compressor.flush())) - self.stream.close() + self.stream.close1(closefileno) def write(self, data): self.stream.write(self.space.str_w(self.compressor.compress(data))) From noreply at buildbot.pypy.org Mon Oct 29 10:41:35 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 10:41:35 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121029094135.D8E081C0250@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58560:f50971fda427 Date: 2012-10-29 10:41 +0100 http://bitbucket.org/pypy/pypy/changeset/f50971fda427/ Log: merge heads diff too long, truncating to 2000 out of 2710 lines diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py deleted file mode 100644 --- a/lib_pypy/itertools.py +++ /dev/null @@ -1,670 +0,0 @@ -# Note that PyPy contains also a built-in module 'itertools' which will -# hide this one if compiled in. - -"""Functional tools for creating and using iterators. - -Infinite iterators: -count([n]) --> n, n+1, n+2, ... -cycle(p) --> p0, p1, ... plast, p0, p1, ... -repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times - -Iterators terminating on the shortest input sequence: -izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... -ifilter(pred, seq) --> elements of seq where pred(elem) is True -ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False -islice(seq, [start,] stop [, step]) --> elements from - seq[start:stop:step] -imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ... -starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ... -tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n -chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... -takewhile(pred, seq) --> seq[0], seq[1], until pred fails -dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails -groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v) -""" - -__all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', - 'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap', - 'takewhile', 'tee', 'compress', 'product'] - -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f - - -class chain(object): - """Make an iterator that returns elements from the first iterable - until it is exhausted, then proceeds to the next iterable, until - all of the iterables are exhausted. Used for treating consecutive - sequences as a single sequence. - - Equivalent to : - - def chain(*iterables): - for it in iterables: - for element in it: - yield element - """ - def __init__(self, *iterables): - self._iterables_iter = iter(map(iter, iterables)) - # little trick for the first chain.next() call - self._cur_iterable_iter = iter([]) - - def __iter__(self): - return self - - def next(self): - while True: - try: - return self._cur_iterable_iter.next() - except StopIteration: - self._cur_iterable_iter = self._iterables_iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iterable_iter)) - - -class compress(object): - def __init__(self, data, selectors): - self.data = iter(data) - self.selectors = iter(selectors) - - def __iter__(self): - return self - - def next(self): - while True: - next_item = self.data.next() - next_selector = self.selectors.next() - if bool(next_selector): - return next_item - - -class count(object): - """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. - - Equivalent to : - - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) - while True: - yield n - n += 1 - """ - def __init__(self, n=0): - if not isinstance(n, int): - raise TypeError('%s is not a regular integer' % n) - self.times = n-1 - - def __iter__(self): - return self - - def next(self): - self.times += 1 - return self.times - - def __repr__(self): - return 'count(%d)' % (self.times + 1) - - - -class cycle(object): - """Make an iterator returning elements from the iterable and - saving a copy of each. When the iterable is exhausted, return - elements from the saved copy. Repeats indefinitely. - - Equivalent to : - - def cycle(iterable): - saved = [] - for element in iterable: - yield element - saved.append(element) - while saved: - for element in saved: - yield element - """ - def __init__(self, iterable): - self._cur_iter = iter(iterable) - self._saved = [] - self._must_save = True - - def __iter__(self): - return self - - def next(self): - # XXX Could probably be improved - try: - next_elt = self._cur_iter.next() - if self._must_save: - self._saved.append(next_elt) - except StopIteration: - self._cur_iter = iter(self._saved) - next_elt = self._cur_iter.next() - self._must_save = False - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iter)) - return next_elt - - -class dropwhile(object): - """Make an iterator that drops elements from the iterable as long - as the predicate is true; afterwards, returns every - element. Note, the iterator does not produce any output until the - predicate is true, so it may have a lengthy start-up time. - - Equivalent to : - - def dropwhile(predicate, iterable): - iterable = iter(iterable) - for x in iterable: - if not predicate(x): - yield x - break - for x in iterable: - yield x - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - self._dropped = False - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if self._dropped: - return value - while self._predicate(value): - value = self._iter.next() - self._dropped = True - return value - -class groupby(object): - """Make an iterator that returns consecutive keys and groups from the - iterable. The key is a function computing a key value for each - element. If not specified or is None, key defaults to an identity - function and returns the element unchanged. Generally, the - iterable needs to already be sorted on the same key function. - - The returned group is itself an iterator that shares the - underlying iterable with groupby(). Because the source is shared, - when the groupby object is advanced, the previous group is no - longer visible. So, if that data is needed later, it should be - stored as a list: - - groups = [] - uniquekeys = [] - for k, g in groupby(data, keyfunc): - groups.append(list(g)) # Store group iterator as a list - uniquekeys.append(k) - """ - def __init__(self, iterable, key=None): - if key is None: - key = lambda x: x - self.keyfunc = key - self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = xrange(0) - - def __iter__(self): - return self - - def next(self): - while self.currkey == self.tgtkey: - try: - self.currvalue = self.it.next() # Exit on StopIteration - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self.it)) - self.currkey = self.keyfunc(self.currvalue) - self.tgtkey = self.currkey - return (self.currkey, self._grouper(self.tgtkey)) - - def _grouper(self, tgtkey): - while self.currkey == tgtkey: - yield self.currvalue - self.currvalue = self.it.next() # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) - - - -class _ifilter_base(object): - """base class for ifilter and ifilterflase""" - def __init__(self, predicate, iterable): - # Make sure iterable *IS* iterable - self._iter = iter(iterable) - if predicate is None: - self._predicate = bool - else: - self._predicate = predicate - - def __iter__(self): - return self - -class ifilter(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is True. If predicate is - None, return the items that are true. - - Equivalent to : - - def ifilter: - if predicate is None: - predicate = bool - for x in iterable: - if predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - -class ifilterfalse(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is False. If predicate is - None, return the items that are false. - - Equivalent to : - - def ifilterfalse(predicate, iterable): - if predicate is None: - predicate = bool - for x in iterable: - if not predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if not self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - - - - -class imap(object): - """Make an iterator that computes the function using arguments - from each of the iterables. If function is set to None, then - imap() returns the arguments as a tuple. Like map() but stops - when the shortest iterable is exhausted instead of filling in - None for shorter iterables. The reason for the difference is that - infinite iterator arguments are typically an error for map() - (because the output is fully evaluated) but represent a common - and useful way of supplying arguments to imap(). - - Equivalent to : - - def imap(function, *iterables): - iterables = map(iter, iterables) - while True: - args = [i.next() for i in iterables] - if function is None: - yield tuple(args) - else: - yield function(*args) - - """ - def __init__(self, function, iterable, *other_iterables): - self._func = function - self._iters = map(iter, (iterable, ) + other_iterables) - - def __iter__(self): - return self - - def next(self): - try: - args = [it.next() for it in self._iters] - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (it)) - if self._func is None: - return tuple(args) - else: - return self._func(*args) - - - -class islice(object): - """Make an iterator that returns selected elements from the - iterable. If start is non-zero, then elements from the iterable - are skipped until start is reached. Afterward, elements are - returned consecutively unless step is set higher than one which - results in items being skipped. If stop is None, then iteration - continues until the iterator is exhausted, if at all; otherwise, - it stops at the specified position. Unlike regular slicing, - islice() does not support negative values for start, stop, or - step. Can be used to extract related fields from data where the - internal structure has been flattened (for example, a multi-line - report may list a name field on every third line). - """ - def __init__(self, iterable, *args): - s = slice(*args) - self.start, self.stop, self.step = s.start or 0, s.stop, s.step - if not isinstance(self.start, (int, long)): - raise ValueError("Start argument must be an integer") - if self.stop is not None and not isinstance(self.stop, (int,long)): - raise ValueError("Stop argument must be an integer or None") - if self.step is None: - self.step = 1 - if self.start<0 or (self.stop is not None and self.stop<0 - ) or self.step<=0: - raise ValueError, "indices for islice() must be positive" - self.it = iter(iterable) - self.donext = None - self.cnt = 0 - - def __iter__(self): - return self - - def next(self): - if self.donext is None: - try: - self.donext = self.it.next - except AttributeError: - raise TypeError - nextindex = self.start - if self.stop is not None and nextindex >= self.stop: - raise StopIteration - while self.cnt <= nextindex: - nextitem = self.donext() - self.cnt += 1 - self.start += self.step - return nextitem - -class izip(object): - """Make an iterator that aggregates elements from each of the - iterables. Like zip() except that it returns an iterator instead - of a list. Used for lock-step iteration over several iterables at - a time. - - Equivalent to : - - def izip(*iterables): - iterables = map(iter, iterables) - while iterables: - result = [i.next() for i in iterables] - yield tuple(result) - """ - def __init__(self, *iterables): - self._iterators = map(iter, iterables) - self._result = [None] * len(self._iterators) - - def __iter__(self): - return self - - def next(self): - if not self._iterators: - raise StopIteration() - try: - return tuple([i.next() for i in self._iterators]) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (i)) - - -class product(object): - - def __init__(self, *args, **kw): - if len(kw) > 1: - raise TypeError("product() takes at most 1 argument (%d given)" % - len(kw)) - self.repeat = kw.get('repeat', 1) - self.gears = [x for x in args] * self.repeat - self.num_gears = len(self.gears) - # initialization of indicies to loop over - self.indicies = [(0, len(self.gears[x])) - for x in range(0, self.num_gears)] - self.cont = True - - def roll_gears(self): - # Starting from the end of the gear indicies work to the front - # incrementing the gear until the limit is reached. When the limit - # is reached carry operation to the next gear - should_carry = True - for n in range(0, self.num_gears): - nth_gear = self.num_gears - n - 1 - if should_carry: - count, lim = self.indicies[nth_gear] - count += 1 - if count == lim and nth_gear == 0: - self.cont = False - if count == lim: - should_carry = True - count = 0 - else: - should_carry = False - self.indicies[nth_gear] = (count, lim) - else: - break - - def __iter__(self): - return self - - def next(self): - if not self.cont: - raise StopIteration - l = [] - for x in range(0, self.num_gears): - index, limit = self.indicies[x] - l.append(self.gears[x][index]) - self.roll_gears() - return tuple(l) - - -class repeat(object): - """Make an iterator that returns object over and over again. - Runs indefinitely unless the times argument is specified. Used - as argument to imap() for invariant parameters to the called - function. Also used with izip() to create an invariant part of a - tuple record. - - Equivalent to : - - def repeat(object, times=None): - if times is None: - while True: - yield object - else: - for i in xrange(times): - yield object - """ - def __init__(self, obj, times=None): - self._obj = obj - if times is not None: - xrange(times) # Raise a TypeError - if times < 0: - times = 0 - self._times = times - - def __iter__(self): - return self - - def next(self): - # next() *need* to decrement self._times when consumed - if self._times is not None: - if self._times <= 0: - raise StopIteration() - self._times -= 1 - return self._obj - - def __repr__(self): - if self._times is not None: - return 'repeat(%r, %r)' % (self._obj, self._times) - else: - return 'repeat(%r)' % (self._obj,) - - def __len__(self): - if self._times == -1 or self._times is None: - raise TypeError("len() of uniszed object") - return self._times - - -class starmap(object): - """Make an iterator that computes the function using arguments - tuples obtained from the iterable. Used instead of imap() when - argument parameters are already grouped in tuples from a single - iterable (the data has been ``pre-zipped''). The difference - between imap() and starmap() parallels the distinction between - function(a,b) and function(*c). - - Equivalent to : - - def starmap(function, iterable): - iterable = iter(iterable) - while True: - yield function(*iterable.next()) - """ - def __init__(self, function, iterable): - self._func = function - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - # CPython raises a TypeError when the iterator doesn't return a tuple - try: - t = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - if not isinstance(t, tuple): - raise TypeError("iterator must return a tuple") - return self._func(*t) - - - -class takewhile(object): - """Make an iterator that returns elements from the iterable as - long as the predicate is true. - - Equivalent to : - - def takewhile(predicate, iterable): - for x in iterable: - if predicate(x): - yield x - else: - break - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if not self._predicate(value): - raise StopIteration() - return value - - -class TeeData(object): - """Holds cached values for TeeObjects""" - def __init__(self, iterator): - self.data = [] - self._iter = iterator - - def __getitem__(self, i): - # iterates until 'i' if not done yet - while i>= len(self.data): - try: - self.data.append( self._iter.next() ) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - return self.data[i] - - -class TeeObject(object): - """Iterables / Iterators as returned by the tee() function""" - def __init__(self, iterable=None, tee_data=None): - if tee_data: - self.tee_data = tee_data - self.pos = 0 - # <=> Copy constructor - elif isinstance(iterable, TeeObject): - self.tee_data = iterable.tee_data - self.pos = iterable.pos - else: - self.tee_data = TeeData(iter(iterable)) - self.pos = 0 - - def next(self): - data = self.tee_data[self.pos] - self.pos += 1 - return data - - def __iter__(self): - return self - - - at builtinify -def tee(iterable, n=2): - """Return n independent iterators from a single iterable. - Note : once tee() has made a split, the original iterable - should not be used anywhere else; otherwise, the iterable could get - advanced without the tee objects being informed. - - Note : this member of the toolkit may require significant auxiliary - storage (depending on how much temporary data needs to be stored). - In general, if one iterator is going to use most or all of the - data before the other iterator, it is faster to use list() instead - of tee() - - Equivalent to : - - def tee(iterable, n=2): - def gen(next, data={}, cnt=[0]): - for i in count(): - if i == cnt[0]: - item = data[i] = next() - cnt[0] += 1 - else: - item = data.pop(i) - yield item - it = iter(iterable) - return tuple([gen(it.next) for i in range(n)]) - """ - if isinstance(iterable, TeeObject): - # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) - return tuple([iterable] + - [TeeObject(tee_data=iterable.tee_data) for i in xrange(n-1)]) - tee_data = TeeData(iter(iterable)) - return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)]) diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,5 +1,5 @@ -from _numpypy import array, ndarray, int_, float_, bool_ #, complex_# , longlong +from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math @@ -200,7 +200,7 @@ typename = "'%s'" % typename lf = '' - if 0: # or issubclass(arr.dtype.type, flexible): + if issubclass(arr.dtype.type, flexible): if arr.dtype.names: typename = "%s" % str(arr.dtype) else: diff --git a/lib_pypy/pypy_test/test_itertools.py b/lib_pypy/pypy_test/test_itertools.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_itertools.py +++ /dev/null @@ -1,50 +0,0 @@ -from py.test import raises -from lib_pypy import itertools - -class TestItertools(object): - - def test_compress(self): - it = itertools.compress(['a', 'b', 'c'], [0, 1, 0]) - - assert list(it) == ['b'] - - def test_compress_diff_len(self): - it = itertools.compress(['a'], []) - raises(StopIteration, it.next) - - def test_product(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')] - - def test_product_repeat(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m, repeat=2) - ans = [(1, 'a', 1, 'a'), (1, 'a', 1, 'b'), (1, 'a', 2, 'a'), - (1, 'a', 2, 'b'), (1, 'b', 1, 'a'), (1, 'b', 1, 'b'), - (1, 'b', 2, 'a'), (1, 'b', 2, 'b'), (2, 'a', 1, 'a'), - (2, 'a', 1, 'b'), (2, 'a', 2, 'a'), (2, 'a', 2, 'b'), - (2, 'b', 1, 'a'), (2, 'b', 1, 'b'), (2, 'b', 2, 'a'), - (2, 'b', 2, 'b')] - assert list(prodlist) == ans - - def test_product_diff_sizes(self): - l = [1, 2] - m = ['a'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (2, 'a')] - - l = [1] - m = ['a', 'b'] - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b')] - - def test_product_toomany_args(self): - l = [1, 2] - m = ['a'] - raises(TypeError, itertools.product, l, m, repeat=1, foo=2) 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 @@ -233,7 +233,7 @@ try: return unicode(line, ENCODING) except UnicodeDecodeError: # bah, silently fall back... - return unicode(line, 'utf-8') + return unicode(line, 'utf-8', 'replace') def get_history_length(self): return self.saved_history_length diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -496,7 +496,7 @@ if iscode: self.__tputs(text) else: - os.write(self.output_fd, text.encode(self.encoding)) + os.write(self.output_fd, text.encode(self.encoding, 'replace')) del self.__buffer[:] def __tputs(self, fmt, prog=delayprog): diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -118,7 +118,7 @@ # 1. find the start of the statement from codeop import compile_command end = None - for start in range(lineno, -1, max(-1, lineno - 10)): + for start in range(lineno, -1, -1): if assertion: line = self.lines[start] # the following lines are not fully tested, change with care @@ -135,9 +135,9 @@ compile_command(trysource) except (SyntaxError, OverflowError, ValueError): continue - + # 2. find the end of the statement - for end in range(lineno+1, min(len(self)+1, lineno + 10)): + for end in range(lineno+1, len(self)+1): trysource = self[start:end] if trysource.isparseable(): return start, end diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -548,7 +548,7 @@ if cell.is_constant(): newcell.const = cell.const cell = newcell - cell.knowntypedata = renamed_knowntypedata + cell.set_knowntypedata(renamed_knowntypedata) cells.append(cell) diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -144,7 +144,7 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key annotator = bk.annotator @@ -168,6 +168,7 @@ bind(obj2, obj1, 0) bind(obj1, obj2, 1) + r.set_knowntypedata(knowntypedata) return r @@ -337,8 +338,7 @@ case = opname in ('gt', 'ge', 'eq') add_knowntypedata(knowntypedata, case, [op.args[0]], SomeInteger(nonneg=True, knowntype=tointtype(int1))) - if knowntypedata: - r.knowntypedata = knowntypedata + r.set_knowntypedata(knowntypedata) # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) @@ -369,8 +369,7 @@ if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) - if ktd: - s.knowntypedata = ktd + s.set_knowntypedata(ktd) return s def and_((boo1, boo2)): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -188,10 +188,10 @@ variables = [op.args[1]] for variable in variables: assert bk.annotator.binding(variable) == s_obj - r.knowntypedata = {} - + knowntypedata = {} if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): - add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) + add_knowntypedata(knowntypedata, True, variables, bk.valueoftype(typ)) + r.set_knowntypedata(knowntypedata) return r # note that this one either needs to be constant, or we will create SomeObject diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -195,6 +195,10 @@ unsigned = False def __init__(self): pass + def set_knowntypedata(self, knowntypedata): + assert not hasattr(self, 'knowntypedata') + if knowntypedata: + self.knowntypedata = knowntypedata class SomeStringOrUnicode(SomeObject): immutable = True diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -76,7 +76,7 @@ s_obj.is_true_behavior(r) bk = getbookkeeper() - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key op = block.operations[i] assert op.opname == "is_true" or op.opname == "nonzero" @@ -86,8 +86,8 @@ if s_obj.can_be_none(): s_nonnone_obj = s_obj.nonnoneify() add_knowntypedata(knowntypedata, True, [arg], s_nonnone_obj) + r.set_knowntypedata(knowntypedata) return r - def nonzero(obj): return obj.is_true() diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -118,7 +118,7 @@ ("translation.gcrootfinder", DEFL_ROOTFINDER_WITHJIT), ("translation.list_comprehension_operations", True)]), ChoiceOption("jit_backend", "choose the backend for the JIT", - ["auto", "x86", "x86-without-sse2", "llvm", 'arm'], + ["auto", "x86", "x86-without-sse2", 'arm'], default="auto", cmdline="--jit-backend"), ChoiceOption("jit_profiler", "integrate profiler support into the JIT", ["off", "oprofile"], 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 @@ -38,6 +38,8 @@ .. branch: numpypy-complex2 Complex dtype support for numpy +.. branch: numpypy-problems +Improve dtypes intp, uintp, void, string and record .. branch: kill-someobject major cleanups including killing some object support diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -74,8 +74,11 @@ elif step == 1: length = stop - start if length != len(newstring): - msg = "buffer slice assignment is wrong size" - raise OperationError(space.w_ValueError, space.wrap(msg)) + if length < 0 and len(newstring) == 0: + pass # ok anyway + else: + msg = "right operand length must match slice length" + raise OperationError(space.w_ValueError, space.wrap(msg)) self.setslice(start, newstring) else: raise OperationError(space.w_ValueError, diff --git a/pypy/jit/backend/detect_cpu.py b/pypy/jit/backend/detect_cpu.py --- a/pypy/jit/backend/detect_cpu.py +++ b/pypy/jit/backend/detect_cpu.py @@ -77,8 +77,6 @@ return "pypy.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "pypy.jit.backend.cli.runner", "CliCPU" - elif backend_name == 'llvm': - return "pypy.jit.backend.llvm.runner", "LLVMCPU" elif backend_name == 'arm': return "pypy.jit.backend.arm.runner", "CPU_ARM" elif backend_name == 'armhf': diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -1,17 +1,17 @@ from pypy.jit.metainterp import jitprof, resume, compile from pypy.jit.metainterp.executor import execute_nonspec -from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF, INT +from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF from pypy.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded, \ ImmutableIntUnbounded, \ IntLowerBound, MININT, MAXINT -from pypy.jit.metainterp.optimizeopt.util import (make_dispatcher_method, - args_dict) +from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method from pypy.jit.metainterp.resoperation import rop, ResOperation, AbstractResOp from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.tool.pairtype import extendabletype -from pypy.rlib.debug import debug_start, debug_stop, debug_print +from pypy.rlib.debug import debug_print from pypy.rlib.objectmodel import specialize + LEVEL_UNKNOWN = '\x00' LEVEL_NONNULL = '\x01' LEVEL_KNOWNCLASS = '\x02' # might also mean KNOWNARRAYDESCR, for arrays @@ -20,6 +20,8 @@ MODE_ARRAY = '\x00' MODE_STR = '\x01' MODE_UNICODE = '\x02' + + class LenBound(object): def __init__(self, mode, descr, bound): self.mode = mode diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -1,8 +1,11 @@ from pypy.jit.codewriter.effectinfo import EffectInfo -from pypy.jit.metainterp.history import ConstInt, make_hashable_int +from pypy.jit.metainterp import compile +from pypy.jit.metainterp.history import (Const, ConstInt, BoxInt, BoxFloat, + BoxPtr, make_hashable_int) from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntBound -from pypy.jit.metainterp.optimizeopt.optimizer import * +from pypy.jit.metainterp.optimizeopt.optimizer import (Optimization, REMOVED, + CONST_0, CONST_1) from pypy.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ResOperation) @@ -426,14 +429,33 @@ source_start_box = self.get_constant_box(op.getarg(3)) dest_start_box = self.get_constant_box(op.getarg(4)) length = self.get_constant_box(op.getarg(5)) - if (source_value.is_virtual() and source_start_box and dest_start_box - and length and (dest_value.is_virtual() or length.getint() <= 8)): + extrainfo = op.getdescr().get_extra_info() + if (source_start_box and dest_start_box + and length and (dest_value.is_virtual() or length.getint() <= 8) and + (source_value.is_virtual() or length.getint() <= 8) and + len(extrainfo.write_descrs_arrays) == 1): # <-sanity check from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue - assert isinstance(source_value, VArrayValue) source_start = source_start_box.getint() dest_start = dest_start_box.getint() + # XXX fish fish fish + arraydescr = extrainfo.write_descrs_arrays[0] for index in range(length.getint()): - val = source_value.getitem(index + source_start) + if source_value.is_virtual(): + assert isinstance(source_value, VArrayValue) + val = source_value.getitem(index + source_start) + else: + if arraydescr.is_array_of_pointers(): + resbox = BoxPtr() + elif arraydescr.is_array_of_floats(): + resbox = BoxFloat() + else: + resbox = BoxInt() + newop = ResOperation(rop.GETARRAYITEM_GC, + [op.getarg(1), + ConstInt(index + source_start)], resbox, + descr=arraydescr) + self.optimizer.propagate_forward(newop) + val = self.getvalue(resbox) if dest_value.is_virtual(): dest_value.setitem(index + dest_start, val) else: @@ -441,7 +463,7 @@ [op.getarg(2), ConstInt(index + dest_start), val.get_key_box()], None, - descr=source_value.arraydescr) + descr=arraydescr) self.emit_operation(newop) return True if length and length.getint() == 0: diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -3239,6 +3239,42 @@ ''' self.optimize_loop(ops, expected) + def test_arraycopy_not_virtual_2(self): + ops = ''' + [p0] + p1 = new_array(3, descr=arraydescr) + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) # removed by the backend + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) # removed by the backend + jump(i0) + ''' + self.optimize_loop(ops, expected) + + def test_arraycopy_not_virtual_3(self): + ops = ''' + [p0, p1] + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0, p1] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) + setarrayitem_gc(p1, 0, i0, descr=arraydescr) + setarrayitem_gc(p1, 1, i1, descr=arraydescr) + setarrayitem_gc(p1, 2, i2, descr=arraydescr) + jump(i0) + ''' + self.optimize_loop(ops, expected) + def test_arraycopy_no_elem(self): """ this was actually observed in the wild """ diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -4,6 +4,7 @@ from pypy.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken from pypy.jit.metainterp.jitexc import JitException from pypy.jit.metainterp.optimize import InvalidLoop +from pypy.rlib.debug import debug_print, debug_start, debug_stop from pypy.jit.metainterp.optimizeopt.optimizer import * from pypy.jit.metainterp.optimizeopt.generalize import KillHugeIntBounds from pypy.jit.metainterp.inliner import Inliner diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py --- a/pypy/jit/metainterp/test/test_list.py +++ b/pypy/jit/metainterp/test/test_list.py @@ -128,6 +128,17 @@ res = self.interp_operations(f, [], listops=True) assert res == 10 + def test_arraycopy_bug(self): + def f(): + l = [1, 2, 3, 4] + l2 = [1, 2, 3, 4] + l[2] = 13 + l2[0:len(l2)] = l[:] + return l2[0] + l2[1] + l2[2] + l2[3] + + res = self.interp_operations(f, [], listops=True) + assert res == f() + def test_arraycopy_full(self): jitdriver = JitDriver(greens = [], reds = ['n']) def f(n): diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -117,6 +117,8 @@ b[:] = '12345' assert a.tostring() == 'hello 12345' raises(IndexError, 'b[5] = "."') + b[4:2] = '' + assert a.tostring() == 'hello 12345' b = buffer(b, 2) assert len(b) == 3 diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,6 +1,7 @@ from pypy.interpreter.error import operationerrfmt from pypy.interpreter.buffer import RWBuffer -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.interpreter.typedef import TypeDef from pypy.rpython.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -34,6 +35,16 @@ for i in range(len(string)): raw_cdata[i] = string[i] +LLBuffer.typedef = TypeDef( + "buffer", + __module__ = "_cffi_backend", + __len__ = interp2app(RWBuffer.descr_len), + __getitem__ = interp2app(RWBuffer.descr_getitem), + __setitem__ = interp2app(RWBuffer.descr_setitem), + __buffer__ = interp2app(RWBuffer.descr__buffer__), + ) +LLBuffer.typedef.acceptable_as_base_class = False + @unwrap_spec(cdata=cdataobj.W_CData, size=int) def buffer(space, cdata, size=-1): diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -5,7 +5,7 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi, rposix +from pypy.rlib import jit, clibffi, jit_libffi from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG 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 @@ -7,6 +7,7 @@ from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.rarithmetic import ovfcheck +from pypy.rlib import rposix from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend import cdataobj, misc, ctypeprim @@ -148,15 +149,7 @@ class W_CTypePtrBase(W_CTypePtrOrArray): # base class for both pointers and pointers-to-functions - _attrs_ = ['is_file'] - _immutable_fields_ = ['is_file'] - - def __init__(self, space, size, extra, extra_position, ctitem, - could_cast_anything=True, is_file=False): - W_CTypePtrOrArray.__init__(self, space, size, - extra, extra_position, ctitem, - could_cast_anything=could_cast_anything) - self.is_file = is_file + _attrs_ = [] def convert_to_object(self, cdata): ptrdata = rffi.cast(rffi.CCHARPP, cdata)[0] @@ -166,11 +159,6 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): - if self.is_file: - result = self.prepare_file(w_ob) - if result: - rffi.cast(rffi.CCHARPP, cdata)[0] = result - return raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -185,23 +173,14 @@ rffi.cast(rffi.CCHARPP, cdata)[0] = ob._cdata - def prepare_file(self, w_ob): - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc - ob = self.space.interpclass_w(w_ob) - if isinstance(ob, W_File): - return prepare_file_argument(self.space, ob) - else: - return lltype.nullptr(rffi.CCHARP.TO) - def _alignof(self): from pypy.module._cffi_backend import newtype return newtype.alignment_of_pointer class W_CTypePointer(W_CTypePtrBase): - _attrs_ = [] - _immutable_fields_ = [] + _attrs_ = ['is_file'] + _immutable_fields_ = ['is_file'] def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -210,9 +189,8 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" - is_file = (ctitem.name == "struct _IO_FILE") - W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem, - is_file=is_file) + self.is_file = (ctitem.name == "struct _IO_FILE") + W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): space = self.space @@ -260,6 +238,22 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) + def cast(self, w_ob): + if self.is_file: + value = self.prepare_file(w_ob) + if value: + return cdataobj.W_CData(self.space, value, self) + return W_CTypePtrBase.cast(self, w_ob) + + def prepare_file(self, w_ob): + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = self.space.interpclass_w(w_ob) + if isinstance(ob, W_File): + return prepare_file_argument(self.space, ob) + else: + return lltype.nullptr(rffi.CCHARP.TO) + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or 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 @@ -5,8 +5,6 @@ type_or_class = "type" mandatory_b_prefix = '' mandatory_u_prefix = 'u' - readbuf = str - bufchar = lambda x: x bytechr = chr class U(object): def __add__(self, other): @@ -20,11 +18,6 @@ unichr = chr mandatory_b_prefix = 'b' mandatory_u_prefix = '' - readbuf = lambda buf: buf.tobytes() - if sys.version_info < (3, 3): - bufchar = lambda x: bytes([ord(x)]) - else: - bufchar = ord bytechr = lambda n: bytes([n]) u = "" @@ -1811,36 +1804,76 @@ assert (p < s) ^ (p > s) def test_buffer(): + import __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() assert sizeof(BShort) == 2 - assert len(readbuf(buffer(s))) == 2 + assert len(buffer(s)) == 2 # BChar = new_primitive_type("char") BCharArray = new_array_type(new_pointer_type(BChar), None) c = newp(BCharArray, b"hi there") + # buf = buffer(c) - assert readbuf(buf) == b"hi there\x00" + assert str(buf).startswith('<_cffi_backend.buffer object at 0x') + # --mb_length-- assert len(buf) == len(b"hi there\x00") - assert buf[0] == bufchar('h') - assert buf[2] == bufchar(' ') - assert list(buf) == list(map(bufchar, "hi there\x00")) - buf[2] = bufchar('-') - assert c[2] == b'-' - assert readbuf(buf) == b"hi-there\x00" - c[2] = b'!' - assert buf[2] == bufchar('!') - assert readbuf(buf) == b"hi!there\x00" - c[2] = b'-' - buf[:2] = b'HI' - assert string(c) == b'HI-there' - if sys.version_info < (3,) or sys.version_info >= (3, 3): - assert buf[:4:2] == b'H-' - if '__pypy__' not in sys.builtin_module_names: - # XXX pypy doesn't support the following assignment so far - buf[:4:2] = b'XY' - assert string(c) == b'XIYthere' + # --mb_item-- + for i in range(-12, 12): + try: + expected = b"hi there\x00"[i] + except IndexError: + py.test.raises(IndexError, "buf[i]") + else: + assert buf[i] == expected + # --mb_slice-- + assert buf[:] == b"hi there\x00" + for i in range(-12, 12): + assert buf[i:] == b"hi there\x00"[i:] + assert buf[:i] == b"hi there\x00"[:i] + for j in range(-12, 12): + assert buf[i:j] == b"hi there\x00"[i:j] + # --misc-- + assert list(buf) == list(b"hi there\x00") + # --mb_as_buffer-- + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 + py.test.raises(TypeError, memoryview, c) + mv1 = memoryview(buf) + assert len(mv1) == len(buf) and mv1[3] == "t" + # --mb_ass_item-- + expected = list(b"hi there\x00") + for i in range(-12, 12): + try: + expected[i] = chr(i & 0xff) + except IndexError: + py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + else: + buf[i] = chr(i & 0xff) + assert list(buf) == expected + # --mb_ass_slice-- + buf[:] = b"hi there\x00" + assert list(buf) == list(c) == list(b"hi there\x00") + py.test.raises(ValueError, 'buf[:] = b"shorter"') + py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + buf[4:2] = b"" # no effect, but should work + assert buf[:] == b"hi there\x00" + expected = list(b"hi there\x00") + x = 0 + for i in range(-12, 12): + for j in range(-12, 12): + start = i if i >= 0 else i + len(buf) + stop = j if j >= 0 else j + len(buf) + start = max(0, min(len(buf), start)) + stop = max(0, min(len(buf), stop)) + sample = chr(x & 0xff) * (stop - start) + x += 1 + buf[i:j] = sample + expected[i:j] = sample + assert list(buf) == expected def test_getcname(): BUChar = new_primitive_type("unsigned char") @@ -2271,7 +2304,6 @@ # BFILE = new_struct_type("_IO_FILE") BFILEP = new_pointer_type(BFILE) - BFILEPP = new_pointer_type(BFILEP) BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) BInt = new_primitive_type("int") @@ -2285,12 +2317,12 @@ fdr, fdw = posix.pipe() fw1 = posix.fdopen(fdw, 'wb', 256) # - fw1p = newp(BFILEPP, fw1) + fw1p = cast(BFILEP, fw1) fw1.write(b"X") fw1.flush() - res = fputs(b"hello\n", fw1p[0]) + res = fputs(b"hello\n", fw1p) assert res >= 0 - res = fileno(fw1p[0]) + res = fileno(fw1p) assert res == fdw fw1.close() # diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -64,20 +64,18 @@ next = interp2app(W_Count.next_w), __reduce__ = interp2app(W_Count.reduce_w), __repr__ = interp2app(W_Count.repr_w), - __doc__ = """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. + __doc__ = """Make an iterator that returns evenly spaced values starting + with n. If not specified n defaults to zero. Often used as an + argument to imap() to generate consecutive data points. Also, + used with izip() to add sequence numbers. - Equivalent to : + Equivalent to: - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) + def count(start=0, step=1): + n = start while True: yield n - n += 1 + n += step """) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -62,6 +62,7 @@ 'flexible': 'interp_boxes.W_FlexibleBox', 'character': 'interp_boxes.W_CharacterBox', 'str_': 'interp_boxes.W_StringBox', + 'string_': 'interp_boxes.W_StringBox', 'unicode_': 'interp_boxes.W_UnicodeBox', 'void': 'interp_boxes.W_VoidBox', 'complexfloating': 'interp_boxes.W_ComplexFloatingBox', 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 @@ -10,6 +10,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rlib import jit from pypy.rlib.rawstorage import free_raw_storage +from pypy.rlib.debug import make_sure_not_resized class ConcreteArrayIterator(base.BaseArrayIterator): def __init__(self, array): @@ -47,7 +48,7 @@ self.skip = array.strides[0] self.dtype = array.dtype self.index = 0 - self.size = array.shape[0] + self.size = array.get_shape()[0] def next(self): self.offset += self.skip @@ -168,7 +169,9 @@ parent = None def get_shape(self): - return self.shape + shape = self.shape + jit.hint(len(shape), promote=True) + return shape def getitem(self, index): return self.dtype.getitem(self, index) @@ -181,7 +184,7 @@ if impl.is_scalar(): self.fill(impl.get_scalar_value()) return - shape = shape_agreement(space, self.shape, arr) + shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: impl = impl.copy() loop.setslice(shape, self, impl) @@ -193,7 +196,7 @@ # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: - new_strides = calc_new_strides(new_shape, self.shape, + new_strides = calc_new_strides(new_shape, self.get_shape(), self.strides, self.order) if new_strides: # We can create a view, strides somehow match up. @@ -216,10 +219,10 @@ raise IndexError idx = int_w(space, w_index) if idx < 0: - idx = self.shape[i] + idx - if idx < 0 or idx >= self.shape[i]: + idx = self.get_shape()[i] + idx + if idx < 0 or idx >= self.get_shape()[i]: raise operationerrfmt(space.w_IndexError, - "index (%d) out of range (0<=index<%d", i, self.shape[i], + "index (%d) out of range (0<=index<%d", i, self.get_shape()[i], ) item += idx * self.strides[i] return item @@ -227,13 +230,14 @@ @jit.unroll_safe def _lookup_by_unwrapped_index(self, space, lst): item = self.start - assert len(lst) == len(self.shape) + shape = self.get_shape() + assert len(lst) == len(shape) for i, idx in enumerate(lst): if idx < 0: - idx = self.shape[i] + idx - if idx < 0 or idx >= self.shape[i]: + idx = shape[i] + idx + if idx < 0 or idx >= shape[i]: raise operationerrfmt(space.w_IndexError, - "index (%d) out of range (0<=index<%d", i, self.shape[i], + "index (%d) out of range (0<=index<%d", i, shape[i], ) item += idx * self.strides[i] return item @@ -255,7 +259,8 @@ raise IndexError if isinstance(w_idx, W_NDimArray): raise ArrayArgumentException - shape_len = len(self.shape) + shape = self.get_shape() + shape_len = len(shape) if shape_len == 0: raise OperationError(space.w_IndexError, space.wrap( "0-d arrays can't be indexed")) @@ -299,7 +304,7 @@ return RecordChunk(idx) if (space.isinstance_w(w_idx, space.w_int) or space.isinstance_w(w_idx, space.w_slice)): - return Chunks([Chunk(*space.decode_index4(w_idx, self.shape[0]))]) + return Chunks([Chunk(*space.decode_index4(w_idx, self.get_shape()[0]))]) elif space.is_w(w_idx, space.w_None): return Chunks([NewAxisChunk()]) result = [] @@ -309,7 +314,7 @@ result.append(NewAxisChunk()) else: result.append(Chunk(*space.decode_index4(w_item, - self.shape[i]))) + self.get_shape()[i]))) i += 1 return Chunks(result) @@ -333,24 +338,24 @@ view.implementation.setslice(space, w_value) def transpose(self): - if len(self.shape) < 2: + if len(self.get_shape()) < 2: return self strides = [] backstrides = [] shape = [] - for i in range(len(self.shape) - 1, -1, -1): + for i in range(len(self.get_shape()) - 1, -1, -1): strides.append(self.strides[i]) backstrides.append(self.backstrides[i]) - shape.append(self.shape[i]) + shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, backstrides, shape, self) def copy(self): - strides, backstrides = support.calc_strides(self.shape, self.dtype, + strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) - impl = ConcreteArray(self.shape, self.dtype, self.order, strides, + impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(self.shape, impl, self) + return loop.setslice(self.get_shape(), impl, self) def create_axis_iter(self, shape, dim): return AxisIterator(self, shape, dim) @@ -361,7 +366,7 @@ return MultiDimViewIterator(self, self.start, r[0], r[1], shape) def swapaxes(self, axis1, axis2): - shape = self.shape[:] + shape = self.get_shape()[:] strides = self.strides[:] backstrides = self.backstrides[:] shape[axis1], shape[axis2] = shape[axis2], shape[axis1] @@ -375,6 +380,9 @@ class ConcreteArray(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides): + make_sure_not_resized(shape) + make_sure_not_resized(strides) + make_sure_not_resized(backstrides) self.shape = shape self.size = support.product(shape) * dtype.get_size() self.storage = dtype.itemtype.malloc(self.size) @@ -383,11 +391,11 @@ self.strides = strides self.backstrides = backstrides - def create_iter(self, shape): - if shape == self.shape: + def create_iter(self, shape=None): + if shape is None or shape == self.get_shape(): return ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.strides, self.backstrides, - self.shape, shape) + self.get_shape(), shape) return MultiDimViewIterator(self, 0, r[0], r[1], shape) def fill(self, box): @@ -420,19 +428,19 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape): - if shape != self.shape: + def create_iter(self, shape=None): + if shape is not None and shape != self.get_shape(): r = calculate_broadcast_strides(self.strides, self.backstrides, - self.shape, shape) + self.get_shape(), shape) return MultiDimViewIterator(self.parent, self.start, r[0], r[1], shape) - if len(self.shape) == 1: + if len(self.get_shape()) == 1: return OneDimViewIterator(self) return MultiDimViewIterator(self.parent, self.start, self.strides, - self.backstrides, self.shape) + self.backstrides, self.get_shape()) def set_shape(self, space, new_shape): - if len(self.shape) < 2 or self.size == 0: + if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor strides = [] @@ -451,7 +459,7 @@ new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, self) - new_strides = calc_new_strides(new_shape, self.shape, self.strides, + new_strides = calc_new_strides(new_shape, self.get_shape(), self.strides, self.order) if new_strides is None: raise OperationError(space.w_AttributeError, space.wrap( 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 @@ -34,7 +34,7 @@ def get_shape(self): return [] - def create_iter(self, shape): + def create_iter(self, shape=None): return ScalarIterator(self.value) def get_scalar_value(self): diff --git a/pypy/module/micronumpy/arrayimpl/voidbox.py b/pypy/module/micronumpy/arrayimpl/voidbox.py --- a/pypy/module/micronumpy/arrayimpl/voidbox.py +++ b/pypy/module/micronumpy/arrayimpl/voidbox.py @@ -6,6 +6,7 @@ def __init__(self, size, dtype): self.storage = alloc_raw_storage(size) self.dtype = dtype + self.size = size def __del__(self): free_raw_storage(self.storage) diff --git a/pypy/module/micronumpy/dot.py b/pypy/module/micronumpy/dot.py --- a/pypy/module/micronumpy/dot.py +++ b/pypy/module/micronumpy/dot.py @@ -11,12 +11,12 @@ right_critical_dim = len(right_shape) - 2 right_critical_dim_size = right_shape[right_critical_dim] assert right_critical_dim >= 0 - out_shape += left_shape[:-1] + \ - right_shape[0:right_critical_dim] + \ - right_shape[right_critical_dim + 1:] + out_shape = out_shape + left_shape[:-1] + \ + right_shape[0:right_critical_dim] + \ + right_shape[right_critical_dim + 1:] elif len(right_shape) > 0: #dot does not reduce for scalars - out_shape += left_shape[:-1] + out_shape = out_shape + left_shape[:-1] if my_critical_dim_size != right_critical_dim_size: raise OperationError(space.w_ValueError, space.wrap( "objects are not aligned")) 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 @@ -246,7 +246,11 @@ except KeyError: raise OperationError(space.w_IndexError, space.wrap("Field %s does not exist" % item)) - return dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + if isinstance (read_val, W_StringBox): + # StringType returns a str + return space.wrap(dtype.itemtype.to_str(read_val)) + return read_val @unwrap_spec(item=str) def descr_setitem(self, space, item, w_value): @@ -271,7 +275,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): from pypy.module.micronumpy.interp_dtype import new_unicode_dtype @@ -474,6 +477,7 @@ W_VoidBox.typedef = TypeDef("void", W_FlexibleBox.typedef, __module__ = "numpypy", + __new__ = interp2app(W_VoidBox.descr__new__.im_func), __getitem__ = interp2app(W_VoidBox.descr_getitem), __setitem__ = interp2app(W_VoidBox.descr_setitem), ) 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 @@ -8,6 +8,7 @@ from pypy.module.micronumpy import types, interp_boxes from pypy.rlib.objectmodel import specialize from pypy.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong +from pypy.rpython.lltypesystem import rffi UNSIGNEDLTR = "u" @@ -17,6 +18,8 @@ VOIDLTR = 'V' STRINGLTR = 'S' UNICODELTR = 'U' +INTPLTR = 'p' +UINTPLTR = 'P' def decode_w_dtype(space, w_dtype): if space.is_none(w_dtype): @@ -66,11 +69,16 @@ def fill(self, storage, box, start, stop): self.itemtype.fill(storage, self.get_size(), box, start, stop, 0) + def get_name(self): + if self.char == 'S': + return '|S' + str(self.get_size()) + return self.name + def descr_str(self, space): - return space.wrap(self.name) + return space.wrap(self.get_name()) def descr_repr(self, space): - return space.wrap("dtype('%s')" % self.name) + return space.wrap("dtype('%s')" % self.get_name()) def descr_get_itemsize(self, space): return space.wrap(self.itemtype.get_element_size()) @@ -135,6 +143,9 @@ def is_record_type(self): return self.fields is not None + def is_flexible_type(self): + return (self.num == 18 or self.num == 19 or self.num == 20) + def __repr__(self): if self.fields is not None: return '' % self.fields @@ -454,6 +465,35 @@ #alternate_constructors=[space.w_buffer], # XXX no buffer in space ) + ptr_size = rffi.sizeof(rffi.CCHARP) + if ptr_size == 4: + intp_box = interp_boxes.W_Int32Box + intp_type = types.Int32() + uintp_box = interp_boxes.W_UInt32Box + uintp_type = types.UInt32() + elif ptr_size == 8: + intp_box = interp_boxes.W_Int64Box + intp_type = types.Int64() + uintp_box = interp_boxes.W_UInt64Box + uintp_type = types.UInt64() + else: + raise ValueError('unknown point size %d' % ptr_size) + self.w_intpdtype = W_Dtype( + intp_type, + num=5, + kind=INTPLTR, + name='intp', + char=INTPLTR, + w_box_type = space.gettypefor(intp_box), + ) + self.w_uintpdtype = W_Dtype( + uintp_type, + num=6, + kind=UINTPLTR, + name='uintp', + char=UINTPLTR, + w_box_type = space.gettypefor(uintp_box), + ) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, @@ -462,7 +502,7 @@ self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, self.w_complex128dtype, self.w_stringdtype, self.w_unicodedtype, - self.w_voiddtype, + self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) @@ -504,7 +544,8 @@ #'CDOUBLE', #'DATETIME', 'UINT': self.w_uint32dtype, - 'INTP': self.w_longdtype, + 'INTP': self.w_intpdtype, + 'UINTP': self.w_uintpdtype, #'HALF', 'BYTE': self.w_int8dtype, #'CFLOAT': , 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 @@ -25,7 +25,7 @@ shape = [] for w_item in space.fixedview(w_size): shape.append(space.int_w(w_item)) - return shape + return shape[:] class __extend__(W_NDimArray): @jit.unroll_safe @@ -190,7 +190,7 @@ return space.call_function(cache.w_array_str, self) def dump_data(self): - i = self.create_iter(self.get_shape()) + i = self.create_iter() first = True dtype = self.get_dtype() s = StringBuilder() @@ -206,8 +206,6 @@ return s.build() def create_iter(self, shape=None): - if shape is None: - shape = self.get_shape() return self.implementation.create_iter(shape) def create_axis_iter(self, shape, dim): @@ -396,7 +394,7 @@ 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()")) - iter = self.create_iter(self.get_shape()) + iter = self.create_iter() return space.wrap(space.is_true(iter.getitem())) def _binop_impl(ufunc_name): @@ -433,9 +431,7 @@ def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): - dtype = interp_ufuncs.find_dtype_for_scalar(space, w_other, - self.get_dtype()) - w_other = W_NDimArray.new_scalar(space, dtype, w_other) + w_other = convert_to_array(space, w_other) return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self, w_out]) return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name) @@ -683,7 +679,7 @@ if ndmin > len(shape): shape = [1] * (ndmin - len(shape)) + shape arr = W_NDimArray.from_shape(shape, dtype, order=order) - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() for w_elem in elems_w: arr_iter.setitem(dtype.coerce(space, w_elem)) arr_iter.next() 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 @@ -150,6 +150,9 @@ "supported for binary functions")) assert isinstance(self, W_Ufunc2) obj = convert_to_array(space, w_obj) + if obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('cannot perform reduce for flexible type')) obj_shape = obj.get_shape() if obj.is_scalar(): return obj.get_scalar_value() @@ -235,6 +238,9 @@ if space.is_w(out, space.w_None): out = None w_obj = convert_to_array(space, w_obj) + if w_obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('Not implemented for this type')) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -301,6 +307,10 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) + if w_lhs.get_dtype().is_flexible_type() or \ + w_rhs.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('unsupported operand types')) calc_dtype = find_binop_result_dtype(space, w_lhs.get_dtype(), w_rhs.get_dtype(), int_only=self.int_only, @@ -413,6 +423,7 @@ return interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] + at jit.unroll_safe def find_unaryop_result_dtype(space, dt, promote_to_float=False, promote_bools=False, promote_to_largest=False, allow_complex=True): if promote_bools and (dt.kind == interp_dtype.BOOLLTR): @@ -446,6 +457,7 @@ int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype complex_type = interp_dtype.get_dtype_cache(space).w_complex128dtype float_type = interp_dtype.get_dtype_cache(space).w_float64dtype + str_dtype = interp_dtype.get_dtype_cache(space).w_stringdtype if isinstance(w_obj, interp_boxes.W_GenericBox): dtype = w_obj.get_dtype(space) if current_guess is None: @@ -472,6 +484,15 @@ current_guess is complex_type or current_guess is float_type): return complex_type return current_guess + elif space.isinstance_w(w_obj, space.w_str): + if (current_guess is None): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + elif current_guess.num ==18: + if current_guess.itemtype.get_size() < space.len_w(w_obj): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + return current_guess if current_guess is complex_type: return complex_type return interp_dtype.get_dtype_cache(space).w_float64dtype 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 @@ -89,7 +89,7 @@ reds = ['obj', 'obj_iter', 'cur_value']) def compute_reduce(obj, calc_dtype, func, done_func, identity): - obj_iter = obj.create_iter(obj.get_shape()) + obj_iter = obj.create_iter() if identity is None: cur_value = obj_iter.getitem().convert_to(calc_dtype) obj_iter.next() @@ -109,7 +109,7 @@ From noreply at buildbot.pypy.org Mon Oct 29 11:07:17 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:07:17 +0100 (CET) Subject: [pypy-commit] pypy default: Fix tests for missing 'itertools'. Message-ID: <20121029100717.AC2EF1C039C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58561:5bdab3fa8259 Date: 2012-10-29 10:49 +0100 http://bitbucket.org/pypy/pypy/changeset/5bdab3fa8259/ Log: Fix tests for missing 'itertools'. diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py --- a/pypy/module/imp/test/test_app.py +++ b/pypy/module/imp/test/test_app.py @@ -3,6 +3,8 @@ class AppTestImpModule: def setup_class(cls): + from pypy.conftest import gettestobjspace + cls.space = gettestobjspace(usemodules=('imp', 'itertools')) cls.w_imp = cls.space.getbuiltinmodule('imp') cls.w_file_module = cls.space.wrap(__file__) 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 @@ -38,7 +38,7 @@ test_reload = "def test():\n raise ValueError\n", infinite_reload = "import infinite_reload; reload(infinite_reload)", del_sys_module = "import sys\ndel sys.modules['del_sys_module']\n", - itertools = "hello_world = 42\n", + _md5 = "hello_world = 42\n", gc = "should_never_be_seen = 42\n", ) root.ensure("notapackage", dir=1) # empty, no __init__.py @@ -148,7 +148,7 @@ class AppTestImport: def setup_class(cls): # interpreter-level - cls.space = gettestobjspace(usemodules=['itertools']) + cls.space = gettestobjspace(usemodules=['_md5']) cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect) cls.saved_modules = _setup(cls.space) #XXX Compile class @@ -597,34 +597,34 @@ def test_shadow_extension_1(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find itertools.py if there is + # 'import _md5' is supposed to find _md5.py if there is # one in sys.path. import sys - assert 'itertools' not in sys.modules - import itertools - assert hasattr(itertools, 'hello_world') - assert not hasattr(itertools, 'count') - assert '(built-in)' not in repr(itertools) - del sys.modules['itertools'] + assert '_md5' not in sys.modules + import _md5 + assert hasattr(_md5, 'hello_world') + assert not hasattr(_md5, 'count') + assert '(built-in)' not in repr(_md5) + del sys.modules['_md5'] def test_shadow_extension_2(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find the built-in module even + # 'import _md5' is supposed to find the built-in module even # if there is also one in sys.path as long as it is *after* the # special entry '.../lib_pypy/__extensions__'. (Note that for now - # there is one in lib_pypy/itertools.py, which should not be seen + # there is one in lib_pypy/_md5.py, which should not be seen # either; hence the (built-in) test below.) import sys - assert 'itertools' not in sys.modules + assert '_md5' not in sys.modules sys.path.append(sys.path.pop(0)) try: - import itertools - assert not hasattr(itertools, 'hello_world') - assert hasattr(itertools, 'izip') - assert '(built-in)' in repr(itertools) + import _md5 + assert not hasattr(_md5, 'hello_world') + assert hasattr(_md5, 'digest_size') + assert '(built-in)' in repr(_md5) finally: sys.path.insert(0, sys.path.pop()) - del sys.modules['itertools'] + del sys.modules['_md5'] def test_invalid_pathname(self): import imp @@ -1005,7 +1005,7 @@ class AppTestImportHooks(object): def setup_class(cls): - space = cls.space = gettestobjspace(usemodules=('struct',)) + space = cls.space = gettestobjspace(usemodules=('struct', 'itertools')) mydir = os.path.dirname(__file__) cls.w_hooktest = space.wrap(os.path.join(mydir, 'hooktest')) space.appexec([space.wrap(mydir)], """ From noreply at buildbot.pypy.org Mon Oct 29 11:07:18 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:07:18 +0100 (CET) Subject: [pypy-commit] pypy default: Fix more tests for missing 'itertools'. Message-ID: <20121029100718.D48F01C039C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58562:d7af40d03ed2 Date: 2012-10-29 10:51 +0100 http://bitbucket.org/pypy/pypy/changeset/d7af40d03ed2/ Log: Fix more tests for missing 'itertools'. diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -10,7 +10,8 @@ class AppTestBufferTooShort: def setup_class(cls): - space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal')) + space = gettestobjspace(usemodules=('_multiprocessing', 'thread', + 'signal', 'itertools')) cls.space = space if option.runappdirect: diff --git a/pypy/module/_multiprocessing/test/test_memory.py b/pypy/module/_multiprocessing/test/test_memory.py --- a/pypy/module/_multiprocessing/test/test_memory.py +++ b/pypy/module/_multiprocessing/test/test_memory.py @@ -3,7 +3,8 @@ class AppTestMemory: def setup_class(cls): space = gettestobjspace( - usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi')) + usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi', + 'itertools')) cls.space = space def test_address_of(self): From noreply at buildbot.pypy.org Mon Oct 29 11:07:19 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:07:19 +0100 (CET) Subject: [pypy-commit] pypy default: Fix more tests for missing 'itertools'. Message-ID: <20121029100719.F03101C039C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58563:7c0e54a3362d Date: 2012-10-29 10:58 +0100 http://bitbucket.org/pypy/pypy/changeset/7c0e54a3362d/ Log: Fix more tests for missing 'itertools'. diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -6,7 +6,7 @@ class AppTestMath: def setup_class(cls): - cls.space = gettestobjspace(usemodules=['math', 'struct']) + cls.space = gettestobjspace(usemodules=['math', 'struct', 'itertools']) cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES) cls.w_consistent_host = cls.space.wrap(test_direct.consistent_host) From noreply at buildbot.pypy.org Mon Oct 29 11:07:21 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:07:21 +0100 (CET) Subject: [pypy-commit] pypy default: Fix more tests for missing 'itertools'. Message-ID: <20121029100721.1A5911C039C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58564:586aaab171d6 Date: 2012-10-29 11:00 +0100 http://bitbucket.org/pypy/pypy/changeset/586aaab171d6/ Log: Fix more tests for missing 'itertools'. diff --git a/pypy/module/cpyext/test/test_import.py b/pypy/module/cpyext/test/test_import.py --- a/pypy/module/cpyext/test/test_import.py +++ b/pypy/module/cpyext/test/test_import.py @@ -4,9 +4,9 @@ class TestImport(BaseApiTest): def test_import(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - assert pdb - assert space.getattr(pdb, space.wrap("pm")) + stat = api.PyImport_Import(space.wrap("stat")) + assert stat + assert space.getattr(stat, space.wrap("S_IMODE")) def test_addmodule(self, space, api): with rffi.scoped_str2charp("sys") as modname: @@ -32,10 +32,10 @@ assert space.is_true(space.contains(w_dict, space.wrap(testmod))) def test_reload(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - space.delattr(pdb, space.wrap("set_trace")) - pdb = api.PyImport_ReloadModule(pdb) - assert space.getattr(pdb, space.wrap("set_trace")) + stat = api.PyImport_Import(space.wrap("stat")) + space.delattr(stat, space.wrap("S_IMODE")) + stat = api.PyImport_ReloadModule(stat) + assert space.getattr(stat, space.wrap("S_IMODE")) class AppTestImportLogic(AppTestCpythonExtensionBase): def test_import_logic(self): From noreply at buildbot.pypy.org Mon Oct 29 11:07:22 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:07:22 +0100 (CET) Subject: [pypy-commit] pypy default: Don't import 'collections' but only '_abcoll' from here. Message-ID: <20121029100722.7D7BF1C039C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58565:51bf893b4bd6 Date: 2012-10-29 11:06 +0100 http://bitbucket.org/pypy/pypy/changeset/51bf893b4bd6/ Log: Don't import 'collections' but only '_abcoll' from here. collections requires itertools. diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py --- a/pypy/module/cpyext/dictobject.py +++ b/pypy/module/cpyext/dictobject.py @@ -198,8 +198,8 @@ @specialize.memo() def make_frozendict(space): return space.appexec([], '''(): - import collections - class FrozenDict(collections.Mapping): + import _abcoll + class FrozenDict(_abcoll.Mapping): def __init__(self, *args, **kwargs): self._d = dict(*args, **kwargs) def __iter__(self): From noreply at buildbot.pypy.org Mon Oct 29 11:20:43 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 11:20:43 +0100 (CET) Subject: [pypy-commit] pypy default: promote lengths of strides and backstrides Message-ID: <20121029102043.192E21C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58566:ccaadf8a5225 Date: 2012-10-29 11:19 +0100 http://bitbucket.org/pypy/pypy/changeset/ccaadf8a5225/ Log: promote lengths of strides and backstrides 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 @@ -45,7 +45,7 @@ def __init__(self, array): self.array = array self.offset = array.start - self.skip = array.strides[0] + self.skip = array.get_strides()[0] self.dtype = array.dtype self.index = 0 self.size = array.get_shape()[0] @@ -116,8 +116,8 @@ class AxisIterator(base.BaseArrayIterator): def __init__(self, array, shape, dim): self.shape = shape - strides = array.strides - backstrides = array.backstrides + strides = array.get_strides() + backstrides = array.get_backstrides() if len(shape) == len(strides): # keepdims = True self.strides = strides[:dim] + [0] + strides[dim + 1:] @@ -167,12 +167,24 @@ class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None + + # JIT hints that length of all those arrays is a constant def get_shape(self): shape = self.shape jit.hint(len(shape), promote=True) return shape + def get_strides(self): + strides = self.strides + jit.hint(len(strides), promote=True) + return strides + + def get_backstrides(self): + backstrides = self.backstrides + jit.hint(len(backstrides), promote=True) + return backstrides + def getitem(self, index): return self.dtype.getitem(self, index) @@ -197,7 +209,7 @@ new_strides = None if self.size > 0: new_strides = calc_new_strides(new_shape, self.get_shape(), - self.strides, self.order) + self.get_strides(), self.order) if new_strides: # We can create a view, strides somehow match up. ndims = len(new_shape) @@ -214,6 +226,7 @@ @jit.unroll_safe def _lookup_by_index(self, space, view_w): item = self.start + strides = self.get_strides() for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError @@ -224,13 +237,14 @@ raise operationerrfmt(space.w_IndexError, "index (%d) out of range (0<=index<%d", i, self.get_shape()[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item @jit.unroll_safe def _lookup_by_unwrapped_index(self, space, lst): item = self.start shape = self.get_shape() + strides = self.get_strides() assert len(lst) == len(shape) for i, idx in enumerate(lst): if idx < 0: @@ -239,7 +253,7 @@ raise operationerrfmt(space.w_IndexError, "index (%d) out of range (0<=index<%d", i, shape[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item def getitem_index(self, space, index): @@ -344,8 +358,8 @@ backstrides = [] shape = [] for i in range(len(self.get_shape()) - 1, -1, -1): - strides.append(self.strides[i]) - backstrides.append(self.backstrides[i]) + strides.append(self.get_strides()[i]) + backstrides.append(self.get_backstrides()[i]) shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, backstrides, shape, self) @@ -361,14 +375,14 @@ return AxisIterator(self, shape, dim) def create_dot_iter(self, shape, skip): - r = calculate_dot_strides(self.strides, self.backstrides, + r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) return MultiDimViewIterator(self, self.start, r[0], r[1], shape) def swapaxes(self, axis1, axis2): shape = self.get_shape()[:] - strides = self.strides[:] - backstrides = self.backstrides[:] + strides = self.get_strides()[:] + backstrides = self.get_backstrides()[:] shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] @@ -394,7 +408,8 @@ def create_iter(self, shape=None): if shape is None or shape == self.get_shape(): return ConcreteArrayIterator(self) - r = calculate_broadcast_strides(self.strides, self.backstrides, + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), self.get_shape(), shape) return MultiDimViewIterator(self, 0, r[0], r[1], shape) @@ -430,14 +445,16 @@ def create_iter(self, shape=None): if shape is not None and shape != self.get_shape(): - r = calculate_broadcast_strides(self.strides, self.backstrides, + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), self.get_shape(), shape) return MultiDimViewIterator(self.parent, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: return OneDimViewIterator(self) - return MultiDimViewIterator(self.parent, self.start, self.strides, - self.backstrides, self.get_shape()) + return MultiDimViewIterator(self.parent, self.start, + self.get_strides(), + self.get_backstrides(), self.get_shape()) def set_shape(self, space, new_shape): if len(self.get_shape()) < 2 or self.size == 0: @@ -446,7 +463,7 @@ strides = [] backstrides = [] dtype = self.dtype - s = self.strides[0] // dtype.get_size() + s = self.get_strides()[0] // dtype.get_size() if self.order == 'C': new_shape.reverse() for sh in new_shape: @@ -459,7 +476,8 @@ new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, self) - new_strides = calc_new_strides(new_shape, self.get_shape(), self.strides, + new_strides = calc_new_strides(new_shape, self.get_shape(), + self.get_strides(), self.order) if new_strides is None: raise OperationError(space.w_AttributeError, space.wrap( 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 @@ -59,8 +59,8 @@ def apply(self, arr): ofs, subdtype = arr.dtype.fields[self.name] # strides backstrides are identical, ofs only changes start - return W_NDimArray.new_slice(arr.start + ofs, arr.strides, - arr.backstrides, + return W_NDimArray.new_slice(arr.start + ofs, arr.get_strides(), + arr.get_backstrides(), arr.shape, arr, subdtype) class Chunks(BaseChunk): @@ -80,8 +80,8 @@ def apply(self, arr): shape = self.extend_shape(arr.shape) - r = calculate_slice_strides(arr.shape, arr.start, arr.strides, - arr.backstrides, self.l) + r = calculate_slice_strides(arr.shape, arr.start, arr.get_strides(), + arr.get_backstrides(), self.l) _, start, strides, backstrides = r return W_NDimArray.new_slice(start, strides[:], backstrides[:], shape[:], arr) From noreply at buildbot.pypy.org Mon Oct 29 11:20:44 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 11:20:44 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20121029102044.57BD91C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58567:ff663b39bd39 Date: 2012-10-29 11:20 +0100 http://bitbucket.org/pypy/pypy/changeset/ff663b39bd39/ Log: merge diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -74,8 +74,11 @@ elif step == 1: length = stop - start if length != len(newstring): - msg = "buffer slice assignment is wrong size" - raise OperationError(space.w_ValueError, space.wrap(msg)) + if length < 0 and len(newstring) == 0: + pass # ok anyway + else: + msg = "right operand length must match slice length" + raise OperationError(space.w_ValueError, space.wrap(msg)) self.setslice(start, newstring) else: raise OperationError(space.w_ValueError, diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -429,15 +429,17 @@ source_start_box = self.get_constant_box(op.getarg(3)) dest_start_box = self.get_constant_box(op.getarg(4)) length = self.get_constant_box(op.getarg(5)) + extrainfo = op.getdescr().get_extra_info() if (source_start_box and dest_start_box and length and (dest_value.is_virtual() or length.getint() <= 8) and - (source_value.is_virtual() or length.getint() <= 8)): + (source_value.is_virtual() or length.getint() <= 8) and + len(extrainfo.write_descrs_arrays) == 1): # <-sanity check from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue source_start = source_start_box.getint() dest_start = dest_start_box.getint() + # XXX fish fish fish + arraydescr = extrainfo.write_descrs_arrays[0] for index in range(length.getint()): - # XXX fish fish fish - arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] if source_value.is_virtual(): assert isinstance(source_value, VArrayValue) val = source_value.getitem(index + source_start) diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -117,6 +117,8 @@ b[:] = '12345' assert a.tostring() == 'hello 12345' raises(IndexError, 'b[5] = "."') + b[4:2] = '' + assert a.tostring() == 'hello 12345' b = buffer(b, 2) assert len(b) == 3 diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,6 +1,7 @@ from pypy.interpreter.error import operationerrfmt from pypy.interpreter.buffer import RWBuffer -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.interpreter.typedef import TypeDef from pypy.rpython.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -34,6 +35,16 @@ for i in range(len(string)): raw_cdata[i] = string[i] +LLBuffer.typedef = TypeDef( + "buffer", + __module__ = "_cffi_backend", + __len__ = interp2app(RWBuffer.descr_len), + __getitem__ = interp2app(RWBuffer.descr_getitem), + __setitem__ = interp2app(RWBuffer.descr_setitem), + __buffer__ = interp2app(RWBuffer.descr__buffer__), + ) +LLBuffer.typedef.acceptable_as_base_class = False + @unwrap_spec(cdata=cdataobj.W_CData, size=int) def buffer(space, cdata, size=-1): 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 @@ -5,8 +5,6 @@ type_or_class = "type" mandatory_b_prefix = '' mandatory_u_prefix = 'u' - readbuf = str - bufchar = lambda x: x bytechr = chr class U(object): def __add__(self, other): @@ -20,11 +18,6 @@ unichr = chr mandatory_b_prefix = 'b' mandatory_u_prefix = '' - readbuf = lambda buf: buf.tobytes() - if sys.version_info < (3, 3): - bufchar = lambda x: bytes([ord(x)]) - else: - bufchar = ord bytechr = lambda n: bytes([n]) u = "" @@ -1811,36 +1804,76 @@ assert (p < s) ^ (p > s) def test_buffer(): + import __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() assert sizeof(BShort) == 2 - assert len(readbuf(buffer(s))) == 2 + assert len(buffer(s)) == 2 # BChar = new_primitive_type("char") BCharArray = new_array_type(new_pointer_type(BChar), None) c = newp(BCharArray, b"hi there") + # buf = buffer(c) - assert readbuf(buf) == b"hi there\x00" + assert str(buf).startswith('<_cffi_backend.buffer object at 0x') + # --mb_length-- assert len(buf) == len(b"hi there\x00") - assert buf[0] == bufchar('h') - assert buf[2] == bufchar(' ') - assert list(buf) == list(map(bufchar, "hi there\x00")) - buf[2] = bufchar('-') - assert c[2] == b'-' - assert readbuf(buf) == b"hi-there\x00" - c[2] = b'!' - assert buf[2] == bufchar('!') - assert readbuf(buf) == b"hi!there\x00" - c[2] = b'-' - buf[:2] = b'HI' - assert string(c) == b'HI-there' - if sys.version_info < (3,) or sys.version_info >= (3, 3): - assert buf[:4:2] == b'H-' - if '__pypy__' not in sys.builtin_module_names: - # XXX pypy doesn't support the following assignment so far - buf[:4:2] = b'XY' - assert string(c) == b'XIYthere' + # --mb_item-- + for i in range(-12, 12): + try: + expected = b"hi there\x00"[i] + except IndexError: + py.test.raises(IndexError, "buf[i]") + else: + assert buf[i] == expected + # --mb_slice-- + assert buf[:] == b"hi there\x00" + for i in range(-12, 12): + assert buf[i:] == b"hi there\x00"[i:] + assert buf[:i] == b"hi there\x00"[:i] + for j in range(-12, 12): + assert buf[i:j] == b"hi there\x00"[i:j] + # --misc-- + assert list(buf) == list(b"hi there\x00") + # --mb_as_buffer-- + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 + py.test.raises(TypeError, memoryview, c) + mv1 = memoryview(buf) + assert len(mv1) == len(buf) and mv1[3] == "t" + # --mb_ass_item-- + expected = list(b"hi there\x00") + for i in range(-12, 12): + try: + expected[i] = chr(i & 0xff) + except IndexError: + py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + else: + buf[i] = chr(i & 0xff) + assert list(buf) == expected + # --mb_ass_slice-- + buf[:] = b"hi there\x00" + assert list(buf) == list(c) == list(b"hi there\x00") + py.test.raises(ValueError, 'buf[:] = b"shorter"') + py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + buf[4:2] = b"" # no effect, but should work + assert buf[:] == b"hi there\x00" + expected = list(b"hi there\x00") + x = 0 + for i in range(-12, 12): + for j in range(-12, 12): + start = i if i >= 0 else i + len(buf) + stop = j if j >= 0 else j + len(buf) + start = max(0, min(len(buf), start)) + stop = max(0, min(len(buf), stop)) + sample = chr(x & 0xff) * (stop - start) + x += 1 + buf[i:j] = sample + expected[i:j] = sample + assert list(buf) == expected def test_getcname(): BUChar = new_primitive_type("unsigned char") diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -10,7 +10,8 @@ class AppTestBufferTooShort: def setup_class(cls): - space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal')) + space = gettestobjspace(usemodules=('_multiprocessing', 'thread', + 'signal', 'itertools')) cls.space = space if option.runappdirect: diff --git a/pypy/module/_multiprocessing/test/test_memory.py b/pypy/module/_multiprocessing/test/test_memory.py --- a/pypy/module/_multiprocessing/test/test_memory.py +++ b/pypy/module/_multiprocessing/test/test_memory.py @@ -3,7 +3,8 @@ class AppTestMemory: def setup_class(cls): space = gettestobjspace( - usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi')) + usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi', + 'itertools')) cls.space = space def test_address_of(self): 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 @@ -357,8 +357,8 @@ buffering = 1024 # minimum amount of compressed data read at once self.buffering = buffering - def close(self): - self.stream.close() + def close1(self, closefileno): + self.stream.close1(closefileno) def tell(self): return self.readlength @@ -479,9 +479,9 @@ self.compressor = W_BZ2Compressor(space, compresslevel) self.writtenlength = 0 - def close(self): + def close1(self, closefileno): self.stream.write(self.space.str_w(self.compressor.flush())) - self.stream.close() + self.stream.close1(closefileno) def write(self, data): self.stream.write(self.space.str_w(self.compressor.compress(data))) diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py --- a/pypy/module/cpyext/dictobject.py +++ b/pypy/module/cpyext/dictobject.py @@ -198,8 +198,8 @@ @specialize.memo() def make_frozendict(space): return space.appexec([], '''(): - import collections - class FrozenDict(collections.Mapping): + import _abcoll + class FrozenDict(_abcoll.Mapping): def __init__(self, *args, **kwargs): self._d = dict(*args, **kwargs) def __iter__(self): diff --git a/pypy/module/cpyext/test/test_import.py b/pypy/module/cpyext/test/test_import.py --- a/pypy/module/cpyext/test/test_import.py +++ b/pypy/module/cpyext/test/test_import.py @@ -4,9 +4,9 @@ class TestImport(BaseApiTest): def test_import(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - assert pdb - assert space.getattr(pdb, space.wrap("pm")) + stat = api.PyImport_Import(space.wrap("stat")) + assert stat + assert space.getattr(stat, space.wrap("S_IMODE")) def test_addmodule(self, space, api): with rffi.scoped_str2charp("sys") as modname: @@ -32,10 +32,10 @@ assert space.is_true(space.contains(w_dict, space.wrap(testmod))) def test_reload(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - space.delattr(pdb, space.wrap("set_trace")) - pdb = api.PyImport_ReloadModule(pdb) - assert space.getattr(pdb, space.wrap("set_trace")) + stat = api.PyImport_Import(space.wrap("stat")) + space.delattr(stat, space.wrap("S_IMODE")) + stat = api.PyImport_ReloadModule(stat) + assert space.getattr(stat, space.wrap("S_IMODE")) class AppTestImportLogic(AppTestCpythonExtensionBase): def test_import_logic(self): diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py --- a/pypy/module/imp/test/test_app.py +++ b/pypy/module/imp/test/test_app.py @@ -3,6 +3,8 @@ class AppTestImpModule: def setup_class(cls): + from pypy.conftest import gettestobjspace + cls.space = gettestobjspace(usemodules=('imp', 'itertools')) cls.w_imp = cls.space.getbuiltinmodule('imp') cls.w_file_module = cls.space.wrap(__file__) 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 @@ -38,7 +38,7 @@ test_reload = "def test():\n raise ValueError\n", infinite_reload = "import infinite_reload; reload(infinite_reload)", del_sys_module = "import sys\ndel sys.modules['del_sys_module']\n", - itertools = "hello_world = 42\n", + _md5 = "hello_world = 42\n", gc = "should_never_be_seen = 42\n", ) root.ensure("notapackage", dir=1) # empty, no __init__.py @@ -148,7 +148,7 @@ class AppTestImport: def setup_class(cls): # interpreter-level - cls.space = gettestobjspace(usemodules=['itertools']) + cls.space = gettestobjspace(usemodules=['_md5']) cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect) cls.saved_modules = _setup(cls.space) #XXX Compile class @@ -597,34 +597,34 @@ def test_shadow_extension_1(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find itertools.py if there is + # 'import _md5' is supposed to find _md5.py if there is # one in sys.path. import sys - assert 'itertools' not in sys.modules - import itertools - assert hasattr(itertools, 'hello_world') - assert not hasattr(itertools, 'count') - assert '(built-in)' not in repr(itertools) - del sys.modules['itertools'] + assert '_md5' not in sys.modules + import _md5 + assert hasattr(_md5, 'hello_world') + assert not hasattr(_md5, 'count') + assert '(built-in)' not in repr(_md5) + del sys.modules['_md5'] def test_shadow_extension_2(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find the built-in module even + # 'import _md5' is supposed to find the built-in module even # if there is also one in sys.path as long as it is *after* the # special entry '.../lib_pypy/__extensions__'. (Note that for now - # there is one in lib_pypy/itertools.py, which should not be seen + # there is one in lib_pypy/_md5.py, which should not be seen # either; hence the (built-in) test below.) import sys - assert 'itertools' not in sys.modules + assert '_md5' not in sys.modules sys.path.append(sys.path.pop(0)) try: - import itertools - assert not hasattr(itertools, 'hello_world') - assert hasattr(itertools, 'izip') - assert '(built-in)' in repr(itertools) + import _md5 + assert not hasattr(_md5, 'hello_world') + assert hasattr(_md5, 'digest_size') + assert '(built-in)' in repr(_md5) finally: sys.path.insert(0, sys.path.pop()) - del sys.modules['itertools'] + del sys.modules['_md5'] def test_invalid_pathname(self): import imp @@ -1005,7 +1005,7 @@ class AppTestImportHooks(object): def setup_class(cls): - space = cls.space = gettestobjspace(usemodules=('struct',)) + space = cls.space = gettestobjspace(usemodules=('struct', 'itertools')) mydir = os.path.dirname(__file__) cls.w_hooktest = space.wrap(os.path.join(mydir, 'hooktest')) space.appexec([space.wrap(mydir)], """ diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -6,7 +6,7 @@ class AppTestMath: def setup_class(cls): - cls.space = gettestobjspace(usemodules=['math', 'struct']) + cls.space = gettestobjspace(usemodules=['math', 'struct', 'itertools']) cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES) cls.w_consistent_host = cls.space.wrap(test_direct.consistent_host) 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 @@ -275,14 +275,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - # Running entire test suite needs this function to succeed, - # running single test_stringarray succeeds without it. - # With convert_to() test_ztranslation fails since - # W_CharacterBox is not a W_GenericBox. - # Why is it needed for multiple tests? - #def convert_to(self, dtype): - # xxx - class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): from pypy.module.micronumpy.interp_dtype import new_unicode_dtype diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -119,6 +119,17 @@ self.size = size or len(digits) self.sign = sign + # __eq__ and __ne__ method exist for testingl only, they are not RPython! + def __eq__(self, other): + # NOT_RPYTHON + if not isinstance(other, rbigint): + return NotImplemented + return self.eq(other) + + def __ne__(self, other): + # NOT_RPYTHON + return not (self == other) + def digit(self, x): """Return the x'th digit, as an int.""" return self._digits[x] diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -1,14 +1,19 @@ from __future__ import division + +import operator +import sys +from random import random, randint, sample + import py -import operator, sys, array -from random import random, randint, sample -from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF -from pypy.rlib.rbigint import _store_digit, _mask_digit -from pypy.rlib.rfloat import NAN + from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask +from pypy.rlib.rbigint import (rbigint, SHIFT, MASK, KARATSUBA_CUTOFF, + _store_digit, _mask_digit) +from pypy.rlib.rfloat import NAN from pypy.rpython.test.test_llinterp import interpret + class TestRLong(object): def test_simple(self): for op1 in [-2, -1, 0, 1, 2, 50]: @@ -112,6 +117,17 @@ rl = rbigint.fromint(sys.maxint).add(rbigint.fromint(42)) assert rl.touint() == result + def test_eq_ne_operators(self): + a1 = rbigint.fromint(12) + a2 = rbigint.fromint(12) + a3 = rbigint.fromint(123) + + assert a1 == a2 + assert a1 != a3 + assert not (a1 != a2) + assert not (a1 == a3) + + def gen_signs(l): for s in l: if s == 0: From noreply at buildbot.pypy.org Mon Oct 29 11:32:27 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:32:27 +0100 (CET) Subject: [pypy-commit] pypy default: one more Message-ID: <20121029103227.225D51C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58568:fcb8710020e8 Date: 2012-10-29 11:07 +0100 http://bitbucket.org/pypy/pypy/changeset/fcb8710020e8/ Log: one more diff --git a/pypy/module/test_lib_pypy/test_itertools.py b/pypy/module/test_lib_pypy/test_itertools.py --- a/pypy/module/test_lib_pypy/test_itertools.py +++ b/pypy/module/test_lib_pypy/test_itertools.py @@ -2,7 +2,7 @@ class AppTestItertools: def setup_class(cls): - cls.space = gettestobjspace() + cls.space = gettestobjspace(usemodules=['itertools']) cls.w_itertools = cls.space.appexec([], "(): import itertools; return itertools") def test_chain(self): From noreply at buildbot.pypy.org Mon Oct 29 11:32:28 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:32:28 +0100 (CET) Subject: [pypy-commit] pypy default: one more Message-ID: <20121029103228.37FD71C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58569:09e65ed74e5b Date: 2012-10-29 11:10 +0100 http://bitbucket.org/pypy/pypy/changeset/09e65ed74e5b/ Log: one more diff --git a/pypy/module/test_lib_pypy/test_pwd.py b/pypy/module/test_lib_pypy/test_pwd.py --- a/pypy/module/test_lib_pypy/test_pwd.py +++ b/pypy/module/test_lib_pypy/test_pwd.py @@ -5,7 +5,8 @@ def setup_class(cls): if sys.platform == 'win32': py.test.skip("Unix only") - cls.space = gettestobjspace(usemodules=('_ffi', '_rawffi')) + cls.space = gettestobjspace(usemodules=('_ffi', '_rawffi', + 'itertools')) cls.space.appexec((), "(): import pwd") def test_getpwuid(self): From noreply at buildbot.pypy.org Mon Oct 29 11:32:29 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:32:29 +0100 (CET) Subject: [pypy-commit] pypy default: Don't import 'collections' but only '_collections' or '_abcoll' from Message-ID: <20121029103229.6706B1C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58570:a049983c8899 Date: 2012-10-29 11:14 +0100 http://bitbucket.org/pypy/pypy/changeset/a049983c8899/ Log: Don't import 'collections' but only '_collections' or '_abcoll' from here. 'collections' imports the world, including itertools. diff --git a/pypy/objspace/std/test/test_iterobject.py b/pypy/objspace/std/test/test_iterobject.py --- a/pypy/objspace/std/test/test_iterobject.py +++ b/pypy/objspace/std/test/test_iterobject.py @@ -68,7 +68,7 @@ raises(TypeError, len, iter(iterable)) def test_no_len_on_deque_iter(self): - from collections import deque + from _collections import deque iterable = deque([1,2,3,4]) raises(TypeError, len, iter(iterable)) @@ -81,15 +81,14 @@ it = reversed([5,6,7]) raises(TypeError, len, it) - def test_no_len_on_UserList_iter(self): + def test_no_len_on_UserList_iter_reversed(self): + import sys, _abcoll + sys.modules['collections'] = _abcoll from UserList import UserList iterable = UserList([1,2,3,4]) raises(TypeError, len, iter(iterable)) - - def test_no_len_on_UserList_reversed(self): - from UserList import UserList - iterable = UserList([1,2,3,4]) raises(TypeError, len, reversed(iterable)) + del sys.modules['collections'] def test_no_len_on_set_iter(self): iterable = set([1,2,3,4]) From noreply at buildbot.pypy.org Mon Oct 29 11:32:30 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:32:30 +0100 (CET) Subject: [pypy-commit] pypy default: two more Message-ID: <20121029103230.7C3401C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58571:62db5979c4e9 Date: 2012-10-29 11:16 +0100 http://bitbucket.org/pypy/pypy/changeset/62db5979c4e9/ Log: two more diff --git a/pypy/module/zipimport/test/test_undocumented.py b/pypy/module/zipimport/test/test_undocumented.py --- a/pypy/module/zipimport/test/test_undocumented.py +++ b/pypy/module/zipimport/test/test_undocumented.py @@ -19,7 +19,8 @@ class AppTestZipImport: def setup_class(cls): - space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct']) + space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct', + 'itertools']) cls.space = space cls.w_created_paths = space.wrap(created_paths) diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -46,11 +46,10 @@ return __file__ """).compile() + usemodules = ['zipimport', 'rctime', 'struct', 'itertools'] if cls.compression == ZIP_DEFLATED: - space = gettestobjspace(usemodules=['zipimport', 'zlib', 'rctime', 'struct']) - else: - space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct']) - + usemodules.append('zlib') + space = gettestobjspace(usemodules=usemodules) cls.space = space tmpdir = udir.ensure('zipimport_%s' % cls.__name__, dir=1) now = time.time() From noreply at buildbot.pypy.org Mon Oct 29 11:32:31 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:32:31 +0100 (CET) Subject: [pypy-commit] pypy default: Move the test to an "expected" place and don't import 'collections' at Message-ID: <20121029103231.8B36A1C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58572:ad81d0ddcc48 Date: 2012-10-29 11:31 +0100 http://bitbucket.org/pypy/pypy/changeset/ad81d0ddcc48/ Log: Move the test to an "expected" place and don't import 'collections' at app-level. diff --git a/pypy/objspace/std/test/test_methodcache.py b/pypy/objspace/std/test/test_methodcache.py --- a/pypy/objspace/std/test/test_methodcache.py +++ b/pypy/objspace/std/test/test_methodcache.py @@ -206,8 +206,3 @@ setattr(a, "a%s" % i, i) cache_counter = __pypy__.method_cache_counter("x") assert cache_counter[0] == 0 # 0 hits, because all the attributes are new - - def test_get_module_from_namedtuple(self): - # this used to crash - from collections import namedtuple - assert namedtuple("a", "b").__module__ diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py --- a/pypy/objspace/std/test/test_typeobject.py +++ b/pypy/objspace/std/test/test_typeobject.py @@ -1063,6 +1063,21 @@ A.__dict__['x'] = 5 assert A.x == 5 + +class AppTestWithMethodCacheCounter: + def setup_class(cls): + cls.space = gettestobjspace( + **{"objspace.std.withmethodcachecounter": True}) + + def test_module_from_handbuilt_type(self): + d = {'tuple': tuple, '__name__': 'foomod'} + exec """class foo(tuple): pass""" in d + t = d['foo'] + t.__module__ = 'barmod' + # this last line used to crash; see ab926f846f39 + assert t.__module__ + + class AppTestMutableBuiltintypes: def setup_class(cls): From noreply at buildbot.pypy.org Mon Oct 29 11:32:32 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 11:32:32 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121029103232.C05841C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58573:c261cc22232d Date: 2012-10-29 11:32 +0100 http://bitbucket.org/pypy/pypy/changeset/c261cc22232d/ Log: merge heads 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 @@ -45,7 +45,7 @@ def __init__(self, array): self.array = array self.offset = array.start - self.skip = array.strides[0] + self.skip = array.get_strides()[0] self.dtype = array.dtype self.index = 0 self.size = array.get_shape()[0] @@ -116,8 +116,8 @@ class AxisIterator(base.BaseArrayIterator): def __init__(self, array, shape, dim): self.shape = shape - strides = array.strides - backstrides = array.backstrides + strides = array.get_strides() + backstrides = array.get_backstrides() if len(shape) == len(strides): # keepdims = True self.strides = strides[:dim] + [0] + strides[dim + 1:] @@ -167,12 +167,24 @@ class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None + + # JIT hints that length of all those arrays is a constant def get_shape(self): shape = self.shape jit.hint(len(shape), promote=True) return shape + def get_strides(self): + strides = self.strides + jit.hint(len(strides), promote=True) + return strides + + def get_backstrides(self): + backstrides = self.backstrides + jit.hint(len(backstrides), promote=True) + return backstrides + def getitem(self, index): return self.dtype.getitem(self, index) @@ -197,7 +209,7 @@ new_strides = None if self.size > 0: new_strides = calc_new_strides(new_shape, self.get_shape(), - self.strides, self.order) + self.get_strides(), self.order) if new_strides: # We can create a view, strides somehow match up. ndims = len(new_shape) @@ -214,6 +226,7 @@ @jit.unroll_safe def _lookup_by_index(self, space, view_w): item = self.start + strides = self.get_strides() for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError @@ -224,13 +237,14 @@ raise operationerrfmt(space.w_IndexError, "index (%d) out of range (0<=index<%d", i, self.get_shape()[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item @jit.unroll_safe def _lookup_by_unwrapped_index(self, space, lst): item = self.start shape = self.get_shape() + strides = self.get_strides() assert len(lst) == len(shape) for i, idx in enumerate(lst): if idx < 0: @@ -239,7 +253,7 @@ raise operationerrfmt(space.w_IndexError, "index (%d) out of range (0<=index<%d", i, shape[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item def getitem_index(self, space, index): @@ -344,8 +358,8 @@ backstrides = [] shape = [] for i in range(len(self.get_shape()) - 1, -1, -1): - strides.append(self.strides[i]) - backstrides.append(self.backstrides[i]) + strides.append(self.get_strides()[i]) + backstrides.append(self.get_backstrides()[i]) shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, backstrides, shape, self) @@ -361,14 +375,14 @@ return AxisIterator(self, shape, dim) def create_dot_iter(self, shape, skip): - r = calculate_dot_strides(self.strides, self.backstrides, + r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) return MultiDimViewIterator(self, self.start, r[0], r[1], shape) def swapaxes(self, axis1, axis2): shape = self.get_shape()[:] - strides = self.strides[:] - backstrides = self.backstrides[:] + strides = self.get_strides()[:] + backstrides = self.get_backstrides()[:] shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] @@ -394,7 +408,8 @@ def create_iter(self, shape=None): if shape is None or shape == self.get_shape(): return ConcreteArrayIterator(self) - r = calculate_broadcast_strides(self.strides, self.backstrides, + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), self.get_shape(), shape) return MultiDimViewIterator(self, 0, r[0], r[1], shape) @@ -430,14 +445,16 @@ def create_iter(self, shape=None): if shape is not None and shape != self.get_shape(): - r = calculate_broadcast_strides(self.strides, self.backstrides, + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), self.get_shape(), shape) return MultiDimViewIterator(self.parent, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: return OneDimViewIterator(self) - return MultiDimViewIterator(self.parent, self.start, self.strides, - self.backstrides, self.get_shape()) + return MultiDimViewIterator(self.parent, self.start, + self.get_strides(), + self.get_backstrides(), self.get_shape()) def set_shape(self, space, new_shape): if len(self.get_shape()) < 2 or self.size == 0: @@ -446,7 +463,7 @@ strides = [] backstrides = [] dtype = self.dtype - s = self.strides[0] // dtype.get_size() + s = self.get_strides()[0] // dtype.get_size() if self.order == 'C': new_shape.reverse() for sh in new_shape: @@ -459,7 +476,8 @@ new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, self) - new_strides = calc_new_strides(new_shape, self.get_shape(), self.strides, + new_strides = calc_new_strides(new_shape, self.get_shape(), + self.get_strides(), self.order) if new_strides is None: raise OperationError(space.w_AttributeError, space.wrap( 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 @@ -59,8 +59,8 @@ def apply(self, arr): ofs, subdtype = arr.dtype.fields[self.name] # strides backstrides are identical, ofs only changes start - return W_NDimArray.new_slice(arr.start + ofs, arr.strides, - arr.backstrides, + return W_NDimArray.new_slice(arr.start + ofs, arr.get_strides(), + arr.get_backstrides(), arr.shape, arr, subdtype) class Chunks(BaseChunk): @@ -80,8 +80,8 @@ def apply(self, arr): shape = self.extend_shape(arr.shape) - r = calculate_slice_strides(arr.shape, arr.start, arr.strides, - arr.backstrides, self.l) + r = calculate_slice_strides(arr.shape, arr.start, arr.get_strides(), + arr.get_backstrides(), self.l) _, start, strides, backstrides = r return W_NDimArray.new_slice(start, strides[:], backstrides[:], shape[:], arr) From noreply at buildbot.pypy.org Mon Oct 29 11:39:24 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 11:39:24 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: byteswap on floats Message-ID: <20121029103924.B93761C0229@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58574:791ffe776736 Date: 2012-10-29 11:39 +0100 http://bitbucket.org/pypy/pypy/changeset/791ffe776736/ Log: byteswap on floats diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py --- a/pypy/rlib/rarithmetic.py +++ b/pypy/rlib/rarithmetic.py @@ -595,10 +595,22 @@ """ Convert little->big endian and the opposite """ from pypy.rpython.lltypesystem import lltype, rffi + from pypy.rlib.longlong2float import longlong2float, float2longlong T = lltype.typeOf(arg) # XXX we cannot do arithmetics on small ints - if isinstance(arg, base_int): + #if isinstance(arg, base_int): + is_float = False + is_single_float = False + if T == lltype.SingleFloat: + T = lltype.Float + arg = rffi.cast(T, arg) + is_single_float = True + if T == lltype.Float: + is_float = True + T = rffi.LONGLONG + arg = float2longlong(arg) + else: arg = widen(arg) if rffi.sizeof(T) == 1: res = arg @@ -622,4 +634,9 @@ (f >> 24) | (g >> 40) | (h >> 56)) else: assert False # unreachable code + if is_float: + res = rffi.cast(rffi.LONGLONG, res) + if is_single_float: + return rffi.cast(lltype.SingleFloat, longlong2float(res)) + return longlong2float(res) return rffi.cast(T, res) diff --git a/pypy/rlib/test/test_rarithmetic.py b/pypy/rlib/test/test_rarithmetic.py --- a/pypy/rlib/test/test_rarithmetic.py +++ b/pypy/rlib/test/test_rarithmetic.py @@ -1,4 +1,5 @@ from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin +from pypy.rpython.test.test_llinterp import interpret from pypy.rlib.rarithmetic import * import sys import py @@ -384,8 +385,14 @@ assert not int_between(1, 1, 1) def test_byteswap(): - from pypy.rpython.lltypesystem import rffi + from pypy.rpython.lltypesystem import rffi, lltype - assert byteswap(rffi.cast(rffi.USHORT, 0x0102)) == 0x0201 - assert byteswap(rffi.cast(rffi.INT, 0x01020304)) == 0x04030201 + assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.USHORT, 0x0102))) == 0x0201 + assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.INT, 0x01020304))) == 0x04030201 assert byteswap(rffi.cast(rffi.ULONGLONG, 0x0102030405060708L)) == 0x0807060504030201L + assert byteswap(rffi.cast(rffi.LONGLONG, 0x0102030405060708L)) == 0x0807060504030201L + assert ((byteswap(2.3) - 1.903598566252326e+185) / 1e185) < 0.000001 + assert (rffi.cast(lltype.Float, byteswap(rffi.cast(lltype.SingleFloat, 2.3))) - 4.173496037651603e-08) < 1e-16 + +def test_byteswap_interpret(): + interpret(test_byteswap, []) From noreply at buildbot.pypy.org Mon Oct 29 12:13:47 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 12:13:47 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: merge default Message-ID: <20121029111347.F18FB1C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58575:635a5238eb34 Date: 2012-10-29 11:48 +0100 http://bitbucket.org/pypy/pypy/changeset/635a5238eb34/ Log: merge default diff too long, truncating to 2000 out of 2412 lines diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,5 +1,5 @@ -from _numpypy import array, ndarray, int_, float_, bool_ #, complex_# , longlong +from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math @@ -200,7 +200,7 @@ typename = "'%s'" % typename lf = '' - if 0: # or issubclass(arr.dtype.type, flexible): + if issubclass(arr.dtype.type, flexible): if arr.dtype.names: typename = "%s" % str(arr.dtype) else: 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 @@ -233,7 +233,7 @@ try: return unicode(line, ENCODING) except UnicodeDecodeError: # bah, silently fall back... - return unicode(line, 'utf-8') + return unicode(line, 'utf-8', 'replace') def get_history_length(self): return self.saved_history_length diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -496,7 +496,7 @@ if iscode: self.__tputs(text) else: - os.write(self.output_fd, text.encode(self.encoding)) + os.write(self.output_fd, text.encode(self.encoding, 'replace')) del self.__buffer[:] def __tputs(self, fmt, prog=delayprog): diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -118,7 +118,7 @@ # 1. find the start of the statement from codeop import compile_command end = None - for start in range(lineno, -1, max(-1, lineno - 10)): + for start in range(lineno, -1, -1): if assertion: line = self.lines[start] # the following lines are not fully tested, change with care @@ -135,9 +135,9 @@ compile_command(trysource) except (SyntaxError, OverflowError, ValueError): continue - + # 2. find the end of the statement - for end in range(lineno+1, min(len(self)+1, lineno + 10)): + for end in range(lineno+1, len(self)+1): trysource = self[start:end] if trysource.isparseable(): return start, end diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -548,7 +548,7 @@ if cell.is_constant(): newcell.const = cell.const cell = newcell - cell.knowntypedata = renamed_knowntypedata + cell.set_knowntypedata(renamed_knowntypedata) cells.append(cell) diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -144,7 +144,7 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key annotator = bk.annotator @@ -168,6 +168,7 @@ bind(obj2, obj1, 0) bind(obj1, obj2, 1) + r.set_knowntypedata(knowntypedata) return r @@ -337,8 +338,7 @@ case = opname in ('gt', 'ge', 'eq') add_knowntypedata(knowntypedata, case, [op.args[0]], SomeInteger(nonneg=True, knowntype=tointtype(int1))) - if knowntypedata: - r.knowntypedata = knowntypedata + r.set_knowntypedata(knowntypedata) # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) @@ -369,8 +369,7 @@ if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) - if ktd: - s.knowntypedata = ktd + s.set_knowntypedata(ktd) return s def and_((boo1, boo2)): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -188,10 +188,10 @@ variables = [op.args[1]] for variable in variables: assert bk.annotator.binding(variable) == s_obj - r.knowntypedata = {} - + knowntypedata = {} if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): - add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) + add_knowntypedata(knowntypedata, True, variables, bk.valueoftype(typ)) + r.set_knowntypedata(knowntypedata) return r # note that this one either needs to be constant, or we will create SomeObject diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -195,6 +195,10 @@ unsigned = False def __init__(self): pass + def set_knowntypedata(self, knowntypedata): + assert not hasattr(self, 'knowntypedata') + if knowntypedata: + self.knowntypedata = knowntypedata class SomeStringOrUnicode(SomeObject): immutable = True diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -76,7 +76,7 @@ s_obj.is_true_behavior(r) bk = getbookkeeper() - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key op = block.operations[i] assert op.opname == "is_true" or op.opname == "nonzero" @@ -86,8 +86,8 @@ if s_obj.can_be_none(): s_nonnone_obj = s_obj.nonnoneify() add_knowntypedata(knowntypedata, True, [arg], s_nonnone_obj) + r.set_knowntypedata(knowntypedata) return r - def nonzero(obj): return obj.is_true() diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -118,7 +118,7 @@ ("translation.gcrootfinder", DEFL_ROOTFINDER_WITHJIT), ("translation.list_comprehension_operations", True)]), ChoiceOption("jit_backend", "choose the backend for the JIT", - ["auto", "x86", "x86-without-sse2", "llvm", 'arm'], + ["auto", "x86", "x86-without-sse2", 'arm'], default="auto", cmdline="--jit-backend"), ChoiceOption("jit_profiler", "integrate profiler support into the JIT", ["off", "oprofile"], 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 @@ -38,6 +38,8 @@ .. branch: numpypy-complex2 Complex dtype support for numpy +.. branch: numpypy-problems +Improve dtypes intp, uintp, void, string and record .. branch: kill-someobject major cleanups including killing some object support diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -74,8 +74,11 @@ elif step == 1: length = stop - start if length != len(newstring): - msg = "buffer slice assignment is wrong size" - raise OperationError(space.w_ValueError, space.wrap(msg)) + if length < 0 and len(newstring) == 0: + pass # ok anyway + else: + msg = "right operand length must match slice length" + raise OperationError(space.w_ValueError, space.wrap(msg)) self.setslice(start, newstring) else: raise OperationError(space.w_ValueError, diff --git a/pypy/jit/backend/detect_cpu.py b/pypy/jit/backend/detect_cpu.py --- a/pypy/jit/backend/detect_cpu.py +++ b/pypy/jit/backend/detect_cpu.py @@ -77,8 +77,6 @@ return "pypy.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "pypy.jit.backend.cli.runner", "CliCPU" - elif backend_name == 'llvm': - return "pypy.jit.backend.llvm.runner", "LLVMCPU" elif backend_name == 'arm': return "pypy.jit.backend.arm.runner", "CPU_ARM" elif backend_name == 'armhf': diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -1,17 +1,17 @@ from pypy.jit.metainterp import jitprof, resume, compile from pypy.jit.metainterp.executor import execute_nonspec -from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF, INT +from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF from pypy.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded, \ ImmutableIntUnbounded, \ IntLowerBound, MININT, MAXINT -from pypy.jit.metainterp.optimizeopt.util import (make_dispatcher_method, - args_dict) +from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method from pypy.jit.metainterp.resoperation import rop, ResOperation, AbstractResOp from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.tool.pairtype import extendabletype -from pypy.rlib.debug import debug_start, debug_stop, debug_print +from pypy.rlib.debug import debug_print from pypy.rlib.objectmodel import specialize + LEVEL_UNKNOWN = '\x00' LEVEL_NONNULL = '\x01' LEVEL_KNOWNCLASS = '\x02' # might also mean KNOWNARRAYDESCR, for arrays @@ -20,6 +20,8 @@ MODE_ARRAY = '\x00' MODE_STR = '\x01' MODE_UNICODE = '\x02' + + class LenBound(object): def __init__(self, mode, descr, bound): self.mode = mode diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -1,8 +1,11 @@ from pypy.jit.codewriter.effectinfo import EffectInfo -from pypy.jit.metainterp.history import ConstInt, make_hashable_int +from pypy.jit.metainterp import compile +from pypy.jit.metainterp.history import (Const, ConstInt, BoxInt, BoxFloat, + BoxPtr, make_hashable_int) from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntBound -from pypy.jit.metainterp.optimizeopt.optimizer import * +from pypy.jit.metainterp.optimizeopt.optimizer import (Optimization, REMOVED, + CONST_0, CONST_1) from pypy.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ResOperation) @@ -426,14 +429,33 @@ source_start_box = self.get_constant_box(op.getarg(3)) dest_start_box = self.get_constant_box(op.getarg(4)) length = self.get_constant_box(op.getarg(5)) - if (source_value.is_virtual() and source_start_box and dest_start_box - and length and (dest_value.is_virtual() or length.getint() <= 8)): + extrainfo = op.getdescr().get_extra_info() + if (source_start_box and dest_start_box + and length and (dest_value.is_virtual() or length.getint() <= 8) and + (source_value.is_virtual() or length.getint() <= 8) and + len(extrainfo.write_descrs_arrays) == 1): # <-sanity check from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue - assert isinstance(source_value, VArrayValue) source_start = source_start_box.getint() dest_start = dest_start_box.getint() + # XXX fish fish fish + arraydescr = extrainfo.write_descrs_arrays[0] for index in range(length.getint()): - val = source_value.getitem(index + source_start) + if source_value.is_virtual(): + assert isinstance(source_value, VArrayValue) + val = source_value.getitem(index + source_start) + else: + if arraydescr.is_array_of_pointers(): + resbox = BoxPtr() + elif arraydescr.is_array_of_floats(): + resbox = BoxFloat() + else: + resbox = BoxInt() + newop = ResOperation(rop.GETARRAYITEM_GC, + [op.getarg(1), + ConstInt(index + source_start)], resbox, + descr=arraydescr) + self.optimizer.propagate_forward(newop) + val = self.getvalue(resbox) if dest_value.is_virtual(): dest_value.setitem(index + dest_start, val) else: @@ -441,7 +463,7 @@ [op.getarg(2), ConstInt(index + dest_start), val.get_key_box()], None, - descr=source_value.arraydescr) + descr=arraydescr) self.emit_operation(newop) return True if length and length.getint() == 0: diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -3239,6 +3239,42 @@ ''' self.optimize_loop(ops, expected) + def test_arraycopy_not_virtual_2(self): + ops = ''' + [p0] + p1 = new_array(3, descr=arraydescr) + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) # removed by the backend + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) # removed by the backend + jump(i0) + ''' + self.optimize_loop(ops, expected) + + def test_arraycopy_not_virtual_3(self): + ops = ''' + [p0, p1] + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0, p1] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) + setarrayitem_gc(p1, 0, i0, descr=arraydescr) + setarrayitem_gc(p1, 1, i1, descr=arraydescr) + setarrayitem_gc(p1, 2, i2, descr=arraydescr) + jump(i0) + ''' + self.optimize_loop(ops, expected) + def test_arraycopy_no_elem(self): """ this was actually observed in the wild """ diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -4,6 +4,7 @@ from pypy.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken from pypy.jit.metainterp.jitexc import JitException from pypy.jit.metainterp.optimize import InvalidLoop +from pypy.rlib.debug import debug_print, debug_start, debug_stop from pypy.jit.metainterp.optimizeopt.optimizer import * from pypy.jit.metainterp.optimizeopt.generalize import KillHugeIntBounds from pypy.jit.metainterp.inliner import Inliner diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py --- a/pypy/jit/metainterp/test/test_list.py +++ b/pypy/jit/metainterp/test/test_list.py @@ -128,6 +128,17 @@ res = self.interp_operations(f, [], listops=True) assert res == 10 + def test_arraycopy_bug(self): + def f(): + l = [1, 2, 3, 4] + l2 = [1, 2, 3, 4] + l[2] = 13 + l2[0:len(l2)] = l[:] + return l2[0] + l2[1] + l2[2] + l2[3] + + res = self.interp_operations(f, [], listops=True) + assert res == f() + def test_arraycopy_full(self): jitdriver = JitDriver(greens = [], reds = ['n']) def f(n): diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -117,6 +117,8 @@ b[:] = '12345' assert a.tostring() == 'hello 12345' raises(IndexError, 'b[5] = "."') + b[4:2] = '' + assert a.tostring() == 'hello 12345' b = buffer(b, 2) assert len(b) == 3 diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,6 +1,7 @@ from pypy.interpreter.error import operationerrfmt from pypy.interpreter.buffer import RWBuffer -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.interpreter.typedef import TypeDef from pypy.rpython.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -34,6 +35,16 @@ for i in range(len(string)): raw_cdata[i] = string[i] +LLBuffer.typedef = TypeDef( + "buffer", + __module__ = "_cffi_backend", + __len__ = interp2app(RWBuffer.descr_len), + __getitem__ = interp2app(RWBuffer.descr_getitem), + __setitem__ = interp2app(RWBuffer.descr_setitem), + __buffer__ = interp2app(RWBuffer.descr__buffer__), + ) +LLBuffer.typedef.acceptable_as_base_class = False + @unwrap_spec(cdata=cdataobj.W_CData, size=int) def buffer(space, cdata, size=-1): diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,9 +4,8 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi, rposix +from pypy.rlib import jit, clibffi, jit_libffi from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -152,9 +151,6 @@ if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') - elif flag == 2: - file = rffi.cast(rffi.CCHARPP, data)[0] - rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -169,27 +165,6 @@ assert isinstance(abi, int) return space.wrap(abi) -rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) - -def prepare_file_call_argument(fileobj): - import os - space = fileobj.space - fileobj.direct_flush() - fd = fileobj.direct_fileno() - if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file has no OS file descriptor")) - try: - fd2 = os.dup(fd) - f = rffi_fdopen(fd2, fileobj.mode) - if not f: - os.close(fd2) - raise OSError(rposix.get_errno(), "fdopen failed") - except OSError, e: - raise wrap_oserror(space, e) - return f - # ____________________________________________________________ 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 @@ -3,9 +3,11 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.rarithmetic import ovfcheck +from pypy.rlib import rposix from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend import cdataobj, misc, ctypeprim @@ -236,6 +238,22 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) + def cast(self, w_ob): + if self.is_file: + value = self.prepare_file(w_ob) + if value: + return cdataobj.W_CData(self.space, value, self) + return W_CTypePtrBase.cast(self, w_ob) + + def prepare_file(self, w_ob): + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = self.space.interpclass_w(w_ob) + if isinstance(ob, W_File): + return prepare_file_argument(self.space, ob) + else: + return lltype.nullptr(rffi.CCHARP.TO) + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or @@ -245,11 +263,8 @@ # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 elif self.is_file: - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc - ob = space.interpclass_w(w_init) - if isinstance(ob, W_File): - result = ctypefunc.prepare_file_call_argument(ob) + result = self.prepare_file(w_init) + if result: rffi.cast(rffi.CCHARPP, cdata)[0] = result return 2 return 0 @@ -303,3 +318,31 @@ else: raise OperationError(space.w_TypeError, space.wrap("expected a 'cdata struct-or-union' object")) + +# ____________________________________________________________ + + +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +class CffiFileObj(object): + _immutable_ = True + def __init__(self, fd, mode): + self.llf = rffi_fdopen(fd, mode) + if not self.llf: + raise OSError(rposix.get_errno(), "fdopen failed") + def close(self): + rffi_fclose(self.llf) + +def prepare_file_argument(space, fileobj): + fileobj.direct_flush() + if fileobj.cffi_fileobj is None: + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + except OSError, e: + raise wrap_oserror(space, e) + return fileobj.cffi_fileobj.llf diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -5,8 +5,6 @@ type_or_class = "type" mandatory_b_prefix = '' mandatory_u_prefix = 'u' - readbuf = str - bufchar = lambda x: x bytechr = chr class U(object): def __add__(self, other): @@ -20,11 +18,6 @@ unichr = chr mandatory_b_prefix = 'b' mandatory_u_prefix = '' - readbuf = lambda buf: buf.tobytes() - if sys.version_info < (3, 3): - bufchar = lambda x: bytes([ord(x)]) - else: - bufchar = ord bytechr = lambda n: bytes([n]) u = "" @@ -1811,36 +1804,76 @@ assert (p < s) ^ (p > s) def test_buffer(): + import __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() assert sizeof(BShort) == 2 - assert len(readbuf(buffer(s))) == 2 + assert len(buffer(s)) == 2 # BChar = new_primitive_type("char") BCharArray = new_array_type(new_pointer_type(BChar), None) c = newp(BCharArray, b"hi there") + # buf = buffer(c) - assert readbuf(buf) == b"hi there\x00" + assert str(buf).startswith('<_cffi_backend.buffer object at 0x') + # --mb_length-- assert len(buf) == len(b"hi there\x00") - assert buf[0] == bufchar('h') - assert buf[2] == bufchar(' ') - assert list(buf) == list(map(bufchar, "hi there\x00")) - buf[2] = bufchar('-') - assert c[2] == b'-' - assert readbuf(buf) == b"hi-there\x00" - c[2] = b'!' - assert buf[2] == bufchar('!') - assert readbuf(buf) == b"hi!there\x00" - c[2] = b'-' - buf[:2] = b'HI' - assert string(c) == b'HI-there' - if sys.version_info < (3,) or sys.version_info >= (3, 3): - assert buf[:4:2] == b'H-' - if '__pypy__' not in sys.builtin_module_names: - # XXX pypy doesn't support the following assignment so far - buf[:4:2] = b'XY' - assert string(c) == b'XIYthere' + # --mb_item-- + for i in range(-12, 12): + try: + expected = b"hi there\x00"[i] + except IndexError: + py.test.raises(IndexError, "buf[i]") + else: + assert buf[i] == expected + # --mb_slice-- + assert buf[:] == b"hi there\x00" + for i in range(-12, 12): + assert buf[i:] == b"hi there\x00"[i:] + assert buf[:i] == b"hi there\x00"[:i] + for j in range(-12, 12): + assert buf[i:j] == b"hi there\x00"[i:j] + # --misc-- + assert list(buf) == list(b"hi there\x00") + # --mb_as_buffer-- + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 + py.test.raises(TypeError, memoryview, c) + mv1 = memoryview(buf) + assert len(mv1) == len(buf) and mv1[3] == "t" + # --mb_ass_item-- + expected = list(b"hi there\x00") + for i in range(-12, 12): + try: + expected[i] = chr(i & 0xff) + except IndexError: + py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + else: + buf[i] = chr(i & 0xff) + assert list(buf) == expected + # --mb_ass_slice-- + buf[:] = b"hi there\x00" + assert list(buf) == list(c) == list(b"hi there\x00") + py.test.raises(ValueError, 'buf[:] = b"shorter"') + py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + buf[4:2] = b"" # no effect, but should work + assert buf[:] == b"hi there\x00" + expected = list(b"hi there\x00") + x = 0 + for i in range(-12, 12): + for j in range(-12, 12): + start = i if i >= 0 else i + len(buf) + stop = j if j >= 0 else j + len(buf) + start = max(0, min(len(buf), start)) + stop = max(0, min(len(buf), stop)) + sample = chr(x & 0xff) * (stop - start) + x += 1 + buf[i:j] = sample + expected[i:j] = sample + assert list(buf) == expected def test_getcname(): BUChar = new_primitive_type("unsigned char") @@ -2264,3 +2297,35 @@ e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " "be a cdata pointer, not file") + +def test_FILE_object(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP,), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fileno = ll.load_function(BFunc2, "fileno") + # + import posix + fdr, fdw = posix.pipe() + fw1 = posix.fdopen(fdw, 'wb', 256) + # + fw1p = cast(BFILEP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p) + assert res >= 0 + res = fileno(fw1p) + assert res == fdw + fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,8 +1,21 @@ from pypy.objspace.fake.checkmodule import checkmodule +from pypy.module._cffi_backend import ctypeptr +from pypy.rpython.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - checkmodule('_cffi_backend') + # prepare_file_argument() is not working without translating the _file + # module too + def dummy_prepare_file_argument(space, fileobj): + return lltype.nullptr(rffi.CCHARP.TO) + old = ctypeptr.prepare_file_argument + try: + ctypeptr.prepare_file_argument = dummy_prepare_file_argument + # + checkmodule('_cffi_backend') + # + finally: + ctypeptr.prepare_file_argument = old diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -32,6 +32,7 @@ encoding = None errors = None fd = -1 + cffi_fileobj = None # pypy/module/_cffi_backend newlines = 0 # Updated when the stream is closed @@ -148,7 +149,14 @@ del openstreams[stream] except KeyError: pass - stream.close() + # close the stream. If cffi_fileobj is None, we close the + # underlying fileno too. Otherwise, we leave that to + # cffi_fileobj.close(). + cffifo = self.cffi_fileobj + self.cffi_fileobj = None + stream.close1(cffifo is None) + if cffifo is not None: + cffifo.close() def direct_fileno(self): self.getstream() # check if the file is still open diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -10,7 +10,8 @@ class AppTestBufferTooShort: def setup_class(cls): - space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal')) + space = gettestobjspace(usemodules=('_multiprocessing', 'thread', + 'signal', 'itertools')) cls.space = space if option.runappdirect: diff --git a/pypy/module/_multiprocessing/test/test_memory.py b/pypy/module/_multiprocessing/test/test_memory.py --- a/pypy/module/_multiprocessing/test/test_memory.py +++ b/pypy/module/_multiprocessing/test/test_memory.py @@ -3,7 +3,8 @@ class AppTestMemory: def setup_class(cls): space = gettestobjspace( - usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi')) + usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi', + 'itertools')) cls.space = space def test_address_of(self): 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 @@ -357,8 +357,8 @@ buffering = 1024 # minimum amount of compressed data read at once self.buffering = buffering - def close(self): - self.stream.close() + def close1(self, closefileno): + self.stream.close1(closefileno) def tell(self): return self.readlength @@ -479,9 +479,9 @@ self.compressor = W_BZ2Compressor(space, compresslevel) self.writtenlength = 0 - def close(self): + def close1(self, closefileno): self.stream.write(self.space.str_w(self.compressor.flush())) - self.stream.close() + self.stream.close1(closefileno) def write(self, data): self.stream.write(self.space.str_w(self.compressor.compress(data))) diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py --- a/pypy/module/cpyext/dictobject.py +++ b/pypy/module/cpyext/dictobject.py @@ -198,8 +198,8 @@ @specialize.memo() def make_frozendict(space): return space.appexec([], '''(): - import collections - class FrozenDict(collections.Mapping): + import _abcoll + class FrozenDict(_abcoll.Mapping): def __init__(self, *args, **kwargs): self._d = dict(*args, **kwargs) def __iter__(self): diff --git a/pypy/module/cpyext/test/test_import.py b/pypy/module/cpyext/test/test_import.py --- a/pypy/module/cpyext/test/test_import.py +++ b/pypy/module/cpyext/test/test_import.py @@ -4,9 +4,9 @@ class TestImport(BaseApiTest): def test_import(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - assert pdb - assert space.getattr(pdb, space.wrap("pm")) + stat = api.PyImport_Import(space.wrap("stat")) + assert stat + assert space.getattr(stat, space.wrap("S_IMODE")) def test_addmodule(self, space, api): with rffi.scoped_str2charp("sys") as modname: @@ -32,10 +32,10 @@ assert space.is_true(space.contains(w_dict, space.wrap(testmod))) def test_reload(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - space.delattr(pdb, space.wrap("set_trace")) - pdb = api.PyImport_ReloadModule(pdb) - assert space.getattr(pdb, space.wrap("set_trace")) + stat = api.PyImport_Import(space.wrap("stat")) + space.delattr(stat, space.wrap("S_IMODE")) + stat = api.PyImport_ReloadModule(stat) + assert space.getattr(stat, space.wrap("S_IMODE")) class AppTestImportLogic(AppTestCpythonExtensionBase): def test_import_logic(self): diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py --- a/pypy/module/imp/test/test_app.py +++ b/pypy/module/imp/test/test_app.py @@ -3,6 +3,8 @@ class AppTestImpModule: def setup_class(cls): + from pypy.conftest import gettestobjspace + cls.space = gettestobjspace(usemodules=('imp', 'itertools')) cls.w_imp = cls.space.getbuiltinmodule('imp') cls.w_file_module = cls.space.wrap(__file__) 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 @@ -38,7 +38,7 @@ test_reload = "def test():\n raise ValueError\n", infinite_reload = "import infinite_reload; reload(infinite_reload)", del_sys_module = "import sys\ndel sys.modules['del_sys_module']\n", - itertools = "hello_world = 42\n", + _md5 = "hello_world = 42\n", gc = "should_never_be_seen = 42\n", ) root.ensure("notapackage", dir=1) # empty, no __init__.py @@ -148,7 +148,7 @@ class AppTestImport: def setup_class(cls): # interpreter-level - cls.space = gettestobjspace(usemodules=['itertools']) + cls.space = gettestobjspace(usemodules=['_md5']) cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect) cls.saved_modules = _setup(cls.space) #XXX Compile class @@ -597,34 +597,34 @@ def test_shadow_extension_1(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find itertools.py if there is + # 'import _md5' is supposed to find _md5.py if there is # one in sys.path. import sys - assert 'itertools' not in sys.modules - import itertools - assert hasattr(itertools, 'hello_world') - assert not hasattr(itertools, 'count') - assert '(built-in)' not in repr(itertools) - del sys.modules['itertools'] + assert '_md5' not in sys.modules + import _md5 + assert hasattr(_md5, 'hello_world') + assert not hasattr(_md5, 'count') + assert '(built-in)' not in repr(_md5) + del sys.modules['_md5'] def test_shadow_extension_2(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find the built-in module even + # 'import _md5' is supposed to find the built-in module even # if there is also one in sys.path as long as it is *after* the # special entry '.../lib_pypy/__extensions__'. (Note that for now - # there is one in lib_pypy/itertools.py, which should not be seen + # there is one in lib_pypy/_md5.py, which should not be seen # either; hence the (built-in) test below.) import sys - assert 'itertools' not in sys.modules + assert '_md5' not in sys.modules sys.path.append(sys.path.pop(0)) try: - import itertools - assert not hasattr(itertools, 'hello_world') - assert hasattr(itertools, 'izip') - assert '(built-in)' in repr(itertools) + import _md5 + assert not hasattr(_md5, 'hello_world') + assert hasattr(_md5, 'digest_size') + assert '(built-in)' in repr(_md5) finally: sys.path.insert(0, sys.path.pop()) - del sys.modules['itertools'] + del sys.modules['_md5'] def test_invalid_pathname(self): import imp @@ -1005,7 +1005,7 @@ class AppTestImportHooks(object): def setup_class(cls): - space = cls.space = gettestobjspace(usemodules=('struct',)) + space = cls.space = gettestobjspace(usemodules=('struct', 'itertools')) mydir = os.path.dirname(__file__) cls.w_hooktest = space.wrap(os.path.join(mydir, 'hooktest')) space.appexec([space.wrap(mydir)], """ diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -6,7 +6,7 @@ class AppTestMath: def setup_class(cls): - cls.space = gettestobjspace(usemodules=['math', 'struct']) + cls.space = gettestobjspace(usemodules=['math', 'struct', 'itertools']) cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES) cls.w_consistent_host = cls.space.wrap(test_direct.consistent_host) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -62,6 +62,7 @@ 'flexible': 'interp_boxes.W_FlexibleBox', 'character': 'interp_boxes.W_CharacterBox', 'str_': 'interp_boxes.W_StringBox', + 'string_': 'interp_boxes.W_StringBox', 'unicode_': 'interp_boxes.W_UnicodeBox', 'void': 'interp_boxes.W_VoidBox', 'complexfloating': 'interp_boxes.W_ComplexFloatingBox', diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -11,6 +11,7 @@ from pypy.rlib import jit from pypy.rlib.rawstorage import free_raw_storage from pypy.module.micronumpy.arrayimpl.sort import argsort_array +from pypy.rlib.debug import make_sure_not_resized def int_w(space, w_obj): try: @@ -21,9 +22,23 @@ class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None + + # JIT hints that length of all those arrays is a constant def get_shape(self): - return self.shape + shape = self.shape + jit.hint(len(shape), promote=True) + return shape + + def get_strides(self): + strides = self.strides + jit.hint(len(strides), promote=True) + return strides + + def get_backstrides(self): + backstrides = self.backstrides + jit.hint(len(backstrides), promote=True) + return backstrides def getitem(self, index): return self.dtype.getitem(self, index) @@ -36,7 +51,7 @@ if impl.is_scalar(): self.fill(impl.get_scalar_value()) return - shape = shape_agreement(space, self.shape, arr) + shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: impl = impl.copy() loop.setslice(shape, self, impl) @@ -48,8 +63,8 @@ # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: - new_strides = calc_new_strides(new_shape, self.shape, - self.strides, self.order) + new_strides = calc_new_strides(new_shape, self.get_shape(), + self.get_strides(), self.order) if new_strides: # We can create a view, strides somehow match up. ndims = len(new_shape) @@ -66,31 +81,34 @@ @jit.unroll_safe def _lookup_by_index(self, space, view_w): item = self.start + strides = self.get_strides() for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError idx = int_w(space, w_index) if idx < 0: - idx = self.shape[i] + idx - if idx < 0 or idx >= self.shape[i]: + idx = self.get_shape()[i] + idx + if idx < 0 or idx >= self.get_shape()[i]: raise operationerrfmt(space.w_IndexError, - "index (%d) out of range (0<=index<%d", i, self.shape[i], + "index (%d) out of range (0<=index<%d", i, self.get_shape()[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item @jit.unroll_safe def _lookup_by_unwrapped_index(self, space, lst): item = self.start - assert len(lst) == len(self.shape) + shape = self.get_shape() + strides = self.get_strides() + assert len(lst) == len(shape) for i, idx in enumerate(lst): if idx < 0: - idx = self.shape[i] + idx - if idx < 0 or idx >= self.shape[i]: + idx = shape[i] + idx + if idx < 0 or idx >= shape[i]: raise operationerrfmt(space.w_IndexError, - "index (%d) out of range (0<=index<%d", i, self.shape[i], + "index (%d) out of range (0<=index<%d", i, shape[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item def getitem_index(self, space, index): @@ -110,7 +128,8 @@ raise IndexError if isinstance(w_idx, W_NDimArray): raise ArrayArgumentException - shape_len = len(self.shape) + shape = self.get_shape() + shape_len = len(shape) if shape_len == 0: raise OperationError(space.w_IndexError, space.wrap( "0-d arrays can't be indexed")) @@ -154,7 +173,7 @@ return RecordChunk(idx) if (space.isinstance_w(w_idx, space.w_int) or space.isinstance_w(w_idx, space.w_slice)): - return Chunks([Chunk(*space.decode_index4(w_idx, self.shape[0]))]) + return Chunks([Chunk(*space.decode_index4(w_idx, self.get_shape()[0]))]) elif space.is_w(w_idx, space.w_None): return Chunks([NewAxisChunk()]) result = [] @@ -164,7 +183,7 @@ result.append(NewAxisChunk()) else: result.append(Chunk(*space.decode_index4(w_item, - self.shape[i]))) + self.get_shape()[i]))) i += 1 return Chunks(result) @@ -188,37 +207,37 @@ view.implementation.setslice(space, w_value) def transpose(self, orig_array): - if len(self.shape) < 2: + if len(self.get_shape()) < 2: return self strides = [] backstrides = [] shape = [] - for i in range(len(self.shape) - 1, -1, -1): - strides.append(self.strides[i]) - backstrides.append(self.backstrides[i]) - shape.append(self.shape[i]) + for i in range(len(self.get_shape()) - 1, -1, -1): + strides.append(self.get_strides()[i]) + backstrides.append(self.get_backstrides()[i]) + shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, backstrides, shape, self, orig_array) def copy(self): - strides, backstrides = support.calc_strides(self.shape, self.dtype, + strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) - impl = ConcreteArray(self.shape, self.dtype, self.order, strides, + impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(self.shape, impl, self) + return loop.setslice(self.get_shape(), impl, self) def create_axis_iter(self, shape, dim): return iter.AxisIterator(self, shape, dim) def create_dot_iter(self, shape, skip): - r = calculate_dot_strides(self.strides, self.backstrides, + r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) return iter.MultiDimViewIterator(self, self.start, r[0], r[1], shape) def swapaxes(self, orig_arr, axis1, axis2): - shape = self.shape[:] - strides = self.strides[:] - backstrides = self.backstrides[:] + shape = self.get_shape()[:] + strides = self.get_strides()[:] + backstrides = self.get_backstrides()[:] shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] @@ -233,6 +252,9 @@ class ConcreteArray(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides): + make_sure_not_resized(shape) + make_sure_not_resized(strides) + make_sure_not_resized(backstrides) self.shape = shape self.size = support.product(shape) * dtype.get_size() self.storage = dtype.itemtype.malloc(self.size) @@ -241,11 +263,12 @@ self.strides = strides self.backstrides = backstrides - def create_iter(self, shape): - if shape == self.shape: + def create_iter(self, shape=None): + if shape is None or shape == self.get_shape(): return iter.ConcreteArrayIterator(self) - r = calculate_broadcast_strides(self.strides, self.backstrides, - self.shape, shape) + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), + self.get_shape(), shape) return iter.MultiDimViewIterator(self, 0, r[0], r[1], shape) def fill(self, box): @@ -295,25 +318,27 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape): - if shape != self.shape: - r = calculate_broadcast_strides(self.strides, self.backstrides, - self.shape, shape) + def create_iter(self, shape=None): + if shape is not None and shape != self.get_shape(): + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), + self.get_shape(), shape) return iter.MultiDimViewIterator(self.parent, - self.start, r[0], r[1], shape) - if len(self.shape) == 1: + self.start, r[0], r[1], shape) + if len(self.get_shape()) == 1: return iter.OneDimViewIterator(self) - return iter.MultiDimViewIterator(self.parent, self.start, self.strides, - self.backstrides, self.shape) + return iter.MultiDimViewIterator(self.parent, self.start, + self.get_strides(), + self.get_backstrides(), self.get_shape()) def set_shape(self, space, orig_array, new_shape): - if len(self.shape) < 2 or self.size == 0: + if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor strides = [] backstrides = [] dtype = self.dtype - s = self.strides[0] // dtype.get_size() + s = self.get_strides()[0] // dtype.get_size() if self.order == 'C': new_shape.reverse() for sh in new_shape: @@ -326,7 +351,8 @@ new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, self, orig_array) - new_strides = calc_new_strides(new_shape, self.shape, self.strides, + new_strides = calc_new_strides(new_shape, self.get_shape(), + self.get_strides(), self.order) if new_strides is None: raise OperationError(space.w_AttributeError, space.wrap( 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 @@ -34,7 +34,7 @@ def get_shape(self): return [] - def create_iter(self, shape): + def create_iter(self, shape=None): return ScalarIterator(self.value) def get_scalar_value(self): diff --git a/pypy/module/micronumpy/arrayimpl/voidbox.py b/pypy/module/micronumpy/arrayimpl/voidbox.py --- a/pypy/module/micronumpy/arrayimpl/voidbox.py +++ b/pypy/module/micronumpy/arrayimpl/voidbox.py @@ -6,6 +6,7 @@ def __init__(self, size, dtype): self.storage = alloc_raw_storage(size) self.dtype = dtype + self.size = size def __del__(self): free_raw_storage(self.storage) diff --git a/pypy/module/micronumpy/dot.py b/pypy/module/micronumpy/dot.py --- a/pypy/module/micronumpy/dot.py +++ b/pypy/module/micronumpy/dot.py @@ -11,12 +11,12 @@ right_critical_dim = len(right_shape) - 2 right_critical_dim_size = right_shape[right_critical_dim] assert right_critical_dim >= 0 - out_shape += left_shape[:-1] + \ - right_shape[0:right_critical_dim] + \ - right_shape[right_critical_dim + 1:] + out_shape = out_shape + left_shape[:-1] + \ + right_shape[0:right_critical_dim] + \ + right_shape[right_critical_dim + 1:] elif len(right_shape) > 0: #dot does not reduce for scalars - out_shape += left_shape[:-1] + out_shape = out_shape + left_shape[:-1] if my_critical_dim_size != right_critical_dim_size: raise OperationError(space.w_ValueError, space.wrap( "objects are not aligned")) 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 @@ -246,7 +246,11 @@ except KeyError: raise OperationError(space.w_IndexError, space.wrap("Field %s does not exist" % item)) - return dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + if isinstance (read_val, W_StringBox): + # StringType returns a str + return space.wrap(dtype.itemtype.to_str(read_val)) + return read_val @unwrap_spec(item=str) def descr_setitem(self, space, item, w_value): @@ -271,7 +275,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): from pypy.module.micronumpy.interp_dtype import new_unicode_dtype @@ -474,6 +477,7 @@ W_VoidBox.typedef = TypeDef("void", W_FlexibleBox.typedef, __module__ = "numpypy", + __new__ = interp2app(W_VoidBox.descr__new__.im_func), __getitem__ = interp2app(W_VoidBox.descr_getitem), __setitem__ = interp2app(W_VoidBox.descr_setitem), ) 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 @@ -8,6 +8,7 @@ from pypy.module.micronumpy import types, interp_boxes from pypy.rlib.objectmodel import specialize from pypy.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong +from pypy.rpython.lltypesystem import rffi UNSIGNEDLTR = "u" @@ -17,6 +18,8 @@ VOIDLTR = 'V' STRINGLTR = 'S' UNICODELTR = 'U' +INTPLTR = 'p' +UINTPLTR = 'P' def decode_w_dtype(space, w_dtype): if space.is_none(w_dtype): @@ -66,11 +69,16 @@ def fill(self, storage, box, start, stop): self.itemtype.fill(storage, self.get_size(), box, start, stop, 0) + def get_name(self): + if self.char == 'S': + return '|S' + str(self.get_size()) + return self.name + def descr_str(self, space): - return space.wrap(self.name) + return space.wrap(self.get_name()) def descr_repr(self, space): - return space.wrap("dtype('%s')" % self.name) + return space.wrap("dtype('%s')" % self.get_name()) def descr_get_itemsize(self, space): return space.wrap(self.itemtype.get_element_size()) @@ -135,6 +143,9 @@ def is_record_type(self): return self.fields is not None + def is_flexible_type(self): + return (self.num == 18 or self.num == 19 or self.num == 20) + def __repr__(self): if self.fields is not None: return '' % self.fields @@ -455,6 +466,35 @@ #alternate_constructors=[space.w_buffer], # XXX no buffer in space ) + ptr_size = rffi.sizeof(rffi.CCHARP) + if ptr_size == 4: + intp_box = interp_boxes.W_Int32Box + intp_type = types.Int32() + uintp_box = interp_boxes.W_UInt32Box + uintp_type = types.UInt32() + elif ptr_size == 8: + intp_box = interp_boxes.W_Int64Box + intp_type = types.Int64() + uintp_box = interp_boxes.W_UInt64Box + uintp_type = types.UInt64() + else: + raise ValueError('unknown point size %d' % ptr_size) + self.w_intpdtype = W_Dtype( + intp_type, + num=5, + kind=INTPLTR, + name='intp', + char=INTPLTR, + w_box_type = space.gettypefor(intp_box), + ) + self.w_uintpdtype = W_Dtype( + uintp_type, + num=6, + kind=UINTPLTR, + name='uintp', + char=UINTPLTR, + w_box_type = space.gettypefor(uintp_box), + ) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, @@ -463,7 +503,7 @@ self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, self.w_complex128dtype, self.w_stringdtype, self.w_unicodedtype, - self.w_voiddtype, + self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) @@ -505,7 +545,8 @@ #'CDOUBLE', #'DATETIME', 'UINT': self.w_uint32dtype, - 'INTP': self.w_longdtype, + 'INTP': self.w_intpdtype, + 'UINTP': self.w_uintpdtype, #'HALF', 'BYTE': self.w_int8dtype, #'CFLOAT': , 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 @@ -25,7 +25,7 @@ shape = [] for w_item in space.fixedview(w_size): shape.append(space.int_w(w_item)) - return shape + return shape[:] class __extend__(W_NDimArray): @jit.unroll_safe @@ -190,7 +190,7 @@ return space.call_function(cache.w_array_str, self) def dump_data(self): - i = self.create_iter(self.get_shape()) + i = self.create_iter() first = True dtype = self.get_dtype() s = StringBuilder() @@ -206,8 +206,6 @@ return s.build() def create_iter(self, shape=None): - if shape is None: - shape = self.get_shape() return self.implementation.create_iter(shape) def create_axis_iter(self, shape, dim): @@ -544,7 +542,7 @@ 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()")) - iter = self.create_iter(self.get_shape()) + iter = self.create_iter() return space.wrap(space.is_true(iter.getitem())) def _binop_impl(ufunc_name): @@ -833,7 +831,7 @@ if ndmin > len(shape): shape = [1] * (ndmin - len(shape)) + shape arr = W_NDimArray.from_shape(shape, dtype, order=order) - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() for w_elem in elems_w: arr_iter.setitem(dtype.coerce(space, w_elem)) arr_iter.next() 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 @@ -150,6 +150,9 @@ "supported for binary functions")) assert isinstance(self, W_Ufunc2) obj = convert_to_array(space, w_obj) + if obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('cannot perform reduce for flexible type')) obj_shape = obj.get_shape() if obj.is_scalar(): return obj.get_scalar_value() @@ -235,6 +238,9 @@ if space.is_w(out, space.w_None): out = None w_obj = convert_to_array(space, w_obj) + if w_obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('Not implemented for this type')) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -301,6 +307,10 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) + if w_lhs.get_dtype().is_flexible_type() or \ + w_rhs.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('unsupported operand types')) calc_dtype = find_binop_result_dtype(space, w_lhs.get_dtype(), w_rhs.get_dtype(), int_only=self.int_only, @@ -413,6 +423,7 @@ return interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] + at jit.unroll_safe def find_unaryop_result_dtype(space, dt, promote_to_float=False, promote_bools=False, promote_to_largest=False, allow_complex=True): if promote_bools and (dt.kind == interp_dtype.BOOLLTR): @@ -446,6 +457,7 @@ int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype complex_type = interp_dtype.get_dtype_cache(space).w_complex128dtype float_type = interp_dtype.get_dtype_cache(space).w_float64dtype + str_dtype = interp_dtype.get_dtype_cache(space).w_stringdtype if isinstance(w_obj, interp_boxes.W_GenericBox): dtype = w_obj.get_dtype(space) if current_guess is None: @@ -472,6 +484,15 @@ current_guess is complex_type or current_guess is float_type): return complex_type return current_guess + elif space.isinstance_w(w_obj, space.w_str): + if (current_guess is None): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + elif current_guess.num ==18: + if current_guess.itemtype.get_size() < space.len_w(w_obj): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + return current_guess if current_guess is complex_type: return complex_type return interp_dtype.get_dtype_cache(space).w_float64dtype 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 @@ -61,8 +61,8 @@ arr = orig_arr.implementation ofs, subdtype = arr.dtype.fields[self.name] # strides backstrides are identical, ofs only changes start - return W_NDimArray.new_slice(arr.start + ofs, arr.strides, - arr.backstrides, + return W_NDimArray.new_slice(arr.start + ofs, arr.get_strides(), + arr.get_backstrides(), arr.shape, arr, orig_arr, subdtype) class Chunks(BaseChunk): @@ -83,8 +83,8 @@ def apply(self, orig_arr): arr = orig_arr.implementation shape = self.extend_shape(arr.shape) - r = calculate_slice_strides(arr.shape, arr.start, arr.strides, - arr.backstrides, self.l) + r = calculate_slice_strides(arr.shape, arr.start, arr.get_strides(), + arr.get_backstrides(), self.l) _, start, strides, backstrides = r return W_NDimArray.new_slice(start, strides[:], backstrides[:], shape[:], arr, orig_arr) diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py --- a/pypy/module/micronumpy/loop.py +++ b/pypy/module/micronumpy/loop.py @@ -90,7 +90,7 @@ reds = ['obj', 'obj_iter', 'cur_value']) def compute_reduce(obj, calc_dtype, func, done_func, identity): - obj_iter = obj.create_iter(obj.get_shape()) + obj_iter = obj.create_iter() if identity is None: cur_value = obj_iter.getitem().convert_to(calc_dtype) obj_iter.next() @@ -110,7 +110,7 @@ return cur_value def fill(arr, box): - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() while not arr_iter.done(): arr_iter.setitem(box) arr_iter.next() @@ -160,7 +160,7 @@ def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): out_iter = out.create_axis_iter(arr.get_shape(), axis) - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() if identity is not None: identity = identity.convert_to(dtype) shapelen = len(shape) @@ -193,7 +193,7 @@ result = 0 idx = 1 dtype = arr.get_dtype() - iter = arr.create_iter(arr.get_shape()) + iter = arr.create_iter() cur_best = iter.getitem() iter.next() shapelen = len(arr.get_shape()) diff --git a/pypy/module/micronumpy/stdobjspace.py b/pypy/module/micronumpy/stdobjspace.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/stdobjspace.py @@ -0,0 +1,11 @@ + +from pypy.objspace.std import stringobject +from pypy.module.micronumpy import interp_boxes + +def delegate_stringbox2stringobj(space, w_box): + return space.wrap(w_box.dtype.itemtype.to_str(w_box)) + +def register_delegates(typeorder): + typeorder[interp_boxes.W_StringBox] = [ + (stringobject.W_StringObject, delegate_stringbox2stringobj), + ] diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -15,16 +15,22 @@ jit.isconstant(len(chunks)) ) def calculate_slice_strides(shape, start, strides, backstrides, chunks): - rstrides = [] - rbackstrides = [] + size = 0 + for chunk in chunks: + if chunk.step != 0: + size += 1 + rstrides = [0] * size + rbackstrides = [0] * size rstart = start - rshape = [] + rshape = [0] * size i = -1 + j = 0 for i, chunk in enumerate_chunks(chunks): if chunk.step != 0: - rstrides.append(strides[i] * chunk.step) - rbackstrides.append(strides[i] * (chunk.lgt - 1) * chunk.step) - rshape.append(chunk.lgt) + rstrides[j] = strides[i] * chunk.step + rbackstrides[j] = strides[i] * (chunk.lgt - 1) * chunk.step + rshape[j] = chunk.lgt + j += 1 rstart += strides[i] * chunk.start # add a reminder s = i + 1 @@ -64,13 +70,13 @@ while True: new_batch = [] if not batch: - return shape, [] + return shape[:], [] if is_single_elem(space, batch[0], is_rec_type): for w_elem in batch: if not is_single_elem(space, w_elem, is_rec_type): raise OperationError(space.w_ValueError, space.wrap( "setting an array element with a sequence")) - return shape, batch + return shape[:], batch size = space.len_w(batch[0]) for w_elem in batch: if (is_single_elem(space, w_elem, is_rec_type) or @@ -255,19 +261,19 @@ cur_step = steps[oldI] n_old_elems_to_use *= old_shape[oldI] assert len(new_strides) == len(new_shape) - return new_strides + return new_strides[:] def calculate_dot_strides(strides, backstrides, res_shape, skip_dims): - rstrides = [] - rbackstrides = [] - j=0 + rstrides = [0] * len(res_shape) + rbackstrides = [0] * len(res_shape) + j = 0 for i in range(len(res_shape)): if i in skip_dims: - rstrides.append(0) - rbackstrides.append(0) + rstrides[i] = 0 + rbackstrides[i] = 0 else: - rstrides.append(strides[j]) - rbackstrides.append(backstrides[j]) + rstrides[i] = strides[j] + rbackstrides[i] = backstrides[j] j += 1 return rstrides, rbackstrides 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 @@ -31,6 +31,8 @@ from _numpypy import dtype assert dtype(bool).num == 0 + assert dtype('intp').num == 5 + assert dtype('uintp').num == 6 assert dtype(int).num == 7 assert dtype(long).num == 9 assert dtype(float).num == 12 @@ -176,10 +178,15 @@ def test_cant_subclass(self): from _numpypy import dtype - # You can't subclass dtype raises(TypeError, type, "Foo", (dtype,), {}) + def test_can_subclass(self): + import _numpypy + class xyz(_numpypy.void): + pass + assert True + def test_aliases(self): from _numpypy import dtype @@ -228,6 +235,17 @@ class AppTestTypes(BaseNumpyAppTest): + def setup_class(cls): + BaseNumpyAppTest.setup_class.im_func(cls) + if option.runappdirect: + import platform + bits, linkage = platform.architecture() + ptr_size = int(bits[:-3]) // 8 + else: + from pypy.rpython.lltypesystem import rffi + ptr_size = rffi.sizeof(rffi.CCHARP) + cls.w_ptr_size = cls.space.wrap(ptr_size) + def test_abstract_types(self): import _numpypy as numpy raises(TypeError, numpy.generic, 0) @@ -269,7 +287,9 @@ def test_int8(self): import _numpypy as numpy - assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, object] a = numpy.array([1, 2, 3], numpy.int8) assert type(a[1]) is numpy.int8 @@ -291,7 +311,9 @@ def test_uint8(self): import _numpypy as numpy - assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, + numpy.integer, numpy.number, + numpy.generic, object] a = numpy.array([1, 2, 3], numpy.uint8) assert type(a[1]) is numpy.uint8 @@ -361,16 +383,22 @@ import _numpypy as numpy assert numpy.int_ is numpy.dtype(int).type - assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, int, object] + assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, int, object] def test_int64(self): import sys import _numpypy as numpy if sys.maxint == 2 ** 63 -1: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, int, object] + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, int, object] else: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, object] assert numpy.dtype(numpy.int64).type is numpy.int64 assert numpy.int64(3) == 3 @@ -385,7 +413,9 @@ import sys import _numpypy as numpy - assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, + numpy.integer, numpy.number, + numpy.generic, object] assert numpy.dtype(numpy.uint64).type is numpy.uint64 skip("see comment") @@ -400,7 +430,9 @@ def test_float32(self): import _numpypy as numpy - assert numpy.float32.mro() == [numpy.float32, numpy.floating, numpy.inexact, numpy.number, numpy.generic, object] + assert numpy.float32.mro() == [numpy.float32, numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, object] assert numpy.float32(12) == numpy.float64(12) assert numpy.float32('23.4') == numpy.float32(23.4) @@ -409,7 +441,9 @@ def test_float64(self): import _numpypy as numpy - assert numpy.float64.mro() == [numpy.float64, numpy.floating, numpy.inexact, numpy.number, numpy.generic, float, object] + assert numpy.float64.mro() == [numpy.float64, numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, float, object] a = numpy.array([1, 2, 3], numpy.float64) assert type(a[1]) is numpy.float64 @@ -508,15 +542,16 @@ def test_various_types(self): import _numpypy as numpy - import sys assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte assert numpy.bool_ is numpy.bool8 - if sys.maxint == (1 << 63) - 1: - assert '%r' % numpy.intp == '%r' % numpy.int64 - else: - assert '%r' % numpy.intp == '%r' % numpy.int32 + if self.ptr_size == 4: + assert numpy.intp is numpy.int32 + assert numpy.uintp is numpy.uint32 + elif self.ptr_size == 8: + assert numpy.intp is numpy.int64 + assert numpy.uintp is numpy.uint64 def test_mro(self): import _numpypy as numpy @@ -562,6 +597,11 @@ assert dtype('=i8').byteorder == '=' assert dtype(byteorder + 'i8').byteorder == '=' + def test_intp(self): + from _numpypy import dtype + assert dtype('p') == dtype('intp') + assert dtype('P') == dtype('uintp') + def test_alignment(self): from _numpypy import dtype assert dtype('i4').alignment == 4 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 @@ -344,6 +344,13 @@ assert a[-1] == 8 raises(IndexError, "a[-6]") + def test_getitem_float(self): + from _numpypy import array + a = array([1, 2, 3, 4]) + assert a[1.2] == 2 + assert a[1.6] == 2 + assert a[-1.2] == 4 + def test_getitem_tuple(self): from _numpypy import array a = array(range(5)) @@ -2282,7 +2289,49 @@ assert arr[1]['y']['y'] == 3.5 assert arr[1]['y']['x'] == 0.0 assert arr[1]['x'] == 15 - + + def test_string_record(self): + from _numpypy import dtype, array + d = dtype([('x', str), ('y', 'int32')]) + assert d.fields['x'] == (dtype(str), 0) + assert d.fields['y'] == (dtype('int32'), 1) + d = dtype([('x', 'S1'), ('y', 'int32')]) + assert d.fields['x'] == (dtype(str), 0) + assert d.fields['y'] == (dtype('int32'), 1) + a = array([('a', 2), ('c', 1)], dtype=d) + assert a[1]['y'] == 1 + assert a[0]['x'] == 'a' + + def test_stringarray(self): + from _numpypy import array, flexible + a = array(['abc'],'S3') + assert str(a.dtype) == '|S3' + a = array(['abc']) + assert str(a.dtype) == '|S3' + a = array(['abc','defg','ab']) + assert str(a.dtype) == '|S4' + assert a[0] == 'abc' + assert a[1] == 'defg' + assert a[2] == 'ab' + raises(TypeError, a, 'sum') + raises(TypeError, 'a+a') + + def test_flexible_repr(self): + # import overrides str(), repr() for array + from numpypy.core import arrayprint + from _numpypy import array + a = array(['abc'],'S3') + s = repr(a) + # simplify test for \n in repr + assert s.replace('\n', '') == "array(['abc'], dtype='|S3')" + # but make sure it exists + assert s.find('\n') == 15 + a = array(['abc','defg','ab']) + s = repr(a) + assert s.replace('\n', '') == \ + "array(['abc', 'defg', 'ab'], dtype='|S4')" + + class AppTestPyPy(BaseNumpyAppTest): def setup_class(cls): if option.runappdirect and '__pypy__' not in sys.builtin_module_names: 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 @@ -16,6 +16,7 @@ from pypy.rlib.rstruct.runpack import runpack from pypy.tool.sourcetools import func_with_new_name from pypy.rlib import jit +from pypy.rlib.rstring import StringBuilder degToRad = math.pi / 180.0 @@ -1467,9 +1468,53 @@ def get_element_size(self): return self.size * rffi.sizeof(self.T) + def get_size(self): + return self.size + class StringType(BaseType, BaseStringType): T = lltype.Char + @jit.unroll_safe + def coerce(self, space, dtype, w_item): + from pypy.module.micronumpy.interp_dtype import new_string_dtype + arg = space.str_w(space.str(w_item)) + arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) + for i in range(len(arg)): + arr.storage[i] = arg[i] + return interp_boxes.W_StringBox(arr, 0, None) + + @jit.unroll_safe + def store(self, arr, i, offset, box): + assert isinstance(box, interp_boxes.W_StringBox) + for k in range(min(self.size, box.arr.size-offset)): + arr.storage[k + i] = box.arr.storage[k + offset] + + def read(self, arr, i, offset, dtype=None): + if dtype is None: + dtype = arr.dtype + return interp_boxes.W_StringBox(arr, i + offset, dtype) + + @jit.unroll_safe + def to_str(self, item): + builder = StringBuilder() + assert isinstance(item, interp_boxes.W_StringBox) + i = item.ofs + end = i+self.size + while i < end: + assert isinstance(item.arr.storage[i], str) + if item.arr.storage[i] == '\x00': + break + builder.append(item.arr.storage[i]) + i += 1 + return builder.build() + + def str_format(self, item): + builder = StringBuilder() + builder.append("'") + builder.append(self.to_str(item)) + builder.append("'") + return builder.build() + class VoidType(BaseType, BaseStringType): T = lltype.Char 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 From noreply at buildbot.pypy.org Mon Oct 29 12:13:49 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 12:13:49 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: improve singlefloat byteswap Message-ID: <20121029111349.458401C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58576:49ce76217456 Date: 2012-10-29 12:03 +0100 http://bitbucket.org/pypy/pypy/changeset/49ce76217456/ Log: improve singlefloat byteswap diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py --- a/pypy/rlib/rarithmetic.py +++ b/pypy/rlib/rarithmetic.py @@ -533,6 +533,9 @@ def __ne__(self, other): return not self.__eq__(other) + def __repr__(self): + return 'r_singlefloat(%s)' % (float(self),) + class r_longfloat(object): """A value of the C type 'long double'. @@ -595,22 +598,22 @@ """ Convert little->big endian and the opposite """ from pypy.rpython.lltypesystem import lltype, rffi - from pypy.rlib.longlong2float import longlong2float, float2longlong + from pypy.rlib.longlong2float import longlong2float, float2longlong,\ + uint2singlefloat, singlefloat2uint T = lltype.typeOf(arg) - # XXX we cannot do arithmetics on small ints - #if isinstance(arg, base_int): is_float = False is_single_float = False if T == lltype.SingleFloat: - T = lltype.Float - arg = rffi.cast(T, arg) + T = rffi.UINT is_single_float = True - if T == lltype.Float: + arg = singlefloat2uint(arg) + elif T == lltype.Float: is_float = True T = rffi.LONGLONG arg = float2longlong(arg) else: + # we cannot do arithmetics on small ints arg = widen(arg) if rffi.sizeof(T) == 1: res = arg @@ -634,9 +637,9 @@ (f >> 24) | (g >> 40) | (h >> 56)) else: assert False # unreachable code + if is_single_float: + return uint2singlefloat(rffi.cast(rffi.UINT, res)) if is_float: res = rffi.cast(rffi.LONGLONG, res) - if is_single_float: - return rffi.cast(lltype.SingleFloat, longlong2float(res)) return longlong2float(res) return rffi.cast(T, res) From noreply at buildbot.pypy.org Mon Oct 29 12:13:50 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 12:13:50 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: implement non-native floats Message-ID: <20121029111350.702191C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58577:2c7822df923e Date: 2012-10-29 12:03 +0100 http://bitbucket.org/pypy/pypy/changeset/2c7822df923e/ Log: implement non-native floats 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 @@ -391,9 +391,16 @@ def descr_get_base(self, space): return self.implementation.base() - def descr_byteswap(self, space, w_inplace=False): - raise OperationError(space.w_NotImplementedError, space.wrap( - "byteswap not implemented yet")) + @unwrap_spec(inplace=bool) + def descr_byteswap(self, space, inplace=False): + raise OperationError(space.w_NotImplementedError, space.wrap("not impl")) + if inplace: + loop.byteswap(self.implementation, self.implementation) + return self + else: + res = W_NDimArray.from_shape(self.get_shape(), self.get_dtype()) + loop.byteswap(self.implementation, res.implementation) + return res def descr_choose(self, space, w_choices, w_out=None, w_mode='raise'): raise OperationError(space.w_NotImplementedError, space.wrap( 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 @@ -684,9 +684,10 @@ else: assert stor2[1] == '\x01' assert stor2[0] == '\x00' - cls.w_check_non_native = cls.space.wrap(interp2app(check_non_native)) if option.runappdirect: - py.test.skip("not a direct test") + cls.w_check_non_native = lambda *args : None + else: + cls.w_check_non_native = cls.space.wrap(interp2app(check_non_native)) def test_non_native(self): from _numpypy import array @@ -694,6 +695,12 @@ assert a[0] == 1 assert (a + a)[1] == 4 self.check_non_native(a, array([1, 2, 3], 'i2')) + a = array([1, 2, 3], dtype=self.non_native_prefix + 'f8') + assert a[0] == 1 + assert (a + a)[1] == 4 + a = array([1, 2, 3], dtype=self.non_native_prefix + 'f4') + assert a[0] == 1 + assert (a + a)[1] == 4 class AppTestPyPyOnly(BaseNumpyAppTest): def setup_class(cls): 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 @@ -1591,6 +1591,10 @@ b = a[::2] assert b.base is a + def test_byteswap(self): + from _numpypy import array + xxx + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import _numpypy 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 @@ -910,16 +910,14 @@ def _read(self, storage, i, offset): res = raw_storage_getitem(self.T, storage, i + offset) - #return byteswap(res) XXX - return res + return rffi.cast(lltype.Float, byteswap(res)) def _write(self, storage, i, offset, value): - #value = byteswap(value) XXX - raw_storage_setitem(storage, i + offset, value) + swapped_value = byteswap(rffi.cast(self.T, value)) + raw_storage_setitem(storage, i + offset, swapped_value) def pack_str(self, box): - # XXX byteswap - return struct.pack(self.format_code, self.unbox(box)) + return struct.pack(self.format_code, byteswap(self.unbox(box))) class Float32(BaseType, Float): From noreply at buildbot.pypy.org Mon Oct 29 12:13:51 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 12:13:51 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: implement byteswap Message-ID: <20121029111351.8E0CA1C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58578:864533f972b6 Date: 2012-10-29 12:13 +0100 http://bitbucket.org/pypy/pypy/changeset/864533f972b6/ Log: implement byteswap 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 @@ -35,6 +35,9 @@ def convert_to(self, dtype): return dtype.box(self.value) + def __repr__(self): + return '%s(%s)' % (self.__class__.__name__, self.value) + class ComplexBox(object): _mixin_ = True 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 @@ -393,7 +393,6 @@ @unwrap_spec(inplace=bool) def descr_byteswap(self, space, inplace=False): - raise OperationError(space.w_NotImplementedError, space.wrap("not impl")) if inplace: loop.byteswap(self.implementation, self.implementation) return self @@ -796,6 +795,7 @@ argsort = interp2app(W_NDimArray.descr_argsort), astype = interp2app(W_NDimArray.descr_astype), base = GetSetProperty(W_NDimArray.descr_get_base), + byteswap = interp2app(W_NDimArray.descr_byteswap), __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) 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 @@ -464,8 +464,8 @@ reds = ['from_iter', 'to_iter']) def copy_from_to(from_, to, dtype): - from_iter = from_.create_iter(from_.get_shape()) - to_iter = to.create_iter(to.get_shape()) + from_iter = from_.create_iter() + to_iter = to.create_iter() while not from_iter.done(): copy_from_to_driver.jit_merge_point(dtype=dtype, from_iter=from_iter, to_iter=to_iter) @@ -473,3 +473,16 @@ to_iter.next() from_iter.next() +byteswap_driver = jit.JitDriver(greens = ['dtype'], + reds = ['from_iter', 'to_iter']) + +def byteswap(from_, to): + dtype = from_.dtype + from_iter = from_.create_iter() + to_iter = to.create_iter() + while not from_iter.done(): + byteswap_driver.jit_merge_point(dtype=dtype, from_iter=from_iter, + to_iter=to_iter) + to_iter.setitem(dtype.itemtype.byteswap(from_iter.getitem())) + to_iter.next() + from_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 @@ -1593,7 +1593,11 @@ def test_byteswap(self): from _numpypy import array - xxx + a = array([1, 256 + 2, 3], dtype='i2') + assert (a.byteswap() == [0x0100, 0x0201, 0x0300]).all() + assert (a == [1, 256 + 2, 3]).all() + assert (a.byteswap(True) == [0x0100, 0x0201, 0x0300]).all() + assert (a == [0x0100, 0x0201, 0x0300]).all() class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -204,6 +204,10 @@ def neg(self, v): return -v + def byteswap(self, w_v): + # no for_computation here + return self.box(byteswap(self.unbox(w_v))) + @simple_unary_op def conj(self, v): return v From noreply at buildbot.pypy.org Mon Oct 29 12:19:30 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 12:19:30 +0100 (CET) Subject: [pypy-commit] pypy default: shape agreement is unroll_safe Message-ID: <20121029111930.4247D1C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58579:5188e5070566 Date: 2012-10-29 12:17 +0100 http://bitbucket.org/pypy/pypy/changeset/5188e5070566/ Log: shape agreement is unroll_safe diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -110,6 +110,7 @@ i //= shape[s] return coords, step, lngth + at jit.unroll_safe def shape_agreement(space, shape1, w_arr2, broadcast_down=True): if w_arr2 is None: return shape1 From noreply at buildbot.pypy.org Mon Oct 29 12:19:31 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 12:19:31 +0100 (CET) Subject: [pypy-commit] pypy default: calc_strides too Message-ID: <20121029111931.7CE9A1C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58580:4acbbf8a634b Date: 2012-10-29 12:19 +0100 http://bitbucket.org/pypy/pypy/changeset/4acbbf8a634b/ Log: calc_strides too diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py --- a/pypy/module/micronumpy/support.py +++ b/pypy/module/micronumpy/support.py @@ -8,6 +8,7 @@ i *= x return i + at jit.unroll_safe def calc_strides(shape, dtype, order): strides = [] backstrides = [] From noreply at buildbot.pypy.org Mon Oct 29 12:19:32 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 12:19:32 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20121029111932.A43211C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58581:e5c85f97583f Date: 2012-10-29 12:19 +0100 http://bitbucket.org/pypy/pypy/changeset/e5c85f97583f/ Log: merge diff --git a/pypy/module/test_lib_pypy/test_itertools.py b/pypy/module/test_lib_pypy/test_itertools.py --- a/pypy/module/test_lib_pypy/test_itertools.py +++ b/pypy/module/test_lib_pypy/test_itertools.py @@ -2,7 +2,7 @@ class AppTestItertools: def setup_class(cls): - cls.space = gettestobjspace() + cls.space = gettestobjspace(usemodules=['itertools']) cls.w_itertools = cls.space.appexec([], "(): import itertools; return itertools") def test_chain(self): diff --git a/pypy/module/test_lib_pypy/test_pwd.py b/pypy/module/test_lib_pypy/test_pwd.py --- a/pypy/module/test_lib_pypy/test_pwd.py +++ b/pypy/module/test_lib_pypy/test_pwd.py @@ -5,7 +5,8 @@ def setup_class(cls): if sys.platform == 'win32': py.test.skip("Unix only") - cls.space = gettestobjspace(usemodules=('_ffi', '_rawffi')) + cls.space = gettestobjspace(usemodules=('_ffi', '_rawffi', + 'itertools')) cls.space.appexec((), "(): import pwd") def test_getpwuid(self): diff --git a/pypy/module/zipimport/test/test_undocumented.py b/pypy/module/zipimport/test/test_undocumented.py --- a/pypy/module/zipimport/test/test_undocumented.py +++ b/pypy/module/zipimport/test/test_undocumented.py @@ -19,7 +19,8 @@ class AppTestZipImport: def setup_class(cls): - space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct']) + space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct', + 'itertools']) cls.space = space cls.w_created_paths = space.wrap(created_paths) diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -46,11 +46,10 @@ return __file__ """).compile() + usemodules = ['zipimport', 'rctime', 'struct', 'itertools'] if cls.compression == ZIP_DEFLATED: - space = gettestobjspace(usemodules=['zipimport', 'zlib', 'rctime', 'struct']) - else: - space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct']) - + usemodules.append('zlib') + space = gettestobjspace(usemodules=usemodules) cls.space = space tmpdir = udir.ensure('zipimport_%s' % cls.__name__, dir=1) now = time.time() diff --git a/pypy/objspace/std/test/test_iterobject.py b/pypy/objspace/std/test/test_iterobject.py --- a/pypy/objspace/std/test/test_iterobject.py +++ b/pypy/objspace/std/test/test_iterobject.py @@ -68,7 +68,7 @@ raises(TypeError, len, iter(iterable)) def test_no_len_on_deque_iter(self): - from collections import deque + from _collections import deque iterable = deque([1,2,3,4]) raises(TypeError, len, iter(iterable)) @@ -81,15 +81,14 @@ it = reversed([5,6,7]) raises(TypeError, len, it) - def test_no_len_on_UserList_iter(self): + def test_no_len_on_UserList_iter_reversed(self): + import sys, _abcoll + sys.modules['collections'] = _abcoll from UserList import UserList iterable = UserList([1,2,3,4]) raises(TypeError, len, iter(iterable)) - - def test_no_len_on_UserList_reversed(self): - from UserList import UserList - iterable = UserList([1,2,3,4]) raises(TypeError, len, reversed(iterable)) + del sys.modules['collections'] def test_no_len_on_set_iter(self): iterable = set([1,2,3,4]) diff --git a/pypy/objspace/std/test/test_methodcache.py b/pypy/objspace/std/test/test_methodcache.py --- a/pypy/objspace/std/test/test_methodcache.py +++ b/pypy/objspace/std/test/test_methodcache.py @@ -206,8 +206,3 @@ setattr(a, "a%s" % i, i) cache_counter = __pypy__.method_cache_counter("x") assert cache_counter[0] == 0 # 0 hits, because all the attributes are new - - def test_get_module_from_namedtuple(self): - # this used to crash - from collections import namedtuple - assert namedtuple("a", "b").__module__ diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py --- a/pypy/objspace/std/test/test_typeobject.py +++ b/pypy/objspace/std/test/test_typeobject.py @@ -1063,6 +1063,21 @@ A.__dict__['x'] = 5 assert A.x == 5 + +class AppTestWithMethodCacheCounter: + def setup_class(cls): + cls.space = gettestobjspace( + **{"objspace.std.withmethodcachecounter": True}) + + def test_module_from_handbuilt_type(self): + d = {'tuple': tuple, '__name__': 'foomod'} + exec """class foo(tuple): pass""" in d + t = d['foo'] + t.__module__ = 'barmod' + # this last line used to crash; see ab926f846f39 + assert t.__module__ + + class AppTestMutableBuiltintypes: def setup_class(cls): From noreply at buildbot.pypy.org Mon Oct 29 13:10:28 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 13:10:28 +0100 (CET) Subject: [pypy-commit] pypy default: oops missed that one Message-ID: <20121029121028.576681C03BA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58582:5893044643da Date: 2012-10-29 13:10 +0100 http://bitbucket.org/pypy/pypy/changeset/5893044643da/ Log: oops missed that one diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -133,6 +133,7 @@ ) return ret + at jit.unroll_safe def _shape_agreement(shape1, shape2): """ Checks agreement about two shapes with respect to broadcasting. Returns the resulting shape. From noreply at buildbot.pypy.org Mon Oct 29 14:07:10 2012 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 29 Oct 2012 14:07:10 +0100 (CET) Subject: [pypy-commit] buildbot default: further increase the timeout for translated tests Message-ID: <20121029130710.AEBF81C0185@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r714:167c1d7fb744 Date: 2012-10-29 11:12 +0100 http://bitbucket.org/pypy/buildbot/changeset/167c1d7fb744/ Log: further increase the timeout for translated tests diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -314,7 +314,7 @@ command=prefix + ["python", "testrunner/runner.py", "--logfile=pytest-A.log", "--config=pypy/pytest-A.cfg", - "--root=pypy", "--timeout=1800" + "--root=pypy", "--timeout=3600" ] + ["--config=%s" % cfg for cfg in app_tests], logfiles={'pytestLog': 'pytest-A.log'}, timeout=4000, @@ -325,7 +325,7 @@ description="lib-python test", command=prefix + ["python", "pypy/test_all.py", "--pypy=pypy/translator/goal/pypy-c", - "--timeout=1800", + "--timeout=3600", "--resultlog=cpython.log", "lib-python"], timeout=4000, logfiles={'pytestLog': 'cpython.log'})) From noreply at buildbot.pypy.org Mon Oct 29 14:59:25 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 14:59:25 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: write choose tests Message-ID: <20121029135925.893411C0229@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58583:1c008cc37599 Date: 2012-10-29 14:32 +0100 http://bitbucket.org/pypy/pypy/changeset/1c008cc37599/ Log: write choose tests 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 @@ -401,7 +401,8 @@ loop.byteswap(self.implementation, res.implementation) return res - def descr_choose(self, space, w_choices, w_out=None, w_mode='raise'): + @unwrap_spec(mode=str) + def descr_choose(self, space, w_choices, w_out=None, mode='raise'): raise OperationError(space.w_NotImplementedError, space.wrap( "choose not implemented yet")) @@ -792,10 +793,11 @@ real = GetSetProperty(W_NDimArray.descr_get_real), imag = GetSetProperty(W_NDimArray.descr_get_imag), - argsort = interp2app(W_NDimArray.descr_argsort), - astype = interp2app(W_NDimArray.descr_astype), - base = GetSetProperty(W_NDimArray.descr_get_base), + argsort = interp2app(W_NDimArray.descr_argsort), + astype = interp2app(W_NDimArray.descr_astype), + base = GetSetProperty(W_NDimArray.descr_get_base), byteswap = interp2app(W_NDimArray.descr_byteswap), + choose = interp2app(W_NDimArray.descr_choose), __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -83,3 +83,33 @@ assert c == 12.0 c = array(3.0).dot(array(4)) assert c == 12.0 + + def test_choose_basic(self): + from _numpypy import array + a, b, c = array([1, 2, 3]), array([4, 5, 6]), array([7, 8, 9]) + r = array([2, 1, 0]).choose([a, b, c]) + assert (r == [7, 5, 3]).all() + + def test_choose_broadcast(self): + from _numpypy import array + a, b, c = array([1, 2, 3]), [4, 5, 6], 13 + r = array([2, 1, 0]).choose([a, b, c]) + assert (r == [13, 5, 3]).all() + + def test_choose_out(self): + from _numpypy import array + a, b, c = array([1, 2, 3]), [4, 5, 6], 13 + r = array([2, 1, 0]).choose([a, b, c], out=a) + assert (r == [13, 5, 3]).all() + assert (a == [13, 5, 3]).all() + + def test_choose_modes(self): + from _numpypy import array + a, b, c = array([1, 2, 3]), [4, 5, 6], 13 + raises(ValueError, "array([3, 1, 0]).choose([a, b, c])") + raises(ValueError, "array([3, 1, 0]).choose([a, b, c], 'raises')") + r = array([4, 1, 0]).choose([a, b, c], mode='clip') + assert (r == [13, 5, 3]).all() + r = array([4, 1, 0]).choose([a, b, c], mode='wrap') + assert (r == [4, 5, 3]).all() + From noreply at buildbot.pypy.org Mon Oct 29 14:59:26 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 14:59:26 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: implement ndarray.choose Message-ID: <20121029135926.A66131C0229@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58584:47b57e79e2fa Date: 2012-10-29 14:59 +0100 http://bitbucket.org/pypy/pypy/changeset/47b57e79e2fa/ Log: implement ndarray.choose 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 @@ -13,12 +13,6 @@ from pypy.module.micronumpy.arrayimpl.sort import argsort_array from pypy.rlib.debug import make_sure_not_resized -def int_w(space, w_obj): - try: - return space.int_w(space.index(w_obj)) - except OperationError: - return space.int_w(space.int(w_obj)) - class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None @@ -85,7 +79,7 @@ for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError - idx = int_w(space, w_index) + idx = support.int_w(space, w_index) if idx < 0: idx = self.get_shape()[i] + idx if idx < 0 or idx >= self.get_shape()[i]: @@ -159,7 +153,7 @@ return self._lookup_by_index(space, view_w) if shape_len > 1: raise IndexError - idx = int_w(space, w_idx) + idx = support.int_w(space, w_idx) return self._lookup_by_index(space, [space.wrap(idx)]) @jit.unroll_safe diff --git a/pypy/module/micronumpy/constants.py b/pypy/module/micronumpy/constants.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/constants.py @@ -0,0 +1,4 @@ + +MODE_WRAP, MODE_RAISE, MODE_CLIP = range(3) + +MODES = {'wrap': MODE_WRAP, 'raise': MODE_RAISE, 'clip': MODE_CLIP} diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -3,6 +3,7 @@ from pypy.module.micronumpy import loop, interp_ufuncs from pypy.module.micronumpy.iter import Chunk, Chunks from pypy.module.micronumpy.strides import shape_agreement +from pypy.module.micronumpy.constants import MODES from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec @@ -153,3 +154,28 @@ def count_nonzero(space, w_obj): return space.wrap(loop.count_all_true(convert_to_array(space, w_obj))) + +def choose(space, arr, w_choices, out, mode): + choices = [convert_to_array(space, w_item) for w_item + in space.listview(w_choices)] + if not choices: + raise OperationError(space.w_ValueError, + space.wrap("choices list cannot be empty")) + # find the shape agreement + shape = arr.get_shape() + for choice in choices: + shape = shape_agreement(space, shape, choice) + if out is not None: + shape = shape_agreement(space, shape, out) + # find the correct dtype + dtype = choices[0].get_dtype() + for choice in choices[1:]: + dtype = interp_ufuncs.find_binop_result_dtype(space, + dtype, choice.get_dtype()) + if out is None: + out = W_NDimArray.from_shape(shape, dtype) + if mode not in MODES: + raise OperationError(space.w_ValueError, + space.wrap("mode %s not known" % (mode,))) + loop.choose(space, arr, choices, shape, dtype, out, MODES[mode]) + return out 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 @@ -4,7 +4,8 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\ ArrayArgumentException -from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes +from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes,\ + interp_arrayops from pypy.module.micronumpy.strides import find_shape_and_elems,\ get_shape_from_iterable, to_coords, shape_agreement from pypy.module.micronumpy.interp_flatiter import W_FlatIterator @@ -402,9 +403,11 @@ return res @unwrap_spec(mode=str) - def descr_choose(self, space, w_choices, w_out=None, mode='raise'): - raise OperationError(space.w_NotImplementedError, space.wrap( - "choose not implemented yet")) + def descr_choose(self, space, w_choices, mode='raise', w_out=None): + if w_out is not None and not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + return interp_arrayops.choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): raise OperationError(space.w_NotImplementedError, space.wrap( 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 @@ -4,11 +4,14 @@ over all the array elements. """ +from pypy.interpreter.error import OperationError from pypy.rlib.rstring import StringBuilder from pypy.rlib import jit from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy.base import W_NDimArray from pypy.module.micronumpy.iter import PureShapeIterator +from pypy.module.micronumpy import constants +from pypy.module.micronumpy.support import int_w call2_driver = jit.JitDriver(name='numpy_call2', greens = ['shapelen', 'func', 'calc_dtype', @@ -486,3 +489,36 @@ to_iter.setitem(dtype.itemtype.byteswap(from_iter.getitem())) to_iter.next() from_iter.next() + +choose_driver = jit.JitDriver(greens = ['shapelen', 'mode', 'dtype'], + reds = ['shape', 'iterators', 'arr_iter', + 'out_iter']) + +def choose(space, arr, choices, shape, dtype, out, mode): + shapelen = len(shape) + iterators = [a.create_iter(shape) for a in choices] + arr_iter = arr.create_iter(shape) + out_iter = out.create_iter(shape) + while not arr_iter.done(): + choose_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + mode=mode, shape=shape, + iterators=iterators, arr_iter=arr_iter, + out_iter=out_iter) + index = int_w(space, arr_iter.getitem()) + if index < 0 or index >= len(iterators): + if mode == constants.MODE_RAISE: + raise OperationError(space.w_ValueError, space.wrap( + "invalid entry in choice array")) + elif mode == constants.MODE_WRAP: + index = index % (len(iterators)) + else: + assert mode == constants.MODE_CLIP + if index < 0: + index = 0 + else: + index = len(iterators) - 1 + out_iter.setitem(iterators[index].getitem().convert_to(dtype)) + for iter in iterators: + iter.next() + out_iter.next() + arr_iter.next() diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py --- a/pypy/module/micronumpy/support.py +++ b/pypy/module/micronumpy/support.py @@ -1,5 +1,11 @@ from pypy.rlib import jit +from pypy.interpreter.error import OperationError +def int_w(space, w_obj): + try: + return space.int_w(space.index(w_obj)) + except OperationError: + return space.int_w(space.int(w_obj)) @jit.unroll_safe def product(s): diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -108,8 +108,16 @@ a, b, c = array([1, 2, 3]), [4, 5, 6], 13 raises(ValueError, "array([3, 1, 0]).choose([a, b, c])") raises(ValueError, "array([3, 1, 0]).choose([a, b, c], 'raises')") + raises(ValueError, "array([3, 1, 0]).choose([])") + raises(ValueError, "array([-1, -2, -3]).choose([a, b, c])") r = array([4, 1, 0]).choose([a, b, c], mode='clip') assert (r == [13, 5, 3]).all() r = array([4, 1, 0]).choose([a, b, c], mode='wrap') assert (r == [4, 5, 3]).all() - + + + def test_choose_dtype(self): + from _numpypy import array + a, b, c = array([1.2, 2, 3]), [4, 5, 6], 13 + r = array([2, 1, 0]).choose([a, b, c]) + assert r.dtype == float From noreply at buildbot.pypy.org Mon Oct 29 15:41:14 2012 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 29 Oct 2012 15:41:14 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: shuffle stuff around and implement clip Message-ID: <20121029144114.A4F1A1C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58585:2de8853d1f02 Date: 2012-10-29 15:40 +0100 http://bitbucket.org/pypy/pypy/changeset/2de8853d1f02/ Log: shuffle stuff around and implement clip diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -1,8 +1,9 @@ from pypy.module.micronumpy.base import convert_to_array, W_NDimArray -from pypy.module.micronumpy import loop, interp_ufuncs +from pypy.module.micronumpy import loop, interp_dtype, interp_ufuncs from pypy.module.micronumpy.iter import Chunk, Chunks -from pypy.module.micronumpy.strides import shape_agreement +from pypy.module.micronumpy.strides import shape_agreement,\ + shape_agreement_multiple from pypy.module.micronumpy.constants import MODES from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec @@ -161,19 +162,9 @@ if not choices: raise OperationError(space.w_ValueError, space.wrap("choices list cannot be empty")) - # find the shape agreement - shape = arr.get_shape() - for choice in choices: - shape = shape_agreement(space, shape, choice) - if out is not None: - shape = shape_agreement(space, shape, out) - # find the correct dtype - dtype = choices[0].get_dtype() - for choice in choices[1:]: - dtype = interp_ufuncs.find_binop_result_dtype(space, - dtype, choice.get_dtype()) - if out is None: - out = W_NDimArray.from_shape(shape, dtype) + shape = shape_agreement_multiple(space, choices + [out]) + out = interp_dtype.dtype_agreement(space, choices, shape, out) + dtype = out.get_dtype() if mode not in MODES: raise OperationError(space.w_ValueError, space.wrap("mode %s not known" % (mode,))) 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 @@ -5,9 +5,10 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import (TypeDef, GetSetProperty, interp_attrproperty, interp_attrproperty_w) -from pypy.module.micronumpy import types, interp_boxes +from pypy.module.micronumpy import types, interp_boxes, base from pypy.rlib.objectmodel import specialize from pypy.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong +from pypy.rlib import jit from pypy.rpython.lltypesystem import rffi @@ -27,6 +28,21 @@ return space.interp_w(W_Dtype, space.call_function(space.gettypefor(W_Dtype), w_dtype)) + at jit.unroll_safe +def dtype_agreement(space, w_arr_list, shape, out=None): + """ agree on dtype from a list of arrays. if out is allocated, + use it's dtype, otherwise allocate a new one with agreed dtype + """ + from pypy.module.micronumpy.interp_ufuncs import find_binop_result_dtype + + if not space.is_none(out): + return out + dtype = w_arr_list[0].get_dtype() + for w_arr in w_arr_list[1:]: + dtype = find_binop_result_dtype(space, dtype, w_arr.get_dtype()) + out = base.W_NDimArray.from_shape(shape, dtype) + return out + class W_Dtype(Wrappable): _immutable_fields_ = ["itemtype", "num", "kind"] 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 @@ -7,7 +7,8 @@ from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes,\ interp_arrayops from pypy.module.micronumpy.strides import find_shape_and_elems,\ - get_shape_from_iterable, to_coords, shape_agreement + get_shape_from_iterable, to_coords, shape_agreement, \ + shape_agreement_multiple from pypy.module.micronumpy.interp_flatiter import W_FlatIterator from pypy.module.micronumpy.interp_support import unwrap_axis_arg from pypy.module.micronumpy.appbridge import get_appbridge_cache @@ -410,8 +411,16 @@ return interp_arrayops.choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): - raise OperationError(space.w_NotImplementedError, space.wrap( - "clip not implemented yet")) + if w_out is not None and not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + min = convert_to_array(space, w_min) + max = convert_to_array(space, w_max) + shape = shape_agreement_multiple(space, [self, min, max, w_out]) + out = interp_dtype.dtype_agreement(space, [self, min, max], shape, + w_out) + loop.clip(space, self, shape, min, max, out) + return out def descr_conj(self, space): raise OperationError(space.w_NotImplementedError, space.wrap( @@ -801,6 +810,7 @@ base = GetSetProperty(W_NDimArray.descr_get_base), byteswap = interp2app(W_NDimArray.descr_byteswap), choose = interp2app(W_NDimArray.descr_choose), + clip = interp2app(W_NDimArray.descr_clip), __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) 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 @@ -522,3 +522,31 @@ iter.next() out_iter.next() arr_iter.next() + +clip_driver = jit.JitDriver(greens = ['shapelen', 'dtype'], + reds = ['min_iter', 'max_iter', 'arr_iter', + 'out_iter']) + +def clip(space, arr, shape, min, max, out): + arr_iter = arr.create_iter(shape) + dtype = out.get_dtype() + shapelen = len(shape) + min_iter = min.create_iter(shape) + max_iter = max.create_iter(shape) + out_iter = out.create_iter(shape) + while not arr_iter.done(): + clip_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + min_iter=min_iter, max_iter=max_iter, + arr_iter=arr_iter, out_iter=out_iter) + w_v = arr_iter.getitem().convert_to(dtype) + w_min = min_iter.getitem().convert_to(dtype) + w_max = max_iter.getitem().convert_to(dtype) + if dtype.itemtype.lt(w_v, w_min): + w_v = w_min + elif dtype.itemtype.gt(w_v, w_max): + w_v = w_max + out_iter.setitem(w_v) + arr_iter.next() + max_iter.next() + out_iter.next() + min_iter.next() diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -132,6 +132,17 @@ ) return ret + at jit.unroll_safe +def shape_agreement_multiple(space, array_list): + """ call shape_agreement recursively, allow elements from array_list to + be None (like w_out) + """ + shape = array_list[0].get_shape() + for arr in array_list[1:]: + if not space.is_none(arr): + shape = shape_agreement(space, shape, arr) + return shape + def _shape_agreement(shape1, shape2): """ Checks agreement about two shapes with respect to broadcasting. Returns the resulting shape. diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -115,9 +115,15 @@ r = array([4, 1, 0]).choose([a, b, c], mode='wrap') assert (r == [4, 5, 3]).all() - def test_choose_dtype(self): from _numpypy import array a, b, c = array([1.2, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c]) assert r.dtype == float + + def test_choose_dtype_out(self): + from _numpypy import array + a, b, c = array([1, 2, 3]), [4, 5, 6], 13 + x = array([0, 0, 0], dtype='i2') + r = array([2, 1, 0]).choose([a, b, c], out=x) + assert r.dtype == 'i2' 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 @@ -1599,6 +1599,15 @@ assert (a.byteswap(True) == [0x0100, 0x0201, 0x0300]).all() assert (a == [0x0100, 0x0201, 0x0300]).all() + def test_clip(self): + from _numpypy import array + a = array([1, 2, 17, -3, 12]) + assert (a.clip(-2, 13) == [1, 2, 13, -2, 12]).all() + assert (a.clip(-1, 1) == [1, 1, 1, -1, 1]).all() + assert (a.clip(-1, [1, 2, 3, 4, 5]) == [1, 2, 3, -1, 5]).all() + assert (a.clip(-2, 13, out=a) == [1, 2, 13, -2, 12]).all() + assert (a == [1, 2, 13, -2, 12]).all() + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import _numpypy From noreply at buildbot.pypy.org Mon Oct 29 17:23:03 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 17:23:03 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: In-progress: reduce the various numbers assigned to ResOps, including Message-ID: <20121029162303.345AB1C03BA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58586:e0e01c9c6532 Date: 2012-10-29 16:01 +0100 http://bitbucket.org/pypy/pypy/changeset/e0e01c9c6532/ Log: In-progress: reduce the various numbers assigned to ResOps, including for __str__(). Now it adds a constraint to oparsed texts: we cannot use e.g. both 'p0' and 'i0' (only one variable is allowed at position 0), or 'f0' and 'f1' (float variables are assumed to take two positions each). This should be nicely checked by oparser, though. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -635,6 +635,18 @@ self.last_exception = None def setenv(self, box, arg): + if box.type == INT: + # typecheck the result + if isinstance(arg, bool): + arg = int(arg) + assert lltype.typeOf(arg) == lltype.Signed + elif box.type == REF: + assert lltype.typeOf(arg) == llmemory.GCREF + elif box.type == FLOAT: + assert lltype.typeOf(arg) == longlong.FLOATSTORAGE + else: + raise AssertionError(box) + # assert box.getvarindex() >= 0 self.env[box] = arg self.framecontent[box.getvarindex()] = arg @@ -673,24 +685,15 @@ if hasattr(gf.descr, '_llgraph_bridge'): i = 0 self.lltrace = gf.descr._llgraph_bridge - newvals = [self.env[arg] for arg in self.lltrace.inputargs] + newvals = [self.framecontent[arg._varindex] + for arg in self.lltrace.inputargs] self.do_renaming(self.lltrace.inputargs, newvals) continue raise - if op.type == INT: - # typecheck the result - if isinstance(resval, bool): - resval = int(resval) - assert lltype.typeOf(resval) == lltype.Signed - elif op.type == REF: - assert lltype.typeOf(resval) == llmemory.GCREF - elif op.type == FLOAT: - assert lltype.typeOf(resval) == longlong.FLOATSTORAGE - else: - assert op.type == VOID - assert resval is None if op.type != VOID: self.setenv(op, resval) + else: + assert resval is None i += 1 def do_renaming(self, newargs, newvalues): diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -24,51 +24,13 @@ add_loop_instruction = ['overload for a specific cpu'] bridge_loop_instruction = ['overload for a specific cpu'] - _nextvarindex = 0 - - def update_varindexes(self, newtext2op): - # 'self.text2op' is a dict mapping variable names (as present in - # the oparser source) to the corresponding ResOp. This function - # updates it with 'newtext2op', then assigns '_varindex' to all - # the new ResOps. The choice of '_varindex' is done automatically - # to avoid conflicts, but existing '_varindex' are not changed. - # If 'newtext2op' is not a dict but a list, comes up with names - # as per str(op). - if isinstance(newtext2op, list): - newtext2op = dict([(str(op), op) for op in newtext2op]) - try: - text2op = self.text2op - except AttributeError: - text2op = self.text2op = {} - text2op.update(newtext2op) - if newtext2op: - # update 'self._nextvarindex' to a value higher than any seen - # in newtext2op. Pick two more rather than one more just in - # case the highest so far was a FLOAT. - newops = newtext2op.values() - random.shuffle(newops) - maximum = max([getattr(op, '_varindex', -2) for op in newops]) - self._nextvarindex = max(self._nextvarindex, maximum + 2) - for op in newops: - self.assign_varindex(op) - - def assign_varindex(self, op): - if (isinstance(op, AbstractResOp) and op.type != VOID and - getattr(op, '_varindex', -1) == -1): - op._varindex = self._nextvarindex - if hasattr(op, '_str'): - del op._str # recompute it - # this op consumes either one or two numbers, depending on its - # type as a non-FLOAT or FLOAT. We don't care too much about - # being on 32-bit vs 64-bit here. - self._nextvarindex += 1 + (op.type == FLOAT) def execute_operation(self, opname, valueboxes, result_type, descr=None): inputargs, operations = self._get_single_operation_list(opname, result_type, valueboxes, descr) - self.update_varindexes(inputargs + operations) + oparser.assign_all_varindices(inputargs + operations) looptoken = JitCellToken() self.cpu.compile_loop(inputargs, operations, looptoken) args = [] @@ -151,14 +113,11 @@ namespace['faildescr3'] = BasicFailDescr(3) if 'faildescr4' not in namespace: namespace['faildescr4'] = BasicFailDescr(4) - loop = oparser.parse(s, namespace=namespace, mutable=True, - oldvars=getattr(self, 'text2op', {})) - self.update_varindexes(loop.text2op) + loop = oparser.parse(s, namespace=namespace, mutable=True) return loop.inputargs, loop.operations, JitCellToken() def get_frame_value(self, frame, varname): - op = self.text2op[varname] - index = op.getvarindex() + index = int(varname[1:]) if varname.startswith('i'): return self.cpu.get_frame_value_int(frame, index) if varname.startswith('p'): @@ -184,8 +143,8 @@ faildescr = BasicFailDescr(1) inputargs, ops, token = self.parse(""" [f0] - f1 = float_add(f0, 1.) - finish(f1, descr=faildescr) + f2 = float_add(f0, 1.) + finish(f2, descr=faildescr) """, namespace=locals()) self.cpu.compile_loop(inputargs, ops, token) frame = self.cpu.execute_token(token, longlong.getfloatstorage(2.8)) @@ -1208,9 +1167,9 @@ label(%s, descr=targettoken) i1 = int_sub(i0, 1) i2 = int_ge(i1, 0) - guard_true(i2, descr=faildescr) [%s] + guard_true(i2, descr=faildescr) jump(%s, descr=targettoken) - """ % (inp, inp, inp, ", ".join(jumpargs)), None) + """ % (inp, inp, ", ".join(jumpargs)), None) # self.cpu.compile_loop(inpargs, operations, looptoken) # @@ -1241,15 +1200,9 @@ # assert dstvalues[index_counter] == 11 dstvalues[index_counter] = 0 - for i, (box, val) in enumerate(zip(inpargs, dstvalues)): - if box.type == 'i': - got = self.cpu.get_latest_value_int(frame, i) - elif box.type == 'r': - got = self.cpu.get_latest_value_ref(frame, i) - elif box.type == 'f': - got = self.cpu.get_latest_value_float(frame, i) - else: - assert 0 + assert len(inputargs) == len(inpargs) == len(dstvalues) + for (name, val) in zip(inputargs, dstvalues): + got = self.get_frame_value(frame, name) assert type(got) == type(val) assert got == val @@ -1264,8 +1217,8 @@ [%(fboxes)s] label(%(fboxes)s, descr=targettoken) i2 = float_le(f0, 9.2) - guard_true(i2, descr=faildescr1) [%(fboxes)s] - finish(descr=faildescr2) [%(fboxes)s] + guard_true(i2, descr=faildescr1) + finish(descr=faildescr2) """ % {'fboxes': fboxes}, {'faildescr1': faildescr1, 'faildescr2': faildescr2, 'targettoken': targettoken}) @@ -1285,55 +1238,53 @@ args.append(longlong.getfloatstorage(x)) frame = self.cpu.execute_token(looptoken, *args) assert self.cpu.get_latest_descr(frame).identifier == 2 - res = self.cpu.get_latest_value_float(frame, 0) + res = self.get_frame_value(frame, "f0") assert longlong.getrealfloat(res) == 8.5 - for i in range(1, len(fboxes.split(","))): - got = longlong.getrealfloat(self.cpu.get_latest_value_float(frame, i)) + fboxeslist = map(str.strip, fboxes.split(",")) + for i in range(1, len(fboxeslist)): + res = self.get_frame_value(frame, fboxeslist[i]) + got = longlong.getrealfloat(res) assert got == 13.5 + 6.73 * i def test_compile_bridge_spilled_float(self): if not self.cpu.supports_floats: py.test.skip("requires floats") fboxes = [boxfloat() for i in range(3)] - faildescr1 = BasicFailDescr(100) loopops = """ - [i0,f1, f2] + [i0, f1, f2] f3 = float_add(f1, f2) force_spill(f3) force_spill(f1) force_spill(f2) - guard_false(i0, descr=faildescr0) [f1, f2, f3] - finish() []""" + guard_false(i0, descr=faildescr0) + finish()""" inputargs, operations, looptoken = self.parse( loopops, namespace={'faildescr0': BasicFailDescr(1)}) self.cpu.compile_loop(inputargs, operations, looptoken) args = [1] args.append(longlong.getfloatstorage(132.25)) args.append(longlong.getfloatstorage(0.75)) - frame = self.cpu.execute_token(looptoken, *args) #xxx check + frame = self.cpu.execute_token(looptoken, *args) assert operations[-2].getdescr()== self.cpu.get_latest_descr(frame) - f1 = self.cpu.get_latest_value_float(frame, 0) - f2 = self.cpu.get_latest_value_float(frame, 1) - f3 = self.cpu.get_latest_value_float(frame, 2) + f1 = self.get_frame_value(frame, "f1") + f2 = self.get_frame_value(frame, "f2") + f3 = self.get_frame_value(frame, "f3") assert longlong.getrealfloat(f1) == 132.25 assert longlong.getrealfloat(f2) == 0.75 assert longlong.getrealfloat(f3) == 133.0 + faildescr1 = BasicFailDescr(100) bridgeops = [ create_resop(rop.FINISH, None, [], descr=faildescr1, mutable=True), ] - bridgeops[-1].setfailargs(fboxes) self.cpu.compile_bridge(operations[-2].getdescr(), fboxes, bridgeops, looptoken) - args = [1, - longlong.getfloatstorage(132.25), - longlong.getfloatstorage(0.75)] frame = self.cpu.execute_token(looptoken, *args) assert self.cpu.get_latest_descr(frame).identifier == 100 - f1 = self.cpu.get_latest_value_float(frame, 0) - f2 = self.cpu.get_latest_value_float(frame, 1) - f3 = self.cpu.get_latest_value_float(frame, 2) + f1 = self.get_frame_value(frame, "f1") + f2 = self.get_frame_value(frame, "f2") + f3 = self.get_frame_value(frame, "f3") assert longlong.getrealfloat(f1) == 132.25 assert longlong.getrealfloat(f2) == 0.75 assert longlong.getrealfloat(f3) == 133.0 diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -557,21 +557,21 @@ return object.__repr__(self) def __str__(self): - if not hasattr(self, '_str'): - if self.type == INT: - t = 'i' - elif self.type == FLOAT: - t = 'f' - elif self.type == REF: - t = 'p' - else: - t = '?' - if getattr(self, '_varindex', -1) < 0: - self._str = '%s%d' % (t, AbstractResOp._counter) + if self.type == INT: + t = 'i' + elif self.type == FLOAT: + t = 'f' + elif self.type == REF: + t = 'p' + else: + t = '?' + if getattr(self, '_varindex', -1) < 0: + if not hasattr(self, '_str'): AbstractResOp._counter += 1 - else: - self._str = '%s%s' % (t.upper(), self._varindex) - return self._str + self._str = '%s-%d' % (t, AbstractResOp._counter) + return self._str + else: + return '%s%d' % (t, self._varindex) def repr(self, graytext=False): # RPython-friendly version diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -7,7 +7,7 @@ from pypy.jit.metainterp.resoperation import rop, opclasses, rop_lowercase,\ ResOpWithDescr, N_aryOp, UnaryOp, PlainResOp, create_resop_dispatch,\ - ResOpNone, create_resop_0, example_for_opnum + ResOpNone, create_resop_0, example_for_opnum, FLOAT from pypy.jit.metainterp import optmodel from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rlib.objectmodel import Symbolic @@ -20,10 +20,8 @@ use_mock_model = False def __init__(self, input, cpu, namespace, type_system, - invent_fail_descr=True, results=None, mutable=False, - oldvars={}): + invent_fail_descr=True, results=None, mutable=False): self.input = input - self.oldvars = oldvars self.vars = {} self.cpu = cpu self._consts = namespace @@ -33,6 +31,7 @@ self.original_jitcell_token = self.model.JitCellToken() self.results = results self.mutable = mutable + self.allops = [] def get_const(self, name, typ): if self._consts is None: @@ -77,20 +76,17 @@ def newvar(self, elem): if elem not in self.vars: - if elem not in self.oldvars: - if elem[0] in 'ifp': - if elem[0] == 'p': - p = 'r' - else: - p = elem[0] - opnum = getattr(rop, 'INPUT_' + p) - box = create_resop_0(opnum, example_for_opnum(opnum), - mutable=self.mutable) + if elem[0] in 'ifp': + if elem[0] == 'p': + p = 'r' else: - raise ParseError("Unknown variable type: %s" % elem) - box._str = elem + p = elem[0] + opnum = getattr(rop, 'INPUT_' + p) + box = create_resop_0(opnum, example_for_opnum(opnum), + mutable=self.mutable) else: - box = self.oldvars[elem] + raise ParseError("Unknown variable type: %s" % elem) + self.setstr(box, elem) self.vars[elem] = box return self.vars[elem] @@ -203,10 +199,20 @@ else: result = self.results[num] opres = self.create_op(opnum, result, args, descr) - opres._str = res + self.setstr(opres, res) self.vars[res] = opres return opres + def setstr(self, op, text): + op._str = text + try: + num = int(text[1:]) + except ValueError: + num = -1 + if num >= 0: + op._varindex = num + self.allops.append(op) + def parse_op_no_result(self, line): opnum, args, descr = self.parse_op(line) res = self.create_op(opnum, None, args, descr) @@ -242,13 +248,13 @@ num, ops, last_offset = self.parse_ops(base_indent, newlines, 0) if num < len(newlines): raise ParseError("unexpected dedent at line: %s" % newlines[num]) + assign_all_varindices(self.allops) loop = self.model.ExtendedTreeLoop("loop") loop.comment = first_comment loop.original_jitcell_token = self.original_jitcell_token loop.operations = ops loop.inputargs = inpargs loop.last_offset = last_offset - loop.text2op = self.vars return loop def parse_ops(self, indent, lines, start): @@ -306,12 +312,42 @@ def parse(input, cpu=None, namespace=DEFAULT, type_system='lltype', invent_fail_descr=True, OpParser=OpParser, - results=None, mutable=False, oldvars={}): + results=None, mutable=False): if namespace is DEFAULT: namespace = {} return OpParser(input, cpu, namespace, type_system, - invent_fail_descr, results, mutable, oldvars).parse() + invent_fail_descr, results, mutable).parse() def pure_parse(*args, **kwds): kwds['invent_fail_descr'] = False return parse(*args, **kwds) + + +def assign_all_varindices(allops): + assigned_varindices = {} + unassigned_varindices = [] + # + for op in allops: + if getattr(op, '_varindex', -1) >= 0: + num = op._varindex + assert num not in assigned_varindices, ( + "duplicate or overlapping var: %s and %s" % ( + op, assigned_varindices[num])) + assigned_varindices[num] = op + if op.type == FLOAT: + assert (num + 1) not in assigned_varindices, ( + "duplicate or overlapping var: %s and %s" % ( + op, assigned_varindices[num + 1])) + assigned_varindices[num + 1] = op + else: + unassigned_varindices.append(op) + # + nextindex = 0 + for op in unassigned_varindices: + while (nextindex in assigned_varindices or + (op.type == FLOAT and (nextindex + 1) in assigned_varindices)): + nextindex += 1 + op._varindex = nextindex + nextindex += 1 + if op.type == FLOAT: + nextindex += 1 diff --git a/pypy/jit/tool/test/test_oparser.py b/pypy/jit/tool/test/test_oparser.py --- a/pypy/jit/tool/test/test_oparser.py +++ b/pypy/jit/tool/test/test_oparser.py @@ -2,8 +2,8 @@ import sys from pypy.rpython.lltypesystem import lltype, llmemory -from pypy.jit.tool.oparser import parse, OpParser -from pypy.jit.metainterp.resoperation import rop +from pypy.jit.tool.oparser import parse, OpParser, assign_all_varindices +from pypy.jit.metainterp.resoperation import rop, INT, FLOAT from pypy.jit.metainterp.history import AbstractDescr, JitCellToken,\ TargetToken @@ -250,3 +250,45 @@ for modname, mod in sys.modules.iteritems(): if isinstance(mod, ForbiddenModule): sys.modules[modname] = mod.old_mod + + +def test_assign_all_varindices(): + class FakeOp: + def __init__(self, varindex=-1, type=INT): + self._varindex = varindex + self.type = type + def indices(lst): + return [op._varindex for op in lst] + + ops = [FakeOp(5), FakeOp(6)] + assign_all_varindices(ops) + assert indices(ops) == [5, 6] + + ops = [FakeOp(5), FakeOp(6, FLOAT)] + assign_all_varindices(ops) + assert indices(ops) == [5, 6] + + ops = [FakeOp(5), FakeOp(5)] + py.test.raises(AssertionError, assign_all_varindices, ops) + ops = [FakeOp(5), FakeOp(5, FLOAT)] + py.test.raises(AssertionError, assign_all_varindices, ops) + ops = [FakeOp(5), FakeOp(4, FLOAT)] + py.test.raises(AssertionError, assign_all_varindices, ops) + ops = [FakeOp(4, FLOAT), FakeOp(5)] + py.test.raises(AssertionError, assign_all_varindices, ops) + + ops = [FakeOp(), FakeOp(type=FLOAT), FakeOp(1)] + assign_all_varindices(ops) + assert indices(ops) == [0, 2, 1] + + ops = [FakeOp(), FakeOp(type=FLOAT), FakeOp(2)] + assign_all_varindices(ops) + assert indices(ops) == [0, 3, 2] + + ops = [FakeOp(), FakeOp(type=FLOAT), FakeOp(3)] + assign_all_varindices(ops) + assert indices(ops) == [0, 1, 3] + + ops = [FakeOp(), FakeOp(type=FLOAT), FakeOp(2, FLOAT)] + assign_all_varindices(ops) + assert indices(ops) == [0, 4, 2] From noreply at buildbot.pypy.org Mon Oct 29 17:23:04 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 17:23:04 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: in-progress Message-ID: <20121029162304.BE3061C03BA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58587:baadf8de0b9b Date: 2012-10-29 16:15 +0100 http://bitbucket.org/pypy/pypy/changeset/baadf8de0b9b/ Log: in-progress diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -24,6 +24,7 @@ add_loop_instruction = ['overload for a specific cpu'] bridge_loop_instruction = ['overload for a specific cpu'] + _autoindex = 0 def execute_operation(self, opname, valueboxes, result_type, descr=None): inputargs, operations = self._get_single_operation_list(opname, @@ -1063,7 +1064,6 @@ for nb_args in range(50): print 'Passing %d arguments to execute_token...' % nb_args # - text2op = {} inputargs = [] values = [] for k in range(nb_args): @@ -1071,11 +1071,9 @@ if kind == 0: inputargs.append(boxint()) values.append(r.randrange(-100000, 100000)) - text2op['ii%d' % k] = inputargs[-1] else: inputargs.append(boxfloat()) values.append(longlong.getfloatstorage(r.random())) - text2op['fi%d' % k] = inputargs[-1] # looptoken = JitCellToken() faildescr = BasicFailDescr(42) @@ -1091,7 +1089,6 @@ create_resop_2(rop.INT_ADD, 0, inputargs[k], ConstInt(x)) ) - text2op['io%d' % k] = operations[-1] y = values[k] + x else: x = r.random() @@ -1099,16 +1096,16 @@ create_resop_2(rop.FLOAT_ADD, 0.0, inputargs[k], constfloat(x)) ) - text2op['fo%d' % k] = operations[-1] y = longlong.getrealfloat(values[k]) + x y = longlong.getfloatstorage(y) retvalues.append(y) + operations[-1]._varindex = 2 * k # operations.append( create_resop(rop.FINISH, None, [], descr=faildescr, mutable=True) ) - self.update_varindexes(text2op) + oparser.assign_all_varindices(inputargs + operations) print inputargs for op in operations: print op @@ -1118,10 +1115,10 @@ assert self.cpu.get_latest_descr(frame).identifier == 42 # for k, expected in zip(ks, retvalues): - if 'io%d' % k in text2op: - got = self.get_frame_value(frame, 'io%d' % k) + if isinstance(expected, float): + got = self.get_frame_value(frame, 'f%d' % (2 * k)) else: - got = self.get_frame_value(frame, 'fo%d' % k) + got = self.get_frame_value(frame, 'i%d' % (2 * k)) assert got == expected def test_jump(self): @@ -1141,12 +1138,13 @@ inputargs = [] for k in range(nb_args): kind = r.randrange(0, numkinds) + num = 2 * k + 4 if kind == 0: - inputargs.append("i%d" % (k + 10)) + inputargs.append("i%d" % num) elif kind == 1: - inputargs.append("p%d" % k) + inputargs.append("p%d" % num) else: - inputargs.append("f%d" % k) + inputargs.append("f%d" % num) jumpargs = [] remixing = [] for srcbox in inputargs: @@ -1209,42 +1207,43 @@ def test_compile_bridge_float(self): if not self.cpu.supports_floats: py.test.skip("requires floats") - fboxes = "f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11" + fboxes = ["f%d" % (k * 2) for k in range(12)] + fboxesstr = ', '.join(fboxes) faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) targettoken = TargetToken() inputargs, operations, looptoken = self.parse(""" - [%(fboxes)s] - label(%(fboxes)s, descr=targettoken) - i2 = float_le(f0, 9.2) - guard_true(i2, descr=faildescr1) + [%(fboxesstr)s] + label(%(fboxesstr)s, descr=targettoken) + i27 = float_le(f0, 9.2) + guard_true(i27, descr=faildescr1) finish(descr=faildescr2) - """ % {'fboxes': fboxes}, {'faildescr1': faildescr1, - 'faildescr2': faildescr2, - 'targettoken': targettoken}) + """ % {'fboxesstr': fboxesstr}, {'faildescr1': faildescr1, + 'faildescr2': faildescr2, + 'targettoken': targettoken}) self.cpu.compile_loop(inputargs, operations, looptoken) inputargs, operations, _ = self.parse(""" [%s] - f15 = float_sub(f0, 1.0) - jump(f15, %s, descr=targettoken) - """ % (fboxes, fboxes[4:]), {'targettoken': targettoken}) + f28 = float_sub(f0, 1.0) + jump(f28, %s, descr=targettoken) + """ % (fboxesstr, ', '.join(fboxes[1:])), {'targettoken': targettoken}) self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken) args = [] - for i in range(len(fboxes.split(","))): + for i in range(len(fboxes)): x = 13.5 + 6.73 * i args.append(longlong.getfloatstorage(x)) frame = self.cpu.execute_token(looptoken, *args) assert self.cpu.get_latest_descr(frame).identifier == 2 - res = self.get_frame_value(frame, "f0") - assert longlong.getrealfloat(res) == 8.5 - fboxeslist = map(str.strip, fboxes.split(",")) - for i in range(1, len(fboxeslist)): - res = self.get_frame_value(frame, fboxeslist[i]) - got = longlong.getrealfloat(res) - assert got == 13.5 + 6.73 * i + + got = [] + for name in fboxes: + res = self.get_frame_value(frame, name) + got.append(longlong.getrealfloat(res)) + expected = [8.5] + [(13.5 + 6.73 * i) for i in range(1, len(fboxes))] + assert got == expected def test_compile_bridge_spilled_float(self): if not self.cpu.supports_floats: @@ -1704,15 +1703,22 @@ t.parent.parent.parent.typeptr = vtable_for_T t_box = boxptr(lltype.cast_opaque_ptr(llmemory.GCREF, t)) T_box = ConstInt(heaptracker.adr2int(vtable_for_T_addr)) + t_box._varindex = self._autoindex + self._autoindex += 1 return t_box, T_box def null_instance(self): - return boxptr(lltype.nullptr(llmemory.GCREF.TO)) + box = boxptr(lltype.nullptr(llmemory.GCREF.TO)) + box._varindex = self._autoindex + self._autoindex += 1 + return box def alloc_array_of(self, ITEM, length): A = lltype.GcArray(ITEM) a = lltype.malloc(A, length) a_box = boxptr(lltype.cast_opaque_ptr(llmemory.GCREF, a)) + a_box._varindex = self._autoindex + self._autoindex += 1 return a_box, A def alloc_string(self, string): @@ -1720,6 +1726,8 @@ for i in range(len(string)): s.chars[i] = string[i] s_box = boxptr(lltype.cast_opaque_ptr(llmemory.GCREF, s)) + s_box._varindex = self._autoindex + self._autoindex += 1 return s_box def look_string(self, string_box): @@ -1731,6 +1739,8 @@ for i in range(len(unicode)): u.chars[i] = unicode[i] u_box = boxptr(lltype.cast_opaque_ptr(llmemory.GCREF, u)) + u_box._varindex = self._autoindex + self._autoindex += 1 return u_box def look_unicode(self, unicode_box): From noreply at buildbot.pypy.org Mon Oct 29 17:23:05 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 17:23:05 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: in-progress Message-ID: <20121029162305.F34C81C03BA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58588:d8d8425206fb Date: 2012-10-29 16:20 +0100 http://bitbucket.org/pypy/pypy/changeset/d8d8425206fb/ Log: in-progress diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -24,6 +24,8 @@ # need to make sure things get freed. # XXX for now + for op in inputargs + operations: + assert op.type == VOID or op._varindex >= 0 self.operations = operations self.inputargs = inputargs return diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -1248,12 +1248,11 @@ def test_compile_bridge_spilled_float(self): if not self.cpu.supports_floats: py.test.skip("requires floats") - fboxes = [boxfloat() for i in range(3)] loopops = """ - [i0, f1, f2] - f3 = float_add(f1, f2) - force_spill(f3) - force_spill(f1) + [i0, f4, f2] + f6 = float_add(f4, f2) + force_spill(f6) + force_spill(f4) force_spill(f2) guard_false(i0, descr=faildescr0) finish()""" @@ -1265,28 +1264,27 @@ args.append(longlong.getfloatstorage(0.75)) frame = self.cpu.execute_token(looptoken, *args) assert operations[-2].getdescr()== self.cpu.get_latest_descr(frame) - f1 = self.get_frame_value(frame, "f1") + f4 = self.get_frame_value(frame, "f4") f2 = self.get_frame_value(frame, "f2") - f3 = self.get_frame_value(frame, "f3") - assert longlong.getrealfloat(f1) == 132.25 + f6 = self.get_frame_value(frame, "f6") + assert longlong.getrealfloat(f4) == 132.25 assert longlong.getrealfloat(f2) == 0.75 - assert longlong.getrealfloat(f3) == 133.0 + assert longlong.getrealfloat(f6) == 133.0 - faildescr1 = BasicFailDescr(100) - bridgeops = [ - create_resop(rop.FINISH, None, [], descr=faildescr1, - mutable=True), - ] + fboxes, bridgeops, _ = self.parse(""" + [f4, f2, f6] + finish(descr=faildescr1) + """, namespace={'faildescr1': BasicFailDescr(100)}) self.cpu.compile_bridge(operations[-2].getdescr(), fboxes, bridgeops, looptoken) frame = self.cpu.execute_token(looptoken, *args) assert self.cpu.get_latest_descr(frame).identifier == 100 - f1 = self.get_frame_value(frame, "f1") + f4 = self.get_frame_value(frame, "f4") f2 = self.get_frame_value(frame, "f2") - f3 = self.get_frame_value(frame, "f3") - assert longlong.getrealfloat(f1) == 132.25 + f6 = self.get_frame_value(frame, "f6") + assert longlong.getrealfloat(f4) == 132.25 assert longlong.getrealfloat(f2) == 0.75 - assert longlong.getrealfloat(f3) == 133.0 + assert longlong.getrealfloat(f6) == 133.0 def test_integers_and_guards2(self): for opname, compare in [ From noreply at buildbot.pypy.org Mon Oct 29 17:23:07 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 17:23:07 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: fixfixfix Message-ID: <20121029162307.209B21C03BA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58589:23b55c5779fc Date: 2012-10-29 17:05 +0100 http://bitbucket.org/pypy/pypy/changeset/23b55c5779fc/ Log: fixfixfix diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -74,7 +74,7 @@ elif result_type == 'ref': result = lltype.nullptr(llmemory.GCREF.TO) elif result_type == 'float' or result_type == 'longlong': - result = 0.0 + result = longlong.ZEROF else: raise ValueError(result_type) op0 = create_resop_dispatch(opnum, result, valueboxes, @@ -91,8 +91,17 @@ if descr is not None: op0.setdescr(descr) inputargs = [box for box in valueboxes if not box.is_constant()] + inputargs = list(set(inputargs)) return inputargs, [op0, op1] + def _duplicate_boxes(self, inputargs): + seen = {} + for box in inputargs: + if box not in seen: + seen[box] = create_resop_0(box.opnum, box.constbox().value, + mutable=True) + return [seen[box] for box in inputargs] + class BaseBackendTest(Runner): avoid_instances = False @@ -1093,7 +1102,8 @@ else: x = r.random() operations.append( - create_resop_2(rop.FLOAT_ADD, 0.0, inputargs[k], + create_resop_2(rop.FLOAT_ADD, + longlong.ZEROF, inputargs[k], constfloat(x)) ) y = longlong.getrealfloat(values[k]) + x @@ -1301,11 +1311,12 @@ op0 = create_resop_1(opname, 0, box) op1 = create_resop_1(opguard, None, op0, mutable=True) op1.setdescr(faildescr1) - op1.setfailargs([]) op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, mutable=True) + operations = [op0, op1, op2] looptoken = JitCellToken() - self.cpu.compile_loop(inputargs, [op0, op1, op2], looptoken) + oparser.assign_all_varindices(inputargs + operations) + self.cpu.compile_loop(inputargs, operations, looptoken) # cpu = self.cpu for value in [-42, 0, 1, 10]: @@ -1346,10 +1357,10 @@ op0 = create_resop_2(opname, 0, ibox1, ibox2) op1 = create_resop_1(opguard, None, op0, mutable=True) op1.setdescr(faildescr1) - op1.setfailargs([]) op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, mutable=True) operations = [op0, op1, op2] + oparser.assign_all_varindices(inputargs + operations) looptoken = JitCellToken() self.cpu.compile_loop(inputargs, operations, looptoken) # @@ -1398,11 +1409,12 @@ op0 = create_resop_2(opname, 0, ibox1, ibox2) op1 = create_resop_1(opguard, None, op0, descr=faildescr1, mutable=True) - op1.setfailargs([]) op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, mutable=True) + operations = [op0, op1, op2] looptoken = JitCellToken() - self.cpu.compile_loop(inputargs, [op0, op1, op2], looptoken) + oparser.assign_all_varindices(inputargs + operations) + self.cpu.compile_loop(inputargs, operations, looptoken) # cpu = self.cpu for test1 in [65, 42, 11, 0, 1]: @@ -1453,11 +1465,11 @@ op0 = create_resop_2(opname, 0, fbox1, fbox2) op1 = create_resop_1(opguard, None, op0, mutable=True) op1.setdescr(faildescr1) - op1.setfailargs([]) op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, mutable=True) operations = [op0, op1, op2] looptoken = JitCellToken() + oparser.assign_all_varindices(inputargs + operations) self.cpu.compile_loop(inputargs, operations, looptoken) # cpu = self.cpu @@ -1506,7 +1518,7 @@ if rettype == 'int': res = 0 elif rettype == 'float': - res = 0.0 + res = longlong.ZEROF else: assert 0 operations.append(create_resop_dispatch(opnum, res, boxargs, @@ -1517,6 +1529,7 @@ operations.append(create_resop(rop.FINISH, None, [], descr=faildescr, mutable=True)) looptoken = JitCellToken() + oparser.assign_all_varindices(inputargs + operations) # self.cpu.compile_loop(inputargs, operations, looptoken) # @@ -1554,14 +1567,14 @@ def nan_and_infinity(opnum, realoperation, testcases): for testcase in testcases: - realvalues = [b.getfloat() for b in testcase] + testcase = self._duplicate_boxes(testcase) + realvalues = [x.getfloat() for x in testcase] expected = realoperation(*realvalues) if isinstance(expected, float): expectedtype = 'float' else: expectedtype = 'int' - got = self.execute_operation(opnum, list(testcase), - expectedtype) + got = self.execute_operation(opnum, testcase, expectedtype) if isnan(expected): ok = isnan(got) elif isinf(expected): @@ -1571,7 +1584,7 @@ if not ok: raise AssertionError("%s(%s): got %r, expected %r" % ( opname[opnum], ', '.join(map(repr, realvalues)), - got.getfloat(), expected)) + got, expected)) # if we expect a boolean, also check the combination with # a GUARD_TRUE or GUARD_FALSE if isinstance(expected, bool): @@ -1580,7 +1593,6 @@ op0 = create_resop_2(opnum, 0, *testcase) op1 = create_resop_1(guard_opnum, None, op0, mutable=True) - op1.setfailargs([]) op1.setdescr(BasicFailDescr(4)) op2 = create_resop(rop.FINISH, None, [], descr=BasicFailDescr(5), @@ -1589,6 +1601,8 @@ looptoken = JitCellToken() # Use "set" to unique-ify inputargs unique_testcase_list = list(set(testcase)) + oparser.assign_all_varindices(unique_testcase_list + + operations) self.cpu.compile_loop(unique_testcase_list, operations, looptoken) args = [box.getfloatstorage() diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -774,8 +774,7 @@ type = FLOAT def __init__(self, floatval): - #assert isinstance(floatval, float) - # XXX not sure between float or float storage + assert lltype.typeOf(floatval) is longlong.FLOATSTORAGE self._floatval = floatval def getresultrepr(self): @@ -1584,7 +1583,7 @@ if opclasses[opnum].type == INT: return 0 elif opclasses[opnum].type == FLOAT: - return 0.0 + return longlong.ZEROF else: return lltype.nullptr(llmemory.GCREF.TO) diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py --- a/pypy/jit/metainterp/test/support.py +++ b/pypy/jit/metainterp/test/support.py @@ -12,9 +12,7 @@ from pypy.jit.codewriter import codewriter, longlong from pypy.rlib.rfloat import isnan -def boxfloat(x=None): - if x is None: - x = example_for_opnum(rop.INPUT_f) +def boxfloat(x=0.0): return create_resop_0(rop.INPUT_f, longlong.getfloatstorage(x)) def boxlonglong_on_32bit(x): diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -131,17 +131,6 @@ raise Exception("unexpected var %s" % (arg,)) return self.vars[arg] - def _example_for(self, opnum): - kind = opclasses[opnum].type - if kind == 'i': - return 0 - elif kind == 'f': - return 0.0 - elif kind == 'r': - return lltype.nullptr(llmemory.GCREF.TO) - else: - return None - def parse_args(self, opname, argspec): args = [] descr = None @@ -195,7 +184,7 @@ if res in self.vars: raise ParseError("Double assign to var %s in line: %s" % (res, line)) if self.results is None: - result = self._example_for(opnum) + result = example_for_opnum(opnum) else: result = self.results[num] opres = self.create_op(opnum, result, args, descr) From noreply at buildbot.pypy.org Mon Oct 29 17:23:08 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 17:23:08 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: fixfix Message-ID: <20121029162308.4EF011C03BA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58590:561d073ceba9 Date: 2012-10-29 17:08 +0100 http://bitbucket.org/pypy/pypy/changeset/561d073ceba9/ Log: fixfix diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -1883,8 +1883,8 @@ [i0] i1 = same_as_i(1) call_v(ConstClass(fptr), i0, descr=calldescr) - p0 = guard_exception(ConstClass(xtp), descr=faildescr2) [i1] - finish(p0, descr=faildescr1) [] + p2 = guard_exception(ConstClass(xtp), descr=faildescr2) + finish(p2, descr=faildescr1) ''' FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) fptr = llhelper(FPTR, func) @@ -1908,7 +1908,7 @@ frame = self.cpu.execute_token(looptoken, 1) assert self.cpu.get_finish_value_ref(frame) == xptr frame = self.cpu.execute_token(looptoken, 0) - assert self.cpu.get_latest_value_int(frame, 0) == 1 + assert self.get_frame_value(frame, "i1") == 1 excvalue = self.cpu.grab_exc_value(frame) assert not excvalue @@ -1926,7 +1926,7 @@ inputargs, operations, looptoken = self.parse(ops, namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) - assert self.cpu.get_latest_value_int(frame, 0) == 1 + assert self.get_frame_value(frame, "i1") == 1 excvalue = self.cpu.grab_exc_value(frame) assert excvalue == yptr @@ -1936,13 +1936,13 @@ [i0] i1 = same_as_i(1) call_v(ConstClass(fptr), i0, descr=calldescr) - guard_no_exception(descr=faildescr1) [i1] - finish(-100, descr=faildescr2) [] + guard_no_exception(descr=faildescr1) + finish(-100, descr=faildescr2) ''' inputargs, operations, looptoken = self.parse(ops, namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) - assert self.cpu.get_latest_value_int(frame, 0) == 1 + assert self.get_frame_value(frame, "i1") == 1 excvalue = self.cpu.grab_exc_value(frame) assert excvalue == xptr frame = self.cpu.execute_token(looptoken, 0) @@ -2123,7 +2123,7 @@ [i0, i1] ptok = jit_frame() call_may_force_v(ConstClass(func_ptr), ptok, i1, descr=calldescr) - guard_not_forced(descr=faildescr) [i1, i0] + guard_not_forced(descr=faildescr) finish(i0, descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, operations, looptoken) @@ -2134,8 +2134,8 @@ frame = self.cpu.execute_token(looptoken, 10, 1) assert self.cpu.get_latest_descr(frame).identifier == 1 - assert self.cpu.get_latest_value_int(frame, 0) == 1 - assert self.cpu.get_latest_value_int(frame, 1) == 10 + assert self.get_frame_value(frame, "i1") == 1 + assert self.get_frame_value(frame, "i0") == 10 assert values == [faildescr, 1, 10, frame] def test_force_operations_returning_int(self): From noreply at buildbot.pypy.org Mon Oct 29 17:32:34 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 17:32:34 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: fixfix Message-ID: <20121029163234.F389B1C03BA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58591:3822db2242c9 Date: 2012-10-29 17:28 +0100 http://bitbucket.org/pypy/pypy/changeset/3822db2242c9/ Log: fixfix diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -855,12 +855,9 @@ call_op = self.lltrace.operations[self.current_index] guard_op = self.lltrace.operations[self.current_index + 1] assert guard_op.getopnum() == rop.GUARD_NOT_FORCED - XXX - self.latest_values = self._getfailargs(guard_op, skip=call_op) self.latest_descr = _getdescr(guard_op) res = self.execute_call(calldescr, func, *args) del self.latest_descr - del self.latest_values return res execute_call_may_force_i = execute_call_may_force execute_call_may_force_r = execute_call_may_force diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2107,8 +2107,8 @@ values.append(descr) x = self.cpu.force(token) assert x is None - values.append(self.cpu.get_latest_value_int(token, 0)) - values.append(self.cpu.get_latest_value_int(token, 1)) + values.append(self.get_frame_value(token, "i1")) + values.append(self.get_frame_value(token, "i0")) values.append(token) FUNC = self.FuncType([self.cpu.JITFRAMEPTR, lltype.Signed], lltype.Void) @@ -2143,8 +2143,8 @@ def maybe_force(token, flag): if flag: self.cpu.force(token) - values.append(self.cpu.get_latest_value_int(token, 0)) - values.append(self.cpu.get_latest_value_int(token, 2)) + values.append(self.get_frame_value(token, "i1")) + values.append(self.get_frame_value(token, "i0")) values.append(token) return 42 @@ -2159,7 +2159,7 @@ [i0, i1] ptok = jit_frame() i2 = call_may_force_i(ConstClass(func_ptr), ptok, i1, descr=calldescr) - guard_not_forced(descr=faildescr) [i1, i2, i0] + guard_not_forced(descr=faildescr) finish(i2, descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) @@ -2170,9 +2170,9 @@ frame = self.cpu.execute_token(looptoken, 10, 1) assert self.cpu.get_latest_descr(frame).identifier == 1 - assert self.cpu.get_latest_value_int(frame, 0) == 1 - assert self.cpu.get_latest_value_int(frame, 1) == 42 - assert self.cpu.get_latest_value_int(frame, 2) == 10 + assert self.get_frame_value(frame, "i1") == 1 + assert self.get_frame_value(frame, "i2") == 42 + assert self.get_frame_value(frame, "i0") == 10 assert values == [1, 10, frame] def test_force_operations_returning_float(self): @@ -2182,8 +2182,8 @@ def maybe_force(token, flag): if flag: self.cpu.force(token) - values.append(self.cpu.get_latest_value_int(token, 0)) - values.append(self.cpu.get_latest_value_int(token, 2)) + values.append(self.get_frame_value(token, "i1")) + values.append(self.get_frame_value(token, "i0")) values.append(token) return 42.5 @@ -2197,9 +2197,9 @@ inputargs, ops, looptoken = self.parse(""" [i0, i1] ptok = jit_frame() - f0 = call_may_force_f(ConstClass(func_ptr), ptok, i1, descr=calldescr) - guard_not_forced(descr=faildescr) [i1, f0, i0] - finish(f0, descr=faildescr0) [] + f2 = call_may_force_f(ConstClass(func_ptr), ptok, i1, descr=calldescr) + guard_not_forced(descr=faildescr) + finish(f2, descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) @@ -2210,10 +2210,9 @@ frame = self.cpu.execute_token(looptoken, 10, 1) assert self.cpu.get_latest_descr(frame).identifier == 1 - assert self.cpu.get_latest_value_int(frame, 0) == 1 - x = self.cpu.get_latest_value_float(frame, 1) - assert longlong.getrealfloat(x) == 42.5 - assert self.cpu.get_latest_value_int(frame, 2) == 10 + assert self.get_frame_value(frame, "i1") == 1 + assert longlong.getrealfloat(self.get_frame_value(frame, "f2")) == 42.5 + assert self.get_frame_value(frame, "i0") == 10 assert values == [1, 10, frame] def test_force_from_finish(self): From noreply at buildbot.pypy.org Mon Oct 29 17:32:36 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 17:32:36 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: fixfix Message-ID: <20121029163236.1D8A81C03BA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58592:9b8db6bc4e6c Date: 2012-10-29 17:32 +0100 http://bitbucket.org/pypy/pypy/changeset/9b8db6bc4e6c/ Log: fixfix diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2220,14 +2220,14 @@ inputargs, operations, looptoken = self.parse(''' [i1, i2] p0 = jit_frame() - finish(p0, descr=faildescr1) [i1, i2] + finish(p0, descr=faildescr1) ''', namespace={'faildescr1': finishdescr}) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) self.cpu.force(frame) assert self.cpu.get_latest_descr(frame) is finishdescr - assert self.cpu.get_latest_value_int(frame, 0) == 20 - assert self.cpu.get_latest_value_int(frame, 1) == 0 + assert self.get_frame_value(frame, "i1") == 20 + assert self.get_frame_value(frame, "i2") == 0 def test_call_to_c_function(self): from pypy.rlib.libffi import CDLL, types, ArgChain, FUNCFLAG_CDECL @@ -2245,8 +2245,8 @@ inputargs, operations, looptoken = self.parse(""" [i1] i2 = call_release_gil_i(ConstClass(func_adr), i1, descr=calldescr) - guard_not_forced(descr=faildescr) [i1, i2] - finish(i2, descr=faildescr0) [] + guard_not_forced(descr=faildescr) + finish(i2, descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, ord('G')) @@ -2295,7 +2295,7 @@ inputargs, ops, looptoken = self.parse(""" [i0, i1, i2, i3] call_release_gil_v(ConstClass(func_ptr), i0, i1, i2, i3, descr=calldescr) - guard_not_forced(descr=faildescr) [] + guard_not_forced(descr=faildescr) finish(descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) @@ -2370,7 +2370,7 @@ faildescr0 = BasicFailDescr(0) inputargs, ops, looptoken = self.parse(""" [i0, i1] - guard_not_invalidated(descr=faildescr) [i1] + guard_not_invalidated(descr=faildescr) finish(i0, descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) @@ -2386,7 +2386,8 @@ frame = self.cpu.execute_token(looptoken, -42, 9) assert self.cpu.get_latest_descr(frame) is faildescr - assert self.cpu.get_latest_value_int(frame, 0) == 9 + assert self.get_frame_value(frame, "i0") == -42 + assert self.get_frame_value(frame, "i1") == 9 print 'step 2 ok' print '-'*79 @@ -2394,9 +2395,9 @@ faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) inputargs, ops, _ = self.parse(""" - [i2] - guard_not_invalidated(descr=faildescr2) [] - finish(i2, descr=faildescr3) + [i1] + guard_not_invalidated(descr=faildescr2) + finish(i1, descr=faildescr3) """, locals()) self.cpu.compile_bridge(faildescr, inputargs, ops, looptoken) @@ -2423,7 +2424,7 @@ faildescr3 = BasicFailDescr(3) inputargs, ops, looptoken = self.parse(""" [i0] - guard_not_invalidated(descr=faildescr) [] + guard_not_invalidated(descr=faildescr) label(i0, descr=labeldescr) finish(i0, descr=faildescr3) """, locals()) @@ -2431,9 +2432,10 @@ # mark as failing self.cpu.invalidate_loop(looptoken) # attach a bridge - ops = [ - create_resop(rop.JUMP, None, [ConstInt(333)], descr=labeldescr), - ] + _, ops, _ = self.parse(""" + [] + jump(333, descr=labeldescr) + """, locals()) self.cpu.compile_bridge(faildescr, [], ops, looptoken) # run: must not be caught in an infinite loop frame = self.cpu.execute_token(looptoken, 16) From noreply at buildbot.pypy.org Mon Oct 29 17:40:18 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 17:40:18 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: fixfixfix Message-ID: <20121029164018.C10051C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58593:b6d464aaf112 Date: 2012-10-29 17:36 +0100 http://bitbucket.org/pypy/pypy/changeset/b6d464aaf112/ Log: fixfixfix diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -879,8 +879,6 @@ call_op = self.lltrace.operations[self.current_index] guard_op = self.lltrace.operations[self.current_index + 1] assert guard_op.getopnum() == rop.GUARD_NOT_FORCED - XXX - self.latest_values = self._getfailargs(guard_op, skip=call_op) self.latest_descr = _getdescr(guard_op) # frame = self.cpu._execute_token(descr, *args) @@ -899,7 +897,6 @@ return None # del self.latest_descr - del self.latest_values return support.cast_result(lltype.typeOf(result), result) execute_call_assembler_i = execute_call_assembler execute_call_assembler_r = execute_call_assembler diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2630,7 +2630,7 @@ ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] i10 = int_add_ovf(i0, i1) - guard_no_overflow(descr=faildescr2) [] + guard_no_overflow(descr=faildescr2) i11 = int_add(i10, i2) i12 = int_add(i11, i3) i13 = int_add(i12, i4) @@ -2639,7 +2639,7 @@ i16 = int_add(i15, i7) i17 = int_add(i16, i8) i18 = int_add(i17, i9) - finish(i18, descr=faildescr1) []''' + finish(i18, descr=faildescr1)''' inputargs, operations, looptoken = self.parse( ops, namespace={'faildescr1': BasicFailDescr(1)}) operations[-1].getdescr().fast_path_done = True @@ -2659,8 +2659,8 @@ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] i10 = int_add(i0, 42) i11 = call_assembler_i(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, descr=looptoken) - guard_not_forced(descr=faildescr1)[] - finish(i11, descr=faildescr2) [] + guard_not_forced(descr=faildescr1) + finish(i11, descr=faildescr2) ''' faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) @@ -2706,11 +2706,11 @@ for _ in range(10): self.cpu.reserve_some_free_fail_descr_number() ops = ''' - [f0, f1] - i0 = float_eq(f0, -1.0) - guard_false(i0, descr=faildescr3) [] - f2 = float_add(f0, f1) - finish(f2, descr=faildescr) []''' + [f0, f4] + i6 = float_eq(f0, -1.0) + guard_false(i6, descr=faildescr3) + f2 = float_add(f0, f4) + finish(f2, descr=faildescr)''' inputargs, operations, looptoken = self.parse( ops, namespace={'faildescr': BasicFailDescr(1)}) operations[-1].getdescr().fast_path_done = True @@ -2724,10 +2724,10 @@ x = self.cpu.get_finish_value_float(frame) assert longlong.getrealfloat(x) == 1.2 + 2.3 ops = ''' - [f4, f5] - f3 = call_assembler_f(f4, f5, descr=looptoken) - guard_not_forced(descr=faildescr1)[] - finish(f3, descr=faildescr2) [] + [f4, f6] + f2 = call_assembler_f(f4, f6, descr=looptoken) + guard_not_forced(descr=faildescr1) + finish(f2, descr=faildescr2) ''' faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) @@ -2775,7 +2775,7 @@ ops = ''' [p0] call_v(ConstClass(fptr2), p0, descr=calldescr2) - finish(p0, descr=faildescr1) []''' + finish(p0, descr=faildescr1)''' inputargs, operations, looptoken = self.parse(ops, namespace=locals()) # not a fast_path finish! looptoken.outermost_jitdriver_sd = FakeJitDriverSD() @@ -2791,8 +2791,8 @@ [] p0 = jit_frame() p1 = call_assembler_r(p0, descr=looptoken) - guard_not_forced(descr=foodescr) [] - finish(descr=faildescr2) [] + guard_not_forced(descr=foodescr) + finish(descr=faildescr2) ''' inputargs, operations, othertoken = self.parse(ops, namespace=locals()) self.cpu.compile_loop(inputargs, operations, othertoken) @@ -2830,7 +2830,7 @@ py.test.skip("requires floats") called = [] def assembler_helper(jitframe): - faildescr =self.cpu.get_latest_descr(jitframe) + faildescr = self.cpu.get_latest_descr(jitframe) failindex = self.cpu.get_fail_descr_number(faildescr) called.append(failindex) return 13.5 @@ -2850,11 +2850,11 @@ for _ in range(10): self.cpu.reserve_some_free_fail_descr_number() ops = ''' - [f0, f1] - i0 = float_eq(f0, -1.0) - guard_false(i0, descr=faildescr2) [] - f2 = float_add(f0, f1) - finish(f2, descr=faildescr1) []''' + [f0, f4] + i6 = float_eq(f0, -1.0) + guard_false(i6, descr=faildescr2) + f2 = float_add(f0, f4) + finish(f2, descr=faildescr1)''' inputargs, operations, looptoken = self.parse( ops, namespace={'faildescr1': BasicFailDescr(1)}) operations[-1].getdescr().fast_path_done = True @@ -2870,10 +2870,10 @@ assert not called ops = ''' - [f4, f5] - f3 = call_assembler_f(f4, f5, descr=looptoken) - guard_not_forced(descr=faildescr1)[] - finish(f3, descr=faildescr2) [] + [f4, f6] + f2 = call_assembler_f(f4, f6, descr=looptoken) + guard_not_forced(descr=faildescr1) + finish(f2, descr=faildescr2) ''' faildescr2 = BasicFailDescr(2) faildescr1 = BasicFailDescr(1) @@ -2897,11 +2897,11 @@ # compile a replacement ops2 = ''' - [f0, f1] - i0 = float_eq(f0, -2.0) - guard_false(i0, descr=faildescr3) [] - f2 = float_sub(f0, f1) - finish(f2, descr=faildescr) []''' + [f0, f2] + ieq = float_eq(f0, -2.0) + guard_false(ieq, descr=faildescr3) + f4 = float_sub(f0, f2) + finish(f4, descr=faildescr)''' inputargs2, operations2, looptoken2 = self.parse( ops2, namespace={'faildescr': BasicFailDescr(1)}) operations2[-1].getdescr().fast_path_done = True From noreply at buildbot.pypy.org Mon Oct 29 17:40:19 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 17:40:19 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: fixfixdone :-) Message-ID: <20121029164019.E9BEB1C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58594:579992e8d40d Date: 2012-10-29 17:40 +0100 http://bitbucket.org/pypy/pypy/changeset/579992e8d40d/ Log: fixfixdone :-) diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -3315,35 +3315,35 @@ label(i0, descr=targettoken1) i1 = int_add(i0, 1) i2 = int_le(i1, 9) - guard_true(i2, descr=faildescr) [i1] + guard_true(i2, descr=faildescr) label(i1, descr=targettoken2) i3 = int_ge(i1, 0) - guard_true(i3, descr=faildescr3) [i1] + guard_true(i3, descr=faildescr3) jump(i1, descr=targettoken1) """, locals()) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 2) assert self.cpu.get_latest_descr(frame).identifier == 2 - res = self.cpu.get_latest_value_int(frame, 0) + res = self.get_frame_value(frame, "i1") assert res == 10 inputargs, operations, _ = self.parse(""" - [i0] - i2 = int_sub(i0, 20) + [i1] + i2 = int_sub(i1, 20) jump(i2, descr=targettoken2) """, locals()) self.cpu.compile_bridge(faildescr, inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 2) assert self.cpu.get_latest_descr(frame).identifier == 3 - res = self.cpu.get_latest_value_int(frame, 0) + res = self.get_frame_value(frame, "i1") assert res == -10 def test_int_force_ge_zero(self): ops = """ [i0] i1 = int_force_ge_zero(i0) # but forced to be in a register - finish(i1, descr=faildescr1) [] + finish(i1, descr=faildescr1) """ faildescr1 = BasicFailDescr(1) inputargs, operations, looptoken = self.parse( @@ -3365,7 +3365,7 @@ i0 = same_as(i2) # but forced to be in a register label(i0, descr=1) i1 = int_add(i0, i0) - guard_true(i1, descr=faildesr) [i1] + guard_true(i1, descr=faildesr) jump(i1, descr=1) """ faildescr = BasicFailDescr(2) @@ -3373,8 +3373,8 @@ faildescr = loop.operations[-2].getdescr() jumpdescr = loop.operations[-1].getdescr() bridge_ops = """ - [i0] - jump(i0, descr=jumpdescr) + [i1] + jump(i1, descr=jumpdescr) """ bridge = parse(bridge_ops, self.cpu, namespace=locals()) looptoken = JitCellToken() @@ -3417,7 +3417,7 @@ inputargs, operations, looptoken = self.parse(""" [i0] i1 = int_le(i0, 1) - guard_true(i1, descr=faildescr1) [i0] + guard_true(i1, descr=faildescr1) finish(i0, descr=faildescr2) """, locals()) self.cpu.compile_loop(inputargs, operations, looptoken1) @@ -3462,7 +3462,7 @@ call_v(ConstClass(func_ptr), i2, i4, i6, i8, i10, i12, i14, i16, i18, descr=calldescr) call_v(ConstClass(func_ptr), i2, i4, i6, i8, i10, i12, i14, i16, i18, descr=calldescr) i20 = int_lt(i19, 100) - guard_true(i20, descr=faildescr42) [] + guard_true(i20, descr=faildescr42) jump(i19, descr=targettoken1) """, locals()) self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken1) @@ -3482,13 +3482,13 @@ faildescr99 = BasicFailDescr(99) inputargs, operations, looptoken = self.parse(""" [p0] - guard_nonnull_class(p0, ConstClass(the_class), descr=faildescr) [] - finish(descr=faildescr1) [] + guard_nonnull_class(p0, ConstClass(the_class), descr=faildescr) + finish(descr=faildescr1) """, namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) _, operations, _ = self.parse(""" [] - finish(descr=faildescr99) [] + finish(descr=faildescr99) """, namespace=locals()) self.cpu.compile_bridge(faildescr, [], operations, looptoken) frame = self.cpu.execute_token(looptoken, @@ -3504,7 +3504,7 @@ ops = """ [i0, i1] i2 = raw_load_i(i0, i1, descr=arraydescr) - finish(i2, descr=faildescr1) [] + finish(i2, descr=faildescr1) """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -3530,7 +3530,7 @@ ops = """ [i0, i1] f2 = raw_load_f(i0, i1, descr=arraydescr) - finish(f2, descr=faildescr1) [] + finish(f2, descr=faildescr1) """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -3558,7 +3558,7 @@ ops = """ [i0, i1, i2] raw_store(i0, i1, i2, descr=arraydescr) - finish(descr=faildescr1) [] + finish(descr=faildescr1) """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -3583,7 +3583,7 @@ ops = """ [i0, i1, f2] raw_store(i0, i1, f2, descr=arraydescr) - finish(descr=faildescr1) [] + finish(descr=faildescr1) """ arraydescr = self.cpu.arraydescrof(rffi.CArray(T)) p = rawstorage.alloc_raw_storage(31) @@ -3605,7 +3605,7 @@ values = [] def maybe_force(token, flag): self.cpu.force(token) - values.append(self.cpu.get_latest_value_int(token, 0)) + values.append(self.get_frame_value(token, "i1")) values.append(token) return 42 @@ -3618,13 +3618,13 @@ [i0, i1] ptok = jit_frame() i2 = call_may_force_i(ConstClass(func_ptr), ptok, i1, descr=calldescr) - guard_not_forced(descr=faildescr) [i2] - finish(i2, descr=faildescr2) [] + guard_not_forced(descr=faildescr) + finish(i2, descr=faildescr2) ''', namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 23 - assert self.cpu.get_latest_value_int(frame, 0) == 42 + assert self.get_frame_value(frame, "i2") == 42 # make sure that force reads the registers from a zeroed piece of # memory assert values[0] == 0 From noreply at buildbot.pypy.org Mon Oct 29 17:42:43 2012 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 29 Oct 2012 17:42:43 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: hg merge result-in-resops Message-ID: <20121029164243.3BB081C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58595:b138acc8137f Date: 2012-10-29 17:42 +0100 http://bitbucket.org/pypy/pypy/changeset/b138acc8137f/ Log: hg merge result-in-resops diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py --- a/pypy/jit/metainterp/optimizeopt/heap.py +++ b/pypy/jit/metainterp/optimizeopt/heap.py @@ -25,6 +25,8 @@ # value pending in the ResOperation is *not* visible in # 'cached_fields'. # + + # XXXX kill dicts here self._cached_fields = {} self._cached_fields_getfield_op = {} self._lazy_setfield = None @@ -32,8 +34,8 @@ def do_setfield(self, optheap, op): # Update the state with the SETFIELD_GC/SETARRAYITEM_GC operation 'op'. - structvalue = optheap.getvalue(op.getarg(0)) - fieldvalue = optheap.getvalue(op.getarglist()[-1]) + structvalue = optheap.getforwarded(op.getarg(0)) + fieldvalue = optheap.getforwarded(op.getarglist()[-1]) if self.possible_aliasing(optheap, structvalue): self.force_lazy_setfield(optheap) assert not self.possible_aliasing(optheap, structvalue) @@ -44,7 +46,7 @@ optheap.optimizer.ensure_imported(cached_fieldvalue) cached_fieldvalue = self._cached_fields.get(structvalue, None) - if not fieldvalue.same_value(cached_fieldvalue): + if not optheap.optimizer.same_value(fieldvalue, cached_fieldvalue): # common case: store the 'op' as lazy_setfield, and register # myself in the optheap's _lazy_setfields_and_arrayitems list self._lazy_setfield = op @@ -94,14 +96,15 @@ # possible aliasing). self.clear() self._lazy_setfield = None - optheap.next_optimization.propagate_forward(op) + # XXX should we push it through the optimizer chain? + optheap.optimizer.emit_operation(op) if not can_cache: return # Once it is done, we can put at least one piece of information # back in the cache: the value of this particular structure's # field. - structvalue = optheap.getvalue(op.getarg(0)) - fieldvalue = optheap.getvalue(op.getarglist()[-1]) + structvalue = optheap.getforwarded(op.getarg(0)) + fieldvalue = optheap.getforwarded(op.getarglist()[-1]) self.remember_field_value(structvalue, fieldvalue, op) elif not can_cache: self.clear() @@ -294,7 +297,7 @@ # of virtualref_info and virtualizable_info are not gcptrs. def turned_constant(self, value): - value = self.getforwarded(value) + newvalue = self.getforwarded(value) for cf in self.cached_fields.itervalues(): cf.turned_constant(newvalue, value) for submap in self.cached_arrayitems.itervalues(): @@ -365,21 +368,29 @@ return pendingfields def optimize_GETFIELD_GC_i(self, op): - structvalue = self.getvalue(op.getarg(0)) + structvalue = self.getforwarded(op.getarg(0)) cf = self.field_cache(op.getdescr()) fieldvalue = cf.getfield_from_cache(self, structvalue) if fieldvalue is not None: self.replace(op, fieldvalue.op) return # default case: produce the operation - structvalue.ensure_nonnull() - self.emit_operation(op) - # then remember the result of reading the field - fieldvalue = self.getvalue(op) - cf.remember_field_value(structvalue, fieldvalue, op) + structvalue.setknownnonnull(True) + return op + optimize_GETFIELD_GC_r = optimize_GETFIELD_GC_i optimize_GETFIELD_GC_f = optimize_GETFIELD_GC_i + def postprocess_GETFIELD_GC_i(self, op): + # then remember the result of reading the field + structvalue = self.getforwarded(op.getarg(0)) + fieldvalue = self.getforwarded(op) + cf = self.field_cache(op.getdescr()) + cf.remember_field_value(structvalue, fieldvalue, op) + + postprocess_GETFIELD_GC_r = postprocess_GETFIELD_GC_i + postprocess_GETFIELD_GC_f = postprocess_GETFIELD_GC_i + def optimize_GETFIELD_GC_PURE_i(self, op): structvalue = self.getvalue(op.getarg(0)) cf = self.field_cache(op.getdescr()) @@ -394,6 +405,7 @@ optimize_GETFIELD_GC_PURE_r = optimize_GETFIELD_GC_PURE_i def optimize_SETFIELD_GC(self, op): + # XXX this is just debugging, should we comment it out somehow? if op.type == INT: op_key = create_resop_1(rop.GETFIELD_GC_PURE_i, 0, op.getarg(0), op.getdescr()) diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -36,7 +36,8 @@ dispatch_bounds_ops(self, op) def postprocess_GUARD_TRUE(self, op): - self.propagate_bounds_backward(op.getarg(0)) + if op.getarg(0).type == INT: + self.propagate_bounds_backward(op.getarg(0)) postprocess_GUARD_FALSE = postprocess_GUARD_TRUE postprocess_GUARD_VALUE = postprocess_GUARD_TRUE diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -158,13 +158,6 @@ return not op.nonnull() return False - def same_value(self, other): - if not other: - return False - if self.is_constant() and other.is_constant(): - return self.box.same_constant(other.box) - return self is other - def make_constant_class(self, classbox, guardop, index): assert self.level < LEVEL_KNOWNCLASS self.known_class = classbox @@ -257,13 +250,6 @@ def __init__(self): pass # make rpython happy - #def propagate_forward(self, op): - # raise NotImplementedError - - #def emit_operation(self, op): - # self.last_emitted_operation = op - # self.next_optimization.propagate_forward(op) - def process_inputargs(self, args): pass @@ -423,21 +409,6 @@ def replace(self, op, with_): self.getforwarded(op)._forwarded = with_ - def copy_op_if_modified_by_optimization(self, op): - xxxx - new_op = op.copy_if_modified_by_optimization(self) - if new_op is not op: - self.replace(op, new_op) - return new_op - - # XXX some RPython magic needed - def copy_and_change(self, op, *args, **kwds): - xxx - new_op = op.copy_and_change(*args, **kwds) - if new_op is not op: - self.replace(op, new_op) - return new_op - def ensure_imported(self, value): pass @@ -469,6 +440,15 @@ if not op.is_constant(): op._forwarded = ConstInt(intvalue) + def same_value(self, op1, op2): + if op1 is op2: + return True + if op2 is None: + return False + if op1.is_constant() and op2.is_constant(): + return op1.same_constant(op2) + return False + def new_ptr_box(self): return self.cpu.ts.BoxRef() @@ -511,10 +491,11 @@ for opt in self.optimizations: opt.process_inputargs(self.loop.inputargs) while i < len(self.loop.operations): - op = self.loop.operations[i] - orig_op = op + orig_op = self.loop.operations[i] + op = orig_op for opt in self.optimizations: op = opt.optimize_operation(op) + # result can be either None, the same thing or a new operation if op is None: break else: @@ -539,6 +520,7 @@ dispatch_opt(self, op) def emit_operation(self, op): + op = self.getforwarded(op) assert op.getopnum() not in opgroups.CALL_PURE assert not op._forwarded if isinstance(op, Const): @@ -558,6 +540,7 @@ def store_final_boxes_in_guard(self, op): return op # XXX we disable it for tests + xxxx assert op.getdescr() is None descr = op.invent_descr(self.jitdriver_sd, self.metainterp_sd) op.setdescr(descr) @@ -570,28 +553,6 @@ raise compile.giveup() descr.store_final_boxes(op, newboxes) # - if op.getopnum() == rop.GUARD_VALUE: - xxx - if self.getvalue(op.getarg(0)).is_bool_box: - # Hack: turn guard_value(bool) into guard_true/guard_false. - # This is done after the operation is emitted to let - # store_final_boxes_in_guard set the guard_opnum field of the - # descr to the original rop.GUARD_VALUE. - constvalue = op.getarg(1).getint() - if constvalue == 0: - newop = create_resop_1(rop.GUARD_FALSE, None, - op.getarg(0)) - elif constvalue == 1: - newop = create_resop_1(rop.GUARD_TRUE, None, - op.getarg(0)) - else: - raise AssertionError("uh?") - newop.set_extra("failargs", op.get_extra("failargs")) - self.replace(op, newop) - return newop - else: - # a real GUARD_VALUE. Make it use one counter per value. - descr.make_a_counter_per_value(op) return op def optimize_default(self, op): @@ -617,9 +578,6 @@ # self.emit_operation(op) # FIXME: Is this still needed? - def optimize_DEBUG_MERGE_POINT(self, op): - self.emit_operation(op) - def optimize_GETARRAYITEM_GC_PURE_i(self, op): indexvalue = self.getvalue(op.getarg(1)) if indexvalue.is_constant(): diff --git a/pypy/jit/metainterp/optimizeopt/pure.py b/pypy/jit/metainterp/optimizeopt/pure.py --- a/pypy/jit/metainterp/optimizeopt/pure.py +++ b/pypy/jit/metainterp/optimizeopt/pure.py @@ -12,6 +12,7 @@ self.emitted_pure_operations = [] def optimize_default(self, op): + orig_op = op op = self.getforwarded(op) canfold = op.is_always_pure() if op.is_ovf(): @@ -38,14 +39,13 @@ return # did we do the exact same operation already? - oldop = self.pure_operations.get(op) + oldop = self.pure_operations.get(orig_op) if oldop is not None: - self.replace(op, oldop) + self.optimizer.replace(op, oldop) return else: - self.pure_operations.set(op, op) + self.pure_operations.set(orig_op, op) self.remember_emitting_pure(op) - # otherwise, the operation remains if nextop: return nextop @@ -61,13 +61,11 @@ self.replace(op, oldop) self.last_emitted_operation = REMOVED return - else: - new_op = op.copy_if_modified_by_optimization(self.optimizer) - self.pure_operations.set(new_op, op) - self.remember_emitting_pure(op) - + new_op = self.optimizer.getforwarded(op) + self.pure_operations.set(op, new_op) + self.remember_emitting_pure(new_op) # replace CALL_PURE with just CALL - self.emit_operation(self.optimizer.copy_and_change(op, opnum)) + return new_op.make_forwarded_copy(opnum) return optimize_CALL_PURE optimize_CALL_PURE_i = _new_optimize_call_pure(rop.CALL_i) optimize_CALL_PURE_f = _new_optimize_call_pure(rop.CALL_f) @@ -79,7 +77,7 @@ # it was a CALL_PURE that was killed; so we also kill the # following GUARD_NO_EXCEPTION return - self.emit_operation(op) + return op def flush(self): assert self.posponedop is None diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -2,10 +2,11 @@ from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntBound from pypy.jit.metainterp.optimizeopt.optimizer import Optimization, CONST_1,\ - CONST_0 + CONST_0, REMOVED from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ConstInt, make_hashable_int, - create_resop_2, Const) + create_resop_2, Const, + create_resop_1) from pypy.rlib.rarithmetic import highest_bit @@ -52,7 +53,7 @@ arg1=op.getarg(0)) oldop = self.get_pure_result(key_op) if oldop is not None and oldop.getdescr() is op.getdescr(): - self.replace(op, oldop) + self.optimizer.replace(op, oldop) return True oldopnum = opboolinvers[opboolreflex[op.getopnum()]] @@ -76,16 +77,16 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) if v1.is_null(): - self.replace(op, op.getarg(1)) + self.optimizer.replace(op, op.getarg(1)) elif v2.is_null(): - self.replace(op, op.getarg(0)) + self.optimizer.replace(op, op.getarg(0)) else: - self.emit_operation(op) + return op def optimize_INT_SUB(self, op): v2 = self.getforwarded(op.getarg(1)) if v2.is_constant() and v2.getint() == 0: - self.replace(op, op.getarg(0)) + self.optimizer.replace(op, op.getarg(0)) else: # Synthesize the reverse ops for optimize_default to reuse self.pure(op.getarg(0), rop.INT_ADD, op.getarg(1), op) @@ -101,9 +102,9 @@ # If one side of the op is 0 the result is the other side. if v1.is_constant() and v1.getint() == 0: - self.replace(op, arg2) + self.optimizer.replace(op, arg2) elif v2.is_constant() and v2.getint() == 0: - self.replace(op, arg1) + self.optimizer.replace(op, arg1) else: # Synthesize the reverse op for optimize_default to reuse self.pure(op.getarg(0), rop.INT_SUB, op, op.getarg(1)) @@ -172,11 +173,11 @@ if v1.is_constant(): if v1.op.getfloat() == 1.0: - self.replace(op, rhs) + self.optimizer.replace(op, rhs) return elif v1.op.getfloat() == -1.0: new_op = create_resop_1(rop.FLOAT_NEG, 0.0, rhs) - self.replace(op, new_op) + self.optimizer.replace(op, new_op) self.emit_operation(new_op) return self.emit_operation(op) @@ -194,7 +195,7 @@ 'always fail') return if emit_operation: - return self.getforwarded(op) + return op def postprocess_guard(self, op, constbox): value = self.getforwarded(op.getarg(0)) @@ -212,31 +213,27 @@ def postprocess_GUARD_FALSE(self, op): self.postprocess_guard(op, CONST_0) - def postprocess_GUARD_NO_OVERFLOW(self, op): - pass # to be killed - - def postprocess_default(self, op): - if op.is_guard(): - xxx - def optimize_GUARD_ISNULL(self, op): - value = self.getvalue(op.getarg(0)) + value = self.getforwarded(op.getarg(0)) if value.is_null(): return elif value.is_nonnull(): raise InvalidLoop('A GUARD_ISNULL was proven to always fail') - self.emit_operation(op) - value.make_constant(self.optimizer.cpu.ts.CONST_NULL) + return op + + def postprocess_GUARD_ISNULL(self, op): + self.optimizer.make_constant(op.getarg(0), + self.optimizer.cpu.ts.CONST_NULL) def optimize_GUARD_NONNULL(self, op): - value = self.getvalue(op.getarg(0)) + value = self.getforwarded(op.getarg(0)) if value.is_nonnull(): return elif value.is_null(): raise InvalidLoop('A GUARD_NONNULL was proven to always fail') - pos = self.optimizer.get_pos() - self.emit_operation(op) - value.make_nonnull(op, pos) + value.setknownnonnull(True) + value.setlastguardpos(self.optimizer.get_pos()) + return op def optimize_GUARD_VALUE(self, op): value = self.getforwarded(op.getarg(0)) @@ -274,6 +271,17 @@ value.last_guard = None emit_operation = False else: + if not value.is_constant() and value.returns_bool_result(): + constvalue = op.getarg(1).getint() + if constvalue == 0: + newop = create_resop_1(rop.GUARD_FALSE, None, + op.getarg(0)) + elif constvalue == 1: + newop = create_resop_1(rop.GUARD_TRUE, None, + op.getarg(0)) + else: + raise AssertionError("uh?") + return newop emit_operation = True constbox = op.getarg(1) assert isinstance(constbox, Const) @@ -354,7 +362,7 @@ resop = self.loop_invariant_results.get(key, None) if resop is not None: - self.replace(op, resop) + self.optimizer.replace(op, resop) self.last_emitted_operation = REMOVED return # change the op to be a normal call, from the backend's point of view @@ -371,25 +379,25 @@ def _optimize_nullness(self, op, arg, expect_nonnull): value = self.getforwarded(arg) - if value.nonnull(): + if value.is_nonnull(): self.make_constant_int(op, expect_nonnull) - elif not value.nonnull(): + elif value.is_null(): self.make_constant_int(op, not expect_nonnull) else: return op def optimize_INT_IS_TRUE(self, op): if op.getarg(0).returns_bool_result(): - self.replace(op, op.getarg(0)) + self.optimizer.replace(op, op.getarg(0)) return return self._optimize_nullness(op, op.getarg(0), True) def optimize_INT_IS_ZERO(self, op): - self._optimize_nullness(op, op.getarg(0), False) + return self._optimize_nullness(op, op.getarg(0), False) def _optimize_oois_ooisnot(self, op, expect_isnot, instance): - value0 = self.getvalue(op.getarg(0)) - value1 = self.getvalue(op.getarg(1)) + value0 = self.getforwarded(op.getarg(0)) + value1 = self.getforwarded(op.getarg(1)) if value0.is_virtual(): if value1.is_virtual(): intres = (value0 is value1) ^ expect_isnot @@ -449,7 +457,7 @@ if oopspecindex == EffectInfo.OS_ARRAYCOPY: if self._optimize_CALL_ARRAYCOPY(op): return - self.emit_operation(op) + return op optimize_CALL_p = optimize_CALL_i optimize_CALL_f = optimize_CALL_i optimize_CALL_v = optimize_CALL_i @@ -490,14 +498,14 @@ # it's being done by someone else) for i in range(op.numargs()): arg = op.getarg(i) - const = self.get_constant_box(arg) + const = self.get_constant_op(arg) if const is None or not const.eq_value(arg): break else: self.make_constant(op, op.constbox()) self.last_emitted_operation = REMOVED return - self.emit_operation(op) + return op optimize_CALL_PURE_f = optimize_CALL_PURE_i optimize_CALL_PURE_p = optimize_CALL_PURE_i optimize_CALL_PURE_v = optimize_CALL_PURE_i @@ -507,7 +515,7 @@ # it was a CALL_PURE or a CALL_LOOPINVARIANT that was killed; # so we also kill the following GUARD_NO_EXCEPTION return - self.emit_operation(op) + return op def optimize_INT_FLOORDIV(self, op): v1 = self.getvalue(op.getarg(0)) @@ -542,6 +550,14 @@ optimize_SAME_AS_r = optimize_SAME_AS_i optimize_SAME_AS_f = optimize_SAME_AS_i + def optimize_JUMP(self, op): + self.optimizer.flush() + return op + + def optimize_FINISH(self, op): + self.optimizer.flush() + return op + #dispatch_opt = make_dispatcher_method(OptRewrite, 'optimize_', # default=OptRewrite.emit_operation) #optimize_guards = _findall(OptRewrite, 'optimize_', 'GUARD') diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -1,4 +1,7 @@ +import random + import py + from pypy.rlib.objectmodel import instantiate from pypy.jit.metainterp.optimizeopt.test.test_util import ( LLtypeMixin, BaseTest, FakeMetaInterpStaticData, convert_old_style_to_targets) @@ -13,6 +16,7 @@ from pypy.jit.metainterp.test.support import boxint from pypy.rlib.rarithmetic import LONG_BIT + def test_store_final_boxes_in_guard(): from pypy.jit.metainterp.resume import tag, TAGBOX b0 = boxint() @@ -185,9 +189,9 @@ self.optimize_loop(ops, expected) def test_constfold_all(self): - from pypy.jit.backend.llgraph.llimpl import TYPES # xxx fish + from pypy.jit.metainterp.optimizeopt.test.types import TYPES from pypy.jit.metainterp.executor import execute_nonspec - import random + for opnum in [rop._ALWAYS_PURE_FIRST, rop._ALWAYS_PURE_NO_PTR_LAST]: try: op = opname[opnum] @@ -195,8 +199,6 @@ continue if op.startswith('_'): continue - if 'FLOAT' in op: - continue argtypes, restype = TYPES[op.lower()] args = [] for argtype in argtypes: @@ -350,29 +352,16 @@ """ self.optimize_loop(ops, expected) - def test_remove_guard_value_if_constant(self): - ops = """ - [p1] - guard_value(p1, ConstPtr(myptr)) - jump(ConstPtr(myptr)) - """ - expected = """ - [] - jump() - """ - py.test.skip("XXX") - self.optimize_loop(ops, 'Constant(myptr)', expected) - def test_ooisnull_oononnull_1(self): ops = """ [p0] - guard_class(p0, ConstClass(node_vtable)) [] - guard_nonnull(p0) [] + guard_class(p0, ConstClass(node_vtable)) + guard_nonnull(p0) jump(p0) """ expected = """ [p0] - guard_class(p0, ConstClass(node_vtable)) [] + guard_class(p0, ConstClass(node_vtable)) jump(p0) """ self.optimize_loop(ops, expected) @@ -381,15 +370,15 @@ ops = """ [i0] i1 = int_is_true(i0) - guard_true(i1) [] + guard_true(i1) i2 = int_is_true(i0) - guard_true(i2) [] + guard_true(i2) jump(i0) """ expected = """ [i0] i1 = int_is_true(i0) - guard_true(i1) [] + guard_true(i1) jump(i0) """ self.optimize_loop(ops, expected) @@ -416,15 +405,15 @@ ops = """ [i0] i1 = int_is_zero(i0) - guard_true(i1) [] + guard_true(i1) i2 = int_is_true(i0) - guard_false(i2) [] + guard_false(i2) jump(i0) """ expected = """ [i0] i1 = int_is_zero(i0) - guard_true(i1) [] + guard_true(i1) jump(0) """ self.optimize_loop(ops, expected) @@ -432,13 +421,13 @@ def test_ooisnull_oononnull_2(self): ops = """ [p0] - guard_nonnull(p0) [] - guard_nonnull(p0) [] + guard_nonnull(p0) + guard_nonnull(p0) jump(p0) """ expected = """ [p0] - guard_nonnull(p0) [] + guard_nonnull(p0) jump(p0) """ self.optimize_loop(ops, expected) @@ -446,13 +435,13 @@ def test_ooisnull_on_null_ptr_1(self): ops = """ [p0, p1] - guard_isnull(p0) [] - guard_isnull(p0) [] + guard_isnull(p0) + guard_isnull(p0) jump(p1, p1) """ expected = """ [p0, p1] - guard_isnull(p0) [] + guard_isnull(p0) jump(p1, p1) """ self.optimize_loop(ops, expected) @@ -462,14 +451,14 @@ [p0] pv = new_with_vtable(ConstClass(node_vtable)) setfield_gc(pv, p0, descr=valuedescr) - guard_nonnull(p0) [] + guard_nonnull(p0) p1 = getfield_gc_r(pv, descr=valuedescr) - guard_nonnull(p1) [] + guard_nonnull(p1) jump(p0) """ expected = """ [p0] - guard_nonnull(p0) [] + guard_nonnull(p0) jump(p0) """ self.optimize_loop(ops, expected) @@ -477,20 +466,20 @@ def test_oois_1(self): ops = """ [p0] - guard_class(p0, ConstClass(node_vtable)) [] + guard_class(p0, ConstClass(node_vtable)) i0 = instance_ptr_ne(p0, NULL) - guard_true(i0) [] + guard_true(i0) i1 = instance_ptr_eq(p0, NULL) - guard_false(i1) [] + guard_false(i1) i2 = instance_ptr_ne(NULL, p0) - guard_true(i0) [] + guard_true(i0) i3 = instance_ptr_eq(NULL, p0) - guard_false(i1) [] + guard_false(i1) jump(p0) """ expected = """ [p0] - guard_class(p0, ConstClass(node_vtable)) [] + guard_class(p0, ConstClass(node_vtable)) jump(p0) """ self.optimize_loop(ops, expected) @@ -500,14 +489,14 @@ [p0] setfield_gc(p0, 5, descr=valuedescr) # forces p0 != NULL i0 = ptr_ne(p0, NULL) - guard_true(i0) [] + guard_true(i0) i1 = ptr_eq(p0, NULL) - guard_false(i1) [] + guard_false(i1) i2 = ptr_ne(NULL, p0) - guard_true(i0) [] + guard_true(i0) i3 = ptr_eq(NULL, p0) - guard_false(i1) [] - guard_nonnull(p0) [] + guard_false(i1) + guard_nonnull(p0) jump(p0) """ expected = """ @@ -520,14 +509,14 @@ def test_const_guard_value(self): ops = """ [i0] - guard_value(i0, 2) [] + guard_value(i0, 2) i = int_add(5, i0) - guard_value(i, 7) [] + guard_value(i, 7) jump(i0) """ expected = """ [i0] - guard_value(i0, 2) [] + guard_value(i0, 2) jump(2) """ self.optimize_loop(ops, expected) @@ -535,12 +524,12 @@ def test_constptr_guard_value(self): ops = """ [p1] - guard_value(p1, ConstPtr(myptr)) [] + guard_value(p1, ConstPtr(myptr)) jump(p1) """ expected = """ [p1] - guard_value(p1, ConstPtr(myptr)) [] + guard_value(p1, ConstPtr(myptr)) jump(ConstPtr(myptr)) """ self.optimize_loop(ops, expected) @@ -549,13 +538,13 @@ ops = """ [i] i1 = int_lt(i, 3) - guard_value(i1, 1) [i] + guard_value(i1, 1) jump(i) """ expected = """ [i] i1 = int_lt(i, 3) - guard_true(i1) [i] + guard_true(i1) jump(i) """ self.optimize_loop(ops, expected) @@ -564,13 +553,13 @@ ops = """ [i] i1 = int_is_true(i) - guard_value(i1, 0) [i] + guard_value(i1, 0) jump(i) """ expected = """ [i] i1 = int_is_true(i) - guard_false(i1) [i] + guard_false(i1) jump(i) """ self.optimize_loop(ops, expected) @@ -579,13 +568,13 @@ ops = """ [i] i1 = int_add(i, 3) - guard_value(i1, 0) [i] + guard_value(i1, 0) jump(i) """ expected = """ [i] i1 = int_add(i, 3) - guard_value(i1, 0) [i] + guard_value(i1, 0) jump(-3) """ self.optimize_loop(ops, expected) @@ -596,20 +585,17 @@ i2 = int_gt(i0, i1) i3 = int_is_true(i2) i4 = int_is_true(i3) - guard_value(i4, 0) [i0, i1] + guard_value(i4, 0) jump(i0, i1) """ expected = """ [i0, i1] i2 = int_gt(i0, i1) - guard_false(i2) [i0, i1] + guard_false(i2) jump(i0, i1) """ self.optimize_loop(ops, expected) - - - def test_p123_simple(self): ops = """ [i1, p2, p3] @@ -629,9 +615,9 @@ escape(i3) p1 = new_with_vtable(ConstClass(node_vtable)) p1sub = new_with_vtable(ConstClass(node_vtable2)) - setfield_gc(p1, i1, descr=valuedescr) setfield_gc(p1sub, i1, descr=valuedescr) setfield_gc(p1, p1sub, descr=nextdescr) + setfield_gc(p1, i1, descr=valuedescr) jump(i1, p1, p2) """ # The same as test_p123_simple, but with a virtual containing another @@ -644,10 +630,10 @@ p3sub = getfield_gc_r(p3, descr=nextdescr) i3 = getfield_gc_i(p3sub, descr=valuedescr) escape(i3) - p1 = new_with_vtable(ConstClass(node_vtable)) p2sub = new_with_vtable(ConstClass(node_vtable2)) setfield_gc(p2sub, i1, descr=valuedescr) setfield_gc(p2, p2sub, descr=nextdescr) + p1 = new_with_vtable(ConstClass(node_vtable)) jump(i1, p1, p2) """ # The same as test_p123_simple, but in the end the "old" p2 contains @@ -660,7 +646,7 @@ ops = """ [i1] i2 = call_i(i1, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() jump(i2) """ self.optimize_loop(ops, ops) @@ -669,13 +655,13 @@ ops = """ [i1] i2 = call_pure_i(123456, i1, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() jump(i2) """ expected = """ [i1] i2 = call_i(123456, i1, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() jump(i2) """ self.optimize_loop(ops, expected) @@ -685,7 +671,7 @@ [i1] i3 = same_as_i(81) i2 = call_pure_i(123456, i3, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() jump(i2) """ expected = """ @@ -698,15 +684,15 @@ ops = """ [i1] i2 = call_pure_i(123456, i1, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() i3 = call_pure_i(123456, i1, descr=nonwritedescr) - guard_no_exception() [i1, i2, i3] + guard_no_exception() jump(i3) """ expected = """ [i1] i2 = call_i(123456, i1, descr=nonwritedescr) - guard_no_exception() [i1, i2] + guard_no_exception() jump(i2) """ self.optimize_loop(ops, expected) @@ -717,26 +703,25 @@ ops = """ [i1] i2 = call_loopinvariant_i(1, i1, descr=nonwritedescr) - guard_no_exception() [] - guard_value(i2, 1) [] + guard_no_exception() + guard_value(i2, 1) i3 = call_loopinvariant_i(1, i1, descr=nonwritedescr) - guard_no_exception() [] - guard_value(i3, 1) [] + guard_no_exception() + guard_value(i3, 1) i4 = call_loopinvariant_i(1, i1, descr=nonwritedescr) - guard_no_exception() [] - guard_value(i4, 1) [] + guard_no_exception() + guard_value(i4, 1) jump(i1) """ expected = """ [i1] i2 = call_i(1, i1, descr=nonwritedescr) - guard_no_exception() [] - guard_value(i2, 1) [] + guard_no_exception() + guard_value(i2, 1) jump(i1) """ self.optimize_loop(ops, expected) - # ---------- def test_virtual_1(self): @@ -1102,13 +1087,13 @@ def test_getfield_gc_pure_2(self): ops = """ [p0, i] - guard_value(p0, ConstPtr(myptr)) [] + guard_value(p0, ConstPtr(myptr)) i1 = getfield_gc_pure_i(p0, descr=valuedescr) jump(p0, i1) """ expected = """ [p0, i] - guard_value(p0, ConstPtr(myptr)) [] + guard_value(p0, ConstPtr(myptr)) jump(ConstPtr(myptr), 5) """ self.node.value = 5 @@ -1128,7 +1113,7 @@ [i1] p1 = new_array(3, descr=arraydescr) i3 = arraylen_gc(p1, descr=arraydescr) - guard_value(i3, 3) [] + guard_value(i3, 3) setarrayitem_gc(p1, 1, i1, descr=arraydescr) setarrayitem_gc(p1, 0, 25, descr=arraydescr) i2 = getarrayitem_gc_i(p1, 1, descr=arraydescr) @@ -1159,7 +1144,7 @@ [f1] p1 = new_array(3, descr=floatarraydescr) i3 = arraylen_gc(p1, descr=floatarraydescr) - guard_value(i3, 3) [] + guard_value(i3, 3) setarrayitem_gc(p1, 1, f1, descr=floatarraydescr) setarrayitem_gc(p1, 0, 3.5, descr=floatarraydescr) f2 = getarrayitem_gc_f(p1, 1, descr=floatarraydescr) diff --git a/pypy/jit/metainterp/optimizeopt/test/types.py b/pypy/jit/metainterp/optimizeopt/test/types.py new file mode 100644 --- /dev/null +++ b/pypy/jit/metainterp/optimizeopt/test/types.py @@ -0,0 +1,105 @@ +TYPES = { + 'int_add' : (('int', 'int'), 'int'), + 'int_sub' : (('int', 'int'), 'int'), + 'int_mul' : (('int', 'int'), 'int'), + 'int_floordiv' : (('int', 'int'), 'int'), + 'int_mod' : (('int', 'int'), 'int'), + 'int_and' : (('int', 'int'), 'int'), + 'int_or' : (('int', 'int'), 'int'), + 'int_xor' : (('int', 'int'), 'int'), + 'int_lshift' : (('int', 'int'), 'int'), + 'int_rshift' : (('int', 'int'), 'int'), + 'int_lt' : (('int', 'int'), 'bool'), + 'int_gt' : (('int', 'int'), 'bool'), + 'int_ge' : (('int', 'int'), 'bool'), + 'int_le' : (('int', 'int'), 'bool'), + 'int_eq' : (('int', 'int'), 'bool'), + 'int_ne' : (('int', 'int'), 'bool'), + 'int_is_true' : (('int',), 'bool'), + 'int_is_zero' : (('int',), 'bool'), + 'int_neg' : (('int',), 'int'), + 'int_invert' : (('int',), 'int'), + 'int_add_ovf' : (('int', 'int'), 'int'), + 'int_sub_ovf' : (('int', 'int'), 'int'), + 'int_mul_ovf' : (('int', 'int'), 'int'), + 'int_force_ge_zero':(('int',), 'int'), + 'uint_add' : (('int', 'int'), 'int'), + 'uint_sub' : (('int', 'int'), 'int'), + 'uint_mul' : (('int', 'int'), 'int'), + 'uint_lt' : (('int', 'int'), 'bool'), + 'uint_le' : (('int', 'int'), 'bool'), + 'uint_eq' : (('int', 'int'), 'bool'), + 'uint_ne' : (('int', 'int'), 'bool'), + 'uint_gt' : (('int', 'int'), 'bool'), + 'uint_ge' : (('int', 'int'), 'bool'), + 'uint_xor' : (('int', 'int'), 'int'), + 'uint_rshift' : (('int', 'int'), 'int'), + 'uint_floordiv' : (('int', 'int'), 'int'), + 'float_add' : (('float', 'float'), 'float'), + 'float_sub' : (('float', 'float'), 'float'), + 'float_mul' : (('float', 'float'), 'float'), + 'float_truediv' : (('float', 'float'), 'float'), + 'float_lt' : (('float', 'float'), 'bool'), + 'float_le' : (('float', 'float'), 'bool'), + 'float_eq' : (('float', 'float'), 'bool'), + 'float_ne' : (('float', 'float'), 'bool'), + 'float_gt' : (('float', 'float'), 'bool'), + 'float_ge' : (('float', 'float'), 'bool'), + 'float_neg' : (('float',), 'float'), + 'float_abs' : (('float',), 'float'), + 'cast_float_to_int':(('float',), 'int'), + 'cast_int_to_float':(('int',), 'float'), + 'same_as' : (('int',), 'int'), # could also be ptr=>ptr + 'new_with_vtable' : (('ref',), 'ref'), + 'new' : ((), 'ref'), + 'new_array' : (('int',), 'ref'), + 'oois' : (('ref', 'ref'), 'bool'), + 'ooisnot' : (('ref', 'ref'), 'bool'), + 'instanceof' : (('ref',), 'bool'), + 'subclassof' : (('ref', 'ref'), 'bool'), + 'runtimenew' : (('ref',), 'ref'), + 'setfield_gc' : (('ref', 'intorptr'), None), + 'getfield_gc' : (('ref',), 'intorptr'), + 'getfield_gc_pure': (('ref',), 'intorptr'), + 'setfield_raw' : (('ref', 'intorptr'), None), + 'getfield_raw' : (('ref',), 'intorptr'), + 'getfield_raw_pure': (('ref',), 'intorptr'), + 'setarrayitem_gc' : (('ref', 'int', 'intorptr'), None), + 'getarrayitem_gc' : (('ref', 'int'), 'intorptr'), + 'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'), + 'setarrayitem_raw' : (('ref', 'int', 'intorptr'), None), + 'getarrayitem_raw' : (('ref', 'int'), 'intorptr'), + 'getarrayitem_raw_pure' : (('ref', 'int'), 'intorptr'), + 'arraylen_gc' : (('ref',), 'int'), + 'call' : (('ref', 'varargs'), 'intorptr'), + 'call_assembler' : (('varargs',), 'intorptr'), + 'cond_call_gc_wb' : (('ptr', 'ptr'), None), + 'cond_call_gc_wb_array': (('ptr', 'int', 'ptr'), None), + 'oosend' : (('varargs',), 'intorptr'), + 'oosend_pure' : (('varargs',), 'intorptr'), + 'guard_true' : (('bool',), None), + 'guard_false' : (('bool',), None), + 'guard_value' : (('int', 'int'), None), + 'guard_class' : (('ref', 'ref'), None), + 'guard_no_exception' : ((), None), + 'guard_exception' : (('ref',), 'ref'), + 'guard_no_overflow' : ((), None), + 'guard_overflow' : ((), None), + 'guard_nonnull' : (('ref',), None), + 'guard_isnull' : (('ref',), None), + 'guard_nonnull_class' : (('ref', 'ref'), None), + 'newstr' : (('int',), 'ref'), + 'strlen' : (('ref',), 'int'), + 'strgetitem' : (('ref', 'int'), 'int'), + 'strsetitem' : (('ref', 'int', 'int'), None), + 'newunicode' : (('int',), 'ref'), + 'unicodelen' : (('ref',), 'int'), + 'unicodegetitem' : (('ref', 'int'), 'int'), + 'unicodesetitem' : (('ref', 'int', 'int'), 'int'), + 'cast_ptr_to_int' : (('ref',), 'int'), + 'cast_int_to_ptr' : (('int',), 'ref'), + 'debug_merge_point': (('ref', 'int', 'int'), None), + 'force_token' : ((), 'int'), + 'call_may_force' : (('int', 'varargs'), 'intorptr'), + 'guard_not_forced': ((), None), +} diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py --- a/pypy/jit/metainterp/optimizeopt/virtualize.py +++ b/pypy/jit/metainterp/optimizeopt/virtualize.py @@ -425,7 +425,7 @@ # was already forced). def optimize_GETFIELD_GC_i(self, op): - value = self.getvalue(op.getarg(0)) + value = self.getforwarded(op.getarg(0)) # If this is an immutable field (as indicated by op.is_always_pure()) # then it's safe to reuse the virtual's field, even if it has been # forced, because it should never be written to again. @@ -435,14 +435,13 @@ self.replace(op, fieldvalue.op) return if value.is_virtual(): - assert isinstance(value, AbstractVirtualValue) fieldvalue = value.getfield(op.getdescr(), None) if fieldvalue is None: fieldvalue = self.optimizer.new_const(op.getdescr()) - self.replace(op, fieldvalue.op) + self.optimizer.replace(op, fieldvalue) else: - value.ensure_nonnull() - self.emit_operation(op) + value.setknownnonnull(True) + return op optimize_GETFIELD_GC_r = optimize_GETFIELD_GC_i optimize_GETFIELD_GC_f = optimize_GETFIELD_GC_i @@ -453,24 +452,23 @@ optimize_GETFIELD_GC_PURE_f = optimize_GETFIELD_GC_i def optimize_SETFIELD_GC(self, op): - value = self.getvalue(op.getarg(0)) + value = self.getforwarded(op.getarg(0)) if value.is_virtual(): - fieldvalue = self.getvalue(op.getarg(1)) + fieldvalue = self.getforwarded(op.getarg(1)) value.setfield(op.getdescr(), fieldvalue) else: - value.ensure_nonnull() - self.emit_operation(op) + value.setknownnonnull(True) + return op def optimize_NEW_WITH_VTABLE(self, op): - value = self.getforwarded(op) - value.setknownclass(op.getarg(0)) + pass def optimize_NEW(self, op): self.make_vstruct(op.getdescr(), op) def optimize_NEW_ARRAY(self, op): - sizebox = self.get_constant_box(op.getarg(0)) + sizebox = self.get_constant_op(op.getarg(0)) if sizebox is not None: # if the original 'op' did not have a ConstInt as argument, # build a new one with the ConstInt argument diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -538,7 +538,7 @@ if oopspecindex == EffectInfo.OS_STR2UNICODE: if self.opt_call_str_STR2UNICODE(op): return - self.emit_operation(op) + return op optimize_CALL_f = optimize_CALL_i optimize_CALL_r = optimize_CALL_i optimize_CALL_v = optimize_CALL_i @@ -551,7 +551,7 @@ def optimize_GUARD_NO_EXCEPTION(self, op): if self.last_emitted_operation is REMOVED: return - self.emit_operation(op) + return op def opt_call_str_STR2UNICODE(self, op): # Constant-fold unicode("constant string"). diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py --- a/pypy/jit/metainterp/optmodel.py +++ b/pypy/jit/metainterp/optmodel.py @@ -4,9 +4,10 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable, rop,\ - VOID, INT, REF, ConstInt, Const + VOID, INT, REF, ConstInt, Const, ConstPtr from pypy.jit.metainterp.optimizeopt.intutils import ImmutableIntUnbounded,\ - ConstantIntBound + ConstantIntBound, IntBound +from pypy.jit.metainterp.virtualmodel import Virtual class __extend__(ConstInt): def getintbound(self): @@ -15,6 +16,13 @@ def getboolres(self): return False # for optimization +class __extend__(ConstPtr): + def is_virtual(self): + return False + + def is_forced_virtual(self): + return False + class __extend__(Const): def getlastguardpos(self): return -1 @@ -22,9 +30,18 @@ def force(self, _): return self + def is_nonnull(self): + return self.nonnull() + + def is_null(self): + return not self.nonnull() + +opclasses_mutable[rop.NEW_WITH_VTABLE] = Virtual + def create_mutable_subclasses(): def addattr(cls, attr, default_value=None): - cls.attributes_to_copy.append('_' + attr) + if hasattr(cls, 'attributes_to_copy'): + cls.attributes_to_copy.append('_' + attr) def getter(self): return getattr(self, '_' + attr) def setter(self, value): @@ -40,22 +57,43 @@ setattr(new, attr, getattr(self, attr)) cls._copy_extra_attrs = _copy_extra_attrs + def int_is_null(self): + return False + + def int_is_nonnull(self): + intbound = self.getintbound() + if intbound is not None: + if intbound.known_gt(IntBound(0, 0)) or \ + intbound.known_lt(IntBound(0, 0)): + return True + return False + return False + + def ref_is_null(self): + return False + + def ref_is_nonnull(self): + return self.getknownclass() is not None or self.getknownnonnull() + imm_int_unbound = ImmutableIntUnbounded() for i, cls in enumerate(opclasses): if cls is None: - Mutable = None + continue + elif opclasses_mutable[cls.getopnum()] is not None: + addattr(opclasses_mutable[cls.getopnum()], 'lastguardpos') + continue else: class Mutable(cls): is_mutable = True attributes_to_copy = [] - if cls.getopnum() in (rop.NEW_WITH_VTABLE, rop.NEW): - def force(self, optimizer): - optimizer.emit_operation(self) - return self - else: - def force(self, _): - return self + def force(self, _): + return self + def is_virtual(self): + return False + def is_forced_virtual(self): + return False + if cls.type != VOID: addattr(Mutable, 'varindex', -1) #if cls.type == REF: @@ -66,16 +104,19 @@ # all the integers have bounds addattr(Mutable, 'intbound', imm_int_unbound) addattr(Mutable, 'boolres', False) + Mutable.is_nonnull = int_is_nonnull + Mutable.is_null = int_is_null elif cls.type == REF: addattr(Mutable, 'knownclass', None) + addattr(Mutable, 'knownnonnull', False) + Mutable.is_nonnull = ref_is_nonnull + Mutable.is_null = ref_is_null # for tracking last guard and merging GUARD_VALUE with # GUARD_NONNULL etc addattr(Mutable, 'lastguardpos', -1) Mutable.__name__ = cls.__name__ + '_mutable' if Mutable.attributes_to_copy: make_new_copy_function(Mutable, cls) - assert len(opclasses_mutable) == i - opclasses_mutable.append(Mutable) - assert len(opclasses) == len(opclasses_mutable) + opclasses_mutable[i] = Mutable create_mutable_subclasses() diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -485,9 +485,9 @@ # XXX this is a hack kill me import sys co_fname = sys._getframe(1).f_code.co_filename - if co_fname.endswith('resume.py') or co_fname.endswith('optimizeopt/util.py') or 'backend/llgraph' in co_fname or 'backend/test' in co_fname or 'test/test_util' in co_fname: + if co_fname.endswith('resume.py') or co_fname.endswith('optimizeopt/util.py') or 'backend/llgraph' in co_fname or 'backend/test' in co_fname or 'test/test_util' in co_fname or co_fname.endswith('heap.py'): return object.__hash__(self) - raise Exception("Should not hash resops, use get/set extra instead") + raise Exception("Should not hash resops") def _get_hash_(self): """ rpython level implementation of hash, cache it because computations @@ -1424,6 +1424,8 @@ pass def setup(debug_print=False): + global opclasses_mutable + i = 0 for basename in _oplist: if '/' in basename: @@ -1466,6 +1468,7 @@ if k.startswith('CALL'): ALLCALLS.append(v) opgroups.ALLCALLS = tuple(ALLCALLS) + opclasses_mutable = [None] * len(opclasses) def get_base_class(mixin, tpmixin, base): try: diff --git a/pypy/jit/metainterp/virtualmodel.py b/pypy/jit/metainterp/virtualmodel.py new file mode 100644 --- /dev/null +++ b/pypy/jit/metainterp/virtualmodel.py @@ -0,0 +1,57 @@ + +from pypy.jit.metainterp.resoperation import rop, opclasses, create_resop_2 +from pypy.rlib.objectmodel import we_are_translated + +NEW_WITH_VTABLE = opclasses[rop.NEW_WITH_VTABLE] + +class Virtual(NEW_WITH_VTABLE): + is_mutable = True + + def __init__(self, pval): + NEW_WITH_VTABLE.__init__(self, pval) + self._fields = {} # XXX convert from dict to a list + self._is_forced = False + + def getfield(self, ofs, default): + return self._fields.get(ofs, default) + + def setfield(self, ofs, fieldvalue): + self._fields[ofs] = fieldvalue + + def getknownclass(self): + return self.getarg(0) + + def setknownclass(self, cls): + pass # ignore + + def is_nonnull(self): + return True + + def is_null(self): + return False + + def _copy_extra_attrs(self, new): + raise Exception("Virtual should not be forwarded") + + def force(self, optimizer): + if not self._is_forced: + self._is_forced = True + optimizer.emit_operation(self) + iteritems = self._fields.iteritems() + if not we_are_translated(): #random order is fine, except for tests + iteritems = list(iteritems) + iteritems.sort(key = lambda (x,y): x.sort_key()) + for ofs, value in iteritems: + if value.is_null(): + continue + subbox = value.force(optimizer) + op = create_resop_2(rop.SETFIELD_GC, None, self, subbox, + descr=ofs) + optimizer.emit_operation(op) + return self + + def is_virtual(self): + return not self._is_forced + + def is_forced_virtual(self): + return self._is_forced From noreply at buildbot.pypy.org Mon Oct 29 20:34:55 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 29 Oct 2012 20:34:55 +0100 (CET) Subject: [pypy-commit] pypy py3k: bounds check for bad data (thanks amaury) Message-ID: <20121029193455.39AE61C039C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58596:77bd102bba03 Date: 2012-10-29 12:27 -0700 http://bitbucket.org/pypy/pypy/changeset/77bd102bba03/ Log: bounds check for bad data (thanks amaury) port input fix checking from http://bugs.python.org/issue16336 diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py --- a/pypy/module/_codecs/interp_codecs.py +++ b/pypy/module/_codecs/interp_codecs.py @@ -275,9 +275,10 @@ # let the codec call us again ch0 = ord(obj[start + 0]) ch1 = ord(obj[start + 1]) - ch2 = ord(obj[start + 2]) - if (ch0 & 0xf0 == 0xe0 or - ch1 & 0xc0 == 0x80 or + ch2 = ord(obj[start + 2]) if len(obj) > start + 2 else -1 + if (ch2 != -1 and + ch0 & 0xf0 == 0xe0 and + ch1 & 0xc0 == 0x80 and ch2 & 0xc0 == 0x80): # it's a three-byte code ch = ((ch0 & 0x0f) << 12) + ((ch1 & 0x3f) << 6) + (ch2 & 0x3f) diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py --- a/pypy/module/_codecs/test/test_codecs.py +++ b/pypy/module/_codecs/test/test_codecs.py @@ -499,6 +499,10 @@ b"abc\xed\xa0\x80def") assert (b"abc\xed\xa0\x80def".decode("utf-8", "surrogatepass") == "abc\ud800def") + raises(UnicodeDecodeError, b"abc\xed\xa0".decode, "utf-8", + "surrogatepass") + raises(UnicodeDecodeError, b"abc\xed\xa0z".decode, "utf-8", + "surrogatepass") def test_badhandler(self): import codecs From noreply at buildbot.pypy.org Mon Oct 29 20:34:56 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 29 Oct 2012 20:34:56 +0100 (CET) Subject: [pypy-commit] pypy py3k: update input to py3 Message-ID: <20121029193456.78FAF1C039C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58597:0aaca88b57f4 Date: 2012-10-29 12:31 -0700 http://bitbucket.org/pypy/pypy/changeset/0aaca88b57f4/ Log: update input to py3 diff --git a/pypy/module/__builtin__/app_io.py b/pypy/module/__builtin__/app_io.py --- a/pypy/module/__builtin__/app_io.py +++ b/pypy/module/__builtin__/app_io.py @@ -13,10 +13,6 @@ pass else: flush() - try: - stdout.softspace = 0 - except (AttributeError, TypeError): - pass def input(prompt=''): """input([prompt]) -> string @@ -33,11 +29,17 @@ stdout = sys.stdout except AttributeError: raise RuntimeError("input: lost sys.stdout") + try: + stderr = sys.stderr + except AttributeError: + raise RuntimeError("input: lost sys.stderr") + + stderr.flush() # hook for the readline module if (hasattr(sys, '__raw_input__') and - isinstance(stdin, file) and stdin.fileno() == 0 and stdin.isatty() and - isinstance(stdout, file) and stdout.fileno() == 1): + stdin.fileno() == 0 and stdin.isatty() and + stdout.fileno() == 1): _write_prompt(stdout, '') return sys.__raw_input__(str(prompt)) diff --git a/pypy/module/__builtin__/test/test_rawinput.py b/pypy/module/__builtin__/test/test_rawinput.py --- a/pypy/module/__builtin__/test/test_rawinput.py +++ b/pypy/module/__builtin__/test/test_rawinput.py @@ -6,6 +6,11 @@ def test_input_and_raw_input(self): import sys, io + flushed = [False] + class CheckFlushed(io.StringIO): + def flush(self): + flushed[0] = True + super().flush() for prompt, expected in [("def:", "abc/def:/ghi\n"), ("", "abc//ghi\n"), (42, "abc/42/ghi\n"), @@ -13,10 +18,14 @@ (Ellipsis, "abc//ghi\n")]: for inputfn, inputtext, gottext in [ (input, "foo\nbar\n", "foo")]: - save = sys.stdin, sys.stdout + save = sys.stdin, sys.stdout, sys.stderr try: sys.stdin = io.StringIO(inputtext) out = sys.stdout = io.StringIO() + # Ensure that input flushes stderr + flushed = [False] + err = sys.stderr = CheckFlushed() + sys.stderr.write('foo') print("abc", end='') out.write('/') if prompt is Ellipsis: @@ -26,8 +35,9 @@ out.write('/') print("ghi") finally: - sys.stdin, sys.stdout = save + sys.stdin, sys.stdout, sys.stderr = save assert out.getvalue() == expected + assert flushed[0] assert got == gottext def test_softspace(self): From noreply at buildbot.pypy.org Mon Oct 29 20:34:57 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 29 Oct 2012 20:34:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: cleanup Message-ID: <20121029193457.B28E01C039C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58598:48d6dbdb7f81 Date: 2012-10-29 12:32 -0700 http://bitbucket.org/pypy/pypy/changeset/48d6dbdb7f81/ Log: cleanup diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -261,9 +261,9 @@ def unicode_from_object(space, w_obj): if space.is_w(space.type(w_obj), space.w_unicode): return w_obj - - w_unicode_method = space.lookup(w_obj, "__str__") - return space.repr(w_obj) if w_unicode_method is None else space.str(w_obj) + if space.lookup(w_obj, "__str__") is not None: + return space.str(w_obj) + return space.repr(w_obj) def ascii_from_object(space, w_obj): """Implements builtins.ascii()""" From noreply at buildbot.pypy.org Mon Oct 29 20:34:58 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 29 Oct 2012 20:34:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: escape surrogates in marshal Message-ID: <20121029193458.CCC891C039C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r58599:6404ccd57b8c Date: 2012-10-29 12:32 -0700 http://bitbucket.org/pypy/pypy/changeset/6404ccd57b8c/ Log: escape surrogates in marshal diff --git a/lib-python/3.2/test/test_marshal.py b/lib-python/3.2/test/test_marshal.py --- a/lib-python/3.2/test/test_marshal.py +++ b/lib-python/3.2/test/test_marshal.py @@ -165,7 +165,7 @@ s = b'c' + (b'X' * 4*4) + b'{' * 2**20 self.assertRaises(ValueError, marshal.loads, s) - @test_support.impl_detail('specific recursion check') + @support.impl_detail('specific recursion check') def test_recursion_limit(self): # Create a deeply nested structure. head = last = [] diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -48,13 +48,15 @@ final=True, errorhandler=decode_error_handler(space)) return result -def PyUnicode_DecodeUTF8(space, string): +def PyUnicode_DecodeUTF8(space, string, allow_surrogates=False): result, consumed = runicode.str_decode_utf_8( string, len(string), "strict", - final=True, errorhandler=decode_error_handler(space)) + final=True, errorhandler=decode_error_handler(space), + allow_surrogates=allow_surrogates) return result -def PyUnicode_EncodeUTF8(space, uni): +def PyUnicode_EncodeUTF8(space, uni, allow_surrogates=False): return runicode.unicode_encode_utf_8( uni, len(uni), "strict", - errorhandler=encode_error_handler(space)) + errorhandler=encode_error_handler(space), + allow_surrogates=allow_surrogates) diff --git a/pypy/objspace/std/marshal_impl.py b/pypy/objspace/std/marshal_impl.py --- a/pypy/objspace/std/marshal_impl.py +++ b/pypy/objspace/std/marshal_impl.py @@ -380,11 +380,14 @@ register(TYPE_CODE, unmarshal_pycode) def marshal_w__Unicode(space, w_unicode, m): - s = unicodehelper.PyUnicode_EncodeUTF8(space, space.unicode_w(w_unicode)) + s = unicodehelper.PyUnicode_EncodeUTF8(space, space.unicode_w(w_unicode), + allow_surrogates=True) m.atom_str(TYPE_UNICODE, s) def unmarshal_Unicode(space, u, tc): - return space.wrap(unicodehelper.PyUnicode_DecodeUTF8(space, u.get_str())) + return space.wrap( + unicodehelper.PyUnicode_DecodeUTF8(space, u.get_str(), + allow_surrogates=True)) register(TYPE_UNICODE, unmarshal_Unicode) app = gateway.applevel(r''' From noreply at buildbot.pypy.org Mon Oct 29 21:50:25 2012 From: noreply at buildbot.pypy.org (wlav) Date: Mon, 29 Oct 2012 21:50:25 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: merge default into branch Message-ID: <20121029205025.787CA1C0185@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r58600:dd2f38048bc5 Date: 2012-10-28 13:36 -0700 http://bitbucket.org/pypy/pypy/changeset/dd2f38048bc5/ Log: merge default into branch diff too long, truncating to 2000 out of 2554 lines diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py deleted file mode 100644 --- a/lib_pypy/itertools.py +++ /dev/null @@ -1,670 +0,0 @@ -# Note that PyPy contains also a built-in module 'itertools' which will -# hide this one if compiled in. - -"""Functional tools for creating and using iterators. - -Infinite iterators: -count([n]) --> n, n+1, n+2, ... -cycle(p) --> p0, p1, ... plast, p0, p1, ... -repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times - -Iterators terminating on the shortest input sequence: -izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... -ifilter(pred, seq) --> elements of seq where pred(elem) is True -ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False -islice(seq, [start,] stop [, step]) --> elements from - seq[start:stop:step] -imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ... -starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ... -tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n -chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... -takewhile(pred, seq) --> seq[0], seq[1], until pred fails -dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails -groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v) -""" - -__all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', - 'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap', - 'takewhile', 'tee', 'compress', 'product'] - -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f - - -class chain(object): - """Make an iterator that returns elements from the first iterable - until it is exhausted, then proceeds to the next iterable, until - all of the iterables are exhausted. Used for treating consecutive - sequences as a single sequence. - - Equivalent to : - - def chain(*iterables): - for it in iterables: - for element in it: - yield element - """ - def __init__(self, *iterables): - self._iterables_iter = iter(map(iter, iterables)) - # little trick for the first chain.next() call - self._cur_iterable_iter = iter([]) - - def __iter__(self): - return self - - def next(self): - while True: - try: - return self._cur_iterable_iter.next() - except StopIteration: - self._cur_iterable_iter = self._iterables_iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iterable_iter)) - - -class compress(object): - def __init__(self, data, selectors): - self.data = iter(data) - self.selectors = iter(selectors) - - def __iter__(self): - return self - - def next(self): - while True: - next_item = self.data.next() - next_selector = self.selectors.next() - if bool(next_selector): - return next_item - - -class count(object): - """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. - - Equivalent to : - - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) - while True: - yield n - n += 1 - """ - def __init__(self, n=0): - if not isinstance(n, int): - raise TypeError('%s is not a regular integer' % n) - self.times = n-1 - - def __iter__(self): - return self - - def next(self): - self.times += 1 - return self.times - - def __repr__(self): - return 'count(%d)' % (self.times + 1) - - - -class cycle(object): - """Make an iterator returning elements from the iterable and - saving a copy of each. When the iterable is exhausted, return - elements from the saved copy. Repeats indefinitely. - - Equivalent to : - - def cycle(iterable): - saved = [] - for element in iterable: - yield element - saved.append(element) - while saved: - for element in saved: - yield element - """ - def __init__(self, iterable): - self._cur_iter = iter(iterable) - self._saved = [] - self._must_save = True - - def __iter__(self): - return self - - def next(self): - # XXX Could probably be improved - try: - next_elt = self._cur_iter.next() - if self._must_save: - self._saved.append(next_elt) - except StopIteration: - self._cur_iter = iter(self._saved) - next_elt = self._cur_iter.next() - self._must_save = False - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iter)) - return next_elt - - -class dropwhile(object): - """Make an iterator that drops elements from the iterable as long - as the predicate is true; afterwards, returns every - element. Note, the iterator does not produce any output until the - predicate is true, so it may have a lengthy start-up time. - - Equivalent to : - - def dropwhile(predicate, iterable): - iterable = iter(iterable) - for x in iterable: - if not predicate(x): - yield x - break - for x in iterable: - yield x - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - self._dropped = False - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if self._dropped: - return value - while self._predicate(value): - value = self._iter.next() - self._dropped = True - return value - -class groupby(object): - """Make an iterator that returns consecutive keys and groups from the - iterable. The key is a function computing a key value for each - element. If not specified or is None, key defaults to an identity - function and returns the element unchanged. Generally, the - iterable needs to already be sorted on the same key function. - - The returned group is itself an iterator that shares the - underlying iterable with groupby(). Because the source is shared, - when the groupby object is advanced, the previous group is no - longer visible. So, if that data is needed later, it should be - stored as a list: - - groups = [] - uniquekeys = [] - for k, g in groupby(data, keyfunc): - groups.append(list(g)) # Store group iterator as a list - uniquekeys.append(k) - """ - def __init__(self, iterable, key=None): - if key is None: - key = lambda x: x - self.keyfunc = key - self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = xrange(0) - - def __iter__(self): - return self - - def next(self): - while self.currkey == self.tgtkey: - try: - self.currvalue = self.it.next() # Exit on StopIteration - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self.it)) - self.currkey = self.keyfunc(self.currvalue) - self.tgtkey = self.currkey - return (self.currkey, self._grouper(self.tgtkey)) - - def _grouper(self, tgtkey): - while self.currkey == tgtkey: - yield self.currvalue - self.currvalue = self.it.next() # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) - - - -class _ifilter_base(object): - """base class for ifilter and ifilterflase""" - def __init__(self, predicate, iterable): - # Make sure iterable *IS* iterable - self._iter = iter(iterable) - if predicate is None: - self._predicate = bool - else: - self._predicate = predicate - - def __iter__(self): - return self - -class ifilter(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is True. If predicate is - None, return the items that are true. - - Equivalent to : - - def ifilter: - if predicate is None: - predicate = bool - for x in iterable: - if predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - -class ifilterfalse(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is False. If predicate is - None, return the items that are false. - - Equivalent to : - - def ifilterfalse(predicate, iterable): - if predicate is None: - predicate = bool - for x in iterable: - if not predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if not self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - - - - -class imap(object): - """Make an iterator that computes the function using arguments - from each of the iterables. If function is set to None, then - imap() returns the arguments as a tuple. Like map() but stops - when the shortest iterable is exhausted instead of filling in - None for shorter iterables. The reason for the difference is that - infinite iterator arguments are typically an error for map() - (because the output is fully evaluated) but represent a common - and useful way of supplying arguments to imap(). - - Equivalent to : - - def imap(function, *iterables): - iterables = map(iter, iterables) - while True: - args = [i.next() for i in iterables] - if function is None: - yield tuple(args) - else: - yield function(*args) - - """ - def __init__(self, function, iterable, *other_iterables): - self._func = function - self._iters = map(iter, (iterable, ) + other_iterables) - - def __iter__(self): - return self - - def next(self): - try: - args = [it.next() for it in self._iters] - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (it)) - if self._func is None: - return tuple(args) - else: - return self._func(*args) - - - -class islice(object): - """Make an iterator that returns selected elements from the - iterable. If start is non-zero, then elements from the iterable - are skipped until start is reached. Afterward, elements are - returned consecutively unless step is set higher than one which - results in items being skipped. If stop is None, then iteration - continues until the iterator is exhausted, if at all; otherwise, - it stops at the specified position. Unlike regular slicing, - islice() does not support negative values for start, stop, or - step. Can be used to extract related fields from data where the - internal structure has been flattened (for example, a multi-line - report may list a name field on every third line). - """ - def __init__(self, iterable, *args): - s = slice(*args) - self.start, self.stop, self.step = s.start or 0, s.stop, s.step - if not isinstance(self.start, (int, long)): - raise ValueError("Start argument must be an integer") - if self.stop is not None and not isinstance(self.stop, (int,long)): - raise ValueError("Stop argument must be an integer or None") - if self.step is None: - self.step = 1 - if self.start<0 or (self.stop is not None and self.stop<0 - ) or self.step<=0: - raise ValueError, "indices for islice() must be positive" - self.it = iter(iterable) - self.donext = None - self.cnt = 0 - - def __iter__(self): - return self - - def next(self): - if self.donext is None: - try: - self.donext = self.it.next - except AttributeError: - raise TypeError - nextindex = self.start - if self.stop is not None and nextindex >= self.stop: - raise StopIteration - while self.cnt <= nextindex: - nextitem = self.donext() - self.cnt += 1 - self.start += self.step - return nextitem - -class izip(object): - """Make an iterator that aggregates elements from each of the - iterables. Like zip() except that it returns an iterator instead - of a list. Used for lock-step iteration over several iterables at - a time. - - Equivalent to : - - def izip(*iterables): - iterables = map(iter, iterables) - while iterables: - result = [i.next() for i in iterables] - yield tuple(result) - """ - def __init__(self, *iterables): - self._iterators = map(iter, iterables) - self._result = [None] * len(self._iterators) - - def __iter__(self): - return self - - def next(self): - if not self._iterators: - raise StopIteration() - try: - return tuple([i.next() for i in self._iterators]) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (i)) - - -class product(object): - - def __init__(self, *args, **kw): - if len(kw) > 1: - raise TypeError("product() takes at most 1 argument (%d given)" % - len(kw)) - self.repeat = kw.get('repeat', 1) - self.gears = [x for x in args] * self.repeat - self.num_gears = len(self.gears) - # initialization of indicies to loop over - self.indicies = [(0, len(self.gears[x])) - for x in range(0, self.num_gears)] - self.cont = True - - def roll_gears(self): - # Starting from the end of the gear indicies work to the front - # incrementing the gear until the limit is reached. When the limit - # is reached carry operation to the next gear - should_carry = True - for n in range(0, self.num_gears): - nth_gear = self.num_gears - n - 1 - if should_carry: - count, lim = self.indicies[nth_gear] - count += 1 - if count == lim and nth_gear == 0: - self.cont = False - if count == lim: - should_carry = True - count = 0 - else: - should_carry = False - self.indicies[nth_gear] = (count, lim) - else: - break - - def __iter__(self): - return self - - def next(self): - if not self.cont: - raise StopIteration - l = [] - for x in range(0, self.num_gears): - index, limit = self.indicies[x] - l.append(self.gears[x][index]) - self.roll_gears() - return tuple(l) - - -class repeat(object): - """Make an iterator that returns object over and over again. - Runs indefinitely unless the times argument is specified. Used - as argument to imap() for invariant parameters to the called - function. Also used with izip() to create an invariant part of a - tuple record. - - Equivalent to : - - def repeat(object, times=None): - if times is None: - while True: - yield object - else: - for i in xrange(times): - yield object - """ - def __init__(self, obj, times=None): - self._obj = obj - if times is not None: - xrange(times) # Raise a TypeError - if times < 0: - times = 0 - self._times = times - - def __iter__(self): - return self - - def next(self): - # next() *need* to decrement self._times when consumed - if self._times is not None: - if self._times <= 0: - raise StopIteration() - self._times -= 1 - return self._obj - - def __repr__(self): - if self._times is not None: - return 'repeat(%r, %r)' % (self._obj, self._times) - else: - return 'repeat(%r)' % (self._obj,) - - def __len__(self): - if self._times == -1 or self._times is None: - raise TypeError("len() of uniszed object") - return self._times - - -class starmap(object): - """Make an iterator that computes the function using arguments - tuples obtained from the iterable. Used instead of imap() when - argument parameters are already grouped in tuples from a single - iterable (the data has been ``pre-zipped''). The difference - between imap() and starmap() parallels the distinction between - function(a,b) and function(*c). - - Equivalent to : - - def starmap(function, iterable): - iterable = iter(iterable) - while True: - yield function(*iterable.next()) - """ - def __init__(self, function, iterable): - self._func = function - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - # CPython raises a TypeError when the iterator doesn't return a tuple - try: - t = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - if not isinstance(t, tuple): - raise TypeError("iterator must return a tuple") - return self._func(*t) - - - -class takewhile(object): - """Make an iterator that returns elements from the iterable as - long as the predicate is true. - - Equivalent to : - - def takewhile(predicate, iterable): - for x in iterable: - if predicate(x): - yield x - else: - break - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if not self._predicate(value): - raise StopIteration() - return value - - -class TeeData(object): - """Holds cached values for TeeObjects""" - def __init__(self, iterator): - self.data = [] - self._iter = iterator - - def __getitem__(self, i): - # iterates until 'i' if not done yet - while i>= len(self.data): - try: - self.data.append( self._iter.next() ) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - return self.data[i] - - -class TeeObject(object): - """Iterables / Iterators as returned by the tee() function""" - def __init__(self, iterable=None, tee_data=None): - if tee_data: - self.tee_data = tee_data - self.pos = 0 - # <=> Copy constructor - elif isinstance(iterable, TeeObject): - self.tee_data = iterable.tee_data - self.pos = iterable.pos - else: - self.tee_data = TeeData(iter(iterable)) - self.pos = 0 - - def next(self): - data = self.tee_data[self.pos] - self.pos += 1 - return data - - def __iter__(self): - return self - - - at builtinify -def tee(iterable, n=2): - """Return n independent iterators from a single iterable. - Note : once tee() has made a split, the original iterable - should not be used anywhere else; otherwise, the iterable could get - advanced without the tee objects being informed. - - Note : this member of the toolkit may require significant auxiliary - storage (depending on how much temporary data needs to be stored). - In general, if one iterator is going to use most or all of the - data before the other iterator, it is faster to use list() instead - of tee() - - Equivalent to : - - def tee(iterable, n=2): - def gen(next, data={}, cnt=[0]): - for i in count(): - if i == cnt[0]: - item = data[i] = next() - cnt[0] += 1 - else: - item = data.pop(i) - yield item - it = iter(iterable) - return tuple([gen(it.next) for i in range(n)]) - """ - if isinstance(iterable, TeeObject): - # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) - return tuple([iterable] + - [TeeObject(tee_data=iterable.tee_data) for i in xrange(n-1)]) - tee_data = TeeData(iter(iterable)) - return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)]) diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,5 +1,5 @@ -from _numpypy import array, ndarray, int_, float_, bool_ #, complex_# , longlong +from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math @@ -200,7 +200,7 @@ typename = "'%s'" % typename lf = '' - if 0: # or issubclass(arr.dtype.type, flexible): + if issubclass(arr.dtype.type, flexible): if arr.dtype.names: typename = "%s" % str(arr.dtype) else: diff --git a/lib_pypy/pypy_test/test_itertools.py b/lib_pypy/pypy_test/test_itertools.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_itertools.py +++ /dev/null @@ -1,50 +0,0 @@ -from py.test import raises -from lib_pypy import itertools - -class TestItertools(object): - - def test_compress(self): - it = itertools.compress(['a', 'b', 'c'], [0, 1, 0]) - - assert list(it) == ['b'] - - def test_compress_diff_len(self): - it = itertools.compress(['a'], []) - raises(StopIteration, it.next) - - def test_product(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')] - - def test_product_repeat(self): - l = [1, 2] - m = ['a', 'b'] - - prodlist = itertools.product(l, m, repeat=2) - ans = [(1, 'a', 1, 'a'), (1, 'a', 1, 'b'), (1, 'a', 2, 'a'), - (1, 'a', 2, 'b'), (1, 'b', 1, 'a'), (1, 'b', 1, 'b'), - (1, 'b', 2, 'a'), (1, 'b', 2, 'b'), (2, 'a', 1, 'a'), - (2, 'a', 1, 'b'), (2, 'a', 2, 'a'), (2, 'a', 2, 'b'), - (2, 'b', 1, 'a'), (2, 'b', 1, 'b'), (2, 'b', 2, 'a'), - (2, 'b', 2, 'b')] - assert list(prodlist) == ans - - def test_product_diff_sizes(self): - l = [1, 2] - m = ['a'] - - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (2, 'a')] - - l = [1] - m = ['a', 'b'] - prodlist = itertools.product(l, m) - assert list(prodlist) == [(1, 'a'), (1, 'b')] - - def test_product_toomany_args(self): - l = [1, 2] - m = ['a'] - raises(TypeError, itertools.product, l, m, repeat=1, foo=2) 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 @@ -233,7 +233,7 @@ try: return unicode(line, ENCODING) except UnicodeDecodeError: # bah, silently fall back... - return unicode(line, 'utf-8') + return unicode(line, 'utf-8', 'replace') def get_history_length(self): return self.saved_history_length diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -496,7 +496,7 @@ if iscode: self.__tputs(text) else: - os.write(self.output_fd, text.encode(self.encoding)) + os.write(self.output_fd, text.encode(self.encoding, 'replace')) del self.__buffer[:] def __tputs(self, fmt, prog=delayprog): diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -548,7 +548,7 @@ if cell.is_constant(): newcell.const = cell.const cell = newcell - cell.knowntypedata = renamed_knowntypedata + cell.set_knowntypedata(renamed_knowntypedata) cells.append(cell) diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -144,7 +144,7 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key annotator = bk.annotator @@ -168,6 +168,7 @@ bind(obj2, obj1, 0) bind(obj1, obj2, 1) + r.set_knowntypedata(knowntypedata) return r @@ -337,8 +338,7 @@ case = opname in ('gt', 'ge', 'eq') add_knowntypedata(knowntypedata, case, [op.args[0]], SomeInteger(nonneg=True, knowntype=tointtype(int1))) - if knowntypedata: - r.knowntypedata = knowntypedata + r.set_knowntypedata(knowntypedata) # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) @@ -369,8 +369,7 @@ if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) - if ktd: - s.knowntypedata = ktd + s.set_knowntypedata(ktd) return s def and_((boo1, boo2)): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -188,10 +188,10 @@ variables = [op.args[1]] for variable in variables: assert bk.annotator.binding(variable) == s_obj - r.knowntypedata = {} - + knowntypedata = {} if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): - add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) + add_knowntypedata(knowntypedata, True, variables, bk.valueoftype(typ)) + r.set_knowntypedata(knowntypedata) return r # note that this one either needs to be constant, or we will create SomeObject diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -195,6 +195,10 @@ unsigned = False def __init__(self): pass + def set_knowntypedata(self, knowntypedata): + assert not hasattr(self, 'knowntypedata') + if knowntypedata: + self.knowntypedata = knowntypedata class SomeStringOrUnicode(SomeObject): immutable = True diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -76,7 +76,7 @@ s_obj.is_true_behavior(r) bk = getbookkeeper() - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key op = block.operations[i] assert op.opname == "is_true" or op.opname == "nonzero" @@ -86,8 +86,8 @@ if s_obj.can_be_none(): s_nonnone_obj = s_obj.nonnoneify() add_knowntypedata(knowntypedata, True, [arg], s_nonnone_obj) + r.set_knowntypedata(knowntypedata) return r - def nonzero(obj): return obj.is_true() diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -118,7 +118,7 @@ ("translation.gcrootfinder", DEFL_ROOTFINDER_WITHJIT), ("translation.list_comprehension_operations", True)]), ChoiceOption("jit_backend", "choose the backend for the JIT", - ["auto", "x86", "x86-without-sse2", "llvm", 'arm'], + ["auto", "x86", "x86-without-sse2", 'arm'], default="auto", cmdline="--jit-backend"), ChoiceOption("jit_profiler", "integrate profiler support into the JIT", ["off", "oprofile"], 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 @@ -38,6 +38,8 @@ .. branch: numpypy-complex2 Complex dtype support for numpy +.. branch: numpypy-problems +Improve dtypes intp, uintp, void, string and record .. branch: kill-someobject major cleanups including killing some object support diff --git a/pypy/jit/backend/detect_cpu.py b/pypy/jit/backend/detect_cpu.py --- a/pypy/jit/backend/detect_cpu.py +++ b/pypy/jit/backend/detect_cpu.py @@ -77,8 +77,6 @@ return "pypy.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "pypy.jit.backend.cli.runner", "CliCPU" - elif backend_name == 'llvm': - return "pypy.jit.backend.llvm.runner", "LLVMCPU" elif backend_name == 'arm': return "pypy.jit.backend.arm.runner", "CPU_ARM" elif backend_name == 'armhf': diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -1,17 +1,17 @@ from pypy.jit.metainterp import jitprof, resume, compile from pypy.jit.metainterp.executor import execute_nonspec -from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF, INT +from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF from pypy.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded, \ ImmutableIntUnbounded, \ IntLowerBound, MININT, MAXINT -from pypy.jit.metainterp.optimizeopt.util import (make_dispatcher_method, - args_dict) +from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method from pypy.jit.metainterp.resoperation import rop, ResOperation, AbstractResOp from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.tool.pairtype import extendabletype -from pypy.rlib.debug import debug_start, debug_stop, debug_print +from pypy.rlib.debug import debug_print from pypy.rlib.objectmodel import specialize + LEVEL_UNKNOWN = '\x00' LEVEL_NONNULL = '\x01' LEVEL_KNOWNCLASS = '\x02' # might also mean KNOWNARRAYDESCR, for arrays @@ -20,6 +20,8 @@ MODE_ARRAY = '\x00' MODE_STR = '\x01' MODE_UNICODE = '\x02' + + class LenBound(object): def __init__(self, mode, descr, bound): self.mode = mode diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -1,8 +1,11 @@ from pypy.jit.codewriter.effectinfo import EffectInfo -from pypy.jit.metainterp.history import ConstInt, make_hashable_int +from pypy.jit.metainterp import compile +from pypy.jit.metainterp.history import (Const, ConstInt, BoxInt, BoxFloat, + BoxPtr, make_hashable_int) from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntBound -from pypy.jit.metainterp.optimizeopt.optimizer import * +from pypy.jit.metainterp.optimizeopt.optimizer import (Optimization, REMOVED, + CONST_0, CONST_1) from pypy.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ResOperation) @@ -426,14 +429,31 @@ source_start_box = self.get_constant_box(op.getarg(3)) dest_start_box = self.get_constant_box(op.getarg(4)) length = self.get_constant_box(op.getarg(5)) - if (source_value.is_virtual() and source_start_box and dest_start_box - and length and (dest_value.is_virtual() or length.getint() <= 8)): + if (source_start_box and dest_start_box + and length and (dest_value.is_virtual() or length.getint() <= 8) and + (source_value.is_virtual() or length.getint() <= 8)): from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue - assert isinstance(source_value, VArrayValue) source_start = source_start_box.getint() dest_start = dest_start_box.getint() for index in range(length.getint()): - val = source_value.getitem(index + source_start) + # XXX fish fish fish + arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] + if source_value.is_virtual(): + assert isinstance(source_value, VArrayValue) + val = source_value.getitem(index + source_start) + else: + if arraydescr.is_array_of_pointers(): + resbox = BoxPtr() + elif arraydescr.is_array_of_floats(): + resbox = BoxFloat() + else: + resbox = BoxInt() + newop = ResOperation(rop.GETARRAYITEM_GC, + [op.getarg(1), + ConstInt(index + source_start)], resbox, + descr=arraydescr) + self.optimizer.propagate_forward(newop) + val = self.getvalue(resbox) if dest_value.is_virtual(): dest_value.setitem(index + dest_start, val) else: @@ -441,7 +461,7 @@ [op.getarg(2), ConstInt(index + dest_start), val.get_key_box()], None, - descr=source_value.arraydescr) + descr=arraydescr) self.emit_operation(newop) return True if length and length.getint() == 0: diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -3239,6 +3239,42 @@ ''' self.optimize_loop(ops, expected) + def test_arraycopy_not_virtual_2(self): + ops = ''' + [p0] + p1 = new_array(3, descr=arraydescr) + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) # removed by the backend + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) # removed by the backend + jump(i0) + ''' + self.optimize_loop(ops, expected) + + def test_arraycopy_not_virtual_3(self): + ops = ''' + [p0, p1] + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0, p1] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) + setarrayitem_gc(p1, 0, i0, descr=arraydescr) + setarrayitem_gc(p1, 1, i1, descr=arraydescr) + setarrayitem_gc(p1, 2, i2, descr=arraydescr) + jump(i0) + ''' + self.optimize_loop(ops, expected) + def test_arraycopy_no_elem(self): """ this was actually observed in the wild """ diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -4,6 +4,7 @@ from pypy.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken from pypy.jit.metainterp.jitexc import JitException from pypy.jit.metainterp.optimize import InvalidLoop +from pypy.rlib.debug import debug_print, debug_start, debug_stop from pypy.jit.metainterp.optimizeopt.optimizer import * from pypy.jit.metainterp.optimizeopt.generalize import KillHugeIntBounds from pypy.jit.metainterp.inliner import Inliner diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,9 +4,8 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi, rposix +from pypy.rlib import jit, clibffi, jit_libffi from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -152,9 +151,6 @@ if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') - elif flag == 2: - file = rffi.cast(rffi.CCHARPP, data)[0] - rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -169,27 +165,6 @@ assert isinstance(abi, int) return space.wrap(abi) -rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) - -def prepare_file_call_argument(fileobj): - import os - space = fileobj.space - fileobj.direct_flush() - fd = fileobj.direct_fileno() - if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file has no OS file descriptor")) - try: - fd2 = os.dup(fd) - f = rffi_fdopen(fd2, fileobj.mode) - if not f: - os.close(fd2) - raise OSError(rposix.get_errno(), "fdopen failed") - except OSError, e: - raise wrap_oserror(space, e) - return f - # ____________________________________________________________ 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 @@ -3,9 +3,11 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.rarithmetic import ovfcheck +from pypy.rlib import rposix from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend import cdataobj, misc, ctypeprim @@ -236,6 +238,22 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) + def cast(self, w_ob): + if self.is_file: + value = self.prepare_file(w_ob) + if value: + return cdataobj.W_CData(self.space, value, self) + return W_CTypePtrBase.cast(self, w_ob) + + def prepare_file(self, w_ob): + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = self.space.interpclass_w(w_ob) + if isinstance(ob, W_File): + return prepare_file_argument(self.space, ob) + else: + return lltype.nullptr(rffi.CCHARP.TO) + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or @@ -245,11 +263,8 @@ # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 elif self.is_file: - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc - ob = space.interpclass_w(w_init) - if isinstance(ob, W_File): - result = ctypefunc.prepare_file_call_argument(ob) + result = self.prepare_file(w_init) + if result: rffi.cast(rffi.CCHARPP, cdata)[0] = result return 2 return 0 @@ -303,3 +318,31 @@ else: raise OperationError(space.w_TypeError, space.wrap("expected a 'cdata struct-or-union' object")) + +# ____________________________________________________________ + + +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +class CffiFileObj(object): + _immutable_ = True + def __init__(self, fd, mode): + self.llf = rffi_fdopen(fd, mode) + if not self.llf: + raise OSError(rposix.get_errno(), "fdopen failed") + def close(self): + rffi_fclose(self.llf) + +def prepare_file_argument(space, fileobj): + fileobj.direct_flush() + if fileobj.cffi_fileobj is None: + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + except OSError, e: + raise wrap_oserror(space, e) + return fileobj.cffi_fileobj.llf diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -2264,3 +2264,35 @@ e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " "be a cdata pointer, not file") + +def test_FILE_object(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP,), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fileno = ll.load_function(BFunc2, "fileno") + # + import posix + fdr, fdw = posix.pipe() + fw1 = posix.fdopen(fdw, 'wb', 256) + # + fw1p = cast(BFILEP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p) + assert res >= 0 + res = fileno(fw1p) + assert res == fdw + fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,8 +1,21 @@ from pypy.objspace.fake.checkmodule import checkmodule +from pypy.module._cffi_backend import ctypeptr +from pypy.rpython.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - checkmodule('_cffi_backend') + # prepare_file_argument() is not working without translating the _file + # module too + def dummy_prepare_file_argument(space, fileobj): + return lltype.nullptr(rffi.CCHARP.TO) + old = ctypeptr.prepare_file_argument + try: + ctypeptr.prepare_file_argument = dummy_prepare_file_argument + # + checkmodule('_cffi_backend') + # + finally: + ctypeptr.prepare_file_argument = old diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -32,6 +32,7 @@ encoding = None errors = None fd = -1 + cffi_fileobj = None # pypy/module/_cffi_backend newlines = 0 # Updated when the stream is closed @@ -148,7 +149,14 @@ del openstreams[stream] except KeyError: pass - stream.close() + # close the stream. If cffi_fileobj is None, we close the + # underlying fileno too. Otherwise, we leave that to + # cffi_fileobj.close(). + cffifo = self.cffi_fileobj + self.cffi_fileobj = None + stream.close1(cffifo is None) + if cffifo is not None: + cffifo.close() def direct_fileno(self): self.getstream() # check if the file is still open 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 @@ -406,12 +406,16 @@ read += length def readall(self): - w_result = self.decompressor.decompress(self.stream.readall()) - if self.decompressor.running: - raise OperationError(self.space.w_EOFError, - self.space.wrap("compressed file ended before the logical end-of-the-stream was detected")) - result = self.space.str_w(w_result) - self.readlength += len(result) + raw = self.stream.readall() + if raw: + w_result = self.decompressor.decompress(raw) + if self.decompressor.running: + raise OperationError(self.space.w_EOFError, + self.space.wrap("compressed file ended before the logical end-of-the-stream was detected")) + result = self.space.str_w(w_result) + self.readlength += len(result) + else: + result = "" if len(self.buffer) != self.pos: pos = self.pos assert pos >= 0 @@ -649,11 +653,11 @@ was found after the end of stream, it'll be ignored and saved in unused_data attribute.""" - if data == '': - return self.space.wrap('') if not self.running: raise OperationError(self.space.w_EOFError, self.space.wrap("end of stream was already found")) + if data == '': + return self.space.wrap('') in_bufsize = len(data) diff --git a/pypy/module/bz2/test/test_bz2_compdecomp.py b/pypy/module/bz2/test/test_bz2_compdecomp.py --- a/pypy/module/bz2/test/test_bz2_compdecomp.py +++ b/pypy/module/bz2/test/test_bz2_compdecomp.py @@ -156,6 +156,7 @@ bz2d = BZ2Decompressor() bz2d.decompress(self.DATA) raises(EOFError, bz2d.decompress, "foo") + raises(EOFError, bz2d.decompress, "") def test_buffer(self): from bz2 import BZ2Decompressor diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -43,9 +43,8 @@ space.newtuple(args_w)]) def check_number(space, w_obj): - if (space.lookup(w_obj, '__add__') is None or - space.is_true(space.isinstance(w_obj, space.w_str)) or - space.is_true(space.isinstance(w_obj, space.w_unicode))): + if (space.lookup(w_obj, '__int__') is None and + space.lookup(w_obj, '__float__') is None): raise OperationError(space.w_TypeError, space.wrap("expected a number")) @@ -65,20 +64,18 @@ next = interp2app(W_Count.next_w), __reduce__ = interp2app(W_Count.reduce_w), __repr__ = interp2app(W_Count.repr_w), - __doc__ = """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. + __doc__ = """Make an iterator that returns evenly spaced values starting + with n. If not specified n defaults to zero. Often used as an + argument to imap() to generate consecutive data points. Also, + used with izip() to add sequence numbers. - Equivalent to : + Equivalent to: - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) + def count(start=0, step=1): + n = start while True: yield n - n += 1 + n += step """) diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -35,6 +35,7 @@ raises(TypeError, itertools.count, None) raises(TypeError, itertools.count, 'a') + raises(TypeError, itertools.count, []) def test_repeat(self): import itertools diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -62,6 +62,7 @@ 'flexible': 'interp_boxes.W_FlexibleBox', 'character': 'interp_boxes.W_CharacterBox', 'str_': 'interp_boxes.W_StringBox', + 'string_': 'interp_boxes.W_StringBox', 'unicode_': 'interp_boxes.W_UnicodeBox', 'void': 'interp_boxes.W_VoidBox', 'complexfloating': 'interp_boxes.W_ComplexFloatingBox', 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 @@ -10,6 +10,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rlib import jit from pypy.rlib.rawstorage import free_raw_storage +from pypy.rlib.debug import make_sure_not_resized class ConcreteArrayIterator(base.BaseArrayIterator): def __init__(self, array): @@ -47,7 +48,7 @@ self.skip = array.strides[0] self.dtype = array.dtype self.index = 0 - self.size = array.shape[0] + self.size = array.get_shape()[0] def next(self): self.offset += self.skip @@ -168,7 +169,9 @@ parent = None def get_shape(self): - return self.shape + shape = self.shape + jit.hint(len(shape), promote=True) + return shape def getitem(self, index): return self.dtype.getitem(self, index) @@ -181,7 +184,7 @@ if impl.is_scalar(): self.fill(impl.get_scalar_value()) return - shape = shape_agreement(space, self.shape, arr) + shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: impl = impl.copy() loop.setslice(shape, self, impl) @@ -193,7 +196,7 @@ # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: - new_strides = calc_new_strides(new_shape, self.shape, + new_strides = calc_new_strides(new_shape, self.get_shape(), self.strides, self.order) if new_strides: # We can create a view, strides somehow match up. @@ -216,10 +219,10 @@ raise IndexError idx = int_w(space, w_index) if idx < 0: - idx = self.shape[i] + idx - if idx < 0 or idx >= self.shape[i]: + idx = self.get_shape()[i] + idx + if idx < 0 or idx >= self.get_shape()[i]: raise operationerrfmt(space.w_IndexError, - "index (%d) out of range (0<=index<%d", i, self.shape[i], + "index (%d) out of range (0<=index<%d", i, self.get_shape()[i], ) item += idx * self.strides[i] return item @@ -227,13 +230,14 @@ @jit.unroll_safe def _lookup_by_unwrapped_index(self, space, lst): item = self.start - assert len(lst) == len(self.shape) + shape = self.get_shape() + assert len(lst) == len(shape) for i, idx in enumerate(lst): if idx < 0: - idx = self.shape[i] + idx - if idx < 0 or idx >= self.shape[i]: + idx = shape[i] + idx + if idx < 0 or idx >= shape[i]: raise operationerrfmt(space.w_IndexError, - "index (%d) out of range (0<=index<%d", i, self.shape[i], + "index (%d) out of range (0<=index<%d", i, shape[i], ) item += idx * self.strides[i] return item @@ -255,7 +259,8 @@ raise IndexError if isinstance(w_idx, W_NDimArray): raise ArrayArgumentException - shape_len = len(self.shape) + shape = self.get_shape() + shape_len = len(shape) if shape_len == 0: raise OperationError(space.w_IndexError, space.wrap( "0-d arrays can't be indexed")) @@ -299,7 +304,7 @@ return RecordChunk(idx) if (space.isinstance_w(w_idx, space.w_int) or space.isinstance_w(w_idx, space.w_slice)): - return Chunks([Chunk(*space.decode_index4(w_idx, self.shape[0]))]) + return Chunks([Chunk(*space.decode_index4(w_idx, self.get_shape()[0]))]) elif space.is_w(w_idx, space.w_None): return Chunks([NewAxisChunk()]) result = [] @@ -309,7 +314,7 @@ result.append(NewAxisChunk()) else: result.append(Chunk(*space.decode_index4(w_item, - self.shape[i]))) + self.get_shape()[i]))) i += 1 return Chunks(result) @@ -333,24 +338,24 @@ view.implementation.setslice(space, w_value) def transpose(self): - if len(self.shape) < 2: + if len(self.get_shape()) < 2: return self strides = [] backstrides = [] shape = [] - for i in range(len(self.shape) - 1, -1, -1): + for i in range(len(self.get_shape()) - 1, -1, -1): strides.append(self.strides[i]) backstrides.append(self.backstrides[i]) - shape.append(self.shape[i]) + shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, backstrides, shape, self) def copy(self): - strides, backstrides = support.calc_strides(self.shape, self.dtype, + strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) - impl = ConcreteArray(self.shape, self.dtype, self.order, strides, + impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(self.shape, impl, self) + return loop.setslice(self.get_shape(), impl, self) def create_axis_iter(self, shape, dim): return AxisIterator(self, shape, dim) @@ -361,7 +366,7 @@ return MultiDimViewIterator(self, self.start, r[0], r[1], shape) def swapaxes(self, axis1, axis2): - shape = self.shape[:] + shape = self.get_shape()[:] strides = self.strides[:] backstrides = self.backstrides[:] shape[axis1], shape[axis2] = shape[axis2], shape[axis1] @@ -375,6 +380,7 @@ class ConcreteArray(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides): + make_sure_not_resized(shape) self.shape = shape self.size = support.product(shape) * dtype.get_size() self.storage = dtype.itemtype.malloc(self.size) @@ -384,10 +390,10 @@ self.backstrides = backstrides def create_iter(self, shape): - if shape == self.shape: + if shape == self.get_shape(): return ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.strides, self.backstrides, - self.shape, shape) + self.get_shape(), shape) return MultiDimViewIterator(self, 0, r[0], r[1], shape) def fill(self, box): @@ -421,18 +427,18 @@ loop.fill(self, box.convert_to(self.dtype)) def create_iter(self, shape): - if shape != self.shape: + if shape != self.get_shape(): r = calculate_broadcast_strides(self.strides, self.backstrides, - self.shape, shape) + self.get_shape(), shape) return MultiDimViewIterator(self.parent, self.start, r[0], r[1], shape) - if len(self.shape) == 1: + if len(self.get_shape()) == 1: return OneDimViewIterator(self) return MultiDimViewIterator(self.parent, self.start, self.strides, - self.backstrides, self.shape) + self.backstrides, self.get_shape()) def set_shape(self, space, new_shape): - if len(self.shape) < 2 or self.size == 0: + if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor strides = [] @@ -451,7 +457,7 @@ new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, self) - new_strides = calc_new_strides(new_shape, self.shape, self.strides, + new_strides = calc_new_strides(new_shape, self.get_shape(), self.strides, self.order) if new_strides is None: raise OperationError(space.w_AttributeError, space.wrap( diff --git a/pypy/module/micronumpy/arrayimpl/voidbox.py b/pypy/module/micronumpy/arrayimpl/voidbox.py --- a/pypy/module/micronumpy/arrayimpl/voidbox.py +++ b/pypy/module/micronumpy/arrayimpl/voidbox.py @@ -6,6 +6,7 @@ def __init__(self, size, dtype): self.storage = alloc_raw_storage(size) self.dtype = dtype + self.size = size def __del__(self): free_raw_storage(self.storage) diff --git a/pypy/module/micronumpy/dot.py b/pypy/module/micronumpy/dot.py --- a/pypy/module/micronumpy/dot.py +++ b/pypy/module/micronumpy/dot.py @@ -11,12 +11,12 @@ right_critical_dim = len(right_shape) - 2 right_critical_dim_size = right_shape[right_critical_dim] assert right_critical_dim >= 0 - out_shape += left_shape[:-1] + \ - right_shape[0:right_critical_dim] + \ - right_shape[right_critical_dim + 1:] + out_shape = out_shape + left_shape[:-1] + \ + right_shape[0:right_critical_dim] + \ + right_shape[right_critical_dim + 1:] elif len(right_shape) > 0: #dot does not reduce for scalars - out_shape += left_shape[:-1] + out_shape = out_shape + left_shape[:-1] if my_critical_dim_size != right_critical_dim_size: raise OperationError(space.w_ValueError, space.wrap( "objects are not aligned")) 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 @@ -246,7 +246,11 @@ except KeyError: raise OperationError(space.w_IndexError, space.wrap("Field %s does not exist" % item)) - return dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + if isinstance (read_val, W_StringBox): + # StringType returns a str + return space.wrap(dtype.itemtype.to_str(read_val)) + return read_val @unwrap_spec(item=str) def descr_setitem(self, space, item, w_value): @@ -271,6 +275,13 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) + # Running entire test suite needs this function to succeed, + # running single test_stringarray succeeds without it. + # With convert_to() test_ztranslation fails since + # W_CharacterBox is not a W_GenericBox. + # Why is it needed for multiple tests? + #def convert_to(self, dtype): + # xxx class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -474,6 +485,7 @@ W_VoidBox.typedef = TypeDef("void", W_FlexibleBox.typedef, __module__ = "numpypy", + __new__ = interp2app(W_VoidBox.descr__new__.im_func), __getitem__ = interp2app(W_VoidBox.descr_getitem), __setitem__ = interp2app(W_VoidBox.descr_setitem), ) 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 @@ -8,6 +8,7 @@ from pypy.module.micronumpy import types, interp_boxes from pypy.rlib.objectmodel import specialize from pypy.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong +from pypy.rpython.lltypesystem import rffi UNSIGNEDLTR = "u" @@ -17,6 +18,8 @@ VOIDLTR = 'V' STRINGLTR = 'S' UNICODELTR = 'U' +INTPLTR = 'p' +UINTPLTR = 'P' def decode_w_dtype(space, w_dtype): if space.is_none(w_dtype): @@ -66,11 +69,16 @@ def fill(self, storage, box, start, stop): self.itemtype.fill(storage, self.get_size(), box, start, stop, 0) + def get_name(self): + if self.char == 'S': + return '|S' + str(self.get_size()) + return self.name + def descr_str(self, space): - return space.wrap(self.name) + return space.wrap(self.get_name()) def descr_repr(self, space): - return space.wrap("dtype('%s')" % self.name) + return space.wrap("dtype('%s')" % self.get_name()) def descr_get_itemsize(self, space): return space.wrap(self.itemtype.get_element_size()) @@ -135,6 +143,9 @@ def is_record_type(self): return self.fields is not None + def is_flexible_type(self): + return (self.num == 18 or self.num == 19 or self.num == 20) + def __repr__(self): if self.fields is not None: return '' % self.fields @@ -454,6 +465,35 @@ #alternate_constructors=[space.w_buffer], # XXX no buffer in space ) + ptr_size = rffi.sizeof(rffi.CCHARP) + if ptr_size == 4: + intp_box = interp_boxes.W_Int32Box + intp_type = types.Int32() + uintp_box = interp_boxes.W_UInt32Box + uintp_type = types.UInt32() + elif ptr_size == 8: + intp_box = interp_boxes.W_Int64Box + intp_type = types.Int64() + uintp_box = interp_boxes.W_UInt64Box + uintp_type = types.UInt64() + else: + raise ValueError('unknown point size %d' % ptr_size) + self.w_intpdtype = W_Dtype( + intp_type, + num=5, + kind=INTPLTR, + name='intp', + char=INTPLTR, + w_box_type = space.gettypefor(intp_box), + ) + self.w_uintpdtype = W_Dtype( + uintp_type, + num=6, + kind=UINTPLTR, + name='uintp', + char=UINTPLTR, + w_box_type = space.gettypefor(uintp_box), + ) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, @@ -462,7 +502,7 @@ self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, self.w_complex128dtype, self.w_stringdtype, self.w_unicodedtype, - self.w_voiddtype, + self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) @@ -504,7 +544,8 @@ #'CDOUBLE', #'DATETIME', 'UINT': self.w_uint32dtype, - 'INTP': self.w_longdtype, + 'INTP': self.w_intpdtype, + 'UINTP': self.w_uintpdtype, #'HALF', 'BYTE': self.w_int8dtype, #'CFLOAT': , 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 @@ -25,7 +25,7 @@ shape = [] for w_item in space.fixedview(w_size): shape.append(space.int_w(w_item)) - return shape + return shape[:] class __extend__(W_NDimArray): @jit.unroll_safe @@ -433,9 +433,7 @@ def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): - dtype = interp_ufuncs.find_dtype_for_scalar(space, w_other, - self.get_dtype()) - w_other = W_NDimArray.new_scalar(space, dtype, w_other) + w_other = convert_to_array(space, w_other) return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self, w_out]) return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name) 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 @@ -150,6 +150,9 @@ "supported for binary functions")) assert isinstance(self, W_Ufunc2) obj = convert_to_array(space, w_obj) + if obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('cannot perform reduce for flexible type')) obj_shape = obj.get_shape() if obj.is_scalar(): return obj.get_scalar_value() @@ -235,6 +238,9 @@ if space.is_w(out, space.w_None): out = None w_obj = convert_to_array(space, w_obj) + if w_obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('Not implemented for this type')) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -301,6 +307,10 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) + if w_lhs.get_dtype().is_flexible_type() or \ + w_rhs.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('unsupported operand types')) calc_dtype = find_binop_result_dtype(space, w_lhs.get_dtype(), w_rhs.get_dtype(), int_only=self.int_only, @@ -413,6 +423,7 @@ return interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] + at jit.unroll_safe def find_unaryop_result_dtype(space, dt, promote_to_float=False, promote_bools=False, promote_to_largest=False, allow_complex=True): if promote_bools and (dt.kind == interp_dtype.BOOLLTR): @@ -446,6 +457,7 @@ int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype complex_type = interp_dtype.get_dtype_cache(space).w_complex128dtype float_type = interp_dtype.get_dtype_cache(space).w_float64dtype + str_dtype = interp_dtype.get_dtype_cache(space).w_stringdtype if isinstance(w_obj, interp_boxes.W_GenericBox): dtype = w_obj.get_dtype(space) if current_guess is None: @@ -472,6 +484,15 @@ current_guess is complex_type or current_guess is float_type): return complex_type return current_guess + elif space.isinstance_w(w_obj, space.w_str): + if (current_guess is None): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + elif current_guess.num ==18: + if current_guess.itemtype.get_size() < space.len_w(w_obj): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + return current_guess if current_guess is complex_type: return complex_type return interp_dtype.get_dtype_cache(space).w_float64dtype diff --git a/pypy/module/micronumpy/stdobjspace.py b/pypy/module/micronumpy/stdobjspace.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/stdobjspace.py @@ -0,0 +1,11 @@ + +from pypy.objspace.std import stringobject +from pypy.module.micronumpy import interp_boxes + +def delegate_stringbox2stringobj(space, w_box): + return space.wrap(w_box.dtype.itemtype.to_str(w_box)) + +def register_delegates(typeorder): + typeorder[interp_boxes.W_StringBox] = [ + (stringobject.W_StringObject, delegate_stringbox2stringobj), + ] diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -64,13 +64,13 @@ while True: new_batch = [] if not batch: - return shape, [] + return shape[:], [] if is_single_elem(space, batch[0], is_rec_type): for w_elem in batch: if not is_single_elem(space, w_elem, is_rec_type): raise OperationError(space.w_ValueError, space.wrap( "setting an array element with a sequence")) - return shape, batch + return shape[:], batch size = space.len_w(batch[0]) for w_elem in batch: if (is_single_elem(space, w_elem, is_rec_type) or 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 @@ -31,6 +31,8 @@ from _numpypy import dtype assert dtype(bool).num == 0 + assert dtype('intp').num == 5 + assert dtype('uintp').num == 6 assert dtype(int).num == 7 assert dtype(long).num == 9 assert dtype(float).num == 12 @@ -176,10 +178,15 @@ def test_cant_subclass(self): from _numpypy import dtype - # You can't subclass dtype raises(TypeError, type, "Foo", (dtype,), {}) + def test_can_subclass(self): + import _numpypy + class xyz(_numpypy.void): + pass + assert True + def test_aliases(self): from _numpypy import dtype @@ -228,6 +235,17 @@ class AppTestTypes(BaseNumpyAppTest): + def setup_class(cls): + BaseNumpyAppTest.setup_class.im_func(cls) + if option.runappdirect: + import platform + bits, linkage = platform.architecture() + ptr_size = int(bits[:-3]) // 8 + else: + from pypy.rpython.lltypesystem import rffi + ptr_size = rffi.sizeof(rffi.CCHARP) + cls.w_ptr_size = cls.space.wrap(ptr_size) + def test_abstract_types(self): import _numpypy as numpy raises(TypeError, numpy.generic, 0) @@ -269,7 +287,9 @@ def test_int8(self): import _numpypy as numpy - assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, object] a = numpy.array([1, 2, 3], numpy.int8) assert type(a[1]) is numpy.int8 @@ -291,7 +311,9 @@ def test_uint8(self): import _numpypy as numpy - assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, + numpy.integer, numpy.number, + numpy.generic, object] a = numpy.array([1, 2, 3], numpy.uint8) assert type(a[1]) is numpy.uint8 @@ -361,16 +383,22 @@ import _numpypy as numpy assert numpy.int_ is numpy.dtype(int).type - assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, int, object] + assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, int, object] def test_int64(self): import sys import _numpypy as numpy if sys.maxint == 2 ** 63 -1: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, int, object] + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, int, object] From noreply at buildbot.pypy.org Mon Oct 29 21:50:26 2012 From: noreply at buildbot.pypy.org (wlav) Date: Mon, 29 Oct 2012 21:50:26 +0100 (CET) Subject: [pypy-commit] pypy reflex-support: remove all _immutable_ references as they don't work the way I expected ... Message-ID: <20121029205026.B0FCD1C0185@cobra.cs.uni-duesseldorf.de> Author: Wim Lavrijsen Branch: reflex-support Changeset: r58601:e0a926dca235 Date: 2012-10-29 13:49 -0700 http://bitbucket.org/pypy/pypy/changeset/e0a926dca235/ Log: remove all _immutable_ references as they don't work the way I expected ... 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 @@ -67,7 +67,6 @@ class TypeConverter(object): - _immutable_ = True libffitype = lltype.nullptr(jit_libffi.FFI_TYPE_P.TO) uses_local = False @@ -128,7 +127,6 @@ class ArrayTypeConverterMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.pointer def __init__(self, space, array_size): @@ -158,7 +156,6 @@ class PtrTypeConverterMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.pointer def __init__(self, space, array_size): @@ -200,7 +197,6 @@ class NumericTypeConverterMixin(object): _mixin_ = True - _immutable_ = True def convert_argument_libffi(self, space, w_obj, address, call_local): x = rffi.cast(self.c_ptrtype, address) @@ -222,7 +218,6 @@ class ConstRefNumericTypeConverterMixin(NumericTypeConverterMixin): _mixin_ = True - _immutable_ = True uses_local = True def convert_argument_libffi(self, space, w_obj, address, call_local): @@ -235,7 +230,6 @@ class IntTypeConverterMixin(NumericTypeConverterMixin): _mixin_ = True - _immutable_ = True def convert_argument(self, space, w_obj, address, call_local): x = rffi.cast(self.c_ptrtype, address) @@ -243,7 +237,6 @@ class FloatTypeConverterMixin(NumericTypeConverterMixin): _mixin_ = True - _immutable_ = True def convert_argument(self, space, w_obj, address, call_local): x = rffi.cast(self.c_ptrtype, address) @@ -253,7 +246,6 @@ class VoidConverter(TypeConverter): - _immutable_ = True libffitype = jit_libffi.types.void def __init__(self, space, name): @@ -265,8 +257,6 @@ class BoolConverter(ffitypes.typeid(bool), TypeConverter): - _immutable_ = True - def convert_argument(self, space, w_obj, address, call_local): x = rffi.cast(rffi.LONGP, address) x[0] = self._unwrap_object(space, w_obj) @@ -290,8 +280,6 @@ address[0] = '\x00' class CharConverter(ffitypes.typeid(rffi.CHAR), TypeConverter): - _immutable_ = True - def convert_argument(self, space, w_obj, address, call_local): x = rffi.cast(rffi.CCHARP, address) x[0] = self._unwrap_object(space, w_obj) @@ -309,8 +297,6 @@ address[0] = self._unwrap_object(space, w_value) class FloatConverter(ffitypes.typeid(rffi.FLOAT), FloatTypeConverterMixin, TypeConverter): - _immutable_ = True - def __init__(self, space, default): if default: fval = float(rfloat.rstring_to_float(default)) @@ -324,7 +310,6 @@ return space.wrap(float(rffiptr[0])) class ConstFloatRefConverter(FloatConverter): - _immutable_ = True libffitype = jit_libffi.types.pointer typecode = 'F' @@ -333,8 +318,6 @@ raise FastCallNotPossible class DoubleConverter(ffitypes.typeid(rffi.DOUBLE), FloatTypeConverterMixin, TypeConverter): - _immutable_ = True - def __init__(self, space, default): if default: self.default = rffi.cast(self.c_type, rfloat.rstring_to_float(default)) @@ -342,14 +325,11 @@ self.default = rffi.cast(self.c_type, 0.) class ConstDoubleRefConverter(ConstRefNumericTypeConverterMixin, DoubleConverter): - _immutable_ = True libffitype = jit_libffi.types.pointer typecode = 'D' class CStringConverter(TypeConverter): - _immutable_ = True - def convert_argument(self, space, w_obj, address, call_local): x = rffi.cast(rffi.LONGP, address) arg = space.str_w(w_obj) @@ -367,7 +347,6 @@ class VoidPtrConverter(TypeConverter): - _immutable_ = True libffitype = jit_libffi.types.pointer def _unwrap_object(self, space, w_obj): @@ -388,7 +367,6 @@ x[0] = self._unwrap_object(space, w_obj) class VoidPtrPtrConverter(TypeConverter): - _immutable_ = True uses_local = True def convert_argument(self, space, w_obj, address, call_local): @@ -410,11 +388,9 @@ pass # no set on buffer/array/None class VoidPtrRefConverter(VoidPtrPtrConverter): - _immutable_ = True uses_local = True class InstancePtrConverter(TypeConverter): - _immutable_ = True libffitype = jit_libffi.types.pointer def __init__(self, space, cppclass): @@ -457,8 +433,6 @@ address[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_value)) class InstanceConverter(InstancePtrConverter): - _immutable_ = True - def convert_argument_libffi(self, space, w_obj, address, call_local): from pypy.module.cppyy.interp_cppyy import FastCallNotPossible raise FastCallNotPossible # TODO: by-value is a jit_libffi special case @@ -473,7 +447,6 @@ self._is_abstract(space) class InstancePtrPtrConverter(InstancePtrConverter): - _immutable_ = True uses_local = True def convert_argument(self, space, w_obj, address, call_local): @@ -505,8 +478,6 @@ class StdStringConverter(InstanceConverter): - _immutable_ = True - def __init__(self, space, extra): from pypy.module.cppyy import interp_cppyy cppclass = interp_cppyy.scope_byname(space, "std::string") @@ -537,8 +508,6 @@ capi.c_free_stdstring(rffi.cast(capi.C_OBJECT, rffi.cast(rffi.VOIDPP, arg)[0])) class StdStringRefConverter(InstancePtrConverter): - _immutable_ = True - def __init__(self, space, extra): from pypy.module.cppyy import interp_cppyy cppclass = interp_cppyy.scope_byname(space, "std::string") @@ -546,7 +515,6 @@ class PyObjectConverter(TypeConverter): - _immutable_ = True libffitype = jit_libffi.types.pointer def convert_argument(self, space, w_obj, address, call_local): @@ -675,11 +643,9 @@ for c_type, names in type_info: class BasicConverter(ffitypes.typeid(c_type), IntTypeConverterMixin, TypeConverter): - _immutable_ = True def __init__(self, space, default): self.default = rffi.cast(self.c_type, capi.c_strtoll(default)) class ConstRefConverter(ConstRefNumericTypeConverterMixin, BasicConverter): - _immutable_ = True libffitype = jit_libffi.types.pointer for name in names: _converters[name] = BasicConverter @@ -692,11 +658,9 @@ for c_type, names in type_info: class BasicConverter(ffitypes.typeid(c_type), IntTypeConverterMixin, TypeConverter): - _immutable_ = True def __init__(self, space, default): self.default = rffi.cast(self.c_type, capi.c_strtoll(default)) class ConstRefConverter(ConstRefNumericTypeConverterMixin, BasicConverter): - _immutable_ = True libffitype = jit_libffi.types.pointer typecode = 'r' def convert_argument(self, space, w_obj, address, call_local): @@ -718,11 +682,9 @@ for c_type, names in type_info: class BasicConverter(ffitypes.typeid(c_type), IntTypeConverterMixin, TypeConverter): - _immutable_ = True def __init__(self, space, default): self.default = rffi.cast(self.c_type, capi.c_strtoull(default)) class ConstRefConverter(ConstRefNumericTypeConverterMixin, BasicConverter): - _immutable_ = True libffitype = jit_libffi.types.pointer for name in names: _converters[name] = BasicConverter @@ -746,11 +708,9 @@ for tcode, tsize, names in array_info: class ArrayConverter(ArrayTypeConverterMixin, TypeConverter): - _immutable_ = True typecode = tcode typesize = tsize class PtrConverter(PtrTypeConverterMixin, TypeConverter): - _immutable_ = True typecode = tcode typesize = tsize for name in names: 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 @@ -27,7 +27,6 @@ NULL = lltype.nullptr(jit_libffi.FFI_TYPE_P.TO) class FunctionExecutor(object): - _immutable_ = True libffitype = NULL def __init__(self, space, extra): @@ -43,7 +42,6 @@ class PtrTypeExecutor(FunctionExecutor): - _immutable_ = True libffitype = jit_libffi.types.pointer typecode = 'P' @@ -65,7 +63,6 @@ class VoidExecutor(FunctionExecutor): - _immutable_ = True libffitype = jit_libffi.types.void def execute(self, space, cppmethod, cppthis, num_args, args): @@ -79,7 +76,6 @@ class NumericExecutorMixin(object): _mixin_ = True - _immutable_ = True def _wrap_object(self, space, obj): return space.wrap(obj) @@ -96,7 +92,6 @@ class NumericRefExecutorMixin(object): _mixin_ = True - _immutable_ = True def __init__(self, space, extra): FunctionExecutor.__init__(self, space, extra) @@ -128,7 +123,6 @@ class CStringExecutor(FunctionExecutor): - _immutable_ = True def execute(self, space, cppmethod, cppthis, num_args, args): lresult = capi.c_call_l(cppmethod, cppthis, num_args, args) @@ -138,7 +132,6 @@ class ConstructorExecutor(VoidExecutor): - _immutable_ = True def execute(self, space, cppmethod, cppthis, num_args, args): capi.c_constructor(cppmethod, cppthis, num_args, args) @@ -146,7 +139,6 @@ class InstancePtrExecutor(FunctionExecutor): - _immutable_ = True libffitype = jit_libffi.types.pointer def __init__(self, space, cppclass): @@ -169,7 +161,6 @@ space, space.w_None, self.cppclass, ptr_result, isref=False, python_owns=False) class InstancePtrPtrExecutor(InstancePtrExecutor): - _immutable_ = True def execute(self, space, cppmethod, cppthis, num_args, args): from pypy.module.cppyy import interp_cppyy @@ -184,7 +175,6 @@ raise FastCallNotPossible class InstanceExecutor(InstancePtrExecutor): - _immutable_ = True def execute(self, space, cppmethod, cppthis, num_args, args): from pypy.module.cppyy import interp_cppyy @@ -199,7 +189,6 @@ class StdStringExecutor(InstancePtrExecutor): - _immutable_ = True def execute(self, space, cppmethod, cppthis, num_args, args): charp_result = capi.c_call_s(cppmethod, cppthis, num_args, args) @@ -211,7 +200,6 @@ class PyObjectExecutor(PtrTypeExecutor): - _immutable_ = True def wrap_result(self, space, lresult): space.getbuiltinmodule("cpyext") @@ -326,10 +314,8 @@ for c_type, stub, names in type_info: class BasicExecutor(ffitypes.typeid(c_type), NumericExecutorMixin, FunctionExecutor): - _immutable_ = True c_stubcall = staticmethod(stub) class BasicRefExecutor(ffitypes.typeid(c_type), NumericRefExecutorMixin, FunctionExecutor): - _immutable_ = True libffitype = jit_libffi.types.pointer for name in names: _executors[name] = BasicExecutor @@ -355,7 +341,6 @@ for tcode, names in ptr_info: class PtrExecutor(PtrTypeExecutor): - _immutable_ = True typecode = tcode for name in names: _executors[name+'*'] = PtrExecutor diff --git a/pypy/module/cppyy/ffitypes.py b/pypy/module/cppyy/ffitypes.py --- a/pypy/module/cppyy/ffitypes.py +++ b/pypy/module/cppyy/ffitypes.py @@ -12,7 +12,6 @@ class BoolTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.uchar c_type = rffi.UCHAR c_ptrtype = rffi.UCHARP @@ -29,7 +28,6 @@ class CharTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.schar c_type = rffi.CHAR c_ptrtype = rffi.CCHARP # there's no such thing as rffi.CHARP @@ -53,7 +51,6 @@ class ShortTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.sshort c_type = rffi.SHORT c_ptrtype = rffi.SHORTP @@ -63,7 +60,6 @@ class UShortTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.ushort c_type = rffi.USHORT c_ptrtype = rffi.USHORTP @@ -73,7 +69,6 @@ class IntTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.sint c_type = rffi.INT c_ptrtype = rffi.INTP @@ -83,7 +78,6 @@ class UIntTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.uint c_type = rffi.UINT c_ptrtype = rffi.UINTP @@ -93,7 +87,6 @@ class LongTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.slong c_type = rffi.LONG c_ptrtype = rffi.LONGP @@ -103,7 +96,6 @@ class ULongTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.ulong c_type = rffi.ULONG c_ptrtype = rffi.ULONGP @@ -113,7 +105,6 @@ class LongLongTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.sint64 c_type = rffi.LONGLONG c_ptrtype = rffi.LONGLONGP @@ -123,7 +114,6 @@ class ULongLongTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.uint64 c_type = rffi.ULONGLONG c_ptrtype = rffi.ULONGLONGP @@ -133,7 +123,6 @@ class FloatTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.float c_type = rffi.FLOAT c_ptrtype = rffi.FLOATP @@ -147,7 +136,6 @@ class DoubleTypeMixin(object): _mixin_ = True - _immutable_ = True libffitype = jit_libffi.types.double c_type = rffi.DOUBLE c_ptrtype = rffi.DOUBLEP 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 @@ -117,7 +117,6 @@ function if available, makes the call, and returns the wrapped result. It also takes care of offset casting and recycling of known objects through the memory_regulator.""" - _immutable_ = True def __init__(self, space, containing_scope, method_index, arg_defs, args_required): self.space = space @@ -145,7 +144,7 @@ @jit.unroll_safe def call(self, cppthis, args_w): - jit.promote(self) + #jit.promote(self) assert lltype.typeOf(cppthis) == capi.C_OBJECT # check number of given arguments against required (== total - defaults) @@ -189,7 +188,7 @@ @jit.unroll_safe def do_fast_call(self, cppthis, args_w, call_local): - jit.promote(self) + #jit.promote(self) if self.cif_descr is None: raise FastCallNotPossible cif_descr = self.cif_descr @@ -313,7 +312,7 @@ @jit.unroll_safe def prepare_arguments(self, args_w, call_local): - jit.promote(self) + #jit.promote(self) args = capi.c_allocate_function_args(len(args_w)) stride = capi.c_function_arg_sizeof() for i in range(len(args_w)): @@ -364,7 +363,6 @@ """Global (namespaced) function dispatcher. For now, the base class has all the needed functionality, by allowing the C++ this pointer to be null in the call. An optimization is expected there, however.""" - _immutable_ = True def __repr__(self): return "CPPFunction: %s" % self.signature() @@ -374,7 +372,6 @@ """Method dispatcher that constructs new objects. In addition to the call, it allocates memory for the newly constructed object and sets ownership to Python.""" - _immutable_ = True def call(self, cppthis, args_w): newthis = capi.c_allocate(self.scope) @@ -395,7 +392,6 @@ """Method dispatcher specific to Python's __setitem__ mapped onto C++'s operator[](int). The former function takes an extra argument to assign to the return type of the latter.""" - _immutable_ = True def call(self, cppthis, args_w): end = len(args_w)-1 @@ -412,8 +408,7 @@ """Dispatcher that is actually available at the app-level: it is a collection of (possibly) overloaded methods or functions. It calls these in order and deals with error handling and reporting.""" - _immutable_ = True - _immutable_fields_ = ["functions[*]"] + #_immutable_fields_ = ["functions[*]"] def __init__(self, space, containing_scope, functions): self.space = space @@ -421,10 +416,9 @@ from pypy.rlib import debug self.functions = debug.make_sure_not_resized(functions) + @jit.elidable_promote() def is_static(self): - f = self.functions[0] - assert isinstance(f, CPPMethod) - if isinstance(f, CPPFunction): + if isinstance(self.functions[0], CPPFunction): return self.space.w_True return self.space.w_False @@ -449,7 +443,7 @@ # # TODO: figure out what happens if a callback into from the C++ call # raises a Python exception. - jit.promote(self) + #jit.promote(self) for i in range(len(self.functions)): cppyyfunc = self.functions[i] try: @@ -492,7 +486,6 @@ class W_CPPDataMember(Wrappable): - _immutable_ = True def __init__(self, space, containing_scope, type_name, offset, is_static): self.space = space @@ -539,8 +532,7 @@ class W_CPPScope(Wrappable): - _immutable_ = True - _immutable_fields_ = ["methods[*]", "datamembers[*]"] + #_immutable_fields_ = ["methods[*]", "datamembers[*]"] kind = "scope" @@ -640,7 +632,6 @@ # classes for inheritance. Both are python classes, though, and refactoring # may be in order at some point. class W_CPPNamespace(W_CPPScope): - _immutable_ = True kind = "namespace" def _make_cppfunction(self, pyname, index): @@ -724,7 +715,6 @@ class W_CPPClass(W_CPPScope): - _immutable_ = True kind = "class" def __init__(self, space, name, opaque_handle): @@ -808,7 +798,6 @@ class W_ComplexCPPClass(W_CPPClass): - _immutable_ = True def get_cppthis(self, cppinstance, calling_scope): assert self == cppinstance.cppclass @@ -830,7 +819,6 @@ class W_CPPTemplateType(Wrappable): - _immutable_ = True def __init__(self, space, name, opaque_handle): self.space = space From noreply at buildbot.pypy.org Mon Oct 29 22:40:03 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:03 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: A branch to remove most calls to gettestobjspace(). Message-ID: <20121029214003.248E31C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58602:d2f675692daf Date: 2012-10-28 21:11 +0100 http://bitbucket.org/pypy/pypy/changeset/d2f675692daf/ Log: A branch to remove most calls to gettestobjspace(). The goal is to move code outside conftest.py From noreply at buildbot.pypy.org Mon Oct 29 22:40:04 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:04 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Simplify test setup_class: replace gettestobjspace() by a spaceconfig. Message-ID: <20121029214004.9F6461C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58603:1c9781c1c676 Date: 2012-10-28 21:26 +0100 http://bitbucket.org/pypy/pypy/changeset/1c9781c1c676/ Log: Simplify test setup_class: replace gettestobjspace() by a spaceconfig. diff --git a/pypy/module/array/test/test_array_old.py b/pypy/module/array/test/test_array_old.py --- a/pypy/module/array/test/test_array_old.py +++ b/pypy/module/array/test/test_array_old.py @@ -3,7 +3,6 @@ import py from py.test import raises import struct -from pypy.conftest import gettestobjspace class BaseArrayTests: @@ -90,18 +89,11 @@ class AppTestArray(BaseArrayTests): - usemodules = ['struct', 'array'] + spaceconfig = dict(usemodules=['struct', 'array']) def setup_class(cls): - """ - Create a space with the array module and import it for use by the - tests. - """ - cls.space = gettestobjspace(usemodules=cls.usemodules) - cls.w_array = cls.space.appexec([], """(): - import array - return array - """) + """Import the array module and make it available as self.array.""" + cls.w_array = cls.space.getbuiltinmodule('array') cls.w_native_sizes = cls.space.wrap(cls.native_sizes) @@ -110,7 +102,7 @@ ## The same as the base class, but with a space that also includes the ## _rawffi module. The array module internally uses it in this case. ## """ -## usemodules = ['struct', '_rawffi'] +## spaceconfig = dict(usemodules=['struct', '_rawffi']) ## def test_buffer_info(self): ## a = self.array.array('l', [123, 456]) From noreply at buildbot.pypy.org Mon Oct 29 22:40:05 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:05 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Progress Message-ID: <20121029214005.CC5931C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58604:f9962d21d772 Date: 2012-10-28 21:58 +0100 http://bitbucket.org/pypy/pypy/changeset/f9962d21d772/ Log: Progress diff --git a/pypy/module/_ast/test/test_ast.py b/pypy/module/_ast/test/test_ast.py --- a/pypy/module/_ast/test/test_ast.py +++ b/pypy/module/_ast/test/test_ast.py @@ -1,16 +1,13 @@ import py -from pypy.conftest import gettestobjspace class AppTestAST: + spaceconfig = dict(usemodules=['struct']) def setup_class(cls): - cls.space = gettestobjspace(usemodules=['struct']) - cls.w_ast = cls.space.appexec([], """(): - import _ast - return _ast""") + cls.w_ast = cls.space.getbuiltinmodule('_ast') def w_get_ast(self, source, mode="exec"): - import _ast as ast + ast = self.ast mod = compile(source, "", mode, ast.PyCF_ONLY_AST) assert isinstance(mod, ast.mod) return mod 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 @@ -1,12 +1,11 @@ -from pypy.conftest import gettestobjspace import sys import py import py.test ## class AppTestSimpleArray: +## spaceconfig = dict(usemodules=('array',)) ## def setup_class(cls): -## cls.space = gettestobjspace(usemodules=('array',)) ## cls.w_simple_array = cls.space.appexec([], """(): ## import array ## return array.simple_array @@ -879,11 +878,9 @@ cls.maxint = sys.maxint class AppTestArray(BaseArrayTests): - OPTIONS = {} + spaceconfig = dict(usemodules=('array', 'struct', '_rawffi')) def setup_class(cls): - cls.space = gettestobjspace(usemodules=('array', 'struct', '_rawffi'), - **cls.OPTIONS) cls.w_array = cls.space.appexec([], """(): import array return array.array @@ -956,4 +953,6 @@ class AppTestArrayBuiltinShortcut(AppTestArray): - OPTIONS = {'objspace.std.builtinshortcut': True} + spaceconfig = AppTestArray.spaceconfig.copy() + spaceconfig['objspace.std.builtinshortcut'] = True + From noreply at buildbot.pypy.org Mon Oct 29 22:40:07 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:07 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Progress. Also set "cls.option", this avoids one conftest import. Message-ID: <20121029214007.07EA01C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58605:be0cb439b5cc Date: 2012-10-28 21:51 +0100 http://bitbucket.org/pypy/pypy/changeset/be0cb439b5cc/ Log: Progress. Also set "cls.option", this avoids one conftest import. diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -326,9 +326,11 @@ if isinstance(item, py.test.collect.Function): appclass = item.getparent(PyPyClassCollector) if appclass is not None: + # Make cls.space and cls.option available in tests. spaceconfig = getattr(appclass.obj, 'spaceconfig', None) if spaceconfig: appclass.obj.space = gettestobjspace(**spaceconfig) + appclass.obj.option = option __multicall__.execute() diff --git a/pypy/module/_bisect/test/test_bisect.py b/pypy/module/_bisect/test/test_bisect.py --- a/pypy/module/_bisect/test/test_bisect.py +++ b/pypy/module/_bisect/test/test_bisect.py @@ -1,10 +1,6 @@ -from pypy.conftest import gettestobjspace - class AppTestBisect: - - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_bisect']) + spaceconfig = dict(usemodules=['_bisect']) def test_bisect_left(self): from _bisect import bisect_left diff --git a/pypy/module/binascii/test/test_binascii.py b/pypy/module/binascii/test/test_binascii.py --- a/pypy/module/binascii/test/test_binascii.py +++ b/pypy/module/binascii/test/test_binascii.py @@ -1,18 +1,10 @@ -from pypy.conftest import gettestobjspace - class AppTestBinascii(object): + spaceconfig = dict(usemodules=['binascii']) def setup_class(cls): - """ - Create a space with the binascii module and import it for use by the - tests. - """ - cls.space = gettestobjspace(usemodules=['binascii']) - cls.w_binascii = cls.space.appexec([], """(): - import binascii - return binascii - """) + """Make binascii module available as self.binascii.""" + cls.w_binascii = cls.space.getbuiltinmodule('binascii') def test_a2b_uu(self): # obscure case, for compability with CPython diff --git a/pypy/module/bz2/test/test_bz2_compdecomp.py b/pypy/module/bz2/test/test_bz2_compdecomp.py --- a/pypy/module/bz2/test/test_bz2_compdecomp.py +++ b/pypy/module/bz2/test/test_bz2_compdecomp.py @@ -1,4 +1,3 @@ -from pypy.conftest import gettestobjspace from pypy.module.bz2.test.support import CheckAllocation from pypy.module.bz2 import interp_bz2 import os, py @@ -37,12 +36,12 @@ interp_bz2.SMALLCHUNK = mod.OLD_SMALLCHUNK class AppTestBZ2Compressor(CheckAllocation): + spaceconfig = dict(usemodules=('bz2',)) + def setup_class(cls): - space = gettestobjspace(usemodules=('bz2',)) - cls.space = space - cls.w_TEXT = space.wrap(TEXT) - cls.w_decompress = space.wrap(decompress) - cls.w_HUGE_OK = space.wrap(HUGE_OK) + cls.w_TEXT = cls.space.wrap(TEXT) + cls.w_decompress = cls.space.wrap(decompress) + cls.w_HUGE_OK = cls.space.wrap(HUGE_OK) def test_creation(self): from bz2 import BZ2Compressor @@ -97,12 +96,12 @@ assert self.decompress(data) == self.TEXT class AppTestBZ2Decompressor(CheckAllocation): + spaceconfig = dict(usemodules=('bz2',)) + def setup_class(cls): - space = gettestobjspace(usemodules=('bz2',)) - cls.space = space - cls.w_TEXT = space.wrap(TEXT) - cls.w_DATA = space.wrap(DATA) - cls.w_BUGGY_DATA = space.wrap(BUGGY_DATA) + cls.w_TEXT = cls.space.wrap(TEXT) + cls.w_DATA = cls.space.wrap(DATA) + cls.w_BUGGY_DATA = cls.space.wrap(BUGGY_DATA) def test_creation(self): from bz2 import BZ2Decompressor @@ -172,13 +171,13 @@ raises(IOError, bz2d.decompress, self.BUGGY_DATA) class AppTestBZ2ModuleFunctions(CheckAllocation): + spaceconfig = dict(usemodules=('bz2',)) + def setup_class(cls): - space = gettestobjspace(usemodules=('bz2',)) - cls.space = space - cls.w_TEXT = space.wrap(TEXT) - cls.w_DATA = space.wrap(DATA) - cls.w_decompress = space.wrap(decompress) - cls.w_HUGE_OK = space.wrap(HUGE_OK) + cls.w_TEXT = cls.space.wrap(TEXT) + cls.w_DATA = cls.space.wrap(DATA) + cls.w_decompress = cls.space.wrap(decompress) + cls.w_HUGE_OK = cls.space.wrap(HUGE_OK) def test_compress_function(self): from bz2 import compress diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -1,7 +1,6 @@ from __future__ import with_statement import py -from pypy.conftest import gettestobjspace from pypy.module.bz2.test.support import CheckAllocation import os import random @@ -48,17 +47,19 @@ class AppTestBZ2File: #(CheckAllocation): # XXX for unknown reasons, we cannot do allocation checks, as sth is # keeping those objects alive (BZ2File objects) + + spaceconfig = dict(usemodules=('bz2',)) + def setup_class(cls): - space = gettestobjspace(usemodules=('bz2',)) - cls.space = space - cls.w_TEXT = space.wrap(TEXT) - cls.w_DATA = space.wrap(DATA) - cls.w_DATA_CRLF = space.wrap(DATA_CRLF) - cls.w_temppath = space.wrap(str(py.test.ensuretemp("bz2").join("foo"))) - cls.w_create_temp_file = space.wrap(create_temp_file) - cls.w_decompress = space.wrap(decompress) - cls.w_create_broken_temp_file = space.wrap(create_broken_temp_file) - cls.w_random_data = space.wrap(RANDOM_DATA) + cls.w_TEXT = cls.space.wrap(TEXT) + cls.w_DATA = cls.space.wrap(DATA) + cls.w_DATA_CRLF = cls.space.wrap(DATA_CRLF) + cls.w_temppath = cls.space.wrap( + str(py.test.ensuretemp("bz2").join("foo"))) + cls.w_create_temp_file = cls.space.wrap(create_temp_file) + cls.w_decompress = cls.space.wrap(decompress) + cls.w_create_broken_temp_file = cls.space.wrap(create_broken_temp_file) + cls.w_random_data = cls.space.wrap(RANDOM_DATA) def test_attributes(self): from bz2 import BZ2File diff --git a/pypy/module/bz2/test/test_large.py b/pypy/module/bz2/test/test_large.py --- a/pypy/module/bz2/test/test_large.py +++ b/pypy/module/bz2/test/test_large.py @@ -1,12 +1,12 @@ import py -from pypy.conftest import gettestobjspace, option class AppTestBZ2File: + spaceconfig = dict(usemodules=('bz2',)) + def setup_class(cls): - if not option.runappdirect: + if not cls.option.runappdirect: py.test.skip("skipping this very slow test; try 'pypy-c -A'") - cls.space = gettestobjspace(usemodules=('bz2',)) largetest_bz2 = py.path.local(__file__).dirpath().join("largetest.bz2") cls.w_compressed_data = cls.space.wrap(largetest_bz2.read('rb')) From noreply at buildbot.pypy.org Mon Oct 29 22:40:08 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:08 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Progress. Fix for spaceconfig={} Message-ID: <20121029214008.2668C1C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58606:9fa214a7ec3d Date: 2012-10-28 22:03 +0100 http://bitbucket.org/pypy/pypy/changeset/9fa214a7ec3d/ Log: Progress. Fix for spaceconfig={} diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -328,7 +328,7 @@ if appclass is not None: # Make cls.space and cls.option available in tests. spaceconfig = getattr(appclass.obj, 'spaceconfig', None) - if spaceconfig: + if spaceconfig is not None: appclass.obj.space = gettestobjspace(**spaceconfig) appclass.obj.option = option diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -1,7 +1,6 @@ """Tests some behaviour of the buffer type that is not tested in lib-python/2.5.2/test/test_types.py where the stdlib buffer tests live.""" import autopath -from pypy.conftest import gettestobjspace class AppTestBuffer: spaceconfig = dict(usemodules=['array']) 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 @@ -1,6 +1,5 @@ import autopath import sys -from pypy import conftest class AppTestBuiltinApp: def setup_class(cls): @@ -21,7 +20,7 @@ # For example if an object x has a __getattr__, we can get # AttributeError if attempting to call x.__getattr__ runs out # of stack. That's annoying, so we just work around it. - if conftest.option.runappdirect: + if cls.option.runappdirect: cls.w_safe_runtimerror = cls.space.wrap(True) else: cls.w_safe_runtimerror = cls.space.wrap(sys.version_info < (2, 6)) @@ -640,10 +639,7 @@ class AppTestGetattr: - OPTIONS = {} - - def setup_class(cls): - cls.space = conftest.gettestobjspace(**cls.OPTIONS) + spaceconfig = {} def test_getattr(self): class a(object): @@ -669,7 +665,7 @@ class AppTestGetattrWithGetAttributeShortcut(AppTestGetattr): - OPTIONS = {"objspace.std.getattributeshortcut": True} + spaceconfig = {"objspace.std.getattributeshortcut": True} class TestInternal: diff --git a/pypy/module/__builtin__/test/test_classobj.py b/pypy/module/__builtin__/test/test_classobj.py --- a/pypy/module/__builtin__/test/test_classobj.py +++ b/pypy/module/__builtin__/test/test_classobj.py @@ -1,6 +1,5 @@ from __future__ import with_statement import py -from pypy.conftest import gettestobjspace, option from pypy.interpreter import gateway @@ -1080,9 +1079,10 @@ assert self.is_strdict(A) class AppTestOldStyleMapDict(AppTestOldstyle): + spaceconfig = {"objspace.std.withmapdict": True} + def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withmapdict": True}) - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("can only be run on py.py") def has_mapdict(space, w_inst): return space.wrap(w_inst._get_mapdict_map() is not None) From noreply at buildbot.pypy.org Mon Oct 29 22:40:09 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:09 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Progress Message-ID: <20121029214009.39C391C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58607:7c02141093f1 Date: 2012-10-28 22:15 +0100 http://bitbucket.org/pypy/pypy/changeset/7c02141093f1/ Log: Progress diff --git a/pypy/module/_cffi_backend/test/test_c.py b/pypy/module/_cffi_backend/test/test_c.py --- a/pypy/module/_cffi_backend/test/test_c.py +++ b/pypy/module/_cffi_backend/test/test_c.py @@ -20,7 +20,6 @@ py.test.skip("requires the b'' literal syntax") from pypy.tool.udir import udir -from pypy.conftest import gettestobjspace, option from pypy.interpreter import gateway from pypy.module._cffi_backend import Module from pypy.translator.platform import host @@ -30,9 +29,9 @@ class AppTestC(object): """Populated below, hack hack hack.""" + spaceconfig = dict(usemodules=('_cffi_backend',)) + def setup_class(cls): - space = gettestobjspace(usemodules=('_cffi_backend',)) - cls.space = space testfuncs_w = [] keepalive_funcs = [] @@ -64,7 +63,8 @@ addr = cdll.gettestfunc(w_num) return space.wrap(addr) - if option.runappdirect: + space = cls.space + if cls.option.runappdirect: def interp2app(func): def run(*args): return func(space, *args) diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py --- a/pypy/module/_codecs/test/test_codecs.py +++ b/pypy/module/_codecs/test/test_codecs.py @@ -1,11 +1,8 @@ import autopath -from pypy.conftest import gettestobjspace class AppTestCodecs: - def setup_class(cls): - space = gettestobjspace(usemodules=('unicodedata', 'struct')) - cls.space = space + spaceconfig = dict(usemodules=('unicodedata', 'struct')) def test_register_noncallable(self): import _codecs @@ -122,10 +119,7 @@ assert unicode_escape_decode('\\x61\\x62\\x63') == (u'abc', 12) class AppTestPartialEvaluation: - - def setup_class(cls): - space = gettestobjspace(usemodules=('array',)) - cls.space = space + spaceconfig = dict(usemodules=('array',)) def test_partial_utf8(self): import _codecs diff --git a/pypy/module/_collections/test/test_defaultdict.py b/pypy/module/_collections/test/test_defaultdict.py --- a/pypy/module/_collections/test/test_defaultdict.py +++ b/pypy/module/_collections/test/test_defaultdict.py @@ -1,9 +1,6 @@ -import py -from pypy.conftest import gettestobjspace class AppTestBasic: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_collections']) + spaceconfig = dict(usemodules=['_collections']) def test_basics(self): from _collections import defaultdict diff --git a/pypy/module/_collections/test/test_deque.py b/pypy/module/_collections/test/test_deque.py --- a/pypy/module/_collections/test/test_deque.py +++ b/pypy/module/_collections/test/test_deque.py @@ -1,9 +1,6 @@ -import py -from pypy.conftest import gettestobjspace class AppTestBasic: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_collections']) + spaceconfig = dict(usemodules=['_collections']) def test_basics(self): from _collections import deque diff --git a/pypy/module/_continuation/test/support.py b/pypy/module/_continuation/test/support.py --- a/pypy/module/_continuation/test/support.py +++ b/pypy/module/_continuation/test/support.py @@ -1,12 +1,13 @@ import py -from pypy.conftest import gettestobjspace from pypy.rpython.tool.rffi_platform import CompilationError class BaseAppTest: + spaceconfig = dict(usemodules=['_continuation'], continuation=True) + def setup_class(cls): try: import pypy.rlib.rstacklet except CompilationError, e: py.test.skip("cannot import rstacklet: %s" % e) - cls.space = gettestobjspace(usemodules=['_continuation'], continuation=True) + 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,11 +1,8 @@ -from pypy.conftest import gettestobjspace - class AppTestCopy: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=('_continuation',), - CALL_METHOD=True) - cls.space.config.translation.continuation = True + spaceconfig = dict(usemodules=['_continuation'], + continuation=True, + CALL_METHOD=True) def test_basic_setup(self): from _continuation import continulet @@ -104,11 +101,11 @@ class AppTestPickle: version = 0 + spaceconfig = dict(usemodules=['_continuation', 'struct'], + continuation=True, + CALL_METHOD=True) def setup_class(cls): - cls.space = gettestobjspace(usemodules=('_continuation', 'struct'), - CALL_METHOD=True) - cls.space.config.translation.continuation = True cls.space.appexec([], """(): global continulet, A, __name__ diff --git a/pypy/module/clr/test/test_clr.py b/pypy/module/clr/test/test_clr.py --- a/pypy/module/clr/test/test_clr.py +++ b/pypy/module/clr/test/test_clr.py @@ -1,4 +1,3 @@ -from pypy.conftest import gettestobjspace from pypy.module.clr.assemblyname import mscorlib def skip_if_not_pythonnet(): @@ -11,10 +10,10 @@ skip_if_not_pythonnet() class AppTestDotnet: + spaceconfig = dict(usemodules=('clr',)) + def setup_class(cls): - space = gettestobjspace(usemodules=('clr',)) - cls.space = space - cls.w_mscorlib = space.wrap(mscorlib) + cls.w_mscorlib = cls.space.wrap(mscorlib) def test_cliobject(self): import clr diff --git a/pypy/module/clr/test/test_importer.py b/pypy/module/clr/test/test_importer.py --- a/pypy/module/clr/test/test_importer.py +++ b/pypy/module/clr/test/test_importer.py @@ -1,12 +1,9 @@ -from pypy.conftest import gettestobjspace from pypy.module.clr.test.test_clr import skip_if_not_pythonnet skip_if_not_pythonnet() class AppTestDotnet: - def setup_class(cls): - space = gettestobjspace(usemodules=('clr', )) - cls.space = space + spaceconfig = dict(usemodules=('clr',)) def test_list_of_namespaces_and_classes(self): import clr diff --git a/pypy/module/cmath/test/test_cmath.py b/pypy/module/cmath/test/test_cmath.py --- a/pypy/module/cmath/test/test_cmath.py +++ b/pypy/module/cmath/test/test_cmath.py @@ -1,5 +1,4 @@ from __future__ import with_statement -from pypy.conftest import gettestobjspace from pypy.rlib.rfloat import copysign, isnan, isinf from pypy.module.cmath import interp_cmath import os, sys, math @@ -16,8 +15,7 @@ class AppTestCMath: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['cmath']) + spaceconfig = dict(usemodules=['cmath']) def test_sign(self): import math From noreply at buildbot.pypy.org Mon Oct 29 22:40:10 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:10 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Progress. cppyy tests could probably share more code. Message-ID: <20121029214010.7BC351C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58608:3c18b10e3af1 Date: 2012-10-28 22:39 +0100 http://bitbucket.org/pypy/pypy/changeset/3c18b10e3af1/ Log: Progress. cppyy tests could probably share more code. diff --git a/pypy/module/cppyy/test/test_aclassloader.py b/pypy/module/cppyy/test/test_aclassloader.py --- a/pypy/module/cppyy/test/test_aclassloader.py +++ b/pypy/module/cppyy/test/test_aclassloader.py @@ -1,5 +1,4 @@ import py, os, sys -from pypy.conftest import gettestobjspace currpath = py.path.local(__file__).dirpath() @@ -13,8 +12,7 @@ class AppTestACLASSLOADER: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['cppyy']) + spaceconfig = dict(usemodules=['cppyy']) def test01_class_autoloading(self): """Test whether a class can be found through .rootmap.""" diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py --- a/pypy/module/cppyy/test/test_advancedcpp.py +++ b/pypy/module/cppyy/test/test_advancedcpp.py @@ -1,5 +1,4 @@ import py, os, sys -from pypy.conftest import gettestobjspace from pypy.module.cppyy import capi @@ -7,8 +6,6 @@ currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("advancedcppDict.so")) -space = gettestobjspace(usemodules=['cppyy', 'array']) - def setup_module(mod): if sys.platform == 'win32': py.test.skip("win32 not supported so far") @@ -18,11 +15,11 @@ raise OSError("'make' failed (see stderr)") class AppTestADVANCEDCPP: + spaceconfig = dict(usemodules=['cppyy', 'array']) + def setup_class(cls): - cls.space = space - env = os.environ - cls.w_test_dct = space.wrap(test_dct) - cls.w_capi_identity = space.wrap(capi.identify()) + cls.w_test_dct = cls.space.wrap(test_dct) + cls.w_capi_identity = cls.space.wrap(capi.identify()) cls.w_advanced = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) 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 @@ -1,5 +1,4 @@ import py, os, sys -from pypy.conftest import gettestobjspace # These tests are for the CINT backend only (they exercise ROOT features # and classes that are not loaded/available with the Reflex backend). At @@ -11,8 +10,6 @@ currpath = py.path.local(__file__).dirpath() iotypes_dct = str(currpath.join("iotypesDict.so")) -space = gettestobjspace(usemodules=['cppyy']) - def setup_module(mod): if sys.platform == 'win32': py.test.skip("win32 not supported so far") @@ -21,8 +18,7 @@ raise OSError("'make' failed (see stderr)") class AppTestCINT: - def setup_class(cls): - cls.space = space + spaceconfig = dict(usemodules=['cppyy']) def test01_globals(self): """Test the availability of ROOT globals""" @@ -100,8 +96,7 @@ class AppTestCINTPythonizations: - def setup_class(cls): - cls.space = space + spaceconfig = dict(usemodules=['cppyy']) def test03_TVector(self): """Test TVector2/3/T behavior""" @@ -121,13 +116,14 @@ class AppTestCINTTTree: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - cls.w_N = space.wrap(5) - cls.w_M = space.wrap(10) - cls.w_fname = space.wrap("test.root") - cls.w_tname = space.wrap("test") - cls.w_title = space.wrap("test tree") + cls.w_N = cls.space.wrap(5) + cls.w_M = cls.space.wrap(10) + cls.w_fname = cls.space.wrap("test.root") + cls.w_tname = cls.space.wrap("test") + cls.w_title = cls.space.wrap("test tree") cls.w_iotypes = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (iotypes_dct,)) diff --git a/pypy/module/cppyy/test/test_cppyy.py b/pypy/module/cppyy/test/test_cppyy.py --- a/pypy/module/cppyy/test/test_cppyy.py +++ b/pypy/module/cppyy/test/test_cppyy.py @@ -1,13 +1,10 @@ import py, os, sys -from pypy.conftest import gettestobjspace from pypy.module.cppyy import interp_cppyy, executor currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("example01Dict.so")) -space = gettestobjspace(usemodules=['cppyy']) - def setup_module(mod): if sys.platform == 'win32': py.test.skip("win32 not supported so far") @@ -16,7 +13,7 @@ raise OSError("'make' failed (see stderr)") class TestCPPYYImplementation: - def test01_class_query(self): + def test01_class_query(self, space): # NOTE: this test needs to run before test_pythonify.py dct = interp_cppyy.load_dictionary(space, test_dct) w_cppyyclass = interp_cppyy.scope_byname(space, "example01") @@ -31,9 +28,9 @@ class AppTestCPPYY: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - env = os.environ cls.w_example01, cls.w_payload = cls.space.unpackiterable(cls.space.appexec([], """(): import cppyy cppyy.load_reflection_info(%r) diff --git a/pypy/module/cppyy/test/test_crossing.py b/pypy/module/cppyy/test/test_crossing.py --- a/pypy/module/cppyy/test/test_crossing.py +++ b/pypy/module/cppyy/test/test_crossing.py @@ -1,5 +1,4 @@ import py, os, sys -from pypy.conftest import gettestobjspace from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase currpath = py.path.local(__file__).dirpath() @@ -14,9 +13,10 @@ class AppTestCrossing(AppTestCpythonExtensionBase): + spaceconfig = dict(usemodules=['cpyext', 'cppyy', 'thread', '_rawffi', '_ffi', 'array']) + def setup_class(cls): # following from AppTestCpythonExtensionBase, with cppyy added - cls.space = gettestobjspace(usemodules=['cpyext', 'cppyy', 'thread', '_rawffi', '_ffi', 'array']) cls.space.getbuiltinmodule("cpyext") from pypy.module.imp.importing import importhook importhook(cls.space, "os") # warm up reference counts 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 @@ -1,12 +1,9 @@ import py, os, sys -from pypy.conftest import gettestobjspace currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("datatypesDict.so")) -space = gettestobjspace(usemodules=['cppyy', 'array', '_rawffi']) - def setup_module(mod): if sys.platform == 'win32': py.test.skip("win32 not supported so far") @@ -15,11 +12,11 @@ raise OSError("'make' failed (see stderr)") class AppTestDATATYPES: + spaceconfig = dict(usemodules=['cppyy', 'array', '_rawffi']) + def setup_class(cls): - cls.space = space - env = os.environ - cls.w_N = space.wrap(5) # should be imported from the dictionary - cls.w_test_dct = space.wrap(test_dct) + cls.w_N = cls.space.wrap(5) # should be imported from the dictionary + cls.w_test_dct = cls.space.wrap(test_dct) cls.w_datatypes = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) 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 @@ -1,13 +1,9 @@ import py, os, sys -from pypy.conftest import gettestobjspace - from pypy.module.cppyy import capi currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("fragileDict.so")) -space = gettestobjspace(usemodules=['cppyy']) - def setup_module(mod): if sys.platform == 'win32': py.test.skip("win32 not supported so far") @@ -16,11 +12,11 @@ raise OSError("'make' failed (see stderr)") class AppTestFRAGILE: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - env = os.environ - cls.w_test_dct = space.wrap(test_dct) - cls.w_capi = space.wrap(capi) + cls.w_test_dct = cls.space.wrap(test_dct) + cls.w_capi = cls.space.wrap(capi) cls.w_fragile = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) diff --git a/pypy/module/cppyy/test/test_operators.py b/pypy/module/cppyy/test/test_operators.py --- a/pypy/module/cppyy/test/test_operators.py +++ b/pypy/module/cppyy/test/test_operators.py @@ -1,12 +1,9 @@ import py, os, sys -from pypy.conftest import gettestobjspace currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("operatorsDict.so")) -space = gettestobjspace(usemodules=['cppyy']) - def setup_module(mod): if sys.platform == 'win32': py.test.skip("win32 not supported so far") @@ -15,11 +12,11 @@ raise OSError("'make' failed (see stderr)") class AppTestOPERATORS: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - env = os.environ - cls.w_N = space.wrap(5) # should be imported from the dictionary - cls.w_test_dct = space.wrap(test_dct) + cls.w_N = cls.space.wrap(5) # should be imported from the dictionary + cls.w_test_dct = cls.space.wrap(test_dct) cls.w_operators = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) diff --git a/pypy/module/cppyy/test/test_overloads.py b/pypy/module/cppyy/test/test_overloads.py --- a/pypy/module/cppyy/test/test_overloads.py +++ b/pypy/module/cppyy/test/test_overloads.py @@ -1,12 +1,9 @@ import py, os, sys -from pypy.conftest import gettestobjspace currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("overloadsDict.so")) -space = gettestobjspace(usemodules=['cppyy']) - def setup_module(mod): if sys.platform == 'win32': py.test.skip("win32 not supported so far") @@ -15,10 +12,10 @@ raise OSError("'make' failed (see stderr)") class AppTestOVERLOADS: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - env = os.environ - cls.w_test_dct = space.wrap(test_dct) + cls.w_test_dct = cls.space.wrap(test_dct) cls.w_overloads = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) 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 @@ -1,13 +1,10 @@ import py, os, sys -from pypy.conftest import gettestobjspace from pypy.module.cppyy import interp_cppyy, executor currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("example01Dict.so")) -space = gettestobjspace(usemodules=['cppyy']) - def setup_module(mod): if sys.platform == 'win32': py.test.skip("win32 not supported so far") @@ -16,10 +13,10 @@ raise OSError("'make' failed (see stderr)") class AppTestPYTHONIFY: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - env = os.environ - cls.w_test_dct = space.wrap(test_dct) + cls.w_test_dct = cls.space.wrap(test_dct) cls.w_example01 = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) @@ -325,10 +322,10 @@ class AppTestPYTHONIFY_UI: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - env = os.environ - cls.w_test_dct = space.wrap(test_dct) + cls.w_test_dct = self.space.wrap(test_dct) cls.w_example01 = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py --- a/pypy/module/cppyy/test/test_stltypes.py +++ b/pypy/module/cppyy/test/test_stltypes.py @@ -1,12 +1,9 @@ import py, os, sys -from pypy.conftest import gettestobjspace currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("stltypesDict.so")) -space = gettestobjspace(usemodules=['cppyy']) - def setup_module(mod): if sys.platform == 'win32': py.test.skip("win32 not supported so far") @@ -15,10 +12,11 @@ raise OSError("'make' failed (see stderr)") class AppTestSTLVECTOR: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - cls.w_N = space.wrap(13) - cls.w_test_dct = space.wrap(test_dct) + cls.w_N = cls.space.wrap(13) + cls.w_test_dct = cls.space.wrap(test_dct) cls.w_stlvector = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) @@ -202,9 +200,10 @@ class AppTestSTLSTRING: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - cls.w_test_dct = space.wrap(test_dct) + cls.w_test_dct = cls.space.wrap(test_dct) cls.w_stlstring = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) @@ -281,10 +280,11 @@ class AppTestSTLSTRING: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - cls.w_N = space.wrap(13) - cls.w_test_dct = space.wrap(test_dct) + cls.w_N = cls.space.wrap(13) + cls.w_test_dct = cls.space.wrap(test_dct) cls.w_stlstring = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) diff --git a/pypy/module/cppyy/test/test_streams.py b/pypy/module/cppyy/test/test_streams.py --- a/pypy/module/cppyy/test/test_streams.py +++ b/pypy/module/cppyy/test/test_streams.py @@ -1,12 +1,9 @@ import py, os, sys -from pypy.conftest import gettestobjspace currpath = py.path.local(__file__).dirpath() test_dct = str(currpath.join("std_streamsDict.so")) -space = gettestobjspace(usemodules=['cppyy']) - def setup_module(mod): if sys.platform == 'win32': py.test.skip("win32 not supported so far") @@ -15,10 +12,10 @@ raise OSError("'make' failed (see stderr)") class AppTestSTDStreams: + spaceconfig = dict(usemodules=['cppyy']) + def setup_class(cls): - cls.space = space - env = os.environ - cls.w_test_dct = space.wrap(test_dct) + cls.w_test_dct = cls.space.wrap(test_dct) cls.w_streams = cls.space.appexec([], """(): import cppyy return cppyy.load_reflection_info(%r)""" % (test_dct, )) From noreply at buildbot.pypy.org Mon Oct 29 22:40:11 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:11 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Progress: cpyext module. Message-ID: <20121029214011.9D26B1C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58609:ed6f80ef63c3 Date: 2012-10-28 23:02 +0100 http://bitbucket.org/pypy/pypy/changeset/ed6f80ef63c3/ Log: Progress: cpyext module. diff --git a/pypy/module/cpyext/test/conftest.py b/pypy/module/cpyext/test/conftest.py --- a/pypy/module/cpyext/test/conftest.py +++ b/pypy/module/cpyext/test/conftest.py @@ -1,6 +1,5 @@ import py import pytest -from pypy.conftest import gettestobjspace def pytest_ignore_collect(path, config): if config.option.runappdirect: @@ -10,7 +9,7 @@ return False def pytest_funcarg__space(request): - return gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi', 'array']) + return request.cls.api def pytest_funcarg__api(request): return request.cls.api 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 @@ -1,5 +1,4 @@ import py -from pypy.conftest import gettestobjspace from pypy.rpython.lltypesystem import rffi, lltype from pypy.interpreter.baseobjspace import W_Root from pypy.module.cpyext.state import State @@ -7,7 +6,6 @@ from pypy.module.cpyext.test.test_cpyext import freeze_refcnts, LeakCheckingTest PyObject = api.PyObject from pypy.interpreter.error import OperationError -from pypy.module.cpyext.state import State import os @api.cpython_api([PyObject], lltype.Void) @@ -19,9 +17,7 @@ class BaseApiTest(LeakCheckingTest): def setup_class(cls): - cls.space = space = gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi', - 'array']) - + space = cls.space # warm up reference counts: # - the posix module allocates a HCRYPTPROV on Windows # - writing to stdout and stderr allocates a file lock diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py --- a/pypy/module/cpyext/test/test_arraymodule.py +++ b/pypy/module/cpyext/test/test_arraymodule.py @@ -1,4 +1,3 @@ -from pypy.conftest import gettestobjspace from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase import py diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py --- a/pypy/module/cpyext/test/test_cpyext.py +++ b/pypy/module/cpyext/test/test_cpyext.py @@ -4,7 +4,6 @@ import py -from pypy.conftest import gettestobjspace from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app from pypy.rpython.lltypesystem import rffi, lltype, ll2ctypes @@ -33,28 +32,6 @@ assert 'PyModule_Check' in api.FUNCTIONS assert api.FUNCTIONS['PyModule_Check'].argtypes == [api.PyObject] -class AppTestApi: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi', 'array']) - from pypy.rlib.clibffi import get_libc_name - cls.w_libc = cls.space.wrap(get_libc_name()) - - def test_load_error(self): - import cpyext - raises(ImportError, cpyext.load_module, "missing.file", "foo") - raises(ImportError, cpyext.load_module, self.libc, "invalid.function") - - def test_dllhandle(self): - import sys - if sys.platform != "win32" or sys.version_info < (2, 6): - skip("Windows Python >= 2.6 only") - assert sys.dllhandle - assert sys.dllhandle.getaddressindll('PyPyErr_NewException') - import ctypes # slow - PyUnicode_GetDefaultEncoding = ctypes.pythonapi.PyPyUnicode_GetDefaultEncoding - PyUnicode_GetDefaultEncoding.restype = ctypes.c_char_p - assert PyUnicode_GetDefaultEncoding() == 'ascii' - def compile_module(space, modname, **kwds): """ Build an extension module and return the filename of the resulting native @@ -92,6 +69,9 @@ self.frozen_ll2callocations = set(ll2ctypes.ALLOCATED.values()) class LeakCheckingTest(object): + """Base class for all cpyext tests.""" + spaceconfig = dict(usemodules=['cpyext', 'thread', '_rawffi', 'array', + 'itertools']) enable_leak_checking = True @staticmethod @@ -164,10 +144,30 @@ # enabled automatically by pypy.conftest. return leaking +class AppTestApi(LeakCheckingTest): + def setup_class(cls): + from pypy.rlib.clibffi import get_libc_name + cls.w_libc = cls.space.wrap(get_libc_name()) + + def test_load_error(self): + import cpyext + raises(ImportError, cpyext.load_module, "missing.file", "foo") + raises(ImportError, cpyext.load_module, self.libc, "invalid.function") + + def test_dllhandle(self): + import sys + if sys.platform != "win32" or sys.version_info < (2, 6): + skip("Windows Python >= 2.6 only") + assert sys.dllhandle + assert sys.dllhandle.getaddressindll('PyPyErr_NewException') + import ctypes # slow + PyUnicode_GetDefaultEncoding = ctypes.pythonapi.PyPyUnicode_GetDefaultEncoding + PyUnicode_GetDefaultEncoding.restype = ctypes.c_char_p + assert PyUnicode_GetDefaultEncoding() == 'ascii' + class AppTestCpythonExtensionBase(LeakCheckingTest): def setup_class(cls): - cls.space = gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi', 'array']) cls.space.getbuiltinmodule("cpyext") from pypy.module.imp.importing import importhook importhook(cls.space, "os") # warm up reference counts diff --git a/pypy/module/cpyext/test/test_setobject.py b/pypy/module/cpyext/test/test_setobject.py --- a/pypy/module/cpyext/test/test_setobject.py +++ b/pypy/module/cpyext/test/test_setobject.py @@ -3,7 +3,6 @@ from pypy.module.cpyext.pyobject import PyObject, PyObjectP, make_ref, from_ref from pypy.module.cpyext.test.test_api import BaseApiTest from pypy.rpython.lltypesystem import rffi, lltype -from pypy.conftest import gettestobjspace class TestTupleObject(BaseApiTest): diff --git a/pypy/module/cpyext/test/test_tupleobject.py b/pypy/module/cpyext/test/test_tupleobject.py --- a/pypy/module/cpyext/test/test_tupleobject.py +++ b/pypy/module/cpyext/test/test_tupleobject.py @@ -3,7 +3,7 @@ from pypy.module.cpyext.pyobject import PyObject, PyObjectP, make_ref, from_ref from pypy.module.cpyext.test.test_api import BaseApiTest from pypy.rpython.lltypesystem import rffi, lltype -from pypy.conftest import gettestobjspace + class TestTupleObject(BaseApiTest): From noreply at buildbot.pypy.org Mon Oct 29 22:40:12 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:12 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress. Message-ID: <20121029214012.B54421C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58610:b0189dd475fa Date: 2012-10-28 23:17 +0100 http://bitbucket.org/pypy/pypy/changeset/b0189dd475fa/ Log: progress. diff --git a/pypy/module/_csv/test/test_dialect.py b/pypy/module/_csv/test/test_dialect.py --- a/pypy/module/_csv/test/test_dialect.py +++ b/pypy/module/_csv/test/test_dialect.py @@ -1,9 +1,5 @@ -from pypy.conftest import gettestobjspace - - class AppTestDialect(object): - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_csv']) + spaceconfig = dict(usemodules=['_csv']) def test_register_dialect(self): import _csv diff --git a/pypy/module/_csv/test/test_reader.py b/pypy/module/_csv/test/test_reader.py --- a/pypy/module/_csv/test/test_reader.py +++ b/pypy/module/_csv/test/test_reader.py @@ -1,10 +1,7 @@ -from pypy.conftest import gettestobjspace +class AppTestReader(object): + spaceconfig = dict(usemodules=['_csv']) - -class AppTestReader(object): def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_csv']) - w__read_test = cls.space.appexec([], r"""(): import _csv def _read_test(input, expect, **kwargs): diff --git a/pypy/module/_csv/test/test_writer.py b/pypy/module/_csv/test/test_writer.py --- a/pypy/module/_csv/test/test_writer.py +++ b/pypy/module/_csv/test/test_writer.py @@ -1,10 +1,7 @@ -from pypy.conftest import gettestobjspace +class AppTestWriter(object): + spaceconfig = dict(usemodules=['_csv']) - -class AppTestWriter(object): def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_csv']) - w__write_test = cls.space.appexec([], r"""(): import _csv diff --git a/pypy/module/_demo/test/test_import.py b/pypy/module/_demo/test/test_import.py --- a/pypy/module/_demo/test/test_import.py +++ b/pypy/module/_demo/test/test_import.py @@ -1,5 +1,5 @@ -from pypy.conftest import gettestobjspace from pypy.module import _demo +from pypy.tool.option import make_config, make_objspace class TestImport: @@ -7,7 +7,8 @@ _demo.Module.demo_events = [] def test_startup(self): - space = gettestobjspace(usemodules=('_demo',)) + config = make_config(None, usemodules=('_demo',)) + space = make_objspace(config) w_modules = space.sys.get('modules') assert _demo.Module.demo_events == ['setup'] diff --git a/pypy/module/_demo/test/test_sieve.py b/pypy/module/_demo/test/test_sieve.py --- a/pypy/module/_demo/test/test_sieve.py +++ b/pypy/module/_demo/test/test_sieve.py @@ -1,9 +1,5 @@ -from pypy.conftest import gettestobjspace - - class AppTestSieve: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=('_demo',)) + spaceconfig = dict(usemodules=('_demo',)) def test_sieve(self): import _demo diff --git a/pypy/module/cStringIO/test/test_interp_stringio.py b/pypy/module/cStringIO/test/test_interp_stringio.py --- a/pypy/module/cStringIO/test/test_interp_stringio.py +++ b/pypy/module/cStringIO/test/test_interp_stringio.py @@ -1,16 +1,12 @@ - -from pypy.conftest import gettestobjspace - import os, sys, py class AppTestcStringIO: + spaceconfig = dict(usemodules=('cStringIO',)) def setup_class(cls): - space = gettestobjspace(usemodules=('cStringIO',)) - cls.space = space - cls.w_write_many_expected_result = space.wrap(''.join( + cls.w_write_many_expected_result = cls.space.wrap(''.join( [chr(i) for j in range(10) for i in range(253)])) - cls.w_StringIO = space.appexec([], """(): + cls.w_StringIO = cls.space.appexec([], """(): import cStringIO return cStringIO.StringIO """) diff --git a/pypy/module/crypt/test/test_crypt.py b/pypy/module/crypt/test/test_crypt.py --- a/pypy/module/crypt/test/test_crypt.py +++ b/pypy/module/crypt/test/test_crypt.py @@ -1,9 +1,7 @@ -from pypy.conftest import gettestobjspace - class AppTestCrypt: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['crypt']) - def test_crypt(self): + spaceconfig = dict(usemodules=['crypt']) + + def test_crypt(self): import crypt res = crypt.crypt("pass", "ab") assert isinstance(res, str) diff --git a/pypy/module/errno/test/test_errno.py b/pypy/module/errno/test/test_errno.py --- a/pypy/module/errno/test/test_errno.py +++ b/pypy/module/errno/test/test_errno.py @@ -1,14 +1,11 @@ -from pypy.conftest import gettestobjspace -import py import errno -def setup_module(mod): - mod.space = gettestobjspace(usemodules=['errno']) -class AppTestErrno: +class AppTestErrno: + spaceconfig = dict(usemodules=['errno']) + def setup_class(cls): - cls.space = space - cls.w_errno = space.appexec([], "(): import errno ; return errno") - cls.w_errorcode = space.wrap(errno.errorcode) + cls.w_errno = cls.space.appexec([], "(): import errno ; return errno") + cls.w_errorcode = cls.space.wrap(errno.errorcode) def test_posix(self): assert self.errno.__file__ diff --git a/pypy/module/exceptions/test/test_exc.py b/pypy/module/exceptions/test/test_exc.py --- a/pypy/module/exceptions/test/test_exc.py +++ b/pypy/module/exceptions/test/test_exc.py @@ -1,9 +1,6 @@ - -from pypy.conftest import gettestobjspace class AppTestExc(object): - def setup_class(cls): - cls.space = gettestobjspace(usemodules=('exceptions',)) + spaceconfig = dict(usemodules=('exceptions',)) def test_baseexc(self): from exceptions import BaseException From noreply at buildbot.pypy.org Mon Oct 29 22:40:13 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:13 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214013.D72FB1C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58611:4c08ac55ba7d Date: 2012-10-28 23:30 +0100 http://bitbucket.org/pypy/pypy/changeset/4c08ac55ba7d/ Log: progress diff --git a/pypy/module/_ffi/test/test_funcptr.py b/pypy/module/_ffi/test/test_funcptr.py --- a/pypy/module/_ffi/test/test_funcptr.py +++ b/pypy/module/_ffi/test/test_funcptr.py @@ -1,4 +1,3 @@ -from pypy.conftest import gettestobjspace from pypy.rpython.lltypesystem import rffi from pypy.rlib.clibffi import get_libc_name from pypy.rlib.libffi import types @@ -8,6 +7,7 @@ import sys, py class BaseAppTestFFI(object): + spaceconfig = dict(usemodules=('_ffi', '_rawffi')) @classmethod def prepare_c_example(cls): @@ -37,8 +37,7 @@ return str(platform.compile([c_file], eci, 'x', standalone=False)) def setup_class(cls): - space = gettestobjspace(usemodules=('_ffi', '_rawffi')) - cls.space = space + space = cls.space cls.w_iswin32 = space.wrap(sys.platform == 'win32') cls.w_libfoo_name = space.wrap(cls.prepare_c_example()) cls.w_libc_name = space.wrap(get_libc_name()) diff --git a/pypy/module/_ffi/test/test_struct.py b/pypy/module/_ffi/test/test_struct.py --- a/pypy/module/_ffi/test/test_struct.py +++ b/pypy/module/_ffi/test/test_struct.py @@ -1,5 +1,4 @@ import sys -from pypy.conftest import gettestobjspace, option from pypy.module._ffi.test.test_funcptr import BaseAppTestFFI from pypy.module._ffi.interp_struct import compute_size_and_alignement, W_Field from pypy.module._ffi.interp_ffitype import app_types, W_FFIType @@ -62,7 +61,7 @@ dummy_type.c_alignment = rffi.cast(rffi.USHORT, 0) dummy_type.c_type = rffi.cast(rffi.USHORT, 0) cls.w_dummy_type = W_FFIType('dummy', dummy_type) - cls.w_runappdirect = cls.space.wrap(option.runappdirect) + cls.w_runappdirect = cls.space.wrap(cls.option.runappdirect) def test__StructDescr(self): from _ffi import _StructDescr, Field, types diff --git a/pypy/module/_ffi/test/test_type_converter.py b/pypy/module/_ffi/test/test_type_converter.py --- a/pypy/module/_ffi/test/test_type_converter.py +++ b/pypy/module/_ffi/test/test_type_converter.py @@ -1,5 +1,4 @@ import sys -from pypy.conftest import gettestobjspace from pypy.rlib.rarithmetic import r_uint, r_singlefloat, r_longlong, r_ulonglong from pypy.rlib.libffi import IS_32_BIT from pypy.module._ffi.interp_ffitype import app_types, descr_new_pointer @@ -30,9 +29,9 @@ class TestFromAppLevel(object): + spaceconfig = dict(usemodules=('_ffi',)) def setup_class(cls): - cls.space = gettestobjspace(usemodules=('_ffi',)) converter = DummyFromAppLevelConverter(cls.space) cls.from_app_level = staticmethod(converter.convert) @@ -152,9 +151,9 @@ class TestFromAppLevel(object): + spaceconfig = dict(usemodules=('_ffi',)) def setup_class(cls): - cls.space = gettestobjspace(usemodules=('_ffi',)) converter = DummyToAppLevelConverter(cls.space) cls.from_app_level = staticmethod(converter.convert) 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 @@ -1,8 +1,6 @@ from __future__ import with_statement import py, os, errno -from pypy.conftest import gettestobjspace, option - def getfile(space): return space.appexec([], """(): try: @@ -13,8 +11,9 @@ """) class AppTestFile(object): + spaceconfig = dict(usemodules=("_file",)) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=("_file", )) cls.w_temppath = cls.space.wrap( str(py.test.ensuretemp("fileimpl").join("foo.txt"))) cls.w_file = getfile(cls.space) @@ -263,7 +262,7 @@ cls.old_read = os.read - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("works with internals of _file impl on py.py") state = [0] def read(fd, n=None): @@ -293,10 +292,11 @@ # these tests only really make sense on top of a translated pypy-c, # because on top of py.py the inner calls to os.write() don't # release our object space's GIL. + spaceconfig = dict(usemodules=("_file",)) + def setup_class(cls): - if not option.runappdirect: + if not cls.option.runappdirect: py.test.skip("likely to deadlock when interpreted by py.py") - cls.space = gettestobjspace(usemodules=("_file", "thread")) cls.w_temppath = cls.space.wrap( str(py.test.ensuretemp("fileimpl").join("concurrency.txt"))) cls.w_file = getfile(cls.space) @@ -387,8 +387,9 @@ class AppTestFile25: + spaceconfig = dict(usemodules=("_file",)) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=("_file", )) cls.w_temppath = cls.space.wrap( str(py.test.ensuretemp("fileimpl").join("foo.txt"))) cls.w_file = getfile(cls.space) diff --git a/pypy/module/_file/test/test_file_extra.py b/pypy/module/_file/test/test_file_extra.py --- a/pypy/module/_file/test/test_file_extra.py +++ b/pypy/module/_file/test/test_file_extra.py @@ -1,7 +1,6 @@ import os, random, sys import pypy.tool.udir import py -from pypy.conftest import gettestobjspace udir = pypy.tool.udir.udir.ensure('test_file_extra', dir=1) @@ -352,10 +351,7 @@ # A few extra tests class AppTestAFewExtra: - - def setup_class(cls): - space = gettestobjspace(usemodules=('array',)) - cls.space = space + spaceconfig = dict(usemodules=('_ffi',)) def setup_method(self, method): fn = str(udir.join('temptestfile')) diff --git a/pypy/module/_file/test/test_large_file.py b/pypy/module/_file/test/test_large_file.py --- a/pypy/module/_file/test/test_large_file.py +++ b/pypy/module/_file/test/test_large_file.py @@ -1,11 +1,11 @@ import py -from pypy.conftest import gettestobjspace from pypy.module._file.test.test_file import getfile class AppTestLargeFile(object): + spaceconfig = dict(usemodules=("_file",)) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=("_file", )) cls.w_temppath = cls.space.wrap( str(py.test.ensuretemp("fileimpl").join("large.data"))) cls.w_file = getfile(cls.space) diff --git a/pypy/module/_hashlib/test/test_hashlib.py b/pypy/module/_hashlib/test/test_hashlib.py --- a/pypy/module/_hashlib/test/test_hashlib.py +++ b/pypy/module/_hashlib/test/test_hashlib.py @@ -1,9 +1,7 @@ import py -from pypy.conftest import gettestobjspace class AppTestHashlib: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_hashlib', 'array', 'struct']) + spaceconfig = dict(usemodules=['_hashlib', 'array', 'struct']) def test_simple(self): import _hashlib diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -1,4 +1,3 @@ -from pypy.conftest import gettestobjspace import os from pypy.tool.udir import udir @@ -12,11 +11,10 @@ os.unlink(i) class AppTestFcntl: + spaceconfig = dict(usemodules=('fcntl', 'array', 'struct', 'termios')) def setup_class(cls): - space = gettestobjspace(usemodules=('fcntl', 'array', 'struct', 'termios')) - cls.space = space tmpprefix = str(udir.ensure('test_fcntl', dir=1).join('tmp_')) - cls.w_tmp = space.wrap(tmpprefix) + cls.w_tmp = cls.space.wrap(tmpprefix) def test_fcntl(self): import fcntl diff --git a/pypy/module/gc/test/test_gc.py b/pypy/module/gc/test/test_gc.py --- a/pypy/module/gc/test/test_gc.py +++ b/pypy/module/gc/test/test_gc.py @@ -1,4 +1,3 @@ -from pypy.conftest import gettestobjspace import py class AppTestGC(object): @@ -88,7 +87,6 @@ cls._heap_stats = rgc._heap_stats rgc._heap_stats = fake_heap_stats fname = udir.join('gcdump.log') - cls.space = gettestobjspace() cls.w_fname = cls.space.wrap(str(fname)) cls._fname = fname @@ -105,8 +103,7 @@ class AppTestGcMethodCache(object): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withmethodcache": True}) + spaceconfig = {"objspace.std.withmethodcache": True} def test_clear_method_cache(self): import gc, weakref @@ -127,10 +124,8 @@ assert r() is None class AppTestGcMapDictIndexCache(AppTestGcMethodCache): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withmethodcache": True, - "objspace.std.withmapdict": True}) - + spaceconfig = {"objspace.std.withmethodcache": True, + "objspace.std.withmapdict": True} def test_clear_index_cache(self): import gc, weakref From noreply at buildbot.pypy.org Mon Oct 29 22:40:15 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:15 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214015.0727E1C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58612:6ad9b5cdd6f4 Date: 2012-10-29 00:00 +0100 http://bitbucket.org/pypy/pypy/changeset/6ad9b5cdd6f4/ Log: progress diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -1,5 +1,4 @@ from __future__ import with_statement -from pypy.conftest import gettestobjspace, option from pypy.interpreter.gateway import interp2app from pypy.tool.udir import udir from pypy.module._io import interp_bufferedio @@ -220,11 +219,12 @@ class AppTestBufferedWriter: + spaceconfig = dict(usemodules=['_io', 'thread']) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_io', 'thread']) tmpfile = udir.join('tmpfile') cls.w_tmpfile = cls.space.wrap(str(tmpfile)) - if option.runappdirect: + if cls.option.runappdirect: cls.w_readfile = tmpfile.read else: def readfile(space): @@ -541,8 +541,9 @@ raises(IOError, _io.BufferedRWPair, _io.BytesIO(), NotWritable()) class AppTestBufferedRandom: + spaceconfig = dict(usemodules=['_io']) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_io']) tmpfile = udir.join('tmpfile') tmpfile.write("a\nb\nc", mode='wb') cls.w_tmpfile = cls.space.wrap(str(tmpfile)) @@ -623,8 +624,9 @@ assert raw.getvalue() == b'1b\n2def\n3\n' class TestNonReentrantLock: - def test_trylock(self): - space = gettestobjspace(usemodules=['thread']) + spaceconfig = dict(usemodules=['thread']) + + def test_trylock(self, space): lock = interp_bufferedio.TryLock(space) with lock: pass diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py --- a/pypy/module/_io/test/test_bytesio.py +++ b/pypy/module/_io/test/test_bytesio.py @@ -1,8 +1,5 @@ -from pypy.conftest import gettestobjspace - class AppTestBytesIO: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_io']) + spaceconfig = dict(usemodules=['_io']) def test_init(self): import _io diff --git a/pypy/module/_io/test/test_fileio.py b/pypy/module/_io/test/test_fileio.py --- a/pypy/module/_io/test/test_fileio.py +++ b/pypy/module/_io/test/test_fileio.py @@ -1,10 +1,10 @@ -from pypy.conftest import gettestobjspace from pypy.tool.udir import udir import os class AppTestFileIO: + spaceconfig = dict(usemodules=['_io']) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_io']) tmpfile = udir.join('tmpfile') tmpfile.write("a\nb\nc", mode='wb') cls.w_tmpfile = cls.space.wrap(str(tmpfile)) diff --git a/pypy/module/_io/test/test_io.py b/pypy/module/_io/test/test_io.py --- a/pypy/module/_io/test/test_io.py +++ b/pypy/module/_io/test/test_io.py @@ -1,13 +1,11 @@ from __future__ import with_statement -from pypy.conftest import gettestobjspace from pypy.tool.udir import udir class AppTestIoModule: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_io']) - + spaceconfig = dict(usemodules=['_io']) +xo def test_import(self): import io @@ -157,8 +155,9 @@ assert s is None class AppTestOpen: + spaceconfig = dict(usemodules=['_io', '_locale', 'array', 'struct']) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_io', '_locale', 'array', 'struct']) tmpfile = udir.join('tmpfile').ensure() cls.w_tmpfile = cls.space.wrap(str(tmpfile)) diff --git a/pypy/module/_io/test/test_textio.py b/pypy/module/_io/test/test_textio.py --- a/pypy/module/_io/test/test_textio.py +++ b/pypy/module/_io/test/test_textio.py @@ -1,8 +1,5 @@ -from pypy.conftest import gettestobjspace - class AppTestTextIO: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_io', '_locale']) + spaceconfig = dict(usemodules=['_io', '_locale']) def test_constructor(self): import _io diff --git a/pypy/module/_locale/test/test_locale.py b/pypy/module/_locale/test/test_locale.py --- a/pypy/module/_locale/test/test_locale.py +++ b/pypy/module/_locale/test/test_locale.py @@ -1,12 +1,11 @@ import py -from pypy.conftest import gettestobjspace import sys class AppTestLocaleTrivia: + spaceconfig = dict(usemodules=['_locale', 'unicodedata']) + def setup_class(cls): - cls.space = space = gettestobjspace(usemodules=['_locale', - 'unicodedata']) if sys.platform != 'win32': cls.w_language_en = cls.space.wrap("C") cls.w_language_utf8 = cls.space.wrap("en_US.utf8") @@ -26,21 +25,21 @@ # some systems are only UTF-8 oriented try: _locale.setlocale(_locale.LC_ALL, - space.str_w(cls.w_language_en)) + cls.space.str_w(cls.w_language_en)) except _locale.Error: _locale.setlocale(_locale.LC_ALL, - space.str_w(cls.w_language_utf8)) + cls.space.str_w(cls.w_language_utf8)) cls.w_language_en = cls.w_language_utf8 _locale.setlocale(_locale.LC_ALL, - space.str_w(cls.w_language_pl)) + cls.space.str_w(cls.w_language_pl)) except _locale.Error: py.test.skip("necessary locales not installed") # Windows forbids the UTF-8 character set since Windows XP. try: _locale.setlocale(_locale.LC_ALL, - space.str_w(cls.w_language_utf8)) + cls.space.str_w(cls.w_language_utf8)) except _locale.Error: del cls.w_language_utf8 finally: 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 @@ -1,14 +1,9 @@ -import py -from pypy.conftest import gettestobjspace, option - class AppTestCProfile(object): - keywords = {} + spaceconfig = dict(usemodules=('_lsprof',)) def setup_class(cls): - space = gettestobjspace(usemodules=('_lsprof',), **cls.keywords) - cls.w_expected_output = space.wrap(expected_output) - cls.space = space - cls.w_file = space.wrap(__file__) + cls.w_expected_output = cls.space.wrap(expected_output) + cls.w_file = cls.space.wrap(__file__) def test_repr(self): import _lsprof @@ -195,7 +190,8 @@ class AppTestWithDifferentBytecodes(AppTestCProfile): - keywords = {'objspace.opcodes.CALL_METHOD': True} + spaceconfig = AppTestCProfile.spaceconfig.copy() + spaceconfig['objspace.opcodes.CALL_METHOD'] = True expected_output = {} 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 @@ -5,7 +5,7 @@ import pypy.interpreter.pycode from pypy.tool.udir import udir from pypy.rlib import streamio -from pypy.conftest import gettestobjspace +from pypy.tool.option import make_config, make_objspace import pytest import sys, os import tempfile, marshal @@ -146,9 +146,9 @@ """) class AppTestImport: + spaceconfig = dict(usemodules=['itertools']) def setup_class(cls): # interpreter-level - cls.space = gettestobjspace(usemodules=['itertools']) cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect) cls.saved_modules = _setup(cls.space) #XXX Compile class @@ -642,8 +642,8 @@ class TestAbi: def test_abi_tag(self): - space1 = gettestobjspace(soabi='TEST') - space2 = gettestobjspace(soabi='') + space1 = make_objspace(make_config(None, soabi='TEST')) + space2 = make_objspace(make_config(None, soabi='')) if sys.platform == 'win32': assert importing.get_so_extension(space1) == '.TESTi.pyd' assert importing.get_so_extension(space2) == '.pyd' @@ -953,7 +953,7 @@ allspaces = [self.space] for opcodename in self.space.config.objspace.opcodes.getpaths(): key = 'objspace.opcodes.' + opcodename - space2 = gettestobjspace(**{key: True}) + space2 = make_objspace(make_config(None, **{key: True})) allspaces.append(space2) for space1 in allspaces: for space2 in allspaces: @@ -1003,12 +1003,12 @@ os.environ['LANG'] = oldlang class AppTestImportHooks(object): + spaceconfig = dict(usemodules=('struct',)) def setup_class(cls): - space = cls.space = gettestobjspace(usemodules=('struct',)) mydir = os.path.dirname(__file__) - cls.w_hooktest = space.wrap(os.path.join(mydir, 'hooktest')) - space.appexec([space.wrap(mydir)], """ + cls.w_hooktest = cls.space.wrap(os.path.join(mydir, 'hooktest')) + cls.space.appexec([cls.space.wrap(mydir)], """ (mydir): import sys sys.path.append(mydir) @@ -1176,9 +1176,9 @@ sys.path_hooks.pop() class AppTestPyPyExtension(object): + spaceconfig = dict(usemodules=['imp', 'zipimport', '__pypy__']) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=['imp', 'zipimport', - '__pypy__']) cls.w_udir = cls.space.wrap(str(udir)) def test_run_compiled_module(self): @@ -1262,10 +1262,11 @@ class AppTestMultithreadedImp(object): + spaceconfig = dict(usemodules=['thread', 'time']) + def setup_class(cls): #if not conftest.option.runappdirect: # py.test.skip("meant as an -A test") - cls.space = gettestobjspace(usemodules=['thread', 'time']) tmpfile = udir.join('test_multithreaded_imp.py') tmpfile.write('''if 1: x = 666 diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -1,10 +1,8 @@ import py -from pypy.conftest import gettestobjspace class AppTestItertools: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['itertools']) + spaceconfig = dict(usemodules=['itertools']) def test_count(self): import itertools @@ -678,8 +676,9 @@ class AppTestItertools26: + spaceconfig = dict(usemodules=['itertools']) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=['itertools']) if cls.space.is_true(cls.space.appexec([], """(): import sys; return sys.version_info < (2, 6) """)): @@ -909,8 +908,9 @@ class AppTestItertools27: + spaceconfig = dict(usemodules=['itertools', 'struct']) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=['itertools', 'struct']) if cls.space.is_true(cls.space.appexec([], """(): import sys; return sys.version_info < (2, 7) """)): From noreply at buildbot.pypy.org Mon Oct 29 22:40:16 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:16 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214016.1A9A51C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58613:663521b4c7e8 Date: 2012-10-29 00:09 +0100 http://bitbucket.org/pypy/pypy/changeset/663521b4c7e8/ Log: progress diff --git a/pypy/module/_md5/test/test_md5.py b/pypy/module/_md5/test/test_md5.py --- a/pypy/module/_md5/test/test_md5.py +++ b/pypy/module/_md5/test/test_md5.py @@ -2,24 +2,16 @@ Tests for the md5 module implemented at interp-level in pypy/module/md5. """ -import py, sys -from pypy.conftest import gettestobjspace - class AppTestMD5(object): + spaceconfig = dict(usemodules=['_md5']) def setup_class(cls): - """ - Create a space with the md5 module and import it for use by the - tests. - """ - cls.space = gettestobjspace(usemodules=['_md5']) cls.w_md5 = cls.space.appexec([], """(): import md5 return md5 """) - def test_digest_size(self): """ md5.digest_size should be 16. diff --git a/pypy/module/marshal/test/test_marshal.py b/pypy/module/marshal/test/test_marshal.py --- a/pypy/module/marshal/test/test_marshal.py +++ b/pypy/module/marshal/test/test_marshal.py @@ -182,16 +182,10 @@ class AppTestRope(AppTestMarshal): - def setup_class(cls): - from pypy.conftest import gettestobjspace - cls.space = gettestobjspace(**{"objspace.std.withrope": True}) - AppTestMarshal.setup_class.im_func(cls) + spaceconfig = {"objspace.std.withrope": True} class AppTestSmallLong(AppTestMarshal): - def setup_class(cls): - from pypy.conftest import gettestobjspace - cls.space = gettestobjspace(**{"objspace.std.withsmalllong": True}) - AppTestMarshal.setup_class.im_func(cls) + spaceconfig = {"objspace.std.withsmalllong": True} def test_smalllong(self): import __pypy__ diff --git a/pypy/module/marshal/test/test_marshalimpl.py b/pypy/module/marshal/test/test_marshalimpl.py --- a/pypy/module/marshal/test/test_marshalimpl.py +++ b/pypy/module/marshal/test/test_marshalimpl.py @@ -1,13 +1,10 @@ from pypy.module.marshal import interp_marshal from pypy.interpreter.error import OperationError -from pypy.conftest import gettestobjspace import sys class AppTestMarshalMore: - def setup_class(cls): - space = gettestobjspace(usemodules=('array',)) - cls.space = space + spaceconfig = dict(usemodules=('array',)) def test_long_0(self): import marshal @@ -57,7 +54,5 @@ class AppTestMarshalSmallLong(AppTestMarshalMore): - def setup_class(cls): - space = gettestobjspace(usemodules=('array',), - **{"objspace.std.withsmalllong": True}) - cls.space = space + spaceconfig = dict(usemodules=('array',), + **{"objspace.std.withsmalllong": True}) diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -1,12 +1,12 @@ from __future__ import with_statement import sys -from pypy.conftest import gettestobjspace from pypy.module.math.test import test_direct class AppTestMath: + spaceconfig = dict(usemodules=['math', 'struct']) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=['math', 'struct']) cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES) cls.w_consistent_host = cls.space.wrap(test_direct.consistent_host) 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 @@ -1,4 +1,3 @@ -from pypy.conftest import gettestobjspace from pypy.module.micronumpy.interp_dtype import get_dtype_cache from pypy.module.micronumpy.interp_ufuncs import (find_binop_result_dtype, find_unaryop_result_dtype) @@ -8,6 +7,8 @@ import sys class BaseNumpyAppTest(object): + spaceconfig = dict(usemodules=['micronumpy']) + @classmethod def setup_class(cls): if option.runappdirect: @@ -15,7 +16,6 @@ import numpy sys.modules['numpypy'] = numpy sys.modules['_numpypy'] = numpy - cls.space = gettestobjspace(usemodules=['micronumpy']) 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/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -1,13 +1,12 @@ from __future__ import with_statement -from pypy.conftest import gettestobjspace from pypy.tool.udir import udir import os class AppTestMMap: + spaceconfig = dict(usemodules=('mmap',)) + def setup_class(cls): - space = gettestobjspace(usemodules=('mmap',)) - cls.space = space - cls.w_tmpname = space.wrap(str(udir.join('mmap-'))) + cls.w_tmpname = cls.space.wrap(str(udir.join('mmap-'))) def test_page_size(self): import mmap From noreply at buildbot.pypy.org Mon Oct 29 22:40:17 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:17 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214017.3CA401C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58614:c48f4c221e50 Date: 2012-10-29 00:17 +0100 http://bitbucket.org/pypy/pypy/changeset/c48f4c221e50/ Log: progress diff --git a/pypy/module/_multibytecodec/test/test_app_codecs.py b/pypy/module/_multibytecodec/test/test_app_codecs.py --- a/pypy/module/_multibytecodec/test/test_app_codecs.py +++ b/pypy/module/_multibytecodec/test/test_app_codecs.py @@ -1,9 +1,5 @@ -from pypy.conftest import gettestobjspace - - class AppTestCodecs: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_multibytecodec']) + spaceconfig = dict(usemodules=['_multibytecodec']) def test_missing_codec(self): import _codecs_cn diff --git a/pypy/module/_multibytecodec/test/test_app_incremental.py b/pypy/module/_multibytecodec/test/test_app_incremental.py --- a/pypy/module/_multibytecodec/test/test_app_incremental.py +++ b/pypy/module/_multibytecodec/test/test_app_incremental.py @@ -1,9 +1,7 @@ -from pypy.conftest import gettestobjspace +class AppTestClasses: + spaceconfig = dict(usemodules=['_multibytecodec']) - -class AppTestClasses: def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_multibytecodec']) cls.w_IncrementalHzDecoder = cls.space.appexec([], """(): import _codecs_cn from _multibytecodec import MultibyteIncrementalDecoder diff --git a/pypy/module/_multibytecodec/test/test_app_stream.py b/pypy/module/_multibytecodec/test/test_app_stream.py --- a/pypy/module/_multibytecodec/test/test_app_stream.py +++ b/pypy/module/_multibytecodec/test/test_app_stream.py @@ -1,9 +1,7 @@ -from pypy.conftest import gettestobjspace +class AppTestStreams: + spaceconfig = dict(usemodules=['_multibytecodec']) - -class AppTestStreams: def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_multibytecodec']) cls.w_HzStreamReader = cls.space.appexec([], """(): import _codecs_cn from _multibytecodec import MultibyteStreamReader diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -1,6 +1,5 @@ import py import sys -from pypy.conftest import gettestobjspace, option from pypy.interpreter.gateway import interp2app, W_Root class TestImport: @@ -9,11 +8,10 @@ from pypy.module._multiprocessing import interp_semaphore class AppTestBufferTooShort: + spaceconfig = dict(usemodules=['_multiprocessing', 'thread', 'signal']) + def setup_class(cls): - space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal')) - cls.space = space - - if option.runappdirect: + if cls.option.runappdirect: def raiseBufferTooShort(self, data): import multiprocessing raise multiprocessing.BufferTooShort(data) @@ -22,7 +20,7 @@ from pypy.module._multiprocessing import interp_connection def raiseBufferTooShort(space, w_data): raise interp_connection.BufferTooShort(space, w_data) - cls.w_raiseBufferTooShort = space.wrap( + cls.w_raiseBufferTooShort = cls.space.wrap( interp2app(raiseBufferTooShort)) def test_exception(self): @@ -69,14 +67,14 @@ assert rhandle.readable class AppTestWinpipeConnection(BaseConnectionTest): + spaceconfig = dict(usemodules=('_multiprocessing', 'thread')) + def setup_class(cls): if sys.platform != "win32": py.test.skip("win32 only") - if not option.runappdirect: - space = gettestobjspace(usemodules=('_multiprocessing', 'thread')) - cls.space = space - + if not cls.option.runappdirect: + space = cls.space # stubs for some modules, # just for multiprocessing to import correctly on Windows w_modules = space.sys.get('modules') @@ -91,11 +89,10 @@ return multiprocessing.Pipe(duplex=False) class AppTestSocketConnection(BaseConnectionTest): + spaceconfig = dict(usemodules=('_multiprocessing', 'thread', 'signal', + 'struct', 'array')) def setup_class(cls): - space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal', - 'struct', 'array')) - cls.space = space - cls.w_connections = space.newlist([]) + cls.w_connections = cls.space.newlist([]) def socketpair(space): "A socket.socketpair() that works on Windows" @@ -117,10 +114,10 @@ space.call_method(cls.w_connections, "append", space.wrap(client)) return space.wrap((server.fileno(), client.fileno())) - if option.runappdirect: - cls.w_socketpair = lambda self: socketpair(space) + if cls.option.runappdirect: + cls.w_socketpair = lambda self: socketpair(cls.space) else: - cls.w_socketpair = space.wrap(interp2app(socketpair)) + cls.w_socketpair = cls.space.wrap(interp2app(socketpair)) def w_make_pair(self): import _multiprocessing diff --git a/pypy/module/_multiprocessing/test/test_memory.py b/pypy/module/_multiprocessing/test/test_memory.py --- a/pypy/module/_multiprocessing/test/test_memory.py +++ b/pypy/module/_multiprocessing/test/test_memory.py @@ -1,10 +1,6 @@ -from pypy.conftest import gettestobjspace - class AppTestMemory: - def setup_class(cls): - space = gettestobjspace( - usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi')) - cls.space = space + spaceconfig = dict(usemodules=('_multiprocessing', 'mmap', + '_rawffi', '_ffi')) def test_address_of(self): import _multiprocessing diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py b/pypy/module/_multiprocessing/test/test_semaphore.py --- a/pypy/module/_multiprocessing/test/test_semaphore.py +++ b/pypy/module/_multiprocessing/test/test_semaphore.py @@ -1,14 +1,13 @@ -from pypy.conftest import gettestobjspace from pypy.module._multiprocessing.interp_semaphore import ( RECURSIVE_MUTEX, SEMAPHORE) class AppTestSemaphore: + spaceconfig = dict(usemodules=('_multiprocessing', 'thread')) + def setup_class(cls): - space = gettestobjspace(usemodules=('_multiprocessing', 'thread')) - cls.space = space - cls.w_SEMAPHORE = space.wrap(SEMAPHORE) - cls.w_RECURSIVE = space.wrap(RECURSIVE_MUTEX) + cls.w_SEMAPHORE = cls.space.wrap(SEMAPHORE) + cls.w_RECURSIVE = cls.space.wrap(RECURSIVE_MUTEX) def test_semaphore(self): from _multiprocessing import SemLock diff --git a/pypy/module/_multiprocessing/test/test_win32.py b/pypy/module/_multiprocessing/test/test_win32.py --- a/pypy/module/_multiprocessing/test/test_win32.py +++ b/pypy/module/_multiprocessing/test/test_win32.py @@ -1,12 +1,12 @@ import py import sys -from pypy.conftest import gettestobjspace class AppTestWin32: + spaceconfig = dict(usemodules=('_multiprocessing',)) + def setup_class(cls): if sys.platform != "win32": py.test.skip("win32 only") - cls.space = gettestobjspace(usemodules=('_multiprocessing',)) def test_CloseHandle(self): from _multiprocessing import win32 diff --git a/pypy/module/oracle/test/test_connect.py b/pypy/module/oracle/test/test_connect.py --- a/pypy/module/oracle/test/test_connect.py +++ b/pypy/module/oracle/test/test_connect.py @@ -1,14 +1,13 @@ -from pypy.conftest import gettestobjspace from pypy.conftest import option from pypy.rpython.tool.rffi_platform import CompilationError import py class OracleNotConnectedTestBase(object): + spaceconfig = dict(usemodules=('oracle',)) @classmethod def setup_class(cls): - space = gettestobjspace(usemodules=('oracle',)) - cls.space = space + space = cls.space space.setitem(space.builtin.w_dict, space.wrap('oracle'), space.getbuiltinmodule('cx_Oracle')) oracle_connect = option.oracle_connect From noreply at buildbot.pypy.org Mon Oct 29 22:40:18 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:18 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214018.5AF071C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58615:ea2d5e2470cf Date: 2012-10-29 00:28 +0100 http://bitbucket.org/pypy/pypy/changeset/ea2d5e2470cf/ Log: progress diff --git a/pypy/module/__pypy__/test/test_builders.py b/pypy/module/__pypy__/test/test_builders.py --- a/pypy/module/__pypy__/test/test_builders.py +++ b/pypy/module/__pypy__/test/test_builders.py @@ -1,9 +1,5 @@ -from pypy.conftest import gettestobjspace - - class AppTestBuilders(object): - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['__pypy__']) + spaceconfig = dict(usemodules=['__pypy__']) def test_simple(self): from __pypy__.builders import UnicodeBuilder diff --git a/pypy/module/__pypy__/test/test_bytebuffer.py b/pypy/module/__pypy__/test/test_bytebuffer.py --- a/pypy/module/__pypy__/test/test_bytebuffer.py +++ b/pypy/module/__pypy__/test/test_bytebuffer.py @@ -1,9 +1,5 @@ -import py -from pypy.conftest import gettestobjspace - class AppTest(object): - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['__pypy__']) + spaceconfig = dict(usemodules=['__pypy__']) def test_bytebuffer(self): from __pypy__ import bytebuffer diff --git a/pypy/module/__pypy__/test/test_debug.py b/pypy/module/__pypy__/test/test_debug.py --- a/pypy/module/__pypy__/test/test_debug.py +++ b/pypy/module/__pypy__/test/test_debug.py @@ -1,13 +1,12 @@ import py -from pypy.conftest import gettestobjspace, option from pypy.rlib import debug class AppTestDebug: + spaceconfig = dict(usemodules=['__pypy__']) + def setup_class(cls): - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("not meant to be run with -A") - cls.space = gettestobjspace(usemodules=['__pypy__']) - space = cls.space cls.w_check_log = cls.space.wrap(cls.check_log) def setup_method(self, meth): diff --git a/pypy/module/__pypy__/test/test_identitydict.py b/pypy/module/__pypy__/test/test_identitydict.py --- a/pypy/module/__pypy__/test/test_identitydict.py +++ b/pypy/module/__pypy__/test/test_identitydict.py @@ -1,9 +1,5 @@ -import py -from pypy.conftest import gettestobjspace - class AppTestIdentityDict: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['__pypy__']) + spaceconfig = dict(usemodules=['__pypy__']) def test_numbers(self): from __pypy__ import identity_dict diff --git a/pypy/module/__pypy__/test/test_special.py b/pypy/module/__pypy__/test/test_special.py --- a/pypy/module/__pypy__/test/test_special.py +++ b/pypy/module/__pypy__/test/test_special.py @@ -1,11 +1,12 @@ import py -from pypy.conftest import gettestobjspace, option class AppTest(object): + spaceconfig = {"objspace.usemodules.select": False, + "objspace.std.withrangelist": True} + def setup_class(cls): - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("does not make sense on pypy-c") - cls.space = gettestobjspace(**{"objspace.usemodules.select": False, "objspace.std.withrangelist": True}) def test__isfake(self): from __pypy__ import isfake diff --git a/pypy/module/parser/test/test_parser.py b/pypy/module/parser/test/test_parser.py --- a/pypy/module/parser/test/test_parser.py +++ b/pypy/module/parser/test/test_parser.py @@ -1,16 +1,11 @@ -from pypy.conftest import gettestobjspace - -def setup_module(mod): - mod.space = gettestobjspace(usemodules=["parser"]) - class ParserModuleTest: + spaceconfig = dict(usemodules=["parser"]) def setup_class(cls): - cls.space = space - cls.w_m = space.appexec([], """(): + cls.w_m = cls.space.appexec([], """(): import parser return parser""") - cls.w_symbol = space.appexec([], """(): + cls.w_symbol = cls.space.appexec([], """(): import symbol return symbol""") diff --git a/pypy/module/posix/test/test_posix_libfile.py b/pypy/module/posix/test/test_posix_libfile.py --- a/pypy/module/posix/test/test_posix_libfile.py +++ b/pypy/module/posix/test/test_posix_libfile.py @@ -1,17 +1,17 @@ -from pypy.conftest import gettestobjspace from pypy.tool.udir import udir import os def setup_module(mod): - mod.space = gettestobjspace(usemodules=['posix']) mod.path = udir.join('posixtestfile.txt') mod.path.write("this is a test") class AppTestPosix: + spaceconfig = dict(usemodules=['posix']) + def setup_class(cls): - cls.space = space - cls.w_posix = space.appexec([], "(): import %s as m ; return m" % os.name) - cls.w_path = space.wrap(str(path)) + cls.w_posix = cls.space.appexec([], """(): + import %s as m ; return m""" % os.name) + cls.w_path = cls.space.wrap(str(path)) def test_posix_is_pypy_s(self): assert self.posix.__file__ diff --git a/pypy/module/pwd/test/test_pwd.py b/pypy/module/pwd/test/test_pwd.py --- a/pypy/module/pwd/test/test_pwd.py +++ b/pypy/module/pwd/test/test_pwd.py @@ -1,8 +1,5 @@ -from pypy.conftest import gettestobjspace - class AppTestPwd: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['pwd']) + spaceconfig = dict(usemodules=['pwd']) def test_getpwuid(self): import pwd, sys diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py --- a/pypy/module/pyexpat/test/test_parser.py +++ b/pypy/module/pyexpat/test/test_parser.py @@ -1,10 +1,8 @@ -from pypy.conftest import gettestobjspace from pypy.module.pyexpat.interp_pyexpat import global_storage from pytest import skip class AppTestPyexpat: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['pyexpat']) + spaceconfig = dict(usemodules=['pyexpat']) def teardown_class(cls): global_storage.clear() diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py --- a/pypy/module/pypyjit/test/test_jit_hook.py +++ b/pypy/module/pypyjit/test/test_jit_hook.py @@ -1,6 +1,5 @@ import py -from pypy.conftest import gettestobjspace, option from pypy.interpreter.gateway import interp2app from pypy.interpreter.pycode import PyCode from pypy.jit.metainterp.history import JitCellToken, ConstInt, ConstPtr @@ -35,12 +34,11 @@ jitdrivers_sd = [MockJitDriverSD] class AppTestJitHook(object): + spaceconfig = dict(usemodules=('pypyjit',)) def setup_class(cls): - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("Can't run this test with -A") - space = gettestobjspace(usemodules=('pypyjit',)) - cls.space = space - w_f = space.appexec([], """(): + w_f = cls.space.appexec([], """(): def function(): pass return function @@ -89,6 +87,7 @@ pypy_hooks.on_abort(Counters.ABORT_TOO_LONG, pypyjitdriver, greenkey, 'blah') + space = cls.space cls.w_on_compile = space.wrap(interp2app(interp_on_compile)) cls.w_on_compile_bridge = space.wrap(interp2app(interp_on_compile_bridge)) cls.w_on_abort = space.wrap(interp2app(interp_on_abort)) diff --git a/pypy/module/pypyjit/test/test_jit_setup.py b/pypy/module/pypyjit/test/test_jit_setup.py --- a/pypy/module/pypyjit/test/test_jit_setup.py +++ b/pypy/module/pypyjit/test/test_jit_setup.py @@ -1,9 +1,5 @@ -from pypy.conftest import gettestobjspace - class AppTestPyPyJIT: - def setup_class(cls): - space = gettestobjspace(usemodules=('pypyjit',)) - cls.space = space + spaceconfig = dict(usemodules=('pypyjit',)) def test_setup(self): # this just checks that the module is setting up things correctly, and @@ -51,13 +47,9 @@ assert type(d) is dict assert 'threshold' in d - -def test_interface_residual_call(): - space = gettestobjspace(usemodules=['pypyjit']) - space.appexec([], """(): + def test_interface_residual_call(self): import pypyjit def f(*args, **kwds): return (args, kwds) res = pypyjit.residual_call(f, 4, x=6) assert res == ((4,), {'x': 6}) - """) From noreply at buildbot.pypy.org Mon Oct 29 22:40:19 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:19 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214019.874AF1C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58616:8c32203152a5 Date: 2012-10-29 00:34 +0100 http://bitbucket.org/pypy/pypy/changeset/8c32203152a5/ Log: progress diff --git a/pypy/module/_random/test/test_random.py b/pypy/module/_random/test/test_random.py --- a/pypy/module/_random/test/test_random.py +++ b/pypy/module/_random/test/test_random.py @@ -1,9 +1,5 @@ -import py -from pypy.conftest import gettestobjspace - class AppTestRandom: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_random']) + spaceconfig = dict(usemodules=['_random']) def test_dict(self): import _random diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -1,6 +1,3 @@ - - -from pypy.conftest import gettestobjspace from pypy.translator.platform import platform from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.module._rawffi.interp_rawffi import TYPEMAP @@ -9,6 +6,8 @@ import os, sys, py class AppTestFfi: + spaceconfig = dict(usemodules=['_rawffi', 'struct']) + def prepare_c_example(): from pypy.tool.udir import udir c_file = udir.ensure("test__rawffi", dir=1).join("xlib.c") @@ -197,9 +196,8 @@ prepare_c_example = staticmethod(prepare_c_example) def setup_class(cls): + space = cls.space from pypy.rlib.clibffi import get_libc_name - space = gettestobjspace(usemodules=('_rawffi', 'struct')) - cls.space = space cls.w_lib_name = space.wrap(cls.prepare_c_example()) cls.w_libc_name = space.wrap(get_libc_name()) if sys.platform == 'win32': @@ -1030,10 +1028,10 @@ S2E.get_ffi_type() # does not hang class AppTestAutoFree: + spaceconfig = dict(usemodules=['_rawffi', 'struct']) + def setup_class(cls): - space = gettestobjspace(usemodules=('_rawffi', 'struct')) - cls.space = space - cls.w_sizes_and_alignments = space.wrap(dict( + cls.w_sizes_and_alignments = cls.space.wrap(dict( [(k, (v.c_size, v.c_alignment)) for k,v in TYPEMAP.iteritems()])) Tracker.DO_TRACING = True diff --git a/pypy/module/_rawffi/test/test_nested.py b/pypy/module/_rawffi/test/test_nested.py --- a/pypy/module/_rawffi/test/test_nested.py +++ b/pypy/module/_rawffi/test/test_nested.py @@ -1,9 +1,5 @@ -from pypy.conftest import gettestobjspace - class AppTestNested: - def setup_class(cls): - space = gettestobjspace(usemodules=('_rawffi', 'struct')) - cls.space = space + spaceconfig = dict(usemodules=['_rawffi', 'struct']) def test_inspect_structure(self): import _rawffi, struct diff --git a/pypy/module/_rawffi/test/test_tracker.py b/pypy/module/_rawffi/test/test_tracker.py --- a/pypy/module/_rawffi/test/test_tracker.py +++ b/pypy/module/_rawffi/test/test_tracker.py @@ -1,12 +1,10 @@ - -from pypy.conftest import gettestobjspace from pypy.module._rawffi.tracker import Tracker class AppTestTracker: + spaceconfig = dict(usemodules=['_rawffi', 'struct']) + def setup_class(cls): Tracker.DO_TRACING = True - space = gettestobjspace(usemodules=('_rawffi','struct')) - cls.space = space def test_array(self): import _rawffi diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -1,10 +1,5 @@ -from pypy.conftest import gettestobjspace -import os - class AppTestRCTime: - def setup_class(cls): - space = gettestobjspace(usemodules=('rctime', 'struct')) - cls.space = space + spaceconfig = dict(usemodules=['rctime', 'struct']) def test_attributes(self): import time as rctime From noreply at buildbot.pypy.org Mon Oct 29 22:40:20 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:20 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214020.BFF491C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58617:21f2c861a4dc Date: 2012-10-29 00:42 +0100 http://bitbucket.org/pypy/pypy/changeset/21f2c861a4dc/ Log: progress diff --git a/pypy/module/_sha/test/test_sha.py b/pypy/module/_sha/test/test_sha.py --- a/pypy/module/_sha/test/test_sha.py +++ b/pypy/module/_sha/test/test_sha.py @@ -3,17 +3,12 @@ """ import py -from pypy.conftest import gettestobjspace class AppTestSHA(object): + spaceconfig = dict(usemodules=['_sha']) def setup_class(cls): - """ - Create a space with the sha module and import it for use by the - tests. - """ - cls.space = gettestobjspace(usemodules=['_sha']) cls.w_sha = cls.space.appexec([], """(): import sha return sha diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py --- a/pypy/module/_ssl/test/test_ssl.py +++ b/pypy/module/_ssl/test/test_ssl.py @@ -1,12 +1,5 @@ -from pypy.conftest import gettestobjspace -import os -import py - - class AppTestSSL: - def setup_class(cls): - space = gettestobjspace(usemodules=('_ssl', '_socket')) - cls.space = space + spaceconfig = dict(usemodules=('_ssl', '_socket')) def test_init_module(self): import _ssl @@ -89,9 +82,7 @@ class AppTestConnectedSSL: - def setup_class(cls): - space = gettestobjspace(usemodules=('_ssl', '_socket', 'struct')) - cls.space = space + spaceconfig = dict(usemodules=('_ssl', '_socket', 'struct')) def setup_method(self, method): # https://www.verisign.net/ @@ -177,10 +168,9 @@ class AppTestConnectedSSL_Timeout(AppTestConnectedSSL): # Same tests, with a socket timeout # to exercise the poll() calls + spaceconfig = dict(usemodules=('_ssl', '_socket', 'struct')) def setup_class(cls): - space = gettestobjspace(usemodules=('_ssl', '_socket', 'struct')) - cls.space = space cls.space.appexec([], """(): import socket; socket.setdefaulttimeout(1) """) diff --git a/pypy/module/_winreg/test/test_winreg.py b/pypy/module/_winreg/test/test_winreg.py --- a/pypy/module/_winreg/test/test_winreg.py +++ b/pypy/module/_winreg/test/test_winreg.py @@ -1,4 +1,3 @@ -from pypy.conftest import gettestobjspace from pypy.tool.udir import udir import os, sys, py @@ -20,9 +19,7 @@ canSaveKey = True class AppTestHKey: - def setup_class(cls): - space = gettestobjspace(usemodules=('_winreg',)) - cls.space = space + spaceconfig = dict(usemodules=('_winreg',)) def test_repr(self): import _winreg @@ -30,10 +27,11 @@ assert str(k) == "" class AppTestFfi: + spaceconfig = dict(usemodules=('_winreg',)) + def setup_class(cls): import _winreg - space = gettestobjspace(usemodules=('_winreg',)) - cls.space = space + space = cls.space cls.root_key = _winreg.HKEY_CURRENT_USER cls.test_key_name = "SOFTWARE\\Pypy Registry Test Key - Delete Me" cls.w_root_key = space.wrap(cls.root_key) diff --git a/pypy/module/select/test/test_epoll.py b/pypy/module/select/test/test_epoll.py --- a/pypy/module/select/test/test_epoll.py +++ b/pypy/module/select/test/test_epoll.py @@ -1,20 +1,17 @@ import py import sys -from pypy.conftest import gettestobjspace - # add a larger timeout for slow ARM machines import platform class AppTestEpoll(object): - + spaceconfig = dict(usemodules=["select", "_socket", "posix"]) def setup_class(cls): # NB. we should ideally py.test.skip() if running on an old linux # where the kernel doesn't support epoll() if not sys.platform.startswith('linux'): py.test.skip("test requires linux (assumed >= 2.6)") - cls.space = gettestobjspace(usemodules=["select", "_socket", "posix"]) def setup_method(self, meth): self.w_sockets = self.space.wrap([]) diff --git a/pypy/module/select/test/test_kqueue.py b/pypy/module/select/test/test_kqueue.py --- a/pypy/module/select/test/test_kqueue.py +++ b/pypy/module/select/test/test_kqueue.py @@ -3,15 +3,13 @@ import py import sys -from pypy.conftest import gettestobjspace +class AppTestKqueue(object): + spaceconfig = dict(usemodules=["select", "_socket", "posix"]) - -class AppTestKqueue(object): def setup_class(cls): if not 'bsd' in sys.platform and \ not sys.platform.startswith('darwin'): py.test.skip("test requires BSD") - cls.space = gettestobjspace(usemodules=["select", "_socket", "posix"]) def test_create(self): import select diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py --- a/pypy/module/select/test/test_select.py +++ b/pypy/module/select/test/test_select.py @@ -1,5 +1,4 @@ import py, sys -from pypy.conftest import gettestobjspace class _AppTestSelect: def test_sleep(self): @@ -228,11 +227,11 @@ class AppTestSelectWithPipes(_AppTestSelect): "Use a pipe to get pairs of file descriptors" + spaceconfig = dict(usemodules=["select"]) + def setup_class(cls): if sys.platform == 'win32': py.test.skip("select() doesn't work with pipes on win32") - space = gettestobjspace(usemodules=('select',)) - cls.space = space def w_getpair(self): # Wraps a file descriptor in an socket-like object @@ -255,11 +254,10 @@ """Same tests with connected sockets. socket.socketpair() does not exists on win32, so we start our own server.""" + spaceconfig = dict(usemodules=["select", "_socket"]) + def setup_class(cls): - space = gettestobjspace(usemodules=('select','_socket')) - cls.space = space - - cls.w_getpair = space.wrap(cls.getsocketpair) + cls.w_getpair = cls.space.wrap(cls.getsocketpair) import socket cls.sock = socket.socket() diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py --- a/pypy/module/signal/test/test_signal.py +++ b/pypy/module/signal/test/test_signal.py @@ -1,16 +1,15 @@ import os, py, sys import signal as cpy_signal -from pypy.conftest import gettestobjspace class TestCheckSignals: + spaceconfig = dict(usemodules=['signal']) def setup_class(cls): if not hasattr(os, 'kill') or not hasattr(os, 'getpid'): py.test.skip("requires os.kill() and os.getpid()") if not hasattr(cpy_signal, 'SIGUSR1'): py.test.skip("requires SIGUSR1 in signal") - cls.space = gettestobjspace(usemodules=['signal']) def test_checksignals(self): space = self.space @@ -36,11 +35,10 @@ class AppTestSignal: + spaceconfig = dict(usemodules=['signal']) def setup_class(cls): - space = gettestobjspace(usemodules=['signal']) - cls.space = space - cls.w_signal = space.appexec([], "(): import signal; return signal") + cls.w_signal = cls.space.getbuiltinmodule('signal') def test_exported_names(self): import os @@ -253,10 +251,7 @@ signal.signal(signum, oldhandler) class AppTestSignalSocket: - - def setup_class(cls): - space = gettestobjspace(usemodules=['signal', '_socket']) - cls.space = space + spaceconfig = dict(usemodules=['signal', '_socket']) def test_alarm_raise(self): try: From noreply at buildbot.pypy.org Mon Oct 29 22:40:21 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:21 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214021.D37751C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58618:3eb05cbcfc2b Date: 2012-10-29 00:55 +0100 http://bitbucket.org/pypy/pypy/changeset/3eb05cbcfc2b/ Log: progress diff --git a/pypy/module/_sre/test/test_app_sre.py b/pypy/module/_sre/test/test_app_sre.py --- a/pypy/module/_sre/test/test_app_sre.py +++ b/pypy/module/_sre/test/test_app_sre.py @@ -3,7 +3,6 @@ import py from py.test import raises, skip from pypy.interpreter.gateway import app2interp_temp -from pypy.conftest import gettestobjspace, option def init_app_test(cls, space): cls.w_s = space.appexec([space.wrap(autopath.this_dir)], @@ -94,8 +93,7 @@ class AppTestSreMatch: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=('array', )) + spaceconfig = dict(usemodules=('array', )) def test_copy(self): import re @@ -336,13 +334,10 @@ class AppTestGetlower: + spaceconfig = dict(usemodules=('_locale',)) def setup_class(cls): # This imports support_test_sre as the global "s" - try: - cls.space = gettestobjspace(usemodules=('_locale',)) - except py.test.skip.Exception: - cls.space = gettestobjspace(usemodules=('_rawffi',)) init_app_test(cls, cls.space) def setup_method(self, method): @@ -600,14 +595,11 @@ class AppTestOpcodes: + spaceconfig = dict(usemodules=('_locale',)) def setup_class(cls): - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("can only be run on py.py: _sre opcodes don't match") - try: - cls.space = gettestobjspace(usemodules=('_locale',)) - except py.test.skip.Exception: - cls.space = gettestobjspace(usemodules=('_rawffi',)) # This imports support_test_sre as the global "s" init_app_test(cls, cls.space) diff --git a/pypy/module/struct/test/test_struct.py b/pypy/module/struct/test/test_struct.py --- a/pypy/module/struct/test/test_struct.py +++ b/pypy/module/struct/test/test_struct.py @@ -3,18 +3,17 @@ """ import py -from pypy.conftest import gettestobjspace from pypy.rlib.rstruct.nativefmttable import native_is_bigendian class AppTestStruct(object): + spaceconfig = dict(usemodules=['struct']) def setup_class(cls): """ Create a space with the struct module and import it for use by the tests. """ - cls.space = gettestobjspace(usemodules=['struct']) cls.w_struct = cls.space.appexec([], """(): import struct return struct @@ -387,12 +386,9 @@ class AppTestStructBuffer(object): + spaceconfig = dict(usemodules=['struct', '__pypy__']) def setup_class(cls): - """ - Create a space with the struct and __pypy__ modules. - """ - cls.space = gettestobjspace(usemodules=['struct', '__pypy__']) cls.w_struct = cls.space.appexec([], """(): import struct return struct 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 @@ -1,8 +1,4 @@ # -*- coding: iso-8859-1 -*- -import autopath -from pypy.conftest import option, gettestobjspace -from py.test import raises -from pypy.interpreter.gateway import app2interp_temp import sys def test_stdin_exists(space): @@ -16,7 +12,7 @@ class AppTestAppSysTests: def setup_class(cls): - cls.w_appdirect = cls.space.wrap(option.runappdirect) + cls.w_appdirect = cls.space.wrap(cls.option.runappdirect) cls.w_filesystemenc = cls.space.wrap(sys.getfilesystemencoding()) def test_sys_in_modules(self): @@ -130,7 +126,7 @@ class AppTestSysModulePortedFromCPython: def setup_class(cls): - cls.w_appdirect = cls.space.wrap(option.runappdirect) + cls.w_appdirect = cls.space.wrap(cls.option.runappdirect) def test_original_displayhook(self): import sys, cStringIO, __builtin__ @@ -560,8 +556,7 @@ assert frames[0].f_code.co_name in ('f', '?') class AppTestCurrentFramesWithThread(AppTestCurrentFrames): - def setup_class(cls): - cls.space = gettestobjspace(usemodules=('thread',)) + spaceconfig = dict(usemodules=('thread',)) def test_current_frames(self): import sys @@ -601,7 +596,7 @@ class AppTestSysExcInfoDirect: def setup_method(self, meth): - self.checking = not option.runappdirect + self.checking = not self.option.runappdirect if self.checking: self.seen = [] from pypy.module.sys import vm @@ -715,5 +710,4 @@ class AppTestSysExcInfoDirectCallMethod(AppTestSysExcInfoDirect): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.opcodes.CALL_METHOD": True}) + spaceconfig = {"objspace.opcodes.CALL_METHOD": True} diff --git a/pypy/module/termios/test/test_termios.py b/pypy/module/termios/test/test_termios.py --- a/pypy/module/termios/test/test_termios.py +++ b/pypy/module/termios/test/test_termios.py @@ -1,7 +1,6 @@ import py import sys -from pypy.conftest import gettestobjspace from pypy.tool.autopath import pypydir from pypy.tool.udir import udir @@ -106,8 +105,9 @@ child.expect('ok!') class AppTestTermios(object): + spaceconfig = dict(usemodules=['termios']) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=['termios']) d = {} import termios for name in dir(termios): 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,6 +1,5 @@ import py import time, gc, thread, os -from pypy.conftest import gettestobjspace, option from pypy.interpreter.gateway import ObjSpace, W_Root, interp2app_temp from pypy.module.thread import gil @@ -30,12 +29,10 @@ thread.start_new_thread(kill, ()) class GenericTestThread: + spaceconfig = dict(usemodules=('thread', 'time', 'signal')) def setup_class(cls): - space = gettestobjspace(usemodules=('thread', 'time', 'signal')) - cls.space = space - - if option.runappdirect: + if cls.option.runappdirect: def plain_waitfor(self, condition, delay=1): adaptivedelay = 0.04 limit = time.time() + NORMAL_TIMEOUT * delay @@ -49,10 +46,12 @@ cls.w_waitfor = plain_waitfor else: - cls.w_waitfor = space.wrap(lambda self, condition, delay=1: waitfor(space, condition, delay)) - cls.w_busywait = space.appexec([], """(): + cls.w_waitfor = cls.space.wrap( + lambda self, condition, delay=1: waitfor(cls.space, condition, delay)) + cls.w_busywait = cls.space.appexec([], """(): import time return time.sleep """) - cls.w_timeout_killer = space.wrap(lambda self, *args, **kwargs: timeout_killer(*args, **kwargs)) + cls.w_timeout_killer = cls.space.wrap( + lambda self, *args, **kwargs: timeout_killer(*args, **kwargs)) diff --git a/pypy/module/thread/test/test_fork.py b/pypy/module/thread/test/test_fork.py --- a/pypy/module/thread/test/test_fork.py +++ b/pypy/module/thread/test/test_fork.py @@ -1,5 +1,3 @@ -import py, sys -from pypy.conftest import gettestobjspace from pypy.module.thread.test.support import GenericTestThread class AppTestFork(GenericTestThread): diff --git a/pypy/module/time/test/test_time.py b/pypy/module/time/test/test_time.py --- a/pypy/module/time/test/test_time.py +++ b/pypy/module/time/test/test_time.py @@ -1,24 +1,21 @@ -from pypy.conftest import gettestobjspace import time -def setup_module(mod): - mod.space = gettestobjspace(usemodules=['time']) +class TestTime: + spaceconfig = dict(usemodules=['time']) -class TestTime: - - def test_clock(self): + def test_clock(self, space): t0 = time.clock() w_t1 = space.appexec([], """(): import time; return time.clock()""") t2 = time.clock() assert t0 <= space.unwrap(w_t1) <= t2 - def test_time(self): + def test_time(self, space): t0 = time.time() w_t1 = space.appexec([], """(): import time; return time.time()""") t2 = time.time() assert t0 <= space.unwrap(w_t1) <= t2 - def test_sleep(self): + def test_sleep(self, space): w_sleep = space.appexec([], """(): import time; return time.sleep""") t0 = time.time() space.call_function(w_sleep, space.wrap(0.3)) From noreply at buildbot.pypy.org Mon Oct 29 22:40:22 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:22 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214022.E7A901C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58619:18619c1f1118 Date: 2012-10-29 01:03 +0100 http://bitbucket.org/pypy/pypy/changeset/18619c1f1118/ Log: progress diff --git a/pypy/module/_warnings/test/test_warnings.py b/pypy/module/_warnings/test/test_warnings.py --- a/pypy/module/_warnings/test/test_warnings.py +++ b/pypy/module/_warnings/test/test_warnings.py @@ -1,11 +1,5 @@ -import py -import sys -from pypy.conftest import gettestobjspace - class AppTestWarnings: - def setup_class(cls): - space = gettestobjspace(usemodules=('_warnings',)) - cls.space = space + spaceconfig = dict(usemodules=('_warnings',)) def test_defaults(self): import _warnings diff --git a/pypy/module/_weakref/test/test_weakref.py b/pypy/module/_weakref/test/test_weakref.py --- a/pypy/module/_weakref/test/test_weakref.py +++ b/pypy/module/_weakref/test/test_weakref.py @@ -1,9 +1,5 @@ -from pypy.conftest import gettestobjspace - class AppTestWeakref(object): - def setup_class(cls): - space = gettestobjspace(usemodules=('_weakref',)) - cls.space = space + spaceconfig = dict(usemodules=('_weakref',)) def test_simple(self): import _weakref, gc @@ -304,9 +300,7 @@ class AppTestProxy(object): - def setup_class(cls): - space = gettestobjspace(usemodules=('_weakref',)) - cls.space = space + spaceconfig = dict(usemodules=('_weakref',)) def test_simple(self): import _weakref, gc diff --git a/pypy/module/unicodedata/test/test_unicodedata.py b/pypy/module/unicodedata/test/test_unicodedata.py --- a/pypy/module/unicodedata/test/test_unicodedata.py +++ b/pypy/module/unicodedata/test/test_unicodedata.py @@ -1,13 +1,8 @@ -from py.test import raises, skip from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin -from pypy.conftest import gettestobjspace - from pypy.module.unicodedata import unicodedb_3_2_0, unicodedb_5_2_0 class AppTestUnicodeData: - def setup_class(cls): - space = gettestobjspace(usemodules=('unicodedata',)) - cls.space = space + spaceconfig = dict(usemodules=('unicodedata',)) def test_hangul_syllables(self): import unicodedata diff --git a/pypy/module/zipimport/test/test_undocumented.py b/pypy/module/zipimport/test/test_undocumented.py --- a/pypy/module/zipimport/test/test_undocumented.py +++ b/pypy/module/zipimport/test/test_undocumented.py @@ -6,7 +6,6 @@ import shutil import time import zipfile -from pypy.conftest import gettestobjspace TESTFN = '@test' @@ -18,10 +17,9 @@ ]) class AppTestZipImport: + spaceconfig = dict(usemodules=['zipimport', 'rctime', 'struct']) def setup_class(cls): - space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct']) - cls.space = space - cls.w_created_paths = space.wrap(created_paths) + cls.w_created_paths = cls.space.wrap(created_paths) def w_temp_zipfile(self, created_paths, source=True, bytecode=True): """Create a temporary zip file for testing. diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -1,5 +1,4 @@ -from pypy.conftest import gettestobjspace import marshal import py, os import time @@ -15,8 +14,10 @@ cpy's regression tests """ compression = ZIP_STORED + spaceconfig = dict(usemodules=['zipimport', 'rctime', 'struct']) pathsep = os.path.sep + @classmethod def make_pyc(cls, space, co, mtime): data = marshal.dumps(co) if type(mtime) is type(0.0): @@ -33,7 +34,8 @@ s.write(imp.get_magic()) pyc = s.getvalue() + struct.pack(" Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58620:9189ff822a90 Date: 2012-10-29 01:48 +0100 http://bitbucket.org/pypy/pypy/changeset/9189ff822a90/ Log: progress: removed many usages of gettestobjspace from objspace/std tests. diff --git a/pypy/objspace/std/test/test_builtinshortcut.py b/pypy/objspace/std/test/test_builtinshortcut.py --- a/pypy/objspace/std/test/test_builtinshortcut.py +++ b/pypy/objspace/std/test/test_builtinshortcut.py @@ -5,15 +5,13 @@ WITH_BUILTINSHORTCUT = {'objspace.std.builtinshortcut': True} class AppTestUserObject(test_userobject.AppTestUserObject): - OPTIONS = WITH_BUILTINSHORTCUT + spaceconfig = WITH_BUILTINSHORTCUT class AppTestWithMultiMethodVersion2(test_userobject.AppTestWithMultiMethodVersion2): - OPTIONS = WITH_BUILTINSHORTCUT + spaceconfig = WITH_BUILTINSHORTCUT class AppTestBug: - def setup_class(cls): - from pypy import conftest - cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) + spaceconfig = WITH_BUILTINSHORTCUT def test_frozen_subtype(self): class S(set): pass @@ -81,10 +79,9 @@ class AppTestSet(test_setobject.AppTestAppSetTest): + spaceconfig = WITH_BUILTINSHORTCUT # this tests tons of funny comparison combinations that can easily go wrong def setup_class(cls): - from pypy import conftest - cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) w_fakeint = cls.space.appexec([], """(): class FakeInt(object): def __init__(self, value): @@ -101,6 +98,4 @@ cls.w_FakeInt = w_fakeint class AppTestString(test_stringobject.AppTestStringObject): - def setup_class(cls): - from pypy import conftest - cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT) + spaceconfig = WITH_BUILTINSHORTCUT 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 @@ -1,15 +1,8 @@ -import py -from pypy.conftest import gettestobjspace - - class AppTestCallMethod: # The exec hacking is needed to have the code snippets compiled # by our own compiler, not CPython's - OPTIONS = {"objspace.opcodes.CALL_METHOD": True} - - def setup_class(cls): - cls.space = gettestobjspace(**cls.OPTIONS) + spaceconfig = {"objspace.opcodes.CALL_METHOD": True} def test_call_method(self): exec """if 1: @@ -118,14 +111,12 @@ class AppTestCallMethodWithGetattributeShortcut(AppTestCallMethod): - OPTIONS = AppTestCallMethod.OPTIONS.copy() - OPTIONS["objspace.std.getattributeshortcut"] = True + spaceconfig = AppTestCallMethod.spaceconfig.copy() + spaceconfig["objspace.std.getattributeshortcut"] = True class TestCallMethod: - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.opcodes.CALL_METHOD": True}) + spaceconfig = {"objspace.opcodes.CALL_METHOD": True} def test_space_call_method(self): space = self.space diff --git a/pypy/objspace/std/test/test_celldict.py b/pypy/objspace/std/test/test_celldict.py --- a/pypy/objspace/std/test/test_celldict.py +++ b/pypy/objspace/std/test/test_celldict.py @@ -1,5 +1,4 @@ import py -from pypy.conftest import gettestobjspace, option from pypy.objspace.std.dictmultiobject import W_DictMultiObject from pypy.objspace.std.celldict import ModuleCell, ModuleDictStrategy from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, \ @@ -54,9 +53,10 @@ assert v2 is v3 class AppTestModuleDict(object): + spaceconfig = {"objspace.std.withcelldict": True} + def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withcelldict": True}) - cls.w_runappdirect = cls.space.wrap(option.runappdirect) + cls.w_runappdirect = cls.space.wrap(cls.option.runappdirect) def w_impl_used(self, obj): if self.runappdirect: @@ -122,10 +122,10 @@ class AppTestCellDict(object): - OPTIONS = {"objspace.std.withcelldict": True} + spaceconfig = {"objspace.std.withcelldict": True} def setup_class(cls): - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("__repr__ doesn't work on appdirect") strategy = ModuleDictStrategy(cls.space) storage = strategy.get_empty_storage() diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -5,14 +5,8 @@ W_DictMultiObject, setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, \ StringDictStrategy, ObjectDictStrategy -from pypy.conftest import gettestobjspace -from pypy.conftest import option - class TestW_DictObject: - def setup_class(cls): - cls.space = gettestobjspace() - def test_empty(self): space = self.space d = self.space.newdict() @@ -777,7 +771,7 @@ class AppTestStrategies(object): def setup_class(cls): - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("__repr__ doesn't work on appdirect") def w_get_strategy(self, obj): diff --git a/pypy/objspace/std/test/test_dictproxy.py b/pypy/objspace/std/test/test_dictproxy.py --- a/pypy/objspace/std/test/test_dictproxy.py +++ b/pypy/objspace/std/test/test_dictproxy.py @@ -1,5 +1,3 @@ -from pypy.conftest import gettestobjspace - class AppTestUserObject: def test_dictproxy(self): class NotEmpty(object): @@ -62,7 +60,5 @@ raises(TypeError, int.__dict__.clear) class AppTestUserObjectMethodCache(AppTestUserObject): - def setup_class(cls): - cls.space = gettestobjspace( - **{"objspace.std.withmethodcachecounter": True}) + spaceconfig = {"objspace.std.withmethodcachecounter": True} diff --git a/pypy/objspace/std/test/test_identitydict.py b/pypy/objspace/std/test/test_identitydict.py --- a/pypy/objspace/std/test/test_identitydict.py +++ b/pypy/objspace/std/test/test_identitydict.py @@ -1,15 +1,12 @@ import py from pypy.interpreter.gateway import interp2app -from pypy.conftest import gettestobjspace -from pypy.conftest import option class AppTestComparesByIdentity: + spaceconfig = {"objspace.std.withidentitydict": True} def setup_class(cls): from pypy.objspace.std import identitydict - cls.space = gettestobjspace( - **{"objspace.std.withidentitydict": True}) - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("interp2app doesn't work on appdirect") def compares_by_identity(space, w_cls): @@ -59,9 +56,10 @@ class AppTestIdentityDict(object): + spaceconfig = {"objspace.std.withidentitydict": True} + def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withidentitydict": True}) - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("interp2app doesn't work on appdirect") def w_uses_identity_strategy(self, obj): diff --git a/pypy/objspace/std/test/test_index.py b/pypy/objspace/std/test/test_index.py --- a/pypy/objspace/std/test/test_index.py +++ b/pypy/objspace/std/test/test_index.py @@ -1,9 +1,7 @@ from py.test import raises -from pypy.conftest import gettestobjspace class AppTest_IndexProtocol: def setup_class(self): - self.space = gettestobjspace() w_oldstyle = self.space.appexec([], """(): class oldstyle: def __index__(self): 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 @@ -500,12 +500,7 @@ class AppTestIntOptimizedAdd(AppTestInt): - def setup_class(cls): - from pypy.conftest import gettestobjspace - cls.space = gettestobjspace(**{"objspace.std.optimized_int_add": True}) + spaceconfig = {"objspace.std.optimized_int_add": True} class AppTestIntOptimizedComp(AppTestInt): - def setup_class(cls): - from pypy.conftest import gettestobjspace - cls.space = gettestobjspace(**{"objspace.std.optimized_comparison_op": True}) - + spaceconfig = {"objspace.std.optimized_comparison_op": True} diff --git a/pypy/objspace/std/test/test_kwargsdict.py b/pypy/objspace/std/test/test_kwargsdict.py --- a/pypy/objspace/std/test/test_kwargsdict.py +++ b/pypy/objspace/std/test/test_kwargsdict.py @@ -1,5 +1,4 @@ import py -from pypy.conftest import gettestobjspace, option from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, W_DictMultiObject from pypy.objspace.std.kwargsdict import * @@ -125,7 +124,7 @@ class AppTestKwargsDictStrategy(object): def setup_class(cls): - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("__repr__ doesn't work on appdirect") def w_get_strategy(self, obj): diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -5,8 +5,6 @@ from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import is_valid_int -from pypy.conftest import gettestobjspace, option - class TestW_ListObject(object): def test_is_true(self): @@ -406,10 +404,10 @@ class AppTestW_ListObject(object): def setup_class(cls): import sys - on_cpython = (option.runappdirect and - not hasattr(sys, 'pypy_translation_info')) + on_cpython = (cls.option.runappdirect and + not hasattr(sys, 'pypy_translation_info')) cls.w_on_cpython = cls.space.wrap(on_cpython) - cls.w_runappdirect = cls.space.wrap(option.runappdirect) + cls.w_runappdirect = cls.space.wrap(cls.option.runappdirect) def test_getstrategyfromlist_w(self): l0 = ["a", "2", "a", True] @@ -1256,10 +1254,7 @@ assert ([5] >= [N]) is False class AppTestForRangeLists(AppTestW_ListObject): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withrangelist" : - True}) + spaceconfig = {"objspace.std.withrangelist": True} def test_range_simple_backwards(self): x = range(5,1) @@ -1376,10 +1371,7 @@ class AppTestWithoutStrategies(object): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withliststrategies" : - False}) + spaceconfig = {"objspace.std.withliststrategies": False} def test_no_shared_empty_list(self): l = [] @@ -1391,10 +1383,7 @@ assert notshared == [] class AppTestListFastSubscr: - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.optimized_list_getitem" : - True}) + spaceconfig = {"objspace.std.optimized_list_getitem": True} def test_getitem(self): import operator diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -3,8 +3,6 @@ from pypy.objspace.std import listobject from pypy.objspace.std.test.test_listobject import TestW_ListObject -from pypy.conftest import gettestobjspace - class TestW_ListStrategies(TestW_ListObject): def test_check_strategy(self): @@ -520,9 +518,7 @@ class TestW_ListStrategiesDisabled: - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withliststrategies" : - False}) + spaceconfig = {"objspace.std.withliststrategies": False} def test_check_strategy(self): assert isinstance(W_ListObject(self.space, []).strategy, ObjectListStrategy) 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 @@ -5,12 +5,9 @@ from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import r_uint from pypy.rlib.rbigint import rbigint -from pypy.conftest import gettestobjspace class TestW_LongObject: - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.nofaking": True}) + spaceconfig = {"objspace.nofaking": True} def test_bigint_w(self): space = self.space 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 @@ -1,4 +1,3 @@ -from pypy.conftest import gettestobjspace, option from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, W_DictMultiObject from pypy.objspace.std.mapdict import * @@ -438,8 +437,7 @@ # XXX write more class AppTestWithMapDict(object): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withmapdict": True}) + spaceconfig = {"objspace.std.withmapdict": True} def test_simple(self): class A(object): @@ -647,12 +645,12 @@ raises(AttributeError, "a.x") class AppTestWithMapDictAndCounters(object): + spaceconfig = {"objspace.std.withmapdict": True, + "objspace.std.withmethodcachecounter": True, + "objspace.opcodes.CALL_METHOD": True} + def setup_class(cls): from pypy.interpreter import gateway - cls.space = gettestobjspace( - **{"objspace.std.withmapdict": True, - "objspace.std.withmethodcachecounter": True, - "objspace.opcodes.CALL_METHOD": True}) # def check(space, w_func, name): w_code = space.getattr(w_func, space.wrap('func_code')) @@ -992,11 +990,9 @@ assert got == 'd' class AppTestGlobalCaching(AppTestWithMapDict): - def setup_class(cls): - cls.space = gettestobjspace( - **{"objspace.std.withmethodcachecounter": True, - "objspace.std.withmapdict": True, - "objspace.opcodes.CALL_METHOD": True}) + spaceconfig = {"objspace.std.withmethodcachecounter": True, + "objspace.std.withmapdict": True, + "objspace.opcodes.CALL_METHOD": True} def test_mix_classes(self): import __pypy__ @@ -1053,10 +1049,8 @@ assert 0, "failed: got %r" % ([got[1] for got in seen],) class TestDictSubclassShortcutBug(object): - def setup_class(cls): - cls.space = gettestobjspace( - **{"objspace.std.withmapdict": True, - "objspace.std.withmethodcachecounter": True}) + spaceconfig = {"objspace.std.withmapdict": True, + "objspace.std.withmethodcachecounter": True} def test_bug(self): w_dict = self.space.appexec([], """(): diff --git a/pypy/objspace/std/test/test_methodcache.py b/pypy/objspace/std/test/test_methodcache.py --- a/pypy/objspace/std/test/test_methodcache.py +++ b/pypy/objspace/std/test/test_methodcache.py @@ -1,11 +1,8 @@ -from pypy.conftest import gettestobjspace from pypy.objspace.std.test import test_typeobject class AppTestMethodCaching(test_typeobject.AppTestTypeObject): - def setup_class(cls): - cls.space = gettestobjspace( - **{"objspace.std.withmethodcachecounter": True}) + spaceconfig = {"objspace.std.withmethodcachecounter": True} def test_mix_classes(self): import __pypy__ diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -1,6 +1,5 @@ """Test unicode/str's format method""" from __future__ import with_statement -from pypy.conftest import gettestobjspace class BaseStringFormatTests: @@ -315,8 +314,7 @@ class AppTestFloatFormatting: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=('_locale',)) + spaceconfig = dict(usemodules=('_locale',)) def test_alternate(self): raises(ValueError, format, 1.0, "#") diff --git a/pypy/objspace/std/test/test_prebuiltint.py b/pypy/objspace/std/test/test_prebuiltint.py --- a/pypy/objspace/std/test/test_prebuiltint.py +++ b/pypy/objspace/std/test/test_prebuiltint.py @@ -1,10 +1,10 @@ from pypy.objspace.std.test import test_intobject -from pypy.conftest import gettestobjspace class AppTestInt(test_intobject.AppTestInt): + spaceconfig = {"objspace.std.withprebuiltint": True} + def setup_class(cls): - cls.space = space = gettestobjspace( - **{"objspace.std.withprebuiltint": True}) + space = cls.space cls.w_start = space.wrap(space.config.objspace.std.prebuiltintfrom) cls.w_stop = space.wrap(space.config.objspace.std.prebuiltintto) diff --git a/pypy/objspace/std/test/test_proxy.py b/pypy/objspace/std/test/test_proxy.py --- a/pypy/objspace/std/test/test_proxy.py +++ b/pypy/objspace/std/test/test_proxy.py @@ -2,11 +2,8 @@ """ test transparent proxy features """ -from pypy.conftest import gettestobjspace - class AppProxyBasic(object): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withtproxy": True}) + spaceconfig = {"objspace.std.withtproxy": True} def setup_method(self, meth): self.w_Controller = self.space.appexec([], """(): diff --git a/pypy/objspace/std/test/test_proxy_function.py b/pypy/objspace/std/test/test_proxy_function.py --- a/pypy/objspace/std/test/test_proxy_function.py +++ b/pypy/objspace/std/test/test_proxy_function.py @@ -2,12 +2,10 @@ """ test proxy on functions and other crazy goodies """ -from pypy.conftest import gettestobjspace from pypy.objspace.std.test.test_proxy import AppProxyBasic class AppTestProxyFunction(object): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withtproxy": True}) + spaceconfig = {"objspace.std.withtproxy": True} def setup_method(self, meth): self.w_get_proxy = self.space.appexec([], """(): diff --git a/pypy/objspace/std/test/test_proxy_internals.py b/pypy/objspace/std/test/test_proxy_internals.py --- a/pypy/objspace/std/test/test_proxy_internals.py +++ b/pypy/objspace/std/test/test_proxy_internals.py @@ -2,11 +2,9 @@ """ test proxy internals like code, traceback, frame """ import py -from pypy.conftest import gettestobjspace, option class AppProxy(object): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withtproxy": True}) + spaceconfig = {"objspace.std.withtproxy": True} def setup_method(self, meth): self.w_get_proxy = self.space.appexec([], """(): @@ -24,7 +22,7 @@ class AppTestProxyInterpOnly(AppProxy): def setup_class(cls): - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("interp only test") from pypy.interpreter.typedef import TypeDef, interp2app from pypy.interpreter.baseobjspace import Wrappable diff --git a/pypy/objspace/std/test/test_rangeobject.py b/pypy/objspace/std/test/test_rangeobject.py --- a/pypy/objspace/std/test/test_rangeobject.py +++ b/pypy/objspace/std/test/test_rangeobject.py @@ -1,14 +1,12 @@ import py -from pypy.conftest import gettestobjspace, option - class AppTestRangeListObject(object): + spaceconfig = {"objspace.std.withrangelist": True} def setup_class(cls): - if option.runappdirect: + if cls.option.runappdirect: py.test.skip("__pypy__.internal_repr() cannot be used to see " "if a range list was forced on top of pypy-c") - cls.space = gettestobjspace(**{"objspace.std.withrangelist": True}) cls.w_not_forced = cls.space.appexec([], """(): import __pypy__ def f(r): diff --git a/pypy/objspace/std/test/test_ropeobject.py b/pypy/objspace/std/test/test_ropeobject.py --- a/pypy/objspace/std/test/test_ropeobject.py +++ b/pypy/objspace/std/test/test_ropeobject.py @@ -1,12 +1,9 @@ import py from pypy.objspace.std.test import test_stringobject, test_unicodeobject -from pypy.conftest import gettestobjspace class AppTestRopeObject(test_stringobject.AppTestStringObject): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withrope": True}) + spaceconfig = {"objspace.std.withrope": True} def test_mul_overflow(self): import sys @@ -52,9 +49,7 @@ pass class AppTestRopeUnicode(object): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withrope": True}) + spaceconfig = {"objspace.std.withrope": True} def test_startswith(self): assert "abc".startswith("a", 0, 2147483647) @@ -65,29 +60,21 @@ class TestUnicodeRopeObject(test_unicodeobject.TestUnicodeObject): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withrope": True}) - + spaceconfig = {"objspace.std.withrope": True} class AppTestUnicodeRopeStdOnly(test_unicodeobject.AppTestUnicodeStringStdOnly): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withrope": True}) + spaceconfig = {"objspace.std.withrope": True} class AppTestUnicodeRope(test_unicodeobject.AppTestUnicodeString): - - def setup_class(cls): - cls.space = gettestobjspace(usemodules=('unicodedata',), - **{"objspace.std.withrope": True}) + spaceconfig = dict(usemodules=('unicodedata',), + **{"objspace.std.withrope": True}) def test_rfind_corner_case(self): skip("XXX Fix") class AppTestPrebuilt(AppTestRopeObject): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withrope": True, - "objspace.std.withprebuiltchar": False}) + spaceconfig = {"objspace.std.withrope": True, + "objspace.std.withprebuiltchar": False} def test_hash(self): # does not make sense, since our hash is different than CPython's @@ -95,19 +82,17 @@ class AppTestShare(AppTestRopeObject): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withrope": True, - "objspace.std.sharesmallstr": False}) + spaceconfig = {"objspace.std.withrope": True, + "objspace.std.sharesmallstr": False} def test_hash(self): # does not make sense, since our hash is different than CPython's pass class AppTestPrebuiltShare(AppTestRopeObject): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withrope": True, - "objspace.std.withprebuiltchar": False, - "objspace.std.sharesmallstr": False}) + spaceconfig = {"objspace.std.withrope": True, + "objspace.std.withprebuiltchar": False, + "objspace.std.sharesmallstr": False} def test_hash(self): # does not make sense, since our hash is different than CPython's diff --git a/pypy/objspace/std/test/test_ropeunicodeobject.py b/pypy/objspace/std/test/test_ropeunicodeobject.py --- a/pypy/objspace/std/test/test_ropeunicodeobject.py +++ b/pypy/objspace/std/test/test_ropeunicodeobject.py @@ -1,18 +1,13 @@ import py from pypy.objspace.std.test import test_stringobject, test_unicodeobject -from pypy.conftest import gettestobjspace class TestRopeUnicodeObject(test_unicodeobject.TestUnicodeObject): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withropeunicode": True}) + spaceconfig = {"objspace.std.withropeunicode": True} class AppTestRopeObject(test_stringobject.AppTestStringObject): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withropeunicode": True}) + spaceconfig = {"objspace.std.withropeunicode": True} def test_hash(self): # doesn't make sense, since ropes hash differently than cpython's @@ -23,23 +18,17 @@ skip("XXX fix") class AppTestRopeUnicode(object): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withropeunicode": True}) + spaceconfig = {"objspace.std.withropeunicode": True} def test_replace_buffer(self): skip("XXX fix") class AppTestUnicodeRopeStdOnly(test_unicodeobject.AppTestUnicodeStringStdOnly): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withropeunicode": True}) + spaceconfig = {"objspace.std.withropeunicode": True} class AppTestUnicodeRope(test_unicodeobject.AppTestUnicodeString): - - def setup_class(cls): - cls.space = gettestobjspace(usemodules=('unicodedata',), - **{"objspace.std.withropeunicode": True}) + spaceconfig = dict(usemodules=('unicodedata',), + **{"objspace.std.withropeunicode": True}) def test_replace_buffer(self): skip("XXX fix") diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py --- a/pypy/objspace/std/test/test_setobject.py +++ b/pypy/objspace/std/test/test_setobject.py @@ -15,7 +15,6 @@ from pypy.objspace.std.setobject import and__Set_Set from pypy.objspace.std.setobject import set_intersection__Set from pypy.objspace.std.setobject import eq__Set_Set -from pypy.conftest import gettestobjspace from pypy.objspace.std.listobject import W_ListObject letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -140,7 +139,6 @@ class AppTestAppSetTest: def setup_class(self): - self.space = gettestobjspace() w_fakeint = self.space.appexec([], """(): class FakeInt(object): def __init__(self, value): diff --git a/pypy/objspace/std/test/test_smallintobject.py b/pypy/objspace/std/test/test_smallintobject.py --- a/pypy/objspace/std/test/test_smallintobject.py +++ b/pypy/objspace/std/test/test_smallintobject.py @@ -9,12 +9,9 @@ from pypy.rlib.rarithmetic import r_uint from pypy.objspace.std.test.test_intobject import AppTestInt -from pypy.conftest import gettestobjspace class TestW_IntObject: - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withsmallint": True}) + spaceconfig = {"objspace.std.withsmallint": True} def test_int_w(self): assert self.space.int_w(self.space.wrap(42)) == 42 @@ -228,7 +225,5 @@ class AppTestSmallInt(AppTestInt): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.optimized_int_add" : True, - "objspace.std.withsmallint" : True}) + spaceconfig = {"objspace.std.optimized_int_add" : True, + "objspace.std.withsmallint" : True} diff --git a/pypy/objspace/std/test/test_smalllongobject.py b/pypy/objspace/std/test/test_smalllongobject.py --- a/pypy/objspace/std/test/test_smalllongobject.py +++ b/pypy/objspace/std/test/test_smalllongobject.py @@ -41,8 +41,7 @@ class AppTestSmallLong(test_longobject.AppTestLong): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withsmalllong": True}) + spaceconfig = {"objspace.std.withsmalllong": True} def test_sl_simple(self): import __pypy__ diff --git a/pypy/objspace/std/test/test_smalltupleobject.py b/pypy/objspace/std/test/test_smalltupleobject.py --- a/pypy/objspace/std/test/test_smalltupleobject.py +++ b/pypy/objspace/std/test/test_smalltupleobject.py @@ -5,9 +5,9 @@ from pypy.conftest import gettestobjspace class AppTestW_SmallTupleObject(AppTestW_TupleObject): + spaceconfig = {"objspace.std.withsmalltuple": True} def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withsmalltuple": True}) cls.w_issmall = cls.space.appexec([], """(): import __pypy__ def issmall(obj): @@ -56,9 +56,7 @@ assert hash(a) != hash(c) class TestW_SmallTupleObject(): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withsmalltuple": True}) + spaceconfig = {"objspace.std.withsmalltuple": True} def test_issmalltupleobject(self): w_tuple = self.space.newtuple([self.space.wrap(1), self.space.wrap(2)]) diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py b/pypy/objspace/std/test/test_specialisedtupleobject.py --- a/pypy/objspace/std/test/test_specialisedtupleobject.py +++ b/pypy/objspace/std/test/test_specialisedtupleobject.py @@ -3,7 +3,7 @@ from pypy.objspace.std.specialisedtupleobject import W_SpecialisedTupleObject from pypy.objspace.std.specialisedtupleobject import _specialisations from pypy.interpreter.error import OperationError -from pypy.conftest import gettestobjspace, option +from pypy.conftest import gettestobjspace from pypy.objspace.std.test import test_tupleobject from pypy.interpreter import gateway @@ -13,9 +13,7 @@ class TestW_SpecialisedTupleObject(): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withspecialisedtuple": True}) + spaceconfig = {"objspace.std.withspecialisedtuple": True} def test_isspecialisedtupleobjectintint(self): w_tuple = self.space.newtuple([self.space.wrap(1), self.space.wrap(2)]) @@ -57,9 +55,9 @@ class AppTestW_SpecialisedTupleObject: + spaceconfig = {"objspace.std.withspecialisedtuple": True} def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withspecialisedtuple": True}) def forbid_delegation(space, w_tuple): def delegation_forbidden(): # haaaack @@ -69,7 +67,7 @@ raise OperationError(space.w_ReferenceError, w_tuple) w_tuple.delegating = delegation_forbidden return w_tuple - if option.runappdirect: + if cls.option.runappdirect: cls.w_forbid_delegation = lambda self, x: x cls.test_delegation = lambda self: skip("runappdirect") else: diff --git a/pypy/objspace/std/test/test_strbufobject.py b/pypy/objspace/std/test/test_strbufobject.py --- a/pypy/objspace/std/test/test_strbufobject.py +++ b/pypy/objspace/std/test/test_strbufobject.py @@ -1,12 +1,9 @@ import py from pypy.objspace.std.test import test_stringobject -from pypy.conftest import gettestobjspace class AppTestStringObject(test_stringobject.AppTestStringObject): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withstrbuf": True}) + spaceconfig = {"objspace.std.withstrbuf": True} def test_basic(self): import __pypy__ diff --git a/pypy/objspace/std/test/test_stringobject.py b/pypy/objspace/std/test/test_stringobject.py --- a/pypy/objspace/std/test/test_stringobject.py +++ b/pypy/objspace/std/test/test_stringobject.py @@ -1,8 +1,3 @@ -from pypy.objspace.std import stringobject -from pypy.objspace.std.stringobject import W_StringObject -from pypy.conftest import gettestobjspace - - class TestW_StringObject: def teardown_method(self, method): @@ -776,14 +771,11 @@ raises(TypeError, len, iter(iterable)) class AppTestPrebuilt(AppTestStringObject): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withprebuiltchar": True}) + spaceconfig = {"objspace.std.withprebuiltchar": True} class AppTestShare(AppTestStringObject): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.sharesmallstr": True}) + spaceconfig = {"objspace.std.sharesmallstr": True} class AppTestPrebuiltShare(AppTestStringObject): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withprebuiltchar": True, - "objspace.std.sharesmallstr": True}) + spaceconfig = {"objspace.std.withprebuiltchar": True, + "objspace.std.sharesmallstr": True} diff --git a/pypy/objspace/std/test/test_strjoinobject.py b/pypy/objspace/std/test/test_strjoinobject.py --- a/pypy/objspace/std/test/test_strjoinobject.py +++ b/pypy/objspace/std/test/test_strjoinobject.py @@ -1,12 +1,7 @@ -import py - from pypy.objspace.std.test import test_stringobject -from pypy.conftest import gettestobjspace class AppTestStringObject(test_stringobject.AppTestStringObject): - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withstrjoin": True}) + spaceconfig = {"objspace.std.withstrjoin": True} def test_basic(self): import __pypy__ diff --git a/pypy/objspace/std/test/test_strsliceobject.py b/pypy/objspace/std/test/test_strsliceobject.py --- a/pypy/objspace/std/test/test_strsliceobject.py +++ b/pypy/objspace/std/test/test_strsliceobject.py @@ -1,14 +1,13 @@ import py from pypy.objspace.std.test import test_stringobject -from pypy.conftest import gettestobjspace from pypy.interpreter import gateway from pypy.objspace.std.strsliceobject import W_StringSliceObject class AppTestStringObject(test_stringobject.AppTestStringObject): + space_config = {"objspace.std.withstrslice": True} def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withstrslice": True}) def not_forced(space, w_s): return space.wrap(isinstance(w_s, W_StringSliceObject) and (w_s.start != 0 or w_s.stop != len(w_s.str))) diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py --- a/pypy/objspace/std/test/test_typeobject.py +++ b/pypy/objspace/std/test/test_typeobject.py @@ -1,6 +1,5 @@ from pypy.objspace.std.model import W_Object from pypy.objspace.std.stdtypedef import StdTypeDef -from pypy.conftest import gettestobjspace from pypy.objspace.std.typeobject import W_TypeObject from pypy.interpreter.gateway import interp2app @@ -1064,9 +1063,7 @@ assert A.x == 5 class AppTestMutableBuiltintypes: - - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.mutable_builtintypes": True}) + spaceconfig = {"objspace.std.mutable_builtintypes": True} def test_del_type_mro(self): del type.mro @@ -1098,10 +1095,7 @@ assert "run-time error" in RuntimeError.__doc__ class AppTestGetattributeShortcut: - - def setup_class(cls): - cls.space = gettestobjspace( - **{"objspace.std.getattributeshortcut": True}) + spaceconfig = {"objspace.std.getattributeshortcut": True} def test_reset_logic(self): class X(object): @@ -1142,10 +1136,7 @@ assert y.x == 'GA2' class TestNewShortcut: - - def setup_class(cls): - cls.space = gettestobjspace( - **{"objspace.std.newshortcut": True}) + spaceconfig = {"objspace.std.newshortcut": True} def test_mechanics(self): space = self.space @@ -1184,10 +1175,7 @@ class AppTestNewShortcut: - - def setup_class(cls): - cls.space = gettestobjspace( - **{"objspace.std.newshortcut": True}) + spaceconfig = {"objspace.std.newshortcut": True} def test_reset_logic(self): class X(object): diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -1,6 +1,5 @@ import py import sys -from pypy.conftest import gettestobjspace class TestUnicodeObject: @@ -45,9 +44,9 @@ class AppTestUnicodeString: + spaceconfig = dict(usemodules=('unicodedata',)) + def setup_class(cls): - space = gettestobjspace(usemodules=('unicodedata',)) - cls.space = space cls.w_version_info = cls.space.wrap(sys.version_info) def test_addition(self): diff --git a/pypy/objspace/std/test/test_userobject.py b/pypy/objspace/std/test/test_userobject.py --- a/pypy/objspace/std/test/test_userobject.py +++ b/pypy/objspace/std/test/test_userobject.py @@ -4,12 +4,10 @@ class AppTestUserObject: - OPTIONS = {} # for test_builtinshortcut.py + spaceconfig = {} def setup_class(cls): - from pypy import conftest - cls.space = conftest.gettestobjspace(**cls.OPTIONS) - cls.w_runappdirect = cls.space.wrap(bool(conftest.option.runappdirect)) + cls.w_runappdirect = cls.space.wrap(bool(cls.option.runappdirect)) def rand(space): import random return space.wrap(random.randrange(0, 5)) @@ -276,18 +274,15 @@ class AppTestWithMultiMethodVersion2(AppTestUserObject): - OPTIONS = {} # for test_builtinshortcut.py + spaceconfig = {} def setup_class(cls): - from pypy import conftest from pypy.objspace.std import multimethod cls.prev_installer = multimethod.Installer multimethod.Installer = multimethod.InstallerVersion2 - if conftest.option.runappdirect: + if cls.option.runappdirect: py.test.skip("Cannot run different installers when runappdirect") - config = conftest.make_config(conftest.option, **cls.OPTIONS) - cls.space = conftest.maketestobjspace(config) def teardown_class(cls): from pypy.objspace.std import multimethod @@ -295,7 +290,7 @@ class AppTestWithGetAttributeShortcut(AppTestUserObject): - OPTIONS = {"objspace.std.getattributeshortcut": True} + spaceconfig = {"objspace.std.getattributeshortcut": True} class AppTestDescriptorWithGetAttributeShortcut( @@ -303,4 +298,4 @@ # for the individual tests see # ====> ../../test/test_descriptor.py - OPTIONS = {"objspace.std.getattributeshortcut": True} + spaceconfig = {"objspace.std.getattributeshortcut": True} diff --git a/pypy/objspace/std/test/test_versionedtype.py b/pypy/objspace/std/test/test_versionedtype.py --- a/pypy/objspace/std/test/test_versionedtype.py +++ b/pypy/objspace/std/test/test_versionedtype.py @@ -1,9 +1,7 @@ from pypy.objspace.std.test import test_typeobject -from pypy.conftest import gettestobjspace class TestVersionedType(test_typeobject.TestTypeObject): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withtypeversion": True}) + spaceconfig = {"objspace.std.withtypeversion": True} def get_three_classes(self): space = self.space @@ -214,6 +212,5 @@ class AppTestVersionedType(test_typeobject.AppTestTypeObject): - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withtypeversion": True}) + spaceconfig = {"objspace.std.withtypeversion": True} From noreply at buildbot.pypy.org Mon Oct 29 22:40:25 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:25 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214025.4729C1C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58621:302e694cc32a Date: 2012-10-29 01:54 +0100 http://bitbucket.org/pypy/pypy/changeset/302e694cc32a/ Log: progress diff --git a/pypy/module/test_lib_pypy/test_collections.py b/pypy/module/test_lib_pypy/test_collections.py --- a/pypy/module/test_lib_pypy/test_collections.py +++ b/pypy/module/test_lib_pypy/test_collections.py @@ -4,8 +4,6 @@ (not used in normal PyPy's) """ -from pypy.conftest import gettestobjspace - class AppTestCollections: def test_copy(self): import _collections diff --git a/pypy/module/test_lib_pypy/test_cstringio.py b/pypy/module/test_lib_pypy/test_cstringio.py --- a/pypy/module/test_lib_pypy/test_cstringio.py +++ b/pypy/module/test_lib_pypy/test_cstringio.py @@ -3,11 +3,8 @@ Tests for the PyPy cStringIO implementation. """ -from pypy.conftest import gettestobjspace - class AppTestcStringIO: def setup_class(cls): - cls.space = gettestobjspace() cls.w_io = cls.space.appexec([], "(): import cStringIO; return cStringIO") cls.w_bytes = cls.space.wrap('some bytes') diff --git a/pypy/module/test_lib_pypy/test_greenlet.py b/pypy/module/test_lib_pypy/test_greenlet.py --- a/pypy/module/test_lib_pypy/test_greenlet.py +++ b/pypy/module/test_lib_pypy/test_greenlet.py @@ -1,9 +1,5 @@ -from pypy.conftest import gettestobjspace - - class AppTestGreenlet: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_continuation'], continuation=True) + spaceconfig = dict(usemodules=['_continuation'], continuation=True) def test_simple(self): from greenlet import greenlet diff --git a/pypy/module/test_lib_pypy/test_itertools.py b/pypy/module/test_lib_pypy/test_itertools.py --- a/pypy/module/test_lib_pypy/test_itertools.py +++ b/pypy/module/test_lib_pypy/test_itertools.py @@ -1,8 +1,5 @@ -from pypy.conftest import gettestobjspace - class AppTestItertools: def setup_class(cls): - cls.space = gettestobjspace() cls.w_itertools = cls.space.appexec([], "(): import itertools; return itertools") def test_chain(self): diff --git a/pypy/module/test_lib_pypy/test_msvcrt.py b/pypy/module/test_lib_pypy/test_msvcrt.py --- a/pypy/module/test_lib_pypy/test_msvcrt.py +++ b/pypy/module/test_lib_pypy/test_msvcrt.py @@ -1,4 +1,3 @@ -from pypy.conftest import gettestobjspace from pypy.tool.udir import udir import py import sys diff --git a/pypy/module/test_lib_pypy/test_pwd.py b/pypy/module/test_lib_pypy/test_pwd.py --- a/pypy/module/test_lib_pypy/test_pwd.py +++ b/pypy/module/test_lib_pypy/test_pwd.py @@ -1,11 +1,10 @@ import py, sys -from pypy.conftest import gettestobjspace class AppTestPwd: + spaceconfig = dict(usemodules=('_ffi', '_rawffi')) def setup_class(cls): if sys.platform == 'win32': py.test.skip("Unix only") - cls.space = gettestobjspace(usemodules=('_ffi', '_rawffi')) cls.space.appexec((), "(): import pwd") def test_getpwuid(self): diff --git a/pypy/module/test_lib_pypy/test_stackless_pickle.py b/pypy/module/test_lib_pypy/test_stackless_pickle.py --- a/pypy/module/test_lib_pypy/test_stackless_pickle.py +++ b/pypy/module/test_lib_pypy/test_stackless_pickle.py @@ -1,16 +1,14 @@ import py py.test.skip("in-progress, maybe") -from pypy.conftest import gettestobjspace, option class AppTest_Stackless: + spaceconfig = dict(usemodules=('_continuation', '_socket')) def setup_class(cls): - space = gettestobjspace(usemodules=('_continuation', '_socket')) - cls.space = space - if option.runappdirect: - cls.w_lev = space.wrap(14) + if cls.option.runappdirect: + cls.w_lev = cls.space.wrap(14) else: - cls.w_lev = space.wrap(2) + cls.w_lev = cls.space.wrap(2) def test_pickle(self): import new, sys diff --git a/pypy/module/test_lib_pypy/test_tputil.py b/pypy/module/test_lib_pypy/test_tputil.py --- a/pypy/module/test_lib_pypy/test_tputil.py +++ b/pypy/module/test_lib_pypy/test_tputil.py @@ -1,8 +1,5 @@ -from pypy.conftest import gettestobjspace - class AppTest_make_proxy: - def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withtproxy": True}) + spaceconfig = {"objspace.std.withtproxy": True} def test_errors(self): from tputil import make_proxy diff --git a/pypy/objspace/test/test_descriptor.py b/pypy/objspace/test/test_descriptor.py --- a/pypy/objspace/test/test_descriptor.py +++ b/pypy/objspace/test/test_descriptor.py @@ -1,12 +1,4 @@ -from pypy.conftest import gettestobjspace - class AppTest_Descriptor: - - OPTIONS = {} - - def setup_class(cls): - cls.space = gettestobjspace(**cls.OPTIONS) - def test_non_data_descr(self): class X(object): def f(self): diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py --- a/pypy/objspace/test/test_descroperation.py +++ b/pypy/objspace/test/test_descroperation.py @@ -31,12 +31,6 @@ class AppTest_Descroperation: - OPTIONS = {} - - def setup_class(cls): - from pypy import conftest - cls.space = conftest.gettestobjspace(**cls.OPTIONS) - def test_special_methods(self): class OldStyle: pass @@ -728,4 +722,4 @@ class AppTestWithBuiltinShortcut(AppTest_Descroperation): - OPTIONS = {'objspace.std.builtinshortcut': True} + spaceconfig = {'objspace.std.builtinshortcut': True} From noreply at buildbot.pypy.org Mon Oct 29 22:40:26 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:26 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: progress Message-ID: <20121029214026.6E18E1C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58622:b24bde921e50 Date: 2012-10-29 01:59 +0100 http://bitbucket.org/pypy/pypy/changeset/b24bde921e50/ Log: progress diff --git a/pypy/interpreter/test/test_code.py b/pypy/interpreter/test/test_code.py --- a/pypy/interpreter/test/test_code.py +++ b/pypy/interpreter/test/test_code.py @@ -1,12 +1,9 @@ -from pypy.conftest import gettestobjspace from pypy.interpreter import gateway from pypy.interpreter.astcompiler import consts import py class AppTestCodeIntrospection: def setup_class(cls): - space = gettestobjspace() - cls.space = space filename = __file__ if filename[-3:] != '.py': filename = filename[:-1] 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 @@ -4,7 +4,6 @@ from pypy.interpreter.pycode import PyCode from pypy.interpreter.error import OperationError from pypy.interpreter.argument import Arguments -from pypy.conftest import gettestobjspace class BaseTestCompiler: def setup_method(self, method): @@ -915,8 +914,7 @@ assert "LOAD_GLOBAL" not in output class AppTestCallMethod(object): - def setup_class(cls): - cls.space = gettestobjspace(**{'objspace.opcodes.CALL_METHOD': True}) + spaceconfig = {'objspace.opcodes.CALL_METHOD': True} def test_call_method_kwargs(self): source = """def _f(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 @@ -1,17 +1,11 @@ import py from pypy.interpreter import executioncontext -from pypy.conftest import gettestobjspace, option class Finished(Exception): pass class TestExecutionContext: - keywords = {} - - def setup_class(cls): - cls.space = gettestobjspace(**cls.keywords) - def test_action(self): class DemoAction(executioncontext.AsyncAction): @@ -260,13 +254,13 @@ class TestExecutionContextWithCallMethod(TestExecutionContext): - keywords = {'objspace.opcodes.CALL_METHOD': True} + spaceconfig ={'objspace.opcodes.CALL_METHOD': True} class AppTestDelNotBlocked: def setup_method(self, meth): - if not option.runappdirect: + if not cls.option.runappdirect: py.test.skip("test is meant for running with py.test -A") from pypy.tool.udir import udir tmpfile = udir.join('test_execution_context') 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 @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- -from pypy.conftest import gettestobjspace from pypy.interpreter import gateway, argument from pypy.interpreter.gateway import ObjSpace, W_Root, WrappedDefault import py @@ -715,12 +714,9 @@ assert isinstance(called[0], argument.Arguments) class TestPassThroughArguments_CALL_METHOD(TestPassThroughArguments): - - def setup_class(cls): - space = gettestobjspace(usemodules=('itertools',), **{ + spaceconfig = dict(usemodules=('itertools',), **{ "objspace.opcodes.CALL_METHOD": True }) - cls.space = space class AppTestKeywordsToBuiltinSanity(object): diff --git a/pypy/interpreter/test/test_syntax.py b/pypy/interpreter/test/test_syntax.py --- a/pypy/interpreter/test/test_syntax.py +++ b/pypy/interpreter/test/test_syntax.py @@ -1,6 +1,5 @@ from __future__ import with_statement import py -from pypy.conftest import gettestobjspace def splitcases(s): lines = [line.rstrip() for line in s.split('\n')] diff --git a/pypy/interpreter/test/test_zzpickle_and_slow.py b/pypy/interpreter/test/test_zzpickle_and_slow.py --- a/pypy/interpreter/test/test_zzpickle_and_slow.py +++ b/pypy/interpreter/test/test_zzpickle_and_slow.py @@ -1,13 +1,10 @@ import py from pypy import conftest -from pypy.conftest import gettestobjspace from pypy.interpreter import gateway from pypy.rlib.jit import non_virtual_ref, vref_None class AppTestSlow: def setup_class(cls): - space = gettestobjspace() - cls.space = space if py.test.config.option.runappdirect: filename = __file__ else: @@ -66,7 +63,7 @@ space.wrap('read_exc_type'), space.wrap(read_exc_type_gw)) -def _detatch_helpers(space): +def _detach_helpers(space): space.delitem(space.builtin.w_dict, space.wrap('hide_top_frame')) space.delitem(space.builtin.w_dict, @@ -74,12 +71,13 @@ class AppTestInterpObjectPickling: pytestmark = py.test.mark.skipif("config.option.runappdirect") + spaceconfig = dict(usemodules=['struct']) + def setup_class(cls): - cls.space = gettestobjspace(usemodules=['struct']) _attach_helpers(cls.space) def teardown_class(cls): - _detatch_helpers(cls.space) + _detach_helpers(cls.space) def test_pickle_code(self): def f(): 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 @@ -1,8 +1,5 @@ -from pypy.conftest import gettestobjspace - class AppTestNumpy: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['micronumpy']) + space_config = dict(usemodules=['micronumpy']) def test_imports(self): try: From noreply at buildbot.pypy.org Mon Oct 29 22:40:27 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:27 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Only export cls.runappdirect instead of the whole option object. Message-ID: <20121029214027.9DC411C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58623:a03792cb9cbb Date: 2012-10-29 08:49 +0100 http://bitbucket.org/pypy/pypy/changeset/a03792cb9cbb/ Log: Only export cls.runappdirect instead of the whole option object. diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -326,11 +326,11 @@ if isinstance(item, py.test.collect.Function): appclass = item.getparent(PyPyClassCollector) if appclass is not None: - # Make cls.space and cls.option available in tests. + # Make cls.space and cls.runappdirect available in tests. spaceconfig = getattr(appclass.obj, 'spaceconfig', None) if spaceconfig is not None: appclass.obj.space = gettestobjspace(**spaceconfig) - appclass.obj.option = option + appclass.obj.runappdirect = option.runappdirect __multicall__.execute() 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 @@ -260,7 +260,7 @@ class AppTestDelNotBlocked: def setup_method(self, meth): - if not cls.option.runappdirect: + if not self.runappdirect: py.test.skip("test is meant for running with py.test -A") from pypy.tool.udir import udir tmpfile = udir.join('test_execution_context') 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 @@ -20,7 +20,7 @@ # For example if an object x has a __getattr__, we can get # AttributeError if attempting to call x.__getattr__ runs out # of stack. That's annoying, so we just work around it. - if cls.option.runappdirect: + if cls.runappdirect: cls.w_safe_runtimerror = cls.space.wrap(True) else: cls.w_safe_runtimerror = cls.space.wrap(sys.version_info < (2, 6)) diff --git a/pypy/module/__builtin__/test/test_classobj.py b/pypy/module/__builtin__/test/test_classobj.py --- a/pypy/module/__builtin__/test/test_classobj.py +++ b/pypy/module/__builtin__/test/test_classobj.py @@ -1082,7 +1082,7 @@ spaceconfig = {"objspace.std.withmapdict": True} def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("can only be run on py.py") def has_mapdict(space, w_inst): return space.wrap(w_inst._get_mapdict_map() is not None) diff --git a/pypy/module/__pypy__/test/test_debug.py b/pypy/module/__pypy__/test/test_debug.py --- a/pypy/module/__pypy__/test/test_debug.py +++ b/pypy/module/__pypy__/test/test_debug.py @@ -5,7 +5,7 @@ spaceconfig = dict(usemodules=['__pypy__']) def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("not meant to be run with -A") cls.w_check_log = cls.space.wrap(cls.check_log) diff --git a/pypy/module/__pypy__/test/test_special.py b/pypy/module/__pypy__/test/test_special.py --- a/pypy/module/__pypy__/test/test_special.py +++ b/pypy/module/__pypy__/test/test_special.py @@ -5,7 +5,7 @@ "objspace.std.withrangelist": True} def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("does not make sense on pypy-c") def test__isfake(self): diff --git a/pypy/module/_cffi_backend/test/test_c.py b/pypy/module/_cffi_backend/test/test_c.py --- a/pypy/module/_cffi_backend/test/test_c.py +++ b/pypy/module/_cffi_backend/test/test_c.py @@ -64,7 +64,7 @@ return space.wrap(addr) space = cls.space - if cls.option.runappdirect: + if cls.runappdirect: def interp2app(func): def run(*args): return func(space, *args) diff --git a/pypy/module/_ffi/test/test_struct.py b/pypy/module/_ffi/test/test_struct.py --- a/pypy/module/_ffi/test/test_struct.py +++ b/pypy/module/_ffi/test/test_struct.py @@ -61,7 +61,7 @@ dummy_type.c_alignment = rffi.cast(rffi.USHORT, 0) dummy_type.c_type = rffi.cast(rffi.USHORT, 0) cls.w_dummy_type = W_FFIType('dummy', dummy_type) - cls.w_runappdirect = cls.space.wrap(cls.option.runappdirect) + cls.w_runappdirect = cls.space.wrap(cls.runappdirect) def test__StructDescr(self): from _ffi import _StructDescr, Field, types 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 @@ -262,7 +262,7 @@ cls.old_read = os.read - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("works with internals of _file impl on py.py") state = [0] def read(fd, n=None): @@ -295,7 +295,7 @@ spaceconfig = dict(usemodules=("_file",)) def setup_class(cls): - if not cls.option.runappdirect: + if not cls.runappdirect: py.test.skip("likely to deadlock when interpreted by py.py") cls.w_temppath = cls.space.wrap( str(py.test.ensuretemp("fileimpl").join("concurrency.txt"))) diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -224,7 +224,7 @@ def setup_class(cls): tmpfile = udir.join('tmpfile') cls.w_tmpfile = cls.space.wrap(str(tmpfile)) - if cls.option.runappdirect: + if cls.runappdirect: cls.w_readfile = tmpfile.read else: def readfile(space): diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -11,7 +11,7 @@ spaceconfig = dict(usemodules=['_multiprocessing', 'thread', 'signal']) def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: def raiseBufferTooShort(self, data): import multiprocessing raise multiprocessing.BufferTooShort(data) @@ -73,7 +73,7 @@ if sys.platform != "win32": py.test.skip("win32 only") - if not cls.option.runappdirect: + if not cls.runappdirect: space = cls.space # stubs for some modules, # just for multiprocessing to import correctly on Windows @@ -114,7 +114,7 @@ space.call_method(cls.w_connections, "append", space.wrap(client)) return space.wrap((server.fileno(), client.fileno())) - if cls.option.runappdirect: + if cls.runappdirect: cls.w_socketpair = lambda self: socketpair(cls.space) else: cls.w_socketpair = cls.space.wrap(interp2app(socketpair)) diff --git a/pypy/module/_sre/test/test_app_sre.py b/pypy/module/_sre/test/test_app_sre.py --- a/pypy/module/_sre/test/test_app_sre.py +++ b/pypy/module/_sre/test/test_app_sre.py @@ -598,7 +598,7 @@ spaceconfig = dict(usemodules=('_locale',)) def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("can only be run on py.py: _sre opcodes don't match") # This imports support_test_sre as the global "s" init_app_test(cls, cls.space) diff --git a/pypy/module/bz2/test/test_large.py b/pypy/module/bz2/test/test_large.py --- a/pypy/module/bz2/test/test_large.py +++ b/pypy/module/bz2/test/test_large.py @@ -5,7 +5,7 @@ spaceconfig = dict(usemodules=('bz2',)) def setup_class(cls): - if not cls.option.runappdirect: + if not cls.runappdirect: py.test.skip("skipping this very slow test; try 'pypy-c -A'") largetest_bz2 = py.path.local(__file__).dirpath().join("largetest.bz2") cls.w_compressed_data = cls.space.wrap(largetest_bz2.read('rb')) diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py --- a/pypy/module/pypyjit/test/test_jit_hook.py +++ b/pypy/module/pypyjit/test/test_jit_hook.py @@ -36,7 +36,7 @@ class AppTestJitHook(object): spaceconfig = dict(usemodules=('pypyjit',)) def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("Can't run this test with -A") w_f = cls.space.appexec([], """(): def function(): 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 @@ -12,7 +12,7 @@ class AppTestAppSysTests: def setup_class(cls): - cls.w_appdirect = cls.space.wrap(cls.option.runappdirect) + cls.w_appdirect = cls.space.wrap(cls.runappdirect) cls.w_filesystemenc = cls.space.wrap(sys.getfilesystemencoding()) def test_sys_in_modules(self): @@ -126,7 +126,7 @@ class AppTestSysModulePortedFromCPython: def setup_class(cls): - cls.w_appdirect = cls.space.wrap(cls.option.runappdirect) + cls.w_appdirect = cls.wrap(cls.runappdirect) def test_original_displayhook(self): import sys, cStringIO, __builtin__ diff --git a/pypy/module/test_lib_pypy/test_stackless_pickle.py b/pypy/module/test_lib_pypy/test_stackless_pickle.py --- a/pypy/module/test_lib_pypy/test_stackless_pickle.py +++ b/pypy/module/test_lib_pypy/test_stackless_pickle.py @@ -5,7 +5,7 @@ spaceconfig = dict(usemodules=('_continuation', '_socket')) def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: cls.w_lev = cls.space.wrap(14) else: cls.w_lev = cls.space.wrap(2) 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 @@ -32,7 +32,7 @@ spaceconfig = dict(usemodules=('thread', 'time', 'signal')) def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: def plain_waitfor(self, condition, delay=1): adaptivedelay = 0.04 limit = time.time() + NORMAL_TIMEOUT * delay diff --git a/pypy/objspace/std/test/test_celldict.py b/pypy/objspace/std/test/test_celldict.py --- a/pypy/objspace/std/test/test_celldict.py +++ b/pypy/objspace/std/test/test_celldict.py @@ -56,7 +56,7 @@ spaceconfig = {"objspace.std.withcelldict": True} def setup_class(cls): - cls.w_runappdirect = cls.space.wrap(cls.option.runappdirect) + cls.w_runappdirect = cls.space.wrap(cls.runappdirect) def w_impl_used(self, obj): if self.runappdirect: @@ -125,7 +125,7 @@ spaceconfig = {"objspace.std.withcelldict": True} def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("__repr__ doesn't work on appdirect") strategy = ModuleDictStrategy(cls.space) storage = strategy.get_empty_storage() diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -771,7 +771,7 @@ class AppTestStrategies(object): def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("__repr__ doesn't work on appdirect") def w_get_strategy(self, obj): diff --git a/pypy/objspace/std/test/test_identitydict.py b/pypy/objspace/std/test/test_identitydict.py --- a/pypy/objspace/std/test/test_identitydict.py +++ b/pypy/objspace/std/test/test_identitydict.py @@ -6,7 +6,7 @@ def setup_class(cls): from pypy.objspace.std import identitydict - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("interp2app doesn't work on appdirect") def compares_by_identity(space, w_cls): @@ -59,7 +59,7 @@ spaceconfig = {"objspace.std.withidentitydict": True} def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("interp2app doesn't work on appdirect") def w_uses_identity_strategy(self, obj): diff --git a/pypy/objspace/std/test/test_kwargsdict.py b/pypy/objspace/std/test/test_kwargsdict.py --- a/pypy/objspace/std/test/test_kwargsdict.py +++ b/pypy/objspace/std/test/test_kwargsdict.py @@ -124,7 +124,7 @@ class AppTestKwargsDictStrategy(object): def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("__repr__ doesn't work on appdirect") def w_get_strategy(self, obj): diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -404,10 +404,10 @@ class AppTestW_ListObject(object): def setup_class(cls): import sys - on_cpython = (cls.option.runappdirect and + on_cpython = (cls.runappdirect and not hasattr(sys, 'pypy_translation_info')) cls.w_on_cpython = cls.space.wrap(on_cpython) - cls.w_runappdirect = cls.space.wrap(cls.option.runappdirect) + cls.w_runappdirect = cls.space.wrap(cls.runappdirect) def test_getstrategyfromlist_w(self): l0 = ["a", "2", "a", True] diff --git a/pypy/objspace/std/test/test_proxy_internals.py b/pypy/objspace/std/test/test_proxy_internals.py --- a/pypy/objspace/std/test/test_proxy_internals.py +++ b/pypy/objspace/std/test/test_proxy_internals.py @@ -22,7 +22,7 @@ class AppTestProxyInterpOnly(AppProxy): def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("interp only test") from pypy.interpreter.typedef import TypeDef, interp2app from pypy.interpreter.baseobjspace import Wrappable diff --git a/pypy/objspace/std/test/test_rangeobject.py b/pypy/objspace/std/test/test_rangeobject.py --- a/pypy/objspace/std/test/test_rangeobject.py +++ b/pypy/objspace/std/test/test_rangeobject.py @@ -4,7 +4,7 @@ spaceconfig = {"objspace.std.withrangelist": True} def setup_class(cls): - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("__pypy__.internal_repr() cannot be used to see " "if a range list was forced on top of pypy-c") cls.w_not_forced = cls.space.appexec([], """(): diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py b/pypy/objspace/std/test/test_specialisedtupleobject.py --- a/pypy/objspace/std/test/test_specialisedtupleobject.py +++ b/pypy/objspace/std/test/test_specialisedtupleobject.py @@ -67,7 +67,7 @@ raise OperationError(space.w_ReferenceError, w_tuple) w_tuple.delegating = delegation_forbidden return w_tuple - if cls.option.runappdirect: + if cls.runappdirect: cls.w_forbid_delegation = lambda self, x: x cls.test_delegation = lambda self: skip("runappdirect") else: diff --git a/pypy/objspace/std/test/test_userobject.py b/pypy/objspace/std/test/test_userobject.py --- a/pypy/objspace/std/test/test_userobject.py +++ b/pypy/objspace/std/test/test_userobject.py @@ -7,7 +7,7 @@ spaceconfig = {} def setup_class(cls): - cls.w_runappdirect = cls.space.wrap(bool(cls.option.runappdirect)) + cls.w_runappdirect = cls.space.wrap(cls.runappdirect) def rand(space): import random return space.wrap(random.randrange(0, 5)) @@ -281,7 +281,7 @@ cls.prev_installer = multimethod.Installer multimethod.Installer = multimethod.InstallerVersion2 - if cls.option.runappdirect: + if cls.runappdirect: py.test.skip("Cannot run different installers when runappdirect") def teardown_class(cls): From noreply at buildbot.pypy.org Mon Oct 29 22:40:28 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:28 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Remove extra import Message-ID: <20121029214028.B51FF1C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58624:38f9de9ce11a Date: 2012-10-29 08:51 +0100 http://bitbucket.org/pypy/pypy/changeset/38f9de9ce11a/ Log: Remove extra import diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -14,7 +14,7 @@ from pypy.interpreter.main import run_string, run_file # the following adds command line options as a side effect! -from pypy.conftest import gettestobjspace, option as pypy_option +from pypy.conftest import option as pypy_option from pypy.tool.pytest import appsupport from pypy.tool.pytest.confpath import pypydir, testdir, testresultdir From noreply at buildbot.pypy.org Mon Oct 29 22:40:29 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:29 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Finlly move gettestobjspace and maketestobjspace to their own file. Message-ID: <20121029214029.D77371C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58625:607b9abb53a6 Date: 2012-10-29 22:29 +0100 http://bitbucket.org/pypy/pypy/changeset/607b9abb53a6/ Log: Finlly move gettestobjspace and maketestobjspace to their own file. diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -3,8 +3,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.function import Method from pypy.tool.pytest import appsupport -from pypy.tool.option import make_config, make_objspace -from pypy.config.config import ConflictConfigError from inspect import isclass, getmro from pypy.tool.udir import udir from pypy.tool.autopath import pypydir @@ -70,49 +68,10 @@ pass def pytest_funcarg__space(request): + from pypy.tool.pytest.objspace import gettestobjspace spaceconfig = getattr(request.cls, 'spaceconfig', {}) return gettestobjspace(**spaceconfig) -_SPACECACHE={} -def gettestobjspace(name=None, **kwds): - """ helper for instantiating and caching space's for testing. - """ - try: - config = make_config(option, objspace=name, **kwds) - except ConflictConfigError, e: - # this exception is typically only raised if a module is not available. - # in this case the test should be skipped - py.test.skip(str(e)) - key = config.getkey() - try: - return _SPACECACHE[key] - except KeyError: - if getattr(option, 'runappdirect', None): - if name not in (None, 'std'): - myname = getattr(sys, 'pypy_objspaceclass', '') - if not myname.lower().startswith(name): - py.test.skip("cannot runappdirect test: " - "%s objspace required" % (name,)) - return TinyObjSpace(**kwds) - space = maketestobjspace(config) - _SPACECACHE[key] = space - return space - -def maketestobjspace(config=None): - if config is None: - config = make_config(option) - space = make_objspace(config) - space.startup() # Initialize all builtin modules - space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), - appsupport.build_pytest_assertion(space)) - space.setitem(space.builtin.w_dict, space.wrap('raises'), - space.wrap(appsupport.app_raises)) - space.setitem(space.builtin.w_dict, space.wrap('skip'), - space.wrap(appsupport.app_skip)) - space.raises_w = appsupport.raises_w.__get__(space) - space.eq_w = appsupport.eq_w.__get__(space) - return space - class TinyObjSpace(object): def __init__(self, **kwds): import sys @@ -311,6 +270,7 @@ class LazyObjSpaceGetter(object): def __get__(self, obj, cls=None): + from pypy.tool.pytest.objspace import gettestobjspace space = gettestobjspace() if cls: cls.space = space @@ -329,6 +289,7 @@ # Make cls.space and cls.runappdirect available in tests. spaceconfig = getattr(appclass.obj, 'spaceconfig', None) if spaceconfig is not None: + from pypy.tool.pytest.objspace import gettestobjspace appclass.obj.space = gettestobjspace(**spaceconfig) appclass.obj.runappdirect = option.runappdirect @@ -407,6 +368,7 @@ target = self.obj if self.config.option.runappdirect: return target() + from pypy.tool.pytest.objspace import gettestobjspace space = gettestobjspace() filename = self._getdynfilename(target) func = app2interp_temp(target, filename=filename) diff --git a/pypy/interpreter/test/test_appinterp.py b/pypy/interpreter/test/test_appinterp.py --- a/pypy/interpreter/test/test_appinterp.py +++ b/pypy/interpreter/test/test_appinterp.py @@ -134,7 +134,7 @@ per-instance attribute, holding a fresh copy of the dictionary. """ from pypy.interpreter.mixedmodule import MixedModule - from pypy.conftest import maketestobjspace + from pypy.tool.pytest.objspace import maketestobjspace class MyModule(MixedModule): interpleveldefs = {} @@ -155,6 +155,9 @@ w_str = space1.getattr(w_mymod1, space1.wrap("hi")) assert space1.str_w(w_str) == "hello" +class TestMixedModuleUnfreeze: + spaceconfig = dict(usemodules=('_ssl', '_socket')) + def test_random_stuff_can_unfreeze(self): # When a module contains an "import" statement in applevel code, the # imported module is initialized, possibly after it has been already @@ -163,11 +166,8 @@ # This is important when the module startup() function does something # at runtime, like setting os.environ (posix module) or initializing # the winsock library (_socket module) - from pypy.conftest import gettestobjspace - space = gettestobjspace(usemodules=('_ssl', '_socket')) - - w_socket = space.builtin_modules['_socket'] - w_ssl = space.builtin_modules['_ssl'] + w_socket = self.space.builtin_modules['_socket'] + w_ssl = self.space.builtin_modules['_ssl'] # Uncomment this line for a workaround # space.getattr(w_ssl, space.wrap('SSLError')) diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -1,6 +1,6 @@ -from pypy.conftest import gettestobjspace import sys import py +from pypy.tool.pytest.objspace import gettestobjspace from pypy.tool.udir import udir from pypy.rlib import rsocket from pypy.rpython.lltypesystem import lltype, rffi diff --git a/pypy/module/cpyext/presetup.py b/pypy/module/cpyext/presetup.py --- a/pypy/module/cpyext/presetup.py +++ b/pypy/module/cpyext/presetup.py @@ -19,7 +19,7 @@ sys.path.insert(0, os.getcwd()) from distutils import sysconfig -from pypy.conftest import gettestobjspace +from pypy.tool.pytest.objspace import gettestobjspace from pypy.module.cpyext.api import build_bridge from pypy.module.imp.importing import get_so_extension diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -4,7 +4,7 @@ from __future__ import with_statement from pypy.objspace.std import StdObjSpace from pypy.tool.udir import udir -from pypy.conftest import gettestobjspace +from pypy.tool.pytest.objspace import gettestobjspace from pypy.tool.autopath import pypydir from pypy.rpython.module.ll_os import RegisterOs import os @@ -38,7 +38,7 @@ os.stat_float_times(True) # Initialize sys.filesystemencoding - space.call_method(space.getbuiltinmodule('sys'), 'getfilesystemencoding') + # space.call_method(space.getbuiltinmodule('sys'), 'getfilesystemencoding') def need_sparse_files(): if sys.platform == 'darwin': @@ -1008,7 +1008,7 @@ def setup_class(cls): cls.space = space cls.w_posix = space.appexec([], GET_POSIX) - if py.test.config.option.runappdirect: + if cls.runappdirect: # Can't change encoding try: u"ą".encode(sys.getfilesystemencoding()) diff --git a/pypy/objspace/std/test/test_smalllongobject.py b/pypy/objspace/std/test/test_smalllongobject.py --- a/pypy/objspace/std/test/test_smalllongobject.py +++ b/pypy/objspace/std/test/test_smalllongobject.py @@ -2,7 +2,7 @@ import sys from pypy.objspace.std.smalllongobject import W_SmallLongObject from pypy.objspace.std.test import test_longobject -from pypy.conftest import gettestobjspace +from pypy.tool.pytest.objspace import gettestobjspace from pypy.rlib.rarithmetic import r_longlong from pypy.interpreter.error import OperationError diff --git a/pypy/objspace/std/test/test_smalltupleobject.py b/pypy/objspace/std/test/test_smalltupleobject.py --- a/pypy/objspace/std/test/test_smalltupleobject.py +++ b/pypy/objspace/std/test/test_smalltupleobject.py @@ -2,7 +2,7 @@ from pypy.objspace.std.smalltupleobject import W_SmallTupleObject from pypy.interpreter.error import OperationError from pypy.objspace.std.test.test_tupleobject import AppTestW_TupleObject -from pypy.conftest import gettestobjspace +from pypy.tool.pytest.objspace import gettestobjspace class AppTestW_SmallTupleObject(AppTestW_TupleObject): spaceconfig = {"objspace.std.withsmalltuple": True} diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py b/pypy/objspace/std/test/test_specialisedtupleobject.py --- a/pypy/objspace/std/test/test_specialisedtupleobject.py +++ b/pypy/objspace/std/test/test_specialisedtupleobject.py @@ -3,7 +3,7 @@ from pypy.objspace.std.specialisedtupleobject import W_SpecialisedTupleObject from pypy.objspace.std.specialisedtupleobject import _specialisations from pypy.interpreter.error import OperationError -from pypy.conftest import gettestobjspace +from pypy.tool.pytest.objspace import gettestobjspace from pypy.objspace.std.test import test_tupleobject from pypy.interpreter import gateway diff --git a/pypy/objspace/std/test/test_stdobjspace.py b/pypy/objspace/std/test/test_stdobjspace.py --- a/pypy/objspace/std/test/test_stdobjspace.py +++ b/pypy/objspace/std/test/test_stdobjspace.py @@ -1,6 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import app2interp -from pypy.conftest import gettestobjspace +from pypy.tool.pytest.objspace import gettestobjspace class TestW_StdObjSpace: diff --git a/pypy/objspace/test/test_thunkobjspace.py b/pypy/objspace/test/test_thunkobjspace.py --- a/pypy/objspace/test/test_thunkobjspace.py +++ b/pypy/objspace/test/test_thunkobjspace.py @@ -1,4 +1,4 @@ -from pypy.conftest import gettestobjspace +from pypy.tool.pytest.objspace import gettestobjspace from pypy.interpreter import gateway class AppTest_Thunk: diff --git a/pypy/tool/pytest/objspace.py b/pypy/tool/pytest/objspace.py new file mode 100644 --- /dev/null +++ b/pypy/tool/pytest/objspace.py @@ -0,0 +1,46 @@ +import py +from pypy.config.config import ConflictConfigError +from pypy.tool.option import make_config, make_objspace +from pypy.tool.pytest import appsupport +from pypy.conftest import option + +_SPACECACHE={} +def gettestobjspace(name=None, **kwds): + """ helper for instantiating and caching space's for testing. + """ + try: + config = make_config(option, objspace=name, **kwds) + except ConflictConfigError, e: + # this exception is typically only raised if a module is not available. + # in this case the test should be skipped + py.test.skip(str(e)) + key = config.getkey() + try: + return _SPACECACHE[key] + except KeyError: + if getattr(option, 'runappdirect', None): + if name not in (None, 'std'): + myname = getattr(sys, 'pypy_objspaceclass', '') + if not myname.lower().startswith(name): + py.test.skip("cannot runappdirect test: " + "%s objspace required" % (name,)) + return TinyObjSpace(**kwds) + space = maketestobjspace(config) + _SPACECACHE[key] = space + return space + +def maketestobjspace(config=None): + if config is None: + config = make_config(option) + space = make_objspace(config) + space.startup() # Initialize all builtin modules + space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), + appsupport.build_pytest_assertion(space)) + space.setitem(space.builtin.w_dict, space.wrap('raises'), + space.wrap(appsupport.app_raises)) + space.setitem(space.builtin.w_dict, space.wrap('skip'), + space.wrap(appsupport.app_skip)) + space.raises_w = appsupport.raises_w.__get__(space) + space.eq_w = appsupport.eq_w.__get__(space) + return space + From noreply at buildbot.pypy.org Mon Oct 29 22:40:31 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 22:40:31 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: hg merge default Message-ID: <20121029214031.5CB6C1C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58626:d6e7687c576c Date: 2012-10-29 22:38 +0100 http://bitbucket.org/pypy/pypy/changeset/d6e7687c576c/ Log: hg merge default diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -74,8 +74,11 @@ elif step == 1: length = stop - start if length != len(newstring): - msg = "buffer slice assignment is wrong size" - raise OperationError(space.w_ValueError, space.wrap(msg)) + if length < 0 and len(newstring) == 0: + pass # ok anyway + else: + msg = "right operand length must match slice length" + raise OperationError(space.w_ValueError, space.wrap(msg)) self.setslice(start, newstring) else: raise OperationError(space.w_ValueError, diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -429,15 +429,17 @@ source_start_box = self.get_constant_box(op.getarg(3)) dest_start_box = self.get_constant_box(op.getarg(4)) length = self.get_constant_box(op.getarg(5)) + extrainfo = op.getdescr().get_extra_info() if (source_start_box and dest_start_box and length and (dest_value.is_virtual() or length.getint() <= 8) and - (source_value.is_virtual() or length.getint() <= 8)): + (source_value.is_virtual() or length.getint() <= 8) and + len(extrainfo.write_descrs_arrays) == 1): # <-sanity check from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue source_start = source_start_box.getint() dest_start = dest_start_box.getint() + # XXX fish fish fish + arraydescr = extrainfo.write_descrs_arrays[0] for index in range(length.getint()): - # XXX fish fish fish - arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] if source_value.is_virtual(): assert isinstance(source_value, VArrayValue) val = source_value.getitem(index + source_start) diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -116,6 +116,8 @@ b[:] = '12345' assert a.tostring() == 'hello 12345' raises(IndexError, 'b[5] = "."') + b[4:2] = '' + assert a.tostring() == 'hello 12345' b = buffer(b, 2) assert len(b) == 3 diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,6 +1,7 @@ from pypy.interpreter.error import operationerrfmt from pypy.interpreter.buffer import RWBuffer -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.interpreter.typedef import TypeDef from pypy.rpython.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -34,6 +35,16 @@ for i in range(len(string)): raw_cdata[i] = string[i] +LLBuffer.typedef = TypeDef( + "buffer", + __module__ = "_cffi_backend", + __len__ = interp2app(RWBuffer.descr_len), + __getitem__ = interp2app(RWBuffer.descr_getitem), + __setitem__ = interp2app(RWBuffer.descr_setitem), + __buffer__ = interp2app(RWBuffer.descr__buffer__), + ) +LLBuffer.typedef.acceptable_as_base_class = False + @unwrap_spec(cdata=cdataobj.W_CData, size=int) def buffer(space, cdata, size=-1): 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 @@ -5,8 +5,6 @@ type_or_class = "type" mandatory_b_prefix = '' mandatory_u_prefix = 'u' - readbuf = str - bufchar = lambda x: x bytechr = chr class U(object): def __add__(self, other): @@ -20,11 +18,6 @@ unichr = chr mandatory_b_prefix = 'b' mandatory_u_prefix = '' - readbuf = lambda buf: buf.tobytes() - if sys.version_info < (3, 3): - bufchar = lambda x: bytes([ord(x)]) - else: - bufchar = ord bytechr = lambda n: bytes([n]) u = "" @@ -1811,36 +1804,76 @@ assert (p < s) ^ (p > s) def test_buffer(): + import __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() assert sizeof(BShort) == 2 - assert len(readbuf(buffer(s))) == 2 + assert len(buffer(s)) == 2 # BChar = new_primitive_type("char") BCharArray = new_array_type(new_pointer_type(BChar), None) c = newp(BCharArray, b"hi there") + # buf = buffer(c) - assert readbuf(buf) == b"hi there\x00" + assert str(buf).startswith('<_cffi_backend.buffer object at 0x') + # --mb_length-- assert len(buf) == len(b"hi there\x00") - assert buf[0] == bufchar('h') - assert buf[2] == bufchar(' ') - assert list(buf) == list(map(bufchar, "hi there\x00")) - buf[2] = bufchar('-') - assert c[2] == b'-' - assert readbuf(buf) == b"hi-there\x00" - c[2] = b'!' - assert buf[2] == bufchar('!') - assert readbuf(buf) == b"hi!there\x00" - c[2] = b'-' - buf[:2] = b'HI' - assert string(c) == b'HI-there' - if sys.version_info < (3,) or sys.version_info >= (3, 3): - assert buf[:4:2] == b'H-' - if '__pypy__' not in sys.builtin_module_names: - # XXX pypy doesn't support the following assignment so far - buf[:4:2] = b'XY' - assert string(c) == b'XIYthere' + # --mb_item-- + for i in range(-12, 12): + try: + expected = b"hi there\x00"[i] + except IndexError: + py.test.raises(IndexError, "buf[i]") + else: + assert buf[i] == expected + # --mb_slice-- + assert buf[:] == b"hi there\x00" + for i in range(-12, 12): + assert buf[i:] == b"hi there\x00"[i:] + assert buf[:i] == b"hi there\x00"[:i] + for j in range(-12, 12): + assert buf[i:j] == b"hi there\x00"[i:j] + # --misc-- + assert list(buf) == list(b"hi there\x00") + # --mb_as_buffer-- + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 + py.test.raises(TypeError, memoryview, c) + mv1 = memoryview(buf) + assert len(mv1) == len(buf) and mv1[3] == "t" + # --mb_ass_item-- + expected = list(b"hi there\x00") + for i in range(-12, 12): + try: + expected[i] = chr(i & 0xff) + except IndexError: + py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + else: + buf[i] = chr(i & 0xff) + assert list(buf) == expected + # --mb_ass_slice-- + buf[:] = b"hi there\x00" + assert list(buf) == list(c) == list(b"hi there\x00") + py.test.raises(ValueError, 'buf[:] = b"shorter"') + py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + buf[4:2] = b"" # no effect, but should work + assert buf[:] == b"hi there\x00" + expected = list(b"hi there\x00") + x = 0 + for i in range(-12, 12): + for j in range(-12, 12): + start = i if i >= 0 else i + len(buf) + stop = j if j >= 0 else j + len(buf) + start = max(0, min(len(buf), start)) + stop = max(0, min(len(buf), stop)) + sample = chr(x & 0xff) * (stop - start) + x += 1 + buf[i:j] = sample + expected[i:j] = sample + assert list(buf) == expected def test_getcname(): BUChar = new_primitive_type("unsigned char") diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -8,7 +8,8 @@ from pypy.module._multiprocessing import interp_semaphore class AppTestBufferTooShort: - spaceconfig = dict(usemodules=['_multiprocessing', 'thread', 'signal']) + spaceconfig = dict(usemodules=['_multiprocessing', 'thread', 'signal', + 'itertools']) def setup_class(cls): if cls.runappdirect: diff --git a/pypy/module/_multiprocessing/test/test_memory.py b/pypy/module/_multiprocessing/test/test_memory.py --- a/pypy/module/_multiprocessing/test/test_memory.py +++ b/pypy/module/_multiprocessing/test/test_memory.py @@ -1,6 +1,6 @@ class AppTestMemory: spaceconfig = dict(usemodules=('_multiprocessing', 'mmap', - '_rawffi', '_ffi')) + '_rawffi', '_ffi', 'itertools')) def test_address_of(self): import _multiprocessing 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 @@ -357,8 +357,8 @@ buffering = 1024 # minimum amount of compressed data read at once self.buffering = buffering - def close(self): - self.stream.close() + def close1(self, closefileno): + self.stream.close1(closefileno) def tell(self): return self.readlength @@ -479,9 +479,9 @@ self.compressor = W_BZ2Compressor(space, compresslevel) self.writtenlength = 0 - def close(self): + def close1(self, closefileno): self.stream.write(self.space.str_w(self.compressor.flush())) - self.stream.close() + self.stream.close1(closefileno) def write(self, data): self.stream.write(self.space.str_w(self.compressor.compress(data))) diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py --- a/pypy/module/cpyext/dictobject.py +++ b/pypy/module/cpyext/dictobject.py @@ -198,8 +198,8 @@ @specialize.memo() def make_frozendict(space): return space.appexec([], '''(): - import collections - class FrozenDict(collections.Mapping): + import _abcoll + class FrozenDict(_abcoll.Mapping): def __init__(self, *args, **kwargs): self._d = dict(*args, **kwargs) def __iter__(self): diff --git a/pypy/module/cpyext/test/test_import.py b/pypy/module/cpyext/test/test_import.py --- a/pypy/module/cpyext/test/test_import.py +++ b/pypy/module/cpyext/test/test_import.py @@ -4,9 +4,9 @@ class TestImport(BaseApiTest): def test_import(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - assert pdb - assert space.getattr(pdb, space.wrap("pm")) + stat = api.PyImport_Import(space.wrap("stat")) + assert stat + assert space.getattr(stat, space.wrap("S_IMODE")) def test_addmodule(self, space, api): with rffi.scoped_str2charp("sys") as modname: @@ -32,10 +32,10 @@ assert space.is_true(space.contains(w_dict, space.wrap(testmod))) def test_reload(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - space.delattr(pdb, space.wrap("set_trace")) - pdb = api.PyImport_ReloadModule(pdb) - assert space.getattr(pdb, space.wrap("set_trace")) + stat = api.PyImport_Import(space.wrap("stat")) + space.delattr(stat, space.wrap("S_IMODE")) + stat = api.PyImport_ReloadModule(stat) + assert space.getattr(stat, space.wrap("S_IMODE")) class AppTestImportLogic(AppTestCpythonExtensionBase): def test_import_logic(self): diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py --- a/pypy/module/imp/test/test_app.py +++ b/pypy/module/imp/test/test_app.py @@ -2,6 +2,8 @@ MARKER = 42 class AppTestImpModule: + spaceconfig = dict(usemodules=('imp', 'itertools')) + def setup_class(cls): cls.w_imp = cls.space.getbuiltinmodule('imp') cls.w_file_module = cls.space.wrap(__file__) 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 @@ -38,7 +38,7 @@ test_reload = "def test():\n raise ValueError\n", infinite_reload = "import infinite_reload; reload(infinite_reload)", del_sys_module = "import sys\ndel sys.modules['del_sys_module']\n", - itertools = "hello_world = 42\n", + _md5 = "hello_world = 42\n", gc = "should_never_be_seen = 42\n", ) root.ensure("notapackage", dir=1) # empty, no __init__.py @@ -146,7 +146,7 @@ """) class AppTestImport: - spaceconfig = dict(usemodules=['itertools']) + spaceconfig = dict(usemodules=['_md5']) def setup_class(cls): # interpreter-level cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect) @@ -597,34 +597,34 @@ def test_shadow_extension_1(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find itertools.py if there is + # 'import _md5' is supposed to find _md5.py if there is # one in sys.path. import sys - assert 'itertools' not in sys.modules - import itertools - assert hasattr(itertools, 'hello_world') - assert not hasattr(itertools, 'count') - assert '(built-in)' not in repr(itertools) - del sys.modules['itertools'] + assert '_md5' not in sys.modules + import _md5 + assert hasattr(_md5, 'hello_world') + assert not hasattr(_md5, 'count') + assert '(built-in)' not in repr(_md5) + del sys.modules['_md5'] def test_shadow_extension_2(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find the built-in module even + # 'import _md5' is supposed to find the built-in module even # if there is also one in sys.path as long as it is *after* the # special entry '.../lib_pypy/__extensions__'. (Note that for now - # there is one in lib_pypy/itertools.py, which should not be seen + # there is one in lib_pypy/_md5.py, which should not be seen # either; hence the (built-in) test below.) import sys - assert 'itertools' not in sys.modules + assert '_md5' not in sys.modules sys.path.append(sys.path.pop(0)) try: - import itertools - assert not hasattr(itertools, 'hello_world') - assert hasattr(itertools, 'izip') - assert '(built-in)' in repr(itertools) + import _md5 + assert not hasattr(_md5, 'hello_world') + assert hasattr(_md5, 'digest_size') + assert '(built-in)' in repr(_md5) finally: sys.path.insert(0, sys.path.pop()) - del sys.modules['itertools'] + del sys.modules['_md5'] def test_invalid_pathname(self): import imp @@ -1003,7 +1003,7 @@ os.environ['LANG'] = oldlang class AppTestImportHooks(object): - spaceconfig = dict(usemodules=('struct',)) + spaceconfig = dict(usemodules=('struct', 'itertools')) def setup_class(cls): mydir = os.path.dirname(__file__) diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -4,7 +4,7 @@ class AppTestMath: - spaceconfig = dict(usemodules=['math', 'struct']) + spaceconfig = dict(usemodules=['math', 'struct', 'itertools']) def setup_class(cls): cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES) 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 @@ -45,7 +45,7 @@ def __init__(self, array): self.array = array self.offset = array.start - self.skip = array.strides[0] + self.skip = array.get_strides()[0] self.dtype = array.dtype self.index = 0 self.size = array.get_shape()[0] @@ -116,8 +116,8 @@ class AxisIterator(base.BaseArrayIterator): def __init__(self, array, shape, dim): self.shape = shape - strides = array.strides - backstrides = array.backstrides + strides = array.get_strides() + backstrides = array.get_backstrides() if len(shape) == len(strides): # keepdims = True self.strides = strides[:dim] + [0] + strides[dim + 1:] @@ -167,12 +167,24 @@ class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None + + # JIT hints that length of all those arrays is a constant def get_shape(self): shape = self.shape jit.hint(len(shape), promote=True) return shape + def get_strides(self): + strides = self.strides + jit.hint(len(strides), promote=True) + return strides + + def get_backstrides(self): + backstrides = self.backstrides + jit.hint(len(backstrides), promote=True) + return backstrides + def getitem(self, index): return self.dtype.getitem(self, index) @@ -197,7 +209,7 @@ new_strides = None if self.size > 0: new_strides = calc_new_strides(new_shape, self.get_shape(), - self.strides, self.order) + self.get_strides(), self.order) if new_strides: # We can create a view, strides somehow match up. ndims = len(new_shape) @@ -214,6 +226,7 @@ @jit.unroll_safe def _lookup_by_index(self, space, view_w): item = self.start + strides = self.get_strides() for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError @@ -224,13 +237,14 @@ raise operationerrfmt(space.w_IndexError, "index (%d) out of range (0<=index<%d", i, self.get_shape()[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item @jit.unroll_safe def _lookup_by_unwrapped_index(self, space, lst): item = self.start shape = self.get_shape() + strides = self.get_strides() assert len(lst) == len(shape) for i, idx in enumerate(lst): if idx < 0: @@ -239,7 +253,7 @@ raise operationerrfmt(space.w_IndexError, "index (%d) out of range (0<=index<%d", i, shape[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item def getitem_index(self, space, index): @@ -344,8 +358,8 @@ backstrides = [] shape = [] for i in range(len(self.get_shape()) - 1, -1, -1): - strides.append(self.strides[i]) - backstrides.append(self.backstrides[i]) + strides.append(self.get_strides()[i]) + backstrides.append(self.get_backstrides()[i]) shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, backstrides, shape, self) @@ -361,14 +375,14 @@ return AxisIterator(self, shape, dim) def create_dot_iter(self, shape, skip): - r = calculate_dot_strides(self.strides, self.backstrides, + r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) return MultiDimViewIterator(self, self.start, r[0], r[1], shape) def swapaxes(self, axis1, axis2): shape = self.get_shape()[:] - strides = self.strides[:] - backstrides = self.backstrides[:] + strides = self.get_strides()[:] + backstrides = self.get_backstrides()[:] shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] @@ -394,7 +408,8 @@ def create_iter(self, shape=None): if shape is None or shape == self.get_shape(): return ConcreteArrayIterator(self) - r = calculate_broadcast_strides(self.strides, self.backstrides, + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), self.get_shape(), shape) return MultiDimViewIterator(self, 0, r[0], r[1], shape) @@ -430,14 +445,16 @@ def create_iter(self, shape=None): if shape is not None and shape != self.get_shape(): - r = calculate_broadcast_strides(self.strides, self.backstrides, + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), self.get_shape(), shape) return MultiDimViewIterator(self.parent, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: return OneDimViewIterator(self) - return MultiDimViewIterator(self.parent, self.start, self.strides, - self.backstrides, self.get_shape()) + return MultiDimViewIterator(self.parent, self.start, + self.get_strides(), + self.get_backstrides(), self.get_shape()) def set_shape(self, space, new_shape): if len(self.get_shape()) < 2 or self.size == 0: @@ -446,7 +463,7 @@ strides = [] backstrides = [] dtype = self.dtype - s = self.strides[0] // dtype.get_size() + s = self.get_strides()[0] // dtype.get_size() if self.order == 'C': new_shape.reverse() for sh in new_shape: @@ -459,7 +476,8 @@ new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, self) - new_strides = calc_new_strides(new_shape, self.get_shape(), self.strides, + new_strides = calc_new_strides(new_shape, self.get_shape(), + self.get_strides(), self.order) if new_strides is None: raise OperationError(space.w_AttributeError, space.wrap( 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 @@ -275,14 +275,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - # Running entire test suite needs this function to succeed, - # running single test_stringarray succeeds without it. - # With convert_to() test_ztranslation fails since - # W_CharacterBox is not a W_GenericBox. - # Why is it needed for multiple tests? - #def convert_to(self, dtype): - # xxx - class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): from pypy.module.micronumpy.interp_dtype import new_unicode_dtype 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 @@ -59,8 +59,8 @@ def apply(self, arr): ofs, subdtype = arr.dtype.fields[self.name] # strides backstrides are identical, ofs only changes start - return W_NDimArray.new_slice(arr.start + ofs, arr.strides, - arr.backstrides, + return W_NDimArray.new_slice(arr.start + ofs, arr.get_strides(), + arr.get_backstrides(), arr.shape, arr, subdtype) class Chunks(BaseChunk): @@ -80,8 +80,8 @@ def apply(self, arr): shape = self.extend_shape(arr.shape) - r = calculate_slice_strides(arr.shape, arr.start, arr.strides, - arr.backstrides, self.l) + r = calculate_slice_strides(arr.shape, arr.start, arr.get_strides(), + arr.get_backstrides(), self.l) _, start, strides, backstrides = r return W_NDimArray.new_slice(start, strides[:], backstrides[:], shape[:], arr) diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -110,6 +110,7 @@ i //= shape[s] return coords, step, lngth + at jit.unroll_safe def shape_agreement(space, shape1, w_arr2, broadcast_down=True): if w_arr2 is None: return shape1 @@ -132,6 +133,7 @@ ) return ret + at jit.unroll_safe def _shape_agreement(shape1, shape2): """ Checks agreement about two shapes with respect to broadcasting. Returns the resulting shape. diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py --- a/pypy/module/micronumpy/support.py +++ b/pypy/module/micronumpy/support.py @@ -8,6 +8,7 @@ i *= x return i + at jit.unroll_safe def calc_strides(shape, dtype, order): strides = [] backstrides = [] diff --git a/pypy/module/test_lib_pypy/test_itertools.py b/pypy/module/test_lib_pypy/test_itertools.py --- a/pypy/module/test_lib_pypy/test_itertools.py +++ b/pypy/module/test_lib_pypy/test_itertools.py @@ -1,4 +1,6 @@ class AppTestItertools: + spaceconfig = dict(usemodules=['itertools']) + def setup_class(cls): cls.w_itertools = cls.space.appexec([], "(): import itertools; return itertools") diff --git a/pypy/module/test_lib_pypy/test_pwd.py b/pypy/module/test_lib_pypy/test_pwd.py --- a/pypy/module/test_lib_pypy/test_pwd.py +++ b/pypy/module/test_lib_pypy/test_pwd.py @@ -1,7 +1,8 @@ import py, sys class AppTestPwd: - spaceconfig = dict(usemodules=('_ffi', '_rawffi')) + spaceconfig = dict(usemodules=('_ffi', '_rawffi', 'itertools')) + def setup_class(cls): if sys.platform == 'win32': py.test.skip("Unix only") diff --git a/pypy/module/zipimport/test/test_undocumented.py b/pypy/module/zipimport/test/test_undocumented.py --- a/pypy/module/zipimport/test/test_undocumented.py +++ b/pypy/module/zipimport/test/test_undocumented.py @@ -17,7 +17,8 @@ ]) class AppTestZipImport: - spaceconfig = dict(usemodules=['zipimport', 'rctime', 'struct']) + spaceconfig = dict(usemodules=['zipimport', 'rctime', 'struct', + 'itertools']) def setup_class(cls): cls.w_created_paths = cls.space.wrap(created_paths) diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -14,7 +14,8 @@ cpy's regression tests """ compression = ZIP_STORED - spaceconfig = dict(usemodules=['zipimport', 'rctime', 'struct']) + spaceconfig = dict(usemodules=['zipimport', 'rctime', 'struct', + 'itertools']) pathsep = os.path.sep @classmethod @@ -49,6 +50,7 @@ """).compile() space = cls.space + tmpdir = udir.ensure('zipimport_%s' % cls.__name__, dir=1) now = time.time() cls.w_now = space.wrap(now) @@ -353,7 +355,8 @@ class AppTestZipimportDeflated(AppTestZipimport): compression = ZIP_DEFLATED - spaceconfig = dict(usemodules=['zipimport', 'zlib', 'rctime', 'struct']) + spaceconfig = dict(usemodules=['zipimport', 'zlib', 'rctime', 'struct', + 'itertools']) def setup_class(cls): try: diff --git a/pypy/objspace/std/test/test_iterobject.py b/pypy/objspace/std/test/test_iterobject.py --- a/pypy/objspace/std/test/test_iterobject.py +++ b/pypy/objspace/std/test/test_iterobject.py @@ -68,7 +68,7 @@ raises(TypeError, len, iter(iterable)) def test_no_len_on_deque_iter(self): - from collections import deque + from _collections import deque iterable = deque([1,2,3,4]) raises(TypeError, len, iter(iterable)) @@ -81,15 +81,14 @@ it = reversed([5,6,7]) raises(TypeError, len, it) - def test_no_len_on_UserList_iter(self): + def test_no_len_on_UserList_iter_reversed(self): + import sys, _abcoll + sys.modules['collections'] = _abcoll from UserList import UserList iterable = UserList([1,2,3,4]) raises(TypeError, len, iter(iterable)) - - def test_no_len_on_UserList_reversed(self): - from UserList import UserList - iterable = UserList([1,2,3,4]) raises(TypeError, len, reversed(iterable)) + del sys.modules['collections'] def test_no_len_on_set_iter(self): iterable = set([1,2,3,4]) diff --git a/pypy/objspace/std/test/test_methodcache.py b/pypy/objspace/std/test/test_methodcache.py --- a/pypy/objspace/std/test/test_methodcache.py +++ b/pypy/objspace/std/test/test_methodcache.py @@ -203,8 +203,3 @@ setattr(a, "a%s" % i, i) cache_counter = __pypy__.method_cache_counter("x") assert cache_counter[0] == 0 # 0 hits, because all the attributes are new - - def test_get_module_from_namedtuple(self): - # this used to crash - from collections import namedtuple - assert namedtuple("a", "b").__module__ diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py --- a/pypy/objspace/std/test/test_typeobject.py +++ b/pypy/objspace/std/test/test_typeobject.py @@ -1062,6 +1062,19 @@ A.__dict__['x'] = 5 assert A.x == 5 + +class AppTestWithMethodCacheCounter: + spaceconfig = {"objspace.std.withmethodcachecounter": True} + + def test_module_from_handbuilt_type(self): + d = {'tuple': tuple, '__name__': 'foomod'} + exec """class foo(tuple): pass""" in d + t = d['foo'] + t.__module__ = 'barmod' + # this last line used to crash; see ab926f846f39 + assert t.__module__ + + class AppTestMutableBuiltintypes: spaceconfig = {"objspace.std.mutable_builtintypes": True} diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -119,6 +119,17 @@ self.size = size or len(digits) self.sign = sign + # __eq__ and __ne__ method exist for testingl only, they are not RPython! + def __eq__(self, other): + # NOT_RPYTHON + if not isinstance(other, rbigint): + return NotImplemented + return self.eq(other) + + def __ne__(self, other): + # NOT_RPYTHON + return not (self == other) + def digit(self, x): """Return the x'th digit, as an int.""" return self._digits[x] diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -1,14 +1,19 @@ from __future__ import division + +import operator +import sys +from random import random, randint, sample + import py -import operator, sys, array -from random import random, randint, sample -from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF -from pypy.rlib.rbigint import _store_digit, _mask_digit -from pypy.rlib.rfloat import NAN + from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask +from pypy.rlib.rbigint import (rbigint, SHIFT, MASK, KARATSUBA_CUTOFF, + _store_digit, _mask_digit) +from pypy.rlib.rfloat import NAN from pypy.rpython.test.test_llinterp import interpret + class TestRLong(object): def test_simple(self): for op1 in [-2, -1, 0, 1, 2, 50]: @@ -112,6 +117,17 @@ rl = rbigint.fromint(sys.maxint).add(rbigint.fromint(42)) assert rl.touint() == result + def test_eq_ne_operators(self): + a1 = rbigint.fromint(12) + a2 = rbigint.fromint(12) + a3 = rbigint.fromint(123) + + assert a1 == a2 + assert a1 != a3 + assert not (a1 != a2) + assert not (a1 == a3) + + def gen_signs(l): for s in l: if s == 0: From noreply at buildbot.pypy.org Mon Oct 29 23:10:36 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 29 Oct 2012 23:10:36 +0100 (CET) Subject: [pypy-commit] pypy remove-PYPY_NOT_MAIN_FILE: hg merge default again Message-ID: <20121029221036.933C71C0250@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: remove-PYPY_NOT_MAIN_FILE Changeset: r58627:684402385d93 Date: 2012-10-29 23:10 +0100 http://bitbucket.org/pypy/pypy/changeset/684402385d93/ Log: hg merge default again diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -74,8 +74,11 @@ elif step == 1: length = stop - start if length != len(newstring): - msg = "buffer slice assignment is wrong size" - raise OperationError(space.w_ValueError, space.wrap(msg)) + if length < 0 and len(newstring) == 0: + pass # ok anyway + else: + msg = "right operand length must match slice length" + raise OperationError(space.w_ValueError, space.wrap(msg)) self.setslice(start, newstring) else: raise OperationError(space.w_ValueError, diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -429,15 +429,17 @@ source_start_box = self.get_constant_box(op.getarg(3)) dest_start_box = self.get_constant_box(op.getarg(4)) length = self.get_constant_box(op.getarg(5)) + extrainfo = op.getdescr().get_extra_info() if (source_start_box and dest_start_box and length and (dest_value.is_virtual() or length.getint() <= 8) and - (source_value.is_virtual() or length.getint() <= 8)): + (source_value.is_virtual() or length.getint() <= 8) and + len(extrainfo.write_descrs_arrays) == 1): # <-sanity check from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue source_start = source_start_box.getint() dest_start = dest_start_box.getint() + # XXX fish fish fish + arraydescr = extrainfo.write_descrs_arrays[0] for index in range(length.getint()): - # XXX fish fish fish - arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0] if source_value.is_virtual(): assert isinstance(source_value, VArrayValue) val = source_value.getitem(index + source_start) diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -117,6 +117,8 @@ b[:] = '12345' assert a.tostring() == 'hello 12345' raises(IndexError, 'b[5] = "."') + b[4:2] = '' + assert a.tostring() == 'hello 12345' b = buffer(b, 2) assert len(b) == 3 diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,6 +1,7 @@ from pypy.interpreter.error import operationerrfmt from pypy.interpreter.buffer import RWBuffer -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.interpreter.typedef import TypeDef from pypy.rpython.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -34,6 +35,16 @@ for i in range(len(string)): raw_cdata[i] = string[i] +LLBuffer.typedef = TypeDef( + "buffer", + __module__ = "_cffi_backend", + __len__ = interp2app(RWBuffer.descr_len), + __getitem__ = interp2app(RWBuffer.descr_getitem), + __setitem__ = interp2app(RWBuffer.descr_setitem), + __buffer__ = interp2app(RWBuffer.descr__buffer__), + ) +LLBuffer.typedef.acceptable_as_base_class = False + @unwrap_spec(cdata=cdataobj.W_CData, size=int) def buffer(space, cdata, size=-1): 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 @@ -5,8 +5,6 @@ type_or_class = "type" mandatory_b_prefix = '' mandatory_u_prefix = 'u' - readbuf = str - bufchar = lambda x: x bytechr = chr class U(object): def __add__(self, other): @@ -20,11 +18,6 @@ unichr = chr mandatory_b_prefix = 'b' mandatory_u_prefix = '' - readbuf = lambda buf: buf.tobytes() - if sys.version_info < (3, 3): - bufchar = lambda x: bytes([ord(x)]) - else: - bufchar = ord bytechr = lambda n: bytes([n]) u = "" @@ -1811,36 +1804,76 @@ assert (p < s) ^ (p > s) def test_buffer(): + import __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() assert sizeof(BShort) == 2 - assert len(readbuf(buffer(s))) == 2 + assert len(buffer(s)) == 2 # BChar = new_primitive_type("char") BCharArray = new_array_type(new_pointer_type(BChar), None) c = newp(BCharArray, b"hi there") + # buf = buffer(c) - assert readbuf(buf) == b"hi there\x00" + assert str(buf).startswith('<_cffi_backend.buffer object at 0x') + # --mb_length-- assert len(buf) == len(b"hi there\x00") - assert buf[0] == bufchar('h') - assert buf[2] == bufchar(' ') - assert list(buf) == list(map(bufchar, "hi there\x00")) - buf[2] = bufchar('-') - assert c[2] == b'-' - assert readbuf(buf) == b"hi-there\x00" - c[2] = b'!' - assert buf[2] == bufchar('!') - assert readbuf(buf) == b"hi!there\x00" - c[2] = b'-' - buf[:2] = b'HI' - assert string(c) == b'HI-there' - if sys.version_info < (3,) or sys.version_info >= (3, 3): - assert buf[:4:2] == b'H-' - if '__pypy__' not in sys.builtin_module_names: - # XXX pypy doesn't support the following assignment so far - buf[:4:2] = b'XY' - assert string(c) == b'XIYthere' + # --mb_item-- + for i in range(-12, 12): + try: + expected = b"hi there\x00"[i] + except IndexError: + py.test.raises(IndexError, "buf[i]") + else: + assert buf[i] == expected + # --mb_slice-- + assert buf[:] == b"hi there\x00" + for i in range(-12, 12): + assert buf[i:] == b"hi there\x00"[i:] + assert buf[:i] == b"hi there\x00"[:i] + for j in range(-12, 12): + assert buf[i:j] == b"hi there\x00"[i:j] + # --misc-- + assert list(buf) == list(b"hi there\x00") + # --mb_as_buffer-- + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 + py.test.raises(TypeError, memoryview, c) + mv1 = memoryview(buf) + assert len(mv1) == len(buf) and mv1[3] == "t" + # --mb_ass_item-- + expected = list(b"hi there\x00") + for i in range(-12, 12): + try: + expected[i] = chr(i & 0xff) + except IndexError: + py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + else: + buf[i] = chr(i & 0xff) + assert list(buf) == expected + # --mb_ass_slice-- + buf[:] = b"hi there\x00" + assert list(buf) == list(c) == list(b"hi there\x00") + py.test.raises(ValueError, 'buf[:] = b"shorter"') + py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + buf[4:2] = b"" # no effect, but should work + assert buf[:] == b"hi there\x00" + expected = list(b"hi there\x00") + x = 0 + for i in range(-12, 12): + for j in range(-12, 12): + start = i if i >= 0 else i + len(buf) + stop = j if j >= 0 else j + len(buf) + start = max(0, min(len(buf), start)) + stop = max(0, min(len(buf), stop)) + sample = chr(x & 0xff) * (stop - start) + x += 1 + buf[i:j] = sample + expected[i:j] = sample + assert list(buf) == expected def test_getcname(): BUChar = new_primitive_type("unsigned char") diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -10,7 +10,8 @@ class AppTestBufferTooShort: def setup_class(cls): - space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal')) + space = gettestobjspace(usemodules=('_multiprocessing', 'thread', + 'signal', 'itertools')) cls.space = space if option.runappdirect: diff --git a/pypy/module/_multiprocessing/test/test_memory.py b/pypy/module/_multiprocessing/test/test_memory.py --- a/pypy/module/_multiprocessing/test/test_memory.py +++ b/pypy/module/_multiprocessing/test/test_memory.py @@ -3,7 +3,8 @@ class AppTestMemory: def setup_class(cls): space = gettestobjspace( - usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi')) + usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi', + 'itertools')) cls.space = space def test_address_of(self): 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 @@ -357,8 +357,8 @@ buffering = 1024 # minimum amount of compressed data read at once self.buffering = buffering - def close(self): - self.stream.close() + def close1(self, closefileno): + self.stream.close1(closefileno) def tell(self): return self.readlength @@ -479,9 +479,9 @@ self.compressor = W_BZ2Compressor(space, compresslevel) self.writtenlength = 0 - def close(self): + def close1(self, closefileno): self.stream.write(self.space.str_w(self.compressor.flush())) - self.stream.close() + self.stream.close1(closefileno) def write(self, data): self.stream.write(self.space.str_w(self.compressor.compress(data))) diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py --- a/pypy/module/cpyext/dictobject.py +++ b/pypy/module/cpyext/dictobject.py @@ -198,8 +198,8 @@ @specialize.memo() def make_frozendict(space): return space.appexec([], '''(): - import collections - class FrozenDict(collections.Mapping): + import _abcoll + class FrozenDict(_abcoll.Mapping): def __init__(self, *args, **kwargs): self._d = dict(*args, **kwargs) def __iter__(self): diff --git a/pypy/module/cpyext/test/test_import.py b/pypy/module/cpyext/test/test_import.py --- a/pypy/module/cpyext/test/test_import.py +++ b/pypy/module/cpyext/test/test_import.py @@ -4,9 +4,9 @@ class TestImport(BaseApiTest): def test_import(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - assert pdb - assert space.getattr(pdb, space.wrap("pm")) + stat = api.PyImport_Import(space.wrap("stat")) + assert stat + assert space.getattr(stat, space.wrap("S_IMODE")) def test_addmodule(self, space, api): with rffi.scoped_str2charp("sys") as modname: @@ -32,10 +32,10 @@ assert space.is_true(space.contains(w_dict, space.wrap(testmod))) def test_reload(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - space.delattr(pdb, space.wrap("set_trace")) - pdb = api.PyImport_ReloadModule(pdb) - assert space.getattr(pdb, space.wrap("set_trace")) + stat = api.PyImport_Import(space.wrap("stat")) + space.delattr(stat, space.wrap("S_IMODE")) + stat = api.PyImport_ReloadModule(stat) + assert space.getattr(stat, space.wrap("S_IMODE")) class AppTestImportLogic(AppTestCpythonExtensionBase): def test_import_logic(self): diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py --- a/pypy/module/imp/test/test_app.py +++ b/pypy/module/imp/test/test_app.py @@ -3,6 +3,8 @@ class AppTestImpModule: def setup_class(cls): + from pypy.conftest import gettestobjspace + cls.space = gettestobjspace(usemodules=('imp', 'itertools')) cls.w_imp = cls.space.getbuiltinmodule('imp') cls.w_file_module = cls.space.wrap(__file__) 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 @@ -38,7 +38,7 @@ test_reload = "def test():\n raise ValueError\n", infinite_reload = "import infinite_reload; reload(infinite_reload)", del_sys_module = "import sys\ndel sys.modules['del_sys_module']\n", - itertools = "hello_world = 42\n", + _md5 = "hello_world = 42\n", gc = "should_never_be_seen = 42\n", ) root.ensure("notapackage", dir=1) # empty, no __init__.py @@ -148,7 +148,7 @@ class AppTestImport: def setup_class(cls): # interpreter-level - cls.space = gettestobjspace(usemodules=['itertools']) + cls.space = gettestobjspace(usemodules=['_md5']) cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect) cls.saved_modules = _setup(cls.space) #XXX Compile class @@ -597,34 +597,34 @@ def test_shadow_extension_1(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find itertools.py if there is + # 'import _md5' is supposed to find _md5.py if there is # one in sys.path. import sys - assert 'itertools' not in sys.modules - import itertools - assert hasattr(itertools, 'hello_world') - assert not hasattr(itertools, 'count') - assert '(built-in)' not in repr(itertools) - del sys.modules['itertools'] + assert '_md5' not in sys.modules + import _md5 + assert hasattr(_md5, 'hello_world') + assert not hasattr(_md5, 'count') + assert '(built-in)' not in repr(_md5) + del sys.modules['_md5'] def test_shadow_extension_2(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find the built-in module even + # 'import _md5' is supposed to find the built-in module even # if there is also one in sys.path as long as it is *after* the # special entry '.../lib_pypy/__extensions__'. (Note that for now - # there is one in lib_pypy/itertools.py, which should not be seen + # there is one in lib_pypy/_md5.py, which should not be seen # either; hence the (built-in) test below.) import sys - assert 'itertools' not in sys.modules + assert '_md5' not in sys.modules sys.path.append(sys.path.pop(0)) try: - import itertools - assert not hasattr(itertools, 'hello_world') - assert hasattr(itertools, 'izip') - assert '(built-in)' in repr(itertools) + import _md5 + assert not hasattr(_md5, 'hello_world') + assert hasattr(_md5, 'digest_size') + assert '(built-in)' in repr(_md5) finally: sys.path.insert(0, sys.path.pop()) - del sys.modules['itertools'] + del sys.modules['_md5'] def test_invalid_pathname(self): import imp @@ -1005,7 +1005,7 @@ class AppTestImportHooks(object): def setup_class(cls): - space = cls.space = gettestobjspace(usemodules=('struct',)) + space = cls.space = gettestobjspace(usemodules=('struct', 'itertools')) mydir = os.path.dirname(__file__) cls.w_hooktest = space.wrap(os.path.join(mydir, 'hooktest')) space.appexec([space.wrap(mydir)], """ diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -6,7 +6,7 @@ class AppTestMath: def setup_class(cls): - cls.space = gettestobjspace(usemodules=['math', 'struct']) + cls.space = gettestobjspace(usemodules=['math', 'struct', 'itertools']) cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES) cls.w_consistent_host = cls.space.wrap(test_direct.consistent_host) 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 @@ -45,7 +45,7 @@ def __init__(self, array): self.array = array self.offset = array.start - self.skip = array.strides[0] + self.skip = array.get_strides()[0] self.dtype = array.dtype self.index = 0 self.size = array.get_shape()[0] @@ -116,8 +116,8 @@ class AxisIterator(base.BaseArrayIterator): def __init__(self, array, shape, dim): self.shape = shape - strides = array.strides - backstrides = array.backstrides + strides = array.get_strides() + backstrides = array.get_backstrides() if len(shape) == len(strides): # keepdims = True self.strides = strides[:dim] + [0] + strides[dim + 1:] @@ -167,12 +167,24 @@ class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None + + # JIT hints that length of all those arrays is a constant def get_shape(self): shape = self.shape jit.hint(len(shape), promote=True) return shape + def get_strides(self): + strides = self.strides + jit.hint(len(strides), promote=True) + return strides + + def get_backstrides(self): + backstrides = self.backstrides + jit.hint(len(backstrides), promote=True) + return backstrides + def getitem(self, index): return self.dtype.getitem(self, index) @@ -197,7 +209,7 @@ new_strides = None if self.size > 0: new_strides = calc_new_strides(new_shape, self.get_shape(), - self.strides, self.order) + self.get_strides(), self.order) if new_strides: # We can create a view, strides somehow match up. ndims = len(new_shape) @@ -214,6 +226,7 @@ @jit.unroll_safe def _lookup_by_index(self, space, view_w): item = self.start + strides = self.get_strides() for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError @@ -224,13 +237,14 @@ raise operationerrfmt(space.w_IndexError, "index (%d) out of range (0<=index<%d", i, self.get_shape()[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item @jit.unroll_safe def _lookup_by_unwrapped_index(self, space, lst): item = self.start shape = self.get_shape() + strides = self.get_strides() assert len(lst) == len(shape) for i, idx in enumerate(lst): if idx < 0: @@ -239,7 +253,7 @@ raise operationerrfmt(space.w_IndexError, "index (%d) out of range (0<=index<%d", i, shape[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item def getitem_index(self, space, index): @@ -344,8 +358,8 @@ backstrides = [] shape = [] for i in range(len(self.get_shape()) - 1, -1, -1): - strides.append(self.strides[i]) - backstrides.append(self.backstrides[i]) + strides.append(self.get_strides()[i]) + backstrides.append(self.get_backstrides()[i]) shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, backstrides, shape, self) @@ -361,14 +375,14 @@ return AxisIterator(self, shape, dim) def create_dot_iter(self, shape, skip): - r = calculate_dot_strides(self.strides, self.backstrides, + r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) return MultiDimViewIterator(self, self.start, r[0], r[1], shape) def swapaxes(self, axis1, axis2): shape = self.get_shape()[:] - strides = self.strides[:] - backstrides = self.backstrides[:] + strides = self.get_strides()[:] + backstrides = self.get_backstrides()[:] shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] @@ -394,7 +408,8 @@ def create_iter(self, shape=None): if shape is None or shape == self.get_shape(): return ConcreteArrayIterator(self) - r = calculate_broadcast_strides(self.strides, self.backstrides, + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), self.get_shape(), shape) return MultiDimViewIterator(self, 0, r[0], r[1], shape) @@ -430,14 +445,16 @@ def create_iter(self, shape=None): if shape is not None and shape != self.get_shape(): - r = calculate_broadcast_strides(self.strides, self.backstrides, + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), self.get_shape(), shape) return MultiDimViewIterator(self.parent, self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: return OneDimViewIterator(self) - return MultiDimViewIterator(self.parent, self.start, self.strides, - self.backstrides, self.get_shape()) + return MultiDimViewIterator(self.parent, self.start, + self.get_strides(), + self.get_backstrides(), self.get_shape()) def set_shape(self, space, new_shape): if len(self.get_shape()) < 2 or self.size == 0: @@ -446,7 +463,7 @@ strides = [] backstrides = [] dtype = self.dtype - s = self.strides[0] // dtype.get_size() + s = self.get_strides()[0] // dtype.get_size() if self.order == 'C': new_shape.reverse() for sh in new_shape: @@ -459,7 +476,8 @@ new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, self) - new_strides = calc_new_strides(new_shape, self.get_shape(), self.strides, + new_strides = calc_new_strides(new_shape, self.get_shape(), + self.get_strides(), self.order) if new_strides is None: raise OperationError(space.w_AttributeError, space.wrap( 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 @@ -275,14 +275,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - # Running entire test suite needs this function to succeed, - # running single test_stringarray succeeds without it. - # With convert_to() test_ztranslation fails since - # W_CharacterBox is not a W_GenericBox. - # Why is it needed for multiple tests? - #def convert_to(self, dtype): - # xxx - class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): from pypy.module.micronumpy.interp_dtype import new_unicode_dtype 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 @@ -59,8 +59,8 @@ def apply(self, arr): ofs, subdtype = arr.dtype.fields[self.name] # strides backstrides are identical, ofs only changes start - return W_NDimArray.new_slice(arr.start + ofs, arr.strides, - arr.backstrides, + return W_NDimArray.new_slice(arr.start + ofs, arr.get_strides(), + arr.get_backstrides(), arr.shape, arr, subdtype) class Chunks(BaseChunk): @@ -80,8 +80,8 @@ def apply(self, arr): shape = self.extend_shape(arr.shape) - r = calculate_slice_strides(arr.shape, arr.start, arr.strides, - arr.backstrides, self.l) + r = calculate_slice_strides(arr.shape, arr.start, arr.get_strides(), + arr.get_backstrides(), self.l) _, start, strides, backstrides = r return W_NDimArray.new_slice(start, strides[:], backstrides[:], shape[:], arr) diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -110,6 +110,7 @@ i //= shape[s] return coords, step, lngth + at jit.unroll_safe def shape_agreement(space, shape1, w_arr2, broadcast_down=True): if w_arr2 is None: return shape1 @@ -132,6 +133,7 @@ ) return ret + at jit.unroll_safe def _shape_agreement(shape1, shape2): """ Checks agreement about two shapes with respect to broadcasting. Returns the resulting shape. diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py --- a/pypy/module/micronumpy/support.py +++ b/pypy/module/micronumpy/support.py @@ -8,6 +8,7 @@ i *= x return i + at jit.unroll_safe def calc_strides(shape, dtype, order): strides = [] backstrides = [] diff --git a/pypy/module/test_lib_pypy/test_itertools.py b/pypy/module/test_lib_pypy/test_itertools.py --- a/pypy/module/test_lib_pypy/test_itertools.py +++ b/pypy/module/test_lib_pypy/test_itertools.py @@ -2,7 +2,7 @@ class AppTestItertools: def setup_class(cls): - cls.space = gettestobjspace() + cls.space = gettestobjspace(usemodules=['itertools']) cls.w_itertools = cls.space.appexec([], "(): import itertools; return itertools") def test_chain(self): diff --git a/pypy/module/test_lib_pypy/test_pwd.py b/pypy/module/test_lib_pypy/test_pwd.py --- a/pypy/module/test_lib_pypy/test_pwd.py +++ b/pypy/module/test_lib_pypy/test_pwd.py @@ -5,7 +5,8 @@ def setup_class(cls): if sys.platform == 'win32': py.test.skip("Unix only") - cls.space = gettestobjspace(usemodules=('_ffi', '_rawffi')) + cls.space = gettestobjspace(usemodules=('_ffi', '_rawffi', + 'itertools')) cls.space.appexec((), "(): import pwd") def test_getpwuid(self): diff --git a/pypy/module/zipimport/test/test_undocumented.py b/pypy/module/zipimport/test/test_undocumented.py --- a/pypy/module/zipimport/test/test_undocumented.py +++ b/pypy/module/zipimport/test/test_undocumented.py @@ -19,7 +19,8 @@ class AppTestZipImport: def setup_class(cls): - space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct']) + space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct', + 'itertools']) cls.space = space cls.w_created_paths = space.wrap(created_paths) diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -46,11 +46,10 @@ return __file__ """).compile() + usemodules = ['zipimport', 'rctime', 'struct', 'itertools'] if cls.compression == ZIP_DEFLATED: - space = gettestobjspace(usemodules=['zipimport', 'zlib', 'rctime', 'struct']) - else: - space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct']) - + usemodules.append('zlib') + space = gettestobjspace(usemodules=usemodules) cls.space = space tmpdir = udir.ensure('zipimport_%s' % cls.__name__, dir=1) now = time.time() diff --git a/pypy/objspace/std/test/test_iterobject.py b/pypy/objspace/std/test/test_iterobject.py --- a/pypy/objspace/std/test/test_iterobject.py +++ b/pypy/objspace/std/test/test_iterobject.py @@ -68,7 +68,7 @@ raises(TypeError, len, iter(iterable)) def test_no_len_on_deque_iter(self): - from collections import deque + from _collections import deque iterable = deque([1,2,3,4]) raises(TypeError, len, iter(iterable)) @@ -81,15 +81,14 @@ it = reversed([5,6,7]) raises(TypeError, len, it) - def test_no_len_on_UserList_iter(self): + def test_no_len_on_UserList_iter_reversed(self): + import sys, _abcoll + sys.modules['collections'] = _abcoll from UserList import UserList iterable = UserList([1,2,3,4]) raises(TypeError, len, iter(iterable)) - - def test_no_len_on_UserList_reversed(self): - from UserList import UserList - iterable = UserList([1,2,3,4]) raises(TypeError, len, reversed(iterable)) + del sys.modules['collections'] def test_no_len_on_set_iter(self): iterable = set([1,2,3,4]) diff --git a/pypy/objspace/std/test/test_methodcache.py b/pypy/objspace/std/test/test_methodcache.py --- a/pypy/objspace/std/test/test_methodcache.py +++ b/pypy/objspace/std/test/test_methodcache.py @@ -206,8 +206,3 @@ setattr(a, "a%s" % i, i) cache_counter = __pypy__.method_cache_counter("x") assert cache_counter[0] == 0 # 0 hits, because all the attributes are new - - def test_get_module_from_namedtuple(self): - # this used to crash - from collections import namedtuple - assert namedtuple("a", "b").__module__ diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py --- a/pypy/objspace/std/test/test_typeobject.py +++ b/pypy/objspace/std/test/test_typeobject.py @@ -1063,6 +1063,21 @@ A.__dict__['x'] = 5 assert A.x == 5 + +class AppTestWithMethodCacheCounter: + def setup_class(cls): + cls.space = gettestobjspace( + **{"objspace.std.withmethodcachecounter": True}) + + def test_module_from_handbuilt_type(self): + d = {'tuple': tuple, '__name__': 'foomod'} + exec """class foo(tuple): pass""" in d + t = d['foo'] + t.__module__ = 'barmod' + # this last line used to crash; see ab926f846f39 + assert t.__module__ + + class AppTestMutableBuiltintypes: def setup_class(cls): diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -119,6 +119,17 @@ self.size = size or len(digits) self.sign = sign + # __eq__ and __ne__ method exist for testingl only, they are not RPython! + def __eq__(self, other): + # NOT_RPYTHON + if not isinstance(other, rbigint): + return NotImplemented + return self.eq(other) + + def __ne__(self, other): + # NOT_RPYTHON + return not (self == other) + def digit(self, x): """Return the x'th digit, as an int.""" return self._digits[x] diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -1,14 +1,19 @@ from __future__ import division + +import operator +import sys +from random import random, randint, sample + import py -import operator, sys, array -from random import random, randint, sample -from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF -from pypy.rlib.rbigint import _store_digit, _mask_digit -from pypy.rlib.rfloat import NAN + from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask +from pypy.rlib.rbigint import (rbigint, SHIFT, MASK, KARATSUBA_CUTOFF, + _store_digit, _mask_digit) +from pypy.rlib.rfloat import NAN from pypy.rpython.test.test_llinterp import interpret + class TestRLong(object): def test_simple(self): for op1 in [-2, -1, 0, 1, 2, 50]: @@ -112,6 +117,17 @@ rl = rbigint.fromint(sys.maxint).add(rbigint.fromint(42)) assert rl.touint() == result + def test_eq_ne_operators(self): + a1 = rbigint.fromint(12) + a2 = rbigint.fromint(12) + a3 = rbigint.fromint(123) + + assert a1 == a2 + assert a1 != a3 + assert not (a1 != a2) + assert not (a1 == a3) + + def gen_signs(l): for s in l: if s == 0: From noreply at buildbot.pypy.org Tue Oct 30 00:49:34 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 30 Oct 2012 00:49:34 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Oops, move TinyObjSpace as well, to fix -A tests. Message-ID: <20121029234934.72C311C039C@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58628:a69f63c9603d Date: 2012-10-30 00:49 +0100 http://bitbucket.org/pypy/pypy/changeset/a69f63c9603d/ Log: Oops, move TinyObjSpace as well, to fix -A tests. diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -72,85 +72,6 @@ spaceconfig = getattr(request.cls, 'spaceconfig', {}) return gettestobjspace(**spaceconfig) -class TinyObjSpace(object): - def __init__(self, **kwds): - import sys - info = getattr(sys, 'pypy_translation_info', None) - for key, value in kwds.iteritems(): - if key == 'usemodules': - if info is not None: - for modname in value: - ok = info.get('objspace.usemodules.%s' % modname, - False) - if not ok: - py.test.skip("cannot runappdirect test: " - "module %r required" % (modname,)) - else: - if '__pypy__' in value: - py.test.skip("no module __pypy__ on top of CPython") - continue - if info is None: - py.test.skip("cannot runappdirect this test on top of CPython") - has = info.get(key, None) - if has != value: - #print sys.pypy_translation_info - py.test.skip("cannot runappdirect test: space needs %s = %s, "\ - "while pypy-c was built with %s" % (key, value, has)) - - for name in ('int', 'long', 'str', 'unicode', 'None'): - setattr(self, 'w_' + name, eval(name)) - - - def appexec(self, args, body): - body = body.lstrip() - assert body.startswith('(') - src = py.code.Source("def anonymous" + body) - d = {} - exec src.compile() in d - return d['anonymous'](*args) - - def wrap(self, obj): - return obj - - def unpackiterable(self, itr): - return list(itr) - - def is_true(self, obj): - return bool(obj) - - def str_w(self, w_str): - return w_str - - def newdict(self, module=None): - return {} - - def newtuple(self, iterable): - return tuple(iterable) - - def newlist(self, iterable): - return list(iterable) - - def call_function(self, func, *args, **kwds): - return func(*args, **kwds) - - def call_method(self, obj, name, *args, **kwds): - return getattr(obj, name)(*args, **kwds) - - def getattr(self, obj, name): - return getattr(obj, name) - - def setattr(self, obj, name, value): - setattr(obj, name, value) - - def getbuiltinmodule(self, name): - return __import__(name) - - def delslice(self, obj, *args): - obj.__delslice__(*args) - - def is_w(self, obj1, obj2): - return obj1 is obj2 - def translation_test_so_skip_if_appdirect(): if option.runappdirect: py.test.skip("translation test, skipped for appdirect") diff --git a/pypy/tool/pytest/objspace.py b/pypy/tool/pytest/objspace.py --- a/pypy/tool/pytest/objspace.py +++ b/pypy/tool/pytest/objspace.py @@ -44,3 +44,83 @@ space.eq_w = appsupport.eq_w.__get__(space) return space + +class TinyObjSpace(object): + """An object space that delegates everything to the hosting Python.""" + def __init__(self, **kwds): + import sys + info = getattr(sys, 'pypy_translation_info', None) + for key, value in kwds.iteritems(): + if key == 'usemodules': + if info is not None: + for modname in value: + ok = info.get('objspace.usemodules.%s' % modname, + False) + if not ok: + py.test.skip("cannot runappdirect test: " + "module %r required" % (modname,)) + else: + if '__pypy__' in value: + py.test.skip("no module __pypy__ on top of CPython") + continue + if info is None: + py.test.skip("cannot runappdirect this test on top of CPython") + has = info.get(key, None) + if has != value: + #print sys.pypy_translation_info + py.test.skip("cannot runappdirect test: space needs %s = %s, "\ + "while pypy-c was built with %s" % (key, value, has)) + + for name in ('int', 'long', 'str', 'unicode', 'None'): + setattr(self, 'w_' + name, eval(name)) + + def appexec(self, args, body): + body = body.lstrip() + assert body.startswith('(') + src = py.code.Source("def anonymous" + body) + d = {} + exec src.compile() in d + return d['anonymous'](*args) + + def wrap(self, obj): + return obj + + def unpackiterable(self, itr): + return list(itr) + + def is_true(self, obj): + return bool(obj) + + def str_w(self, w_str): + return w_str + + def newdict(self, module=None): + return {} + + def newtuple(self, iterable): + return tuple(iterable) + + def newlist(self, iterable): + return list(iterable) + + def call_function(self, func, *args, **kwds): + return func(*args, **kwds) + + def call_method(self, obj, name, *args, **kwds): + return getattr(obj, name)(*args, **kwds) + + def getattr(self, obj, name): + return getattr(obj, name) + + def setattr(self, obj, name, value): + setattr(obj, name, value) + + def getbuiltinmodule(self, name): + return __import__(name) + + def delslice(self, obj, *args): + obj.__delslice__(*args) + + def is_w(self, obj1, obj2): + return obj1 is obj2 + From noreply at buildbot.pypy.org Tue Oct 30 10:52:30 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 30 Oct 2012 10:52:30 +0100 (CET) Subject: [pypy-commit] cffi default: Fixes for Python 3: the easy part (thanks Gabriel). Message-ID: <20121030095230.B19021C0ECC@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1019:e46ecf80c64f Date: 2012-10-30 10:52 +0100 http://bitbucket.org/cffi/cffi/changeset/e46ecf80c64f/ Log: Fixes for Python 3: the easy part (thanks Gabriel). diff --git a/c/minibuffer.h b/c/minibuffer.h --- a/c/minibuffer.h +++ b/c/minibuffer.h @@ -32,7 +32,7 @@ if (left < 0) left = 0; if (right > size) right = size; if (left > right) left = right; - return PyString_FromStringAndSize(self->mb_data + left, right - left); + return PyBytes_FromStringAndSize(self->mb_data + left, right - left); } static int mb_ass_item(MiniBufferObj *self, Py_ssize_t idx, PyObject *other) @@ -78,6 +78,7 @@ return 0; } +#if PY_MAJOR_VERSION < 3 static Py_ssize_t mb_getdata(MiniBufferObj *self, Py_ssize_t idx, void **pp) { *pp = self->mb_data; @@ -90,6 +91,7 @@ *lenp = self->mb_size; return 1; } +#endif static int mb_getbuf(MiniBufferObj *self, Py_buffer *view, int flags) { @@ -108,14 +110,22 @@ }; static PyBufferProcs mb_as_buffer = { +#if PY_MAJOR_VERSION < 3 (readbufferproc)mb_getdata, (writebufferproc)mb_getdata, (segcountproc)mb_getsegcount, (charbufferproc)mb_getdata, +#endif (getbufferproc)mb_getbuf, (releasebufferproc)0, }; +#if PY_MAJOR_VERSION >= 3 +# define MINIBUF_TPFLAGS (Py_TPFLAGS_DEFAULT) +#else +# define MINIBUF_TPFLAGS (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER) +#endif + static PyTypeObject MiniBuffer_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_cffi_backend.buffer", @@ -136,8 +146,7 @@ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ &mb_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | - Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */ + MINIBUF_TPFLAGS, /* tp_flags */ }; static PyObject *minibuffer_new(char *data, Py_ssize_t size) From noreply at buildbot.pypy.org Tue Oct 30 12:17:01 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 30 Oct 2012 12:17:01 +0100 (CET) Subject: [pypy-commit] cffi default: Progress for Python 3, but not done Message-ID: <20121030111701.751891C0229@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1020:adc872f1af4f Date: 2012-10-30 12:16 +0100 http://bitbucket.org/cffi/cffi/changeset/adc872f1af4f/ Log: Progress for Python 3, but not done diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -207,6 +207,10 @@ #include "minibuffer.h" +#if PY_MAJOR_VERSION >= 3 +# include "file_emulator.h" +#endif + #ifdef HAVE_WCHAR_H # include "wchar_helper.h" #endif @@ -1729,8 +1733,10 @@ /* from a unicode, we add the null terminator */ length = _my_PyUnicode_SizeAsWideChar(init) + 1; } - else if (PyFile_Check(init) && (ctitem->ct_flags & CT_IS_FILE)) { + else if ((ctitem->ct_flags & CT_IS_FILE) && PyFile_Check(init)) { output_data[0] = (char *)PyFile_AsFile(init); + if (output_data[0] == NULL && PyErr_Occurred()) + return -1; return 1; } else { @@ -2462,9 +2468,13 @@ return new_simple_cdata(cdsrc->c_data, ct); } } - if (PyFile_Check(ob) && (ct->ct_flags & CT_POINTER) && - (ct->ct_itemdescr->ct_flags & CT_IS_FILE)) { - return new_simple_cdata((char *)PyFile_AsFile(ob), ct); + if ((ct->ct_flags & CT_POINTER) && + (ct->ct_itemdescr->ct_flags & CT_IS_FILE) && + PyFile_Check(ob)) { + FILE *f = PyFile_AsFile(ob); + if (f == NULL && PyErr_Occurred()) + return NULL; + return new_simple_cdata((char *)f, ct); } value = _my_PyLong_AsUnsignedLongLong(ob, 0); if (value == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) @@ -4599,8 +4609,9 @@ { char *result; if (convert_from_object((char *)&result, ct, obj) < 0) { - if (PyFile_Check(obj) && (ct->ct_flags & CT_POINTER) && - (ct->ct_itemdescr->ct_flags & CT_IS_FILE)) { + if ((ct->ct_flags & CT_POINTER) && + (ct->ct_itemdescr->ct_flags & CT_IS_FILE) && + PyFile_Check(obj)) { PyErr_Clear(); return (char *)PyFile_AsFile(obj); } diff --git a/c/file_emulator.h b/c/file_emulator.h new file mode 100644 --- /dev/null +++ b/c/file_emulator.h @@ -0,0 +1,78 @@ + +/* Emulation of PyFile_Check() and PyFile_AsFile() for Python 3. */ + +extern PyTypeObject PyIOBase_Type; + + +#define PyFile_Check(p) PyObject_IsInstance(p, (PyObject *)&PyIOBase_Type) + + +void _close_file_capsule(PyObject *ob_capsule) +{ + FILE *f = (FILE *)PyCapsule_GetPointer(ob_capsule, "FILE"); + if (f != NULL) + fclose(f); +} + + +static FILE *PyFile_AsFile(PyObject *ob_file) +{ + PyObject *ob, *ob_capsule = NULL, *ob_mode = NULL; + FILE *f = NULL; + int fd; + char *mode; + _Py_IDENTIFIER(flush); + _Py_IDENTIFIER(mode); + _Py_IDENTIFIER(__cffi_FILE); + + ob = _PyObject_CallMethodId(ob_file, &PyId_flush, NULL); + if (ob == NULL) + goto fail; + Py_DECREF(ob); + + ob_capsule = _PyObject_GetAttrId(ob_file, &PyId___cffi_FILE); + if (ob_capsule == NULL) { + PyErr_Clear(); + + fd = PyObject_AsFileDescriptor(ob_file); + if (fd < 0) + goto fail; + + ob_mode = _PyObject_GetAttrId(ob_file, &PyId_mode); + if (ob_mode == NULL) + goto fail; + mode = PyText_AsUTF8(ob_mode); + if (mode == NULL) + goto fail; + + fd = dup(fd); + if (fd < 0) { + PyErr_SetFromErrno(PyExc_OSError); + goto fail; + } + + f = fdopen(fd, mode); + if (f == NULL) { + close(fd); + PyErr_SetFromErrno(PyExc_OSError); + goto fail; + } + Py_DECREF(ob_mode); + ob_mode = NULL; + + ob_capsule = PyCapsule_New(f, "FILE", _close_file_capsule); + if (ob_capsule == NULL) { + fclose(f); + goto fail; + } + + if (_PyObject_SetAttrId(ob_file, &PyId___cffi_FILE, ob_capsule) < 0) + goto fail; + } + return PyCapsule_GetPointer(ob_capsule, "FILE"); + + fail: + Py_XDECREF(ob_mode); + Py_XDECREF(ob_capsule); + return NULL; +} diff --git a/c/minibuffer.h b/c/minibuffer.h --- a/c/minibuffer.h +++ b/c/minibuffer.h @@ -121,6 +121,83 @@ }; #if PY_MAJOR_VERSION >= 3 +/* pfffffffffffff pages of copy-paste from listobject.c */ +static PyObject *mb_subscript(MiniBufferObj *self, PyObject *item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += self->mb_size; + return mb_item(self, i); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx(item, self->mb_size, + &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (step == 1) + return mb_slice(self, start, stop); + else { + PyErr_SetString(PyExc_TypeError, + "buffer doesn't support slicing with step != 1"); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, + "buffer indices must be integers, not %.200s", + item->ob_type->tp_name); + return NULL; + } +} +static int +mb_ass_subscript(MiniBufferObj* self, PyObject* item, PyObject* value) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += self->mb_size; + return mb_ass_item(self, i, value); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx(item, self->mb_size, + &start, &stop, &step, &slicelength) < 0) { + return -1; + } + + if (step == 1) + return mb_ass_slice(self, start, stop, value); + else { + PyErr_SetString(PyExc_TypeError, + "buffer doesn't support slicing with step != 1"); + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, + "buffer indices must be integers, not %.200s", + item->ob_type->tp_name); + return -1; + } +} + +static PyMappingMethods mb_as_mapping = { + (lenfunc)mb_length, /*mp_length*/ + (binaryfunc)mb_subscript, /*mp_subscript*/ + (objobjargproc)mb_ass_subscript, /*mp_ass_subscript*/ +}; +#endif + +#if PY_MAJOR_VERSION >= 3 # define MINIBUF_TPFLAGS (Py_TPFLAGS_DEFAULT) #else # define MINIBUF_TPFLAGS (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER) @@ -139,7 +216,11 @@ 0, /* tp_repr */ 0, /* tp_as_number */ &mb_as_sequence, /* tp_as_sequence */ +#if PY_MAJOR_VERSION < 3 0, /* tp_as_mapping */ +#else + &mb_as_mapping, /* tp_as_mapping */ +#endif 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -10,6 +10,7 @@ mandatory_b_prefix = '' mandatory_u_prefix = 'u' bytechr = chr + bitem2bchr = lambda x: x class U(object): def __add__(self, other): return eval('u'+repr(other).replace(r'\\u', r'\u') @@ -23,6 +24,7 @@ mandatory_b_prefix = 'b' mandatory_u_prefix = '' bytechr = lambda n: bytes([n]) + bitem2bchr = bytechr u = "" def size_of_int(): @@ -1808,7 +1810,10 @@ assert (p < s) ^ (p > s) def test_buffer(): - import __builtin__ + try: + import __builtin__ + except ImportError: + import builtins as __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() @@ -1830,7 +1835,7 @@ except IndexError: py.test.raises(IndexError, "buf[i]") else: - assert buf[i] == expected + assert buf[i] == bitem2bchr(expected) # --mb_slice-- assert buf[:] == b"hi there\x00" for i in range(-12, 12): @@ -1839,33 +1844,34 @@ for j in range(-12, 12): assert buf[i:j] == b"hi there\x00"[i:j] # --misc-- - assert list(buf) == list(b"hi there\x00") + assert list(buf) == list(map(bitem2bchr, b"hi there\x00")) # --mb_as_buffer-- - py.test.raises(TypeError, __builtin__.buffer, c) - bf1 = __builtin__.buffer(buf) - assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'buffer'): # Python <= 2.7 + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 py.test.raises(TypeError, memoryview, c) mv1 = memoryview(buf) - assert len(mv1) == len(buf) and mv1[3] == "t" + assert len(mv1) == len(buf) and mv1[3] in (b"t", ord(b"t")) # --mb_ass_item-- - expected = list(b"hi there\x00") + expected = list(map(bitem2bchr, b"hi there\x00")) for i in range(-12, 12): try: - expected[i] = chr(i & 0xff) + expected[i] = bytechr(i & 0xff) except IndexError: - py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") else: - buf[i] = chr(i & 0xff) + buf[i] = bytechr(i & 0xff) assert list(buf) == expected # --mb_ass_slice-- buf[:] = b"hi there\x00" - assert list(buf) == list(c) == list(b"hi there\x00") + assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) py.test.raises(ValueError, 'buf[:] = b"shorter"') py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" - expected = list(b"hi there\x00") + expected = list(map(bitem2bchr, b"hi there\x00")) x = 0 for i in range(-12, 12): for j in range(-12, 12): @@ -1873,10 +1879,10 @@ stop = j if j >= 0 else j + len(buf) start = max(0, min(len(buf), start)) stop = max(0, min(len(buf), stop)) - sample = chr(x & 0xff) * (stop - start) + sample = bytechr(x & 0xff) * (stop - start) x += 1 buf[i:j] = sample - expected[i:j] = sample + expected[i:j] = map(bitem2bchr, sample) assert list(buf) == expected def test_getcname(): @@ -2249,6 +2255,11 @@ assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] +# XXX hack +if sys.version_info >= (3,): + import posix, io + posix.fdopen = io.open + def test_FILE(): if sys.platform == "win32": py.test.skip("testing FILE not implemented") @@ -2266,8 +2277,8 @@ # import posix fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r', 256) - fw1 = posix.fdopen(fdw, 'w', 256) + fr1 = posix.fdopen(fdr, 'rb', 256) + fw1 = posix.fdopen(fdw, 'wb', 256) # fw1.write(b"X") res = fputs(b"hello world\n", fw1) From noreply at buildbot.pypy.org Tue Oct 30 12:45:05 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 30 Oct 2012 12:45:05 +0100 (CET) Subject: [pypy-commit] cffi default: Two hours of debugging... Message-ID: <20121030114505.5A8CF1C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1021:bc5a570ba696 Date: 2012-10-30 12:42 +0100 http://bitbucket.org/cffi/cffi/changeset/bc5a570ba696/ Log: Two hours of debugging... diff --git a/c/file_emulator.h b/c/file_emulator.h --- a/c/file_emulator.h +++ b/c/file_emulator.h @@ -57,6 +57,7 @@ PyErr_SetFromErrno(PyExc_OSError); goto fail; } + setbuf(f, NULL); /* non-buffered */ Py_DECREF(ob_mode); ob_mode = NULL; From noreply at buildbot.pypy.org Tue Oct 30 12:45:06 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 30 Oct 2012 12:45:06 +0100 (CET) Subject: [pypy-commit] cffi default: Fix tests. Message-ID: <20121030114506.70C431C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1022:c7af62d13de6 Date: 2012-10-30 12:44 +0100 http://bitbucket.org/cffi/cffi/changeset/c7af62d13de6/ Log: Fix tests. diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2310,8 +2310,9 @@ fw1 = posix.fdopen(fdw, 'w') # e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not file") + assert str(e.value).startswith( + "initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not ") def test_FILE_object(): if sys.platform == "win32": @@ -2338,7 +2339,7 @@ res = fputs(b"hello\n", fw1p) assert res >= 0 res = fileno(fw1p) - assert res == fdw + assert (res == fdw) == (sys.version_info < (3,)) fw1.close() # data = posix.read(fdr, 256) From noreply at buildbot.pypy.org Tue Oct 30 12:47:14 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 30 Oct 2012 12:47:14 +0100 (CET) Subject: [pypy-commit] pypy default: For now, disable buffering on the FILE object, to avoid issues. Message-ID: <20121030114714.F09D81C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58629:4fe5af46568b Date: 2012-10-30 12:42 +0100 http://bitbucket.org/pypy/pypy/changeset/4fe5af46568b/ Log: For now, disable buffering on the FILE object, to avoid issues. 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 @@ -323,6 +323,7 @@ rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void) rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) class CffiFileObj(object): @@ -331,6 +332,7 @@ self.llf = rffi_fdopen(fd, mode) if not self.llf: raise OSError(rposix.get_errno(), "fdopen failed") + rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) def close(self): rffi_fclose(self.llf) From noreply at buildbot.pypy.org Tue Oct 30 12:47:16 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 30 Oct 2012 12:47:16 +0100 (CET) Subject: [pypy-commit] pypy default: Import from cffi/c7af62d13de6. Message-ID: <20121030114716.31A0B1C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58630:8a242b9aecdf Date: 2012-10-30 12:46 +0100 http://bitbucket.org/pypy/pypy/changeset/8a242b9aecdf/ Log: Import from cffi/c7af62d13de6. 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 @@ -6,6 +6,7 @@ mandatory_b_prefix = '' mandatory_u_prefix = 'u' bytechr = chr + bitem2bchr = lambda x: x class U(object): def __add__(self, other): return eval('u'+repr(other).replace(r'\\u', r'\u') @@ -19,6 +20,7 @@ mandatory_b_prefix = 'b' mandatory_u_prefix = '' bytechr = lambda n: bytes([n]) + bitem2bchr = bytechr u = "" def size_of_int(): @@ -1804,7 +1806,10 @@ assert (p < s) ^ (p > s) def test_buffer(): - import __builtin__ + try: + import __builtin__ + except ImportError: + import builtins as __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() @@ -1826,7 +1831,7 @@ except IndexError: py.test.raises(IndexError, "buf[i]") else: - assert buf[i] == expected + assert buf[i] == bitem2bchr(expected) # --mb_slice-- assert buf[:] == b"hi there\x00" for i in range(-12, 12): @@ -1835,33 +1840,34 @@ for j in range(-12, 12): assert buf[i:j] == b"hi there\x00"[i:j] # --misc-- - assert list(buf) == list(b"hi there\x00") + assert list(buf) == list(map(bitem2bchr, b"hi there\x00")) # --mb_as_buffer-- - py.test.raises(TypeError, __builtin__.buffer, c) - bf1 = __builtin__.buffer(buf) - assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'buffer'): # Python <= 2.7 + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 py.test.raises(TypeError, memoryview, c) mv1 = memoryview(buf) - assert len(mv1) == len(buf) and mv1[3] == "t" + assert len(mv1) == len(buf) and mv1[3] in (b"t", ord(b"t")) # --mb_ass_item-- - expected = list(b"hi there\x00") + expected = list(map(bitem2bchr, b"hi there\x00")) for i in range(-12, 12): try: - expected[i] = chr(i & 0xff) + expected[i] = bytechr(i & 0xff) except IndexError: - py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") else: - buf[i] = chr(i & 0xff) + buf[i] = bytechr(i & 0xff) assert list(buf) == expected # --mb_ass_slice-- buf[:] = b"hi there\x00" - assert list(buf) == list(c) == list(b"hi there\x00") + assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) py.test.raises(ValueError, 'buf[:] = b"shorter"') py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" - expected = list(b"hi there\x00") + expected = list(map(bitem2bchr, b"hi there\x00")) x = 0 for i in range(-12, 12): for j in range(-12, 12): @@ -1869,10 +1875,10 @@ stop = j if j >= 0 else j + len(buf) start = max(0, min(len(buf), start)) stop = max(0, min(len(buf), stop)) - sample = chr(x & 0xff) * (stop - start) + sample = bytechr(x & 0xff) * (stop - start) x += 1 buf[i:j] = sample - expected[i:j] = sample + expected[i:j] = map(bitem2bchr, sample) assert list(buf) == expected def test_getcname(): @@ -2245,6 +2251,11 @@ assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] +# XXX hack +if sys.version_info >= (3,): + import posix, io + posix.fdopen = io.open + def test_FILE(): if sys.platform == "win32": py.test.skip("testing FILE not implemented") @@ -2262,8 +2273,8 @@ # import posix fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r', 256) - fw1 = posix.fdopen(fdw, 'w', 256) + fr1 = posix.fdopen(fdr, 'rb', 256) + fw1 = posix.fdopen(fdw, 'wb', 256) # fw1.write(b"X") res = fputs(b"hello world\n", fw1) @@ -2295,8 +2306,9 @@ fw1 = posix.fdopen(fdw, 'w') # e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not file") + assert str(e.value).startswith( + "initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not ") def test_FILE_object(): if sys.platform == "win32": @@ -2323,7 +2335,7 @@ res = fputs(b"hello\n", fw1p) assert res >= 0 res = fileno(fw1p) - assert res == fdw + assert (res == fdw) == (sys.version_info < (3,)) fw1.close() # data = posix.read(fdr, 256) From noreply at buildbot.pypy.org Tue Oct 30 12:47:17 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 30 Oct 2012 12:47:17 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121030114717.69A211C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58631:780e2e44a0fd Date: 2012-10-30 12:46 +0100 http://bitbucket.org/pypy/pypy/changeset/780e2e44a0fd/ Log: merge heads diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -110,6 +110,7 @@ i //= shape[s] return coords, step, lngth + at jit.unroll_safe def shape_agreement(space, shape1, w_arr2, broadcast_down=True): if w_arr2 is None: return shape1 @@ -132,6 +133,7 @@ ) return ret + at jit.unroll_safe def _shape_agreement(shape1, shape2): """ Checks agreement about two shapes with respect to broadcasting. Returns the resulting shape. diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py --- a/pypy/module/micronumpy/support.py +++ b/pypy/module/micronumpy/support.py @@ -8,6 +8,7 @@ i *= x return i + at jit.unroll_safe def calc_strides(shape, dtype, order): strides = [] backstrides = [] From noreply at buildbot.pypy.org Tue Oct 30 12:50:04 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 30 Oct 2012 12:50:04 +0100 (CET) Subject: [pypy-commit] cffi default: Improve the test: this should pass too. Message-ID: <20121030115004.CE5DB1C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1023:b516da9bebb9 Date: 2012-10-30 12:49 +0100 http://bitbucket.org/cffi/cffi/changeset/b516da9bebb9/ Log: Improve the test: this should pass too. diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2283,13 +2283,14 @@ fw1.write(b"X") res = fputs(b"hello world\n", fw1) assert res >= 0 - fw1.close() + fw1.flush() # should not be needed # p = newp(new_array_type(BCharP, 100), None) res = fscanf(fr1, b"%s\n", p) assert res == 1 assert string(p) == b"Xhello" fr1.close() + fw1.close() def test_FILE_only_for_FILE_arg(): if sys.platform == "win32": From noreply at buildbot.pypy.org Tue Oct 30 12:50:24 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 30 Oct 2012 12:50:24 +0100 (CET) Subject: [pypy-commit] pypy default: Import cffi/b516da9bebb9. Message-ID: <20121030115024.7257F1C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58632:08971293d572 Date: 2012-10-30 12:50 +0100 http://bitbucket.org/pypy/pypy/changeset/08971293d572/ Log: Import cffi/b516da9bebb9. 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 @@ -2279,13 +2279,14 @@ fw1.write(b"X") res = fputs(b"hello world\n", fw1) assert res >= 0 - fw1.close() + fw1.flush() # should not be needed # p = newp(new_array_type(BCharP, 100), None) res = fscanf(fr1, b"%s\n", p) assert res == 1 assert string(p) == b"Xhello" fr1.close() + fw1.close() def test_FILE_only_for_FILE_arg(): if sys.platform == "win32": From noreply at buildbot.pypy.org Tue Oct 30 15:08:51 2012 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 30 Oct 2012 15:08:51 +0100 (CET) Subject: [pypy-commit] cffi default: Fix the tests for Python 3. Message-ID: <20121030140851.781C81C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1024:568b239a7824 Date: 2012-10-30 15:08 +0100 http://bitbucket.org/cffi/cffi/changeset/568b239a7824/ Log: Fix the tests for Python 3. diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -9,11 +9,6 @@ SIZE_OF_PTR = ctypes.sizeof(ctypes.c_void_p) SIZE_OF_WCHAR = ctypes.sizeof(ctypes.c_wchar) -if sys.version_info < (3, 3): - bufitem = lambda x: x -else: - bufitem = ord - class BackendTests: @@ -1078,12 +1073,12 @@ assert len(content) == len(b) == 2 if sys.byteorder == 'little': assert content == b'\x64\x00' - assert b[0] == bufitem(b'\x64') - b[0] = bufitem(b'\x65') + assert b[0] == b'\x64' + b[0] = b'\x65' else: assert content == b'\x00\x64' - assert b[1] == bufitem(b'\x64') - b[1] = bufitem(b'\x65') + assert b[1] == b'\x64' + b[1] = b'\x65' assert a[0] == 101 def test_ffi_buffer_array(self): @@ -1096,10 +1091,10 @@ content = b[:] if sys.byteorder == 'little': assert content.startswith(b'\x64\x00\x00\x00\x65\x00\x00\x00') - b[4] = bufitem(b'\x45') + b[4] = b'\x45' else: assert content.startswith('\x00\x00\x00\x64\x00\x00\x00\x65') - b[7] = bufitem(b'\x45') + b[7] = b'\x45' assert len(content) == 4 * 10 assert a[1] == 0x45 @@ -1114,11 +1109,11 @@ assert len(content) == 1 if sys.byteorder == 'little': assert content == b'\x43' - b[0] = bufitem(b'\x62') + b[0] = b'\x62' assert a[0] == 0x4262 else: assert content == b'\x42' - b[0] = bufitem(b'\x63') + b[0] = b'\x63' assert a[0] == 0x6343 def test_ffi_buffer_array_size(self): diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1234,9 +1234,9 @@ return result; } """) - import posix - fdr, fdw = posix.pipe() - fw1 = posix.fdopen(fdw, 'wb', 256) + import os + fdr, fdw = os.pipe() + fw1 = os.fdopen(fdw, 'wb', 256) old_stdout = lib.setstdout(fw1) try: # @@ -1248,9 +1248,11 @@ finally: lib.setstdout(old_stdout) # - result = posix.read(fdr, 256) - posix.close(fdr) - assert result == b"Xhello, 42!\n" + result = os.read(fdr, 256) + os.close(fdr) + # the 'X' might remain in the user-level buffer of 'fw1' and + # end up showing up after the 'hello, 42!\n' + assert result == b"Xhello, 42!\n" or result == b"hello, 42!\nX" def test_FILE_stored_explicitly(): ffi = FFI() @@ -1262,9 +1264,9 @@ return fprintf(myfile, out, value); } """) - import posix - fdr, fdw = posix.pipe() - fw1 = posix.fdopen(fdw, 'wb', 256) + import os + fdr, fdw = os.pipe() + fw1 = os.fdopen(fdw, 'wb', 256) lib.myfile = ffi.cast("FILE *", fw1) # fw1.write(b"X") @@ -1272,9 +1274,11 @@ fw1.close() assert r == len("hello, 42!\n") # - result = posix.read(fdr, 256) - posix.close(fdr) - assert result == b"Xhello, 42!\n" + result = os.read(fdr, 256) + os.close(fdr) + # the 'X' might remain in the user-level buffer of 'fw1' and + # end up showing up after the 'hello, 42!\n' + assert result == b"Xhello, 42!\n" or result == b"hello, 42!\nX" def test_global_array_with_missing_length(): ffi = FFI() From noreply at buildbot.pypy.org Wed Oct 31 01:15:10 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 31 Oct 2012 01:15:10 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: Fix many tests Message-ID: <20121031001510.D7B6C1C00FA@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58633:ab670ceeeffe Date: 2012-10-31 01:13 +0100 http://bitbucket.org/pypy/pypy/changeset/ab670ceeeffe/ Log: Fix many tests diff --git a/pypy/interpreter/test/test_code.py b/pypy/interpreter/test/test_code.py --- a/pypy/interpreter/test/test_code.py +++ b/pypy/interpreter/test/test_code.py @@ -8,8 +8,8 @@ if filename[-3:] != '.py': filename = filename[:-1] - cls.w_file = space.wrap(filename) - cls.w_CO_CONTAINSGLOBALS = space.wrap(consts.CO_CONTAINSGLOBALS) + cls.w_file = cls.space.wrap(filename) + cls.w_CO_CONTAINSGLOBALS = cls.space.wrap(consts.CO_CONTAINSGLOBALS) def test_attributes(self): def f(): pass diff --git a/pypy/interpreter/test/test_zzpickle_and_slow.py b/pypy/interpreter/test/test_zzpickle_and_slow.py --- a/pypy/interpreter/test/test_zzpickle_and_slow.py +++ b/pypy/interpreter/test/test_zzpickle_and_slow.py @@ -13,7 +13,7 @@ if filename[-3:] != '.py': filename = filename[:-1] - cls.w_file = space.wrap(filename) + cls.w_file = cls.space.wrap(filename) def test_inspect(self): if not hasattr(len, 'func_code'): diff --git a/pypy/module/_io/test/test_io.py b/pypy/module/_io/test/test_io.py --- a/pypy/module/_io/test/test_io.py +++ b/pypy/module/_io/test/test_io.py @@ -5,7 +5,7 @@ class AppTestIoModule: spaceconfig = dict(usemodules=['_io']) -xo + def test_import(self): import io diff --git a/pypy/module/crypt/test/test_crypt.py b/pypy/module/crypt/test/test_crypt.py --- a/pypy/module/crypt/test/test_crypt.py +++ b/pypy/module/crypt/test/test_crypt.py @@ -1,7 +1,7 @@ class AppTestCrypt: spaceconfig = dict(usemodules=['crypt']) - def test_crypt(self): + def test_crypt(self): import crypt res = crypt.crypt("pass", "ab") assert isinstance(res, str) 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 @@ -5,7 +5,8 @@ import pypy.interpreter.pycode from pypy.tool.udir import udir from pypy.rlib import streamio -from pypy.tool.option import make_config, make_objspace +from pypy.tool.option import make_config +from pypy.tool.pytest.objspace import maketestobjspace import pytest import sys, os import tempfile, marshal @@ -642,8 +643,8 @@ class TestAbi: def test_abi_tag(self): - space1 = make_objspace(make_config(None, soabi='TEST')) - space2 = make_objspace(make_config(None, soabi='')) + space1 = maketestobjspace(make_config(None, soabi='TEST')) + space2 = maketestobjspace(make_config(None, soabi='')) if sys.platform == 'win32': assert importing.get_so_extension(space1) == '.TESTi.pyd' assert importing.get_so_extension(space2) == '.pyd' @@ -953,7 +954,7 @@ allspaces = [self.space] for opcodename in self.space.config.objspace.opcodes.getpaths(): key = 'objspace.opcodes.' + opcodename - space2 = make_objspace(make_config(None, **{key: True})) + space2 = maketestobjspace(make_config(None, **{key: True})) allspaces.append(space2) for space1 in allspaces: for space2 in allspaces: 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 @@ -126,7 +126,7 @@ class AppTestSysModulePortedFromCPython: def setup_class(cls): - cls.w_appdirect = cls.wrap(cls.runappdirect) + cls.w_appdirect = cls.space.wrap(cls.runappdirect) def test_original_displayhook(self): import sys, cStringIO, __builtin__ @@ -596,7 +596,7 @@ class AppTestSysExcInfoDirect: def setup_method(self, meth): - self.checking = not self.option.runappdirect + self.checking = not self.runappdirect if self.checking: self.seen = [] from pypy.module.sys import vm 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 @@ -1,5 +1,5 @@ class AppTestNumpy: - space_config = dict(usemodules=['micronumpy']) + spaceconfig = dict(usemodules=['micronumpy']) def test_imports(self): try: diff --git a/pypy/objspace/std/test/test_proxy_internals.py b/pypy/objspace/std/test/test_proxy_internals.py --- a/pypy/objspace/std/test/test_proxy_internals.py +++ b/pypy/objspace/std/test/test_proxy_internals.py @@ -6,6 +6,9 @@ class AppProxy(object): spaceconfig = {"objspace.std.withtproxy": True} + def setup_class(cls): + pass # So that subclasses can call the super method. + def setup_method(self, meth): self.w_get_proxy = self.space.appexec([], """(): class Controller(object): diff --git a/pypy/objspace/std/test/test_strsliceobject.py b/pypy/objspace/std/test/test_strsliceobject.py --- a/pypy/objspace/std/test/test_strsliceobject.py +++ b/pypy/objspace/std/test/test_strsliceobject.py @@ -5,7 +5,7 @@ from pypy.objspace.std.strsliceobject import W_StringSliceObject class AppTestStringObject(test_stringobject.AppTestStringObject): - space_config = {"objspace.std.withstrslice": True} + spaceconfig = {"objspace.std.withstrslice": True} def setup_class(cls): def not_forced(space, w_s): From noreply at buildbot.pypy.org Wed Oct 31 01:15:12 2012 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 31 Oct 2012 01:15:12 +0100 (CET) Subject: [pypy-commit] pypy less-gettestobjspace: hg merge default Message-ID: <20121031001512.4BD081C0185@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: less-gettestobjspace Changeset: r58634:1dbceccf1a90 Date: 2012-10-31 01:14 +0100 http://bitbucket.org/pypy/pypy/changeset/1dbceccf1a90/ Log: hg merge default diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -323,6 +323,7 @@ rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void) rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) class CffiFileObj(object): @@ -331,6 +332,7 @@ self.llf = rffi_fdopen(fd, mode) if not self.llf: raise OSError(rposix.get_errno(), "fdopen failed") + rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) def close(self): rffi_fclose(self.llf) 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 @@ -6,6 +6,7 @@ mandatory_b_prefix = '' mandatory_u_prefix = 'u' bytechr = chr + bitem2bchr = lambda x: x class U(object): def __add__(self, other): return eval('u'+repr(other).replace(r'\\u', r'\u') @@ -19,6 +20,7 @@ mandatory_b_prefix = 'b' mandatory_u_prefix = '' bytechr = lambda n: bytes([n]) + bitem2bchr = bytechr u = "" def size_of_int(): @@ -1804,7 +1806,10 @@ assert (p < s) ^ (p > s) def test_buffer(): - import __builtin__ + try: + import __builtin__ + except ImportError: + import builtins as __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() @@ -1826,7 +1831,7 @@ except IndexError: py.test.raises(IndexError, "buf[i]") else: - assert buf[i] == expected + assert buf[i] == bitem2bchr(expected) # --mb_slice-- assert buf[:] == b"hi there\x00" for i in range(-12, 12): @@ -1835,33 +1840,34 @@ for j in range(-12, 12): assert buf[i:j] == b"hi there\x00"[i:j] # --misc-- - assert list(buf) == list(b"hi there\x00") + assert list(buf) == list(map(bitem2bchr, b"hi there\x00")) # --mb_as_buffer-- - py.test.raises(TypeError, __builtin__.buffer, c) - bf1 = __builtin__.buffer(buf) - assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'buffer'): # Python <= 2.7 + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 py.test.raises(TypeError, memoryview, c) mv1 = memoryview(buf) - assert len(mv1) == len(buf) and mv1[3] == "t" + assert len(mv1) == len(buf) and mv1[3] in (b"t", ord(b"t")) # --mb_ass_item-- - expected = list(b"hi there\x00") + expected = list(map(bitem2bchr, b"hi there\x00")) for i in range(-12, 12): try: - expected[i] = chr(i & 0xff) + expected[i] = bytechr(i & 0xff) except IndexError: - py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") else: - buf[i] = chr(i & 0xff) + buf[i] = bytechr(i & 0xff) assert list(buf) == expected # --mb_ass_slice-- buf[:] = b"hi there\x00" - assert list(buf) == list(c) == list(b"hi there\x00") + assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) py.test.raises(ValueError, 'buf[:] = b"shorter"') py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" - expected = list(b"hi there\x00") + expected = list(map(bitem2bchr, b"hi there\x00")) x = 0 for i in range(-12, 12): for j in range(-12, 12): @@ -1869,10 +1875,10 @@ stop = j if j >= 0 else j + len(buf) start = max(0, min(len(buf), start)) stop = max(0, min(len(buf), stop)) - sample = chr(x & 0xff) * (stop - start) + sample = bytechr(x & 0xff) * (stop - start) x += 1 buf[i:j] = sample - expected[i:j] = sample + expected[i:j] = map(bitem2bchr, sample) assert list(buf) == expected def test_getcname(): @@ -2245,6 +2251,11 @@ assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] +# XXX hack +if sys.version_info >= (3,): + import posix, io + posix.fdopen = io.open + def test_FILE(): if sys.platform == "win32": py.test.skip("testing FILE not implemented") @@ -2262,19 +2273,20 @@ # import posix fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r', 256) - fw1 = posix.fdopen(fdw, 'w', 256) + fr1 = posix.fdopen(fdr, 'rb', 256) + fw1 = posix.fdopen(fdw, 'wb', 256) # fw1.write(b"X") res = fputs(b"hello world\n", fw1) assert res >= 0 - fw1.close() + fw1.flush() # should not be needed # p = newp(new_array_type(BCharP, 100), None) res = fscanf(fr1, b"%s\n", p) assert res == 1 assert string(p) == b"Xhello" fr1.close() + fw1.close() def test_FILE_only_for_FILE_arg(): if sys.platform == "win32": @@ -2295,8 +2307,9 @@ fw1 = posix.fdopen(fdw, 'w') # e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not file") + assert str(e.value).startswith( + "initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not ") def test_FILE_object(): if sys.platform == "win32": @@ -2323,7 +2336,7 @@ res = fputs(b"hello\n", fw1p) assert res >= 0 res = fileno(fw1p) - assert res == fdw + assert (res == fdw) == (sys.version_info < (3,)) fw1.close() # data = posix.read(fdr, 256) From noreply at buildbot.pypy.org Wed Oct 31 09:59:06 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 09:59:06 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: Tweaks Message-ID: <20121031085906.72A881C01DB@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58635:9a21fc7f0ca1 Date: 2012-10-30 14:49 +0100 http://bitbucket.org/pypy/pypy/changeset/9a21fc7f0ca1/ Log: Tweaks diff --git a/pypy/jit/backend/llsupport/jitframe.py b/pypy/jit/backend/llsupport/jitframe.py --- a/pypy/jit/backend/llsupport/jitframe.py +++ b/pypy/jit/backend/llsupport/jitframe.py @@ -12,6 +12,7 @@ # For the front-end: a GCREF for the savedata ('jf_savedata', llmemory.GCREF), - # XXX + # All values are stored in the following array. ('jf_values', lltype.Array(llmemory.Address))) + JITFRAMEPTR = lltype.Ptr(JITFRAME) diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -39,6 +39,8 @@ """ NOT_RPYTHON this is for tests only! """ cls = opclasses[opnum] + if 0 <= cls.NUMARGS <= 3: + assert len(args) == cls.NUMARGS if cls.NUMARGS == 0: return create_resop_0(opnum, result, descr, mutable=mutable) elif cls.NUMARGS == 1: From noreply at buildbot.pypy.org Wed Oct 31 09:59:08 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 09:59:08 +0100 (CET) Subject: [pypy-commit] pypy no-failargs: Tentative (may be reverted): change FINISH to take 0 argument. Message-ID: <20121031085908.078531C01DB@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: no-failargs Changeset: r58636:d331eab8d5af Date: 2012-10-31 09:58 +0100 http://bitbucket.org/pypy/pypy/changeset/d331eab8d5af/ Log: Tentative (may be reverted): change FINISH to take 0 argument. diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -260,7 +260,7 @@ except ExecutionFinished, e: frame.finish_value = e.arg frame.latest_descr = e.descr - frame._execution_finished_normally = e.descr.fast_path_done + frame._fast_path_done = e.descr.fast_path_done return frame except GuardFailed, e: frame.latest_descr = e.descr @@ -274,13 +274,6 @@ def get_latest_descr(self, frame): return frame.latest_descr - def get_finish_value_int(self, frame): - res = frame.finish_value - del frame.finish_value - return res - get_finish_value_float = get_finish_value_int - get_finish_value_ref = get_finish_value_int - def grab_exc_value(self, frame): if frame.last_exception is not None: result = frame.last_exception.args[1] @@ -484,7 +477,7 @@ def bh_getinteriorfield_gc(self, a, index, descr): if isinstance(descr, JFValueDescr): assert isinstance(a, LLFrame) - return a.latest_values[index] + return a.framecontent[index] array = a._obj.container return support.cast_result(descr.FIELD, getattr(array.getitem(index), descr.fieldname)) @@ -623,7 +616,7 @@ return isinstance(other, LLFrame) and self is other _forced = False - _execution_finished_normally = False + _fast_path_done = False finish_value = None def __init__(self, cpu, argboxes, args): @@ -674,9 +667,9 @@ args = [self.lookup(arg) for arg in op.getarglist()] self.current_op = op # for label self.current_index = i + execute = getattr(self, 'execute_' + op.getopname()) try: - resval = getattr(self, 'execute_' + op.getopname())( - _getdescr(op), *args) + resval = execute(_getdescr(op), *args) except Jump, j: self.lltrace, i = j.descr._llgraph_target label_op = self.lltrace.operations[i] @@ -876,32 +869,35 @@ execute_call_release_gil_v = execute_call_release_gil def execute_call_assembler(self, descr, *args): + # pframe = CALL_ASSEMBLER(args..., descr=looptoken) + # ==> + # pframe = CALL looptoken.loopaddr(*args) + # JUMP_IF_NOT_CARRY @forward + # pframe = CALL assembler_call_helper(pframe) + # @forward: + # + # CARRY is set before most returns, and cleared only + # on FINISH with descr.fast_path_done. + # call_op = self.lltrace.operations[self.current_index] guard_op = self.lltrace.operations[self.current_index + 1] assert guard_op.getopnum() == rop.GUARD_NOT_FORCED self.latest_descr = _getdescr(guard_op) # - frame = self.cpu._execute_token(descr, *args) - if frame._execution_finished_normally: # fast path - result = frame.finish_value - else: + pframe = self.cpu._execute_token(descr, *args) + if not pframe._fast_path_done: jd = descr.outermost_jitdriver_sd assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish try: - result = assembler_helper_ptr(frame) + result = assembler_helper_ptr(pframe) except LLException, lle: assert self.last_exception is None, "exception left behind" self.last_exception = lle - if self.current_op.result is not None: - return _example_res[self.current_op.result.type] - return None + return lltype.nullptr(llmemory.GCREF.TO) + assert result is pframe # del self.latest_descr - return support.cast_result(lltype.typeOf(result), result) - execute_call_assembler_i = execute_call_assembler - execute_call_assembler_r = execute_call_assembler - execute_call_assembler_f = execute_call_assembler - execute_call_assembler_v = execute_call_assembler + return pframe def execute_same_as(self, _, x): return x diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py --- a/pypy/jit/backend/model.py +++ b/pypy/jit/backend/model.py @@ -138,18 +138,10 @@ Returns a GCREF.""" raise NotImplementedError - def get_finish_value_int(self, jitframe): - """Return the result passed to FINISH, which was an int.""" - raise NotImplementedError - - def get_finish_value_float(self, jitframe): - """Return the result passed to FINISH, which was a FLOATSTORAGE.""" - raise NotImplementedError - - def get_finish_value_ref(self, jitframe): - """Return and clear the result passed to FINISH, which was a GCREF. - Also used when it exits due to a failure of a GUARD_EXCEPTION or - GUARD_NO_EXCEPTION, to return the exception.""" + def grab_exc_value(self, jitframe): + """Return and clear the exception set by the latest execute_token(), + when it exits due to a failure of a GUARD_EXCEPTION or + GUARD_NO_EXCEPTION. (Returns a GCREF)""" raise NotImplementedError def get_savedata_ref(self, jitframe): diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -27,10 +27,8 @@ _autoindex = 0 def execute_operation(self, opname, valueboxes, result_type, descr=None): - inputargs, operations = self._get_single_operation_list(opname, - result_type, - valueboxes, - descr) + inputargs, operations, opresult = self._get_single_operation_list( + opname, result_type, valueboxes, descr) oparser.assign_all_varindices(inputargs + operations) looptoken = JitCellToken() self.cpu.compile_loop(inputargs, operations, looptoken) @@ -50,20 +48,13 @@ self.guard_failed = False else: self.guard_failed = True - if result_type == 'int': - return self.cpu.get_finish_value_int(frame) - elif result_type == 'ref': - return self.cpu.get_finish_value_ref(frame) - elif result_type == 'float': - x = self.cpu.get_finish_value_float(frame) - return longlong.getrealfloat(x) - elif result_type == 'longlong': - assert longlong.supports_longlong - return self.cpu.get_finish_value_float(frame) - elif result_type == 'void': + if result_type != 'void': + res = self.get_frame_value(frame, str(opresult)) + if result_type == 'float': + res = longlong.getrealfloat(res) + return res + else: return None - else: - assert False def _get_single_operation_list(self, opnum, result_type, valueboxes, descr): @@ -79,12 +70,8 @@ raise ValueError(result_type) op0 = create_resop_dispatch(opnum, result, valueboxes, mutable=True) - if result is None: - results = [] - else: - results = [op0] - op1 = create_resop(rop.FINISH, None, results, descr=BasicFailDescr(0), - mutable=True) + op1 = create_resop_0(rop.FINISH, None, descr=BasicFailDescr(0), + mutable=True) if op0.is_guard(): if not descr: descr = BasicFailDescr(1) @@ -92,7 +79,7 @@ op0.setdescr(descr) inputargs = [box for box in valueboxes if not box.is_constant()] inputargs = list(set(inputargs)) - return inputargs, [op0, op1] + return inputargs, [op0, op1], op0 def _duplicate_boxes(self, inputargs): seen = {} @@ -141,11 +128,11 @@ inputargs, ops, token = self.parse(""" [i0] i1 = int_add(i0, 1) - finish(i1, descr=faildescr) + finish(descr=faildescr) """, namespace=locals()) self.cpu.compile_loop(inputargs, ops, token) frame = self.cpu.execute_token(token, 2) - res = self.cpu.get_finish_value_int(frame) + res = self.get_frame_value(frame, 'i1') assert res == 3 assert self.cpu.get_latest_descr(frame).identifier == 1 @@ -154,11 +141,11 @@ inputargs, ops, token = self.parse(""" [f0] f2 = float_add(f0, 1.) - finish(f2, descr=faildescr) + finish(descr=faildescr) """, namespace=locals()) self.cpu.compile_loop(inputargs, ops, token) frame = self.cpu.execute_token(token, longlong.getfloatstorage(2.8)) - res = self.cpu.get_finish_value_float(frame) + res = self.get_frame_value(frame, 'f2') assert longlong.getrealfloat(res) == 3.8 assert self.cpu.get_latest_descr(frame).identifier == 1 @@ -291,54 +278,26 @@ namespace = {'faildescr': faildescr} inputargs, operations, looptoken = self.parse(""" [i0] - finish(i0, descr=faildescr) + finish(descr=faildescr) """, namespace=namespace) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 99) assert self.cpu.get_latest_descr(frame) is faildescr - res = self.cpu.get_finish_value_int(frame) + res = self.get_frame_value(frame, 'i0') assert res == 99 - inputargs, operations, looptoken = self.parse(""" - [] - finish(42, descr=faildescr) - """, namespace=namespace) - self.cpu.compile_loop(inputargs, operations, looptoken) - frame = self.cpu.execute_token(looptoken) - assert self.cpu.get_latest_descr(frame) is faildescr - res = self.cpu.get_finish_value_int(frame) - assert res == 42 - - _, operations, looptoken = self.parse(""" - [] - finish(descr=faildescr) - """, namespace=namespace) - self.cpu.compile_loop([], operations, looptoken) - frame = self.cpu.execute_token(looptoken) - assert self.cpu.get_latest_descr(frame) is faildescr - if self.cpu.supports_floats: inputargs, operations, looptoken = self.parse(""" [f0] - finish(f0, descr=faildescr) + finish(descr=faildescr) """, namespace) self.cpu.compile_loop(inputargs, operations, looptoken) value = longlong.getfloatstorage(-61.25) frame = self.cpu.execute_token(looptoken, value) assert self.cpu.get_latest_descr(frame) is faildescr - res = self.cpu.get_finish_value_float(frame) + res = self.get_frame_value(frame, 'f0') assert longlong.getrealfloat(res) == -61.25 - _, operations, looptoken = self.parse(""" - [] - finish(42.5, descr=faildescr) - """, namespace) - self.cpu.compile_loop([], operations, looptoken) - frame = self.cpu.execute_token(looptoken) - assert self.cpu.get_latest_descr(frame) is faildescr - res = self.cpu.get_finish_value_float(frame) - assert longlong.getrealfloat(res) == 42.5 - def test_execute_operations_in_env(self): cpu = self.cpu inputargs, operations, looptoken = self.parse(""" @@ -386,7 +345,7 @@ [i1, i2] i3 = %s(i1, i2) guard_no_overflow(descr=faildescr1) - finish(i3, descr=faildescr2) + finish(descr=faildescr2) """ % op, namespace={'faildescr1': BasicFailDescr(1), 'faildescr2': BasicFailDescr(2)}) else: @@ -406,10 +365,7 @@ else: assert self.cpu.get_latest_descr(frame).identifier == 2 if z != boom: - if not reversed: - assert self.cpu.get_finish_value_int(frame) == z - else: - assert self.get_frame_value(frame, 'i3') == z + assert self.get_frame_value(frame, 'i3') == z def test_ovf_operations_reversed(self): self.test_ovf_operations(reversed=True) @@ -1112,8 +1068,8 @@ operations[-1]._varindex = 2 * k # operations.append( - create_resop(rop.FINISH, None, [], descr=faildescr, - mutable=True) + create_resop_0(rop.FINISH, None, descr=faildescr, + mutable=True) ) oparser.assign_all_varindices(inputargs + operations) print inputargs @@ -1311,8 +1267,8 @@ op0 = create_resop_1(opname, 0, box) op1 = create_resop_1(opguard, None, op0, mutable=True) op1.setdescr(faildescr1) - op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, - mutable=True) + op2 = create_resop_0(rop.FINISH, None, descr=faildescr2, + mutable=True) operations = [op0, op1, op2] looptoken = JitCellToken() oparser.assign_all_varindices(inputargs + operations) @@ -1357,8 +1313,8 @@ op0 = create_resop_2(opname, 0, ibox1, ibox2) op1 = create_resop_1(opguard, None, op0, mutable=True) op1.setdescr(faildescr1) - op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, - mutable=True) + op2 = create_resop_0(rop.FINISH, None, descr=faildescr2, + mutable=True) operations = [op0, op1, op2] oparser.assign_all_varindices(inputargs + operations) looptoken = JitCellToken() @@ -1409,8 +1365,8 @@ op0 = create_resop_2(opname, 0, ibox1, ibox2) op1 = create_resop_1(opguard, None, op0, descr=faildescr1, mutable=True) - op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, - mutable=True) + op2 = create_resop_0(rop.FINISH, None, descr=faildescr2, + mutable=True) operations = [op0, op1, op2] looptoken = JitCellToken() oparser.assign_all_varindices(inputargs + operations) @@ -1465,8 +1421,8 @@ op0 = create_resop_2(opname, 0, fbox1, fbox2) op1 = create_resop_1(opguard, None, op0, mutable=True) op1.setdescr(faildescr1) - op2 = create_resop(rop.FINISH, None, [], descr=faildescr2, - mutable=True) + op2 = create_resop_0(rop.FINISH, None, descr=faildescr2, + mutable=True) operations = [op0, op1, op2] looptoken = JitCellToken() oparser.assign_all_varindices(inputargs + operations) @@ -1526,8 +1482,8 @@ # Unique-ify inputargs inputargs = list(set(inputargs)) faildescr = BasicFailDescr(1) - operations.append(create_resop(rop.FINISH, None, [], - descr=faildescr, mutable=True)) + operations.append(create_resop_0(rop.FINISH, None, + descr=faildescr, mutable=True)) looptoken = JitCellToken() oparser.assign_all_varindices(inputargs + operations) # @@ -1594,9 +1550,9 @@ op1 = create_resop_1(guard_opnum, None, op0, mutable=True) op1.setdescr(BasicFailDescr(4)) - op2 = create_resop(rop.FINISH, None, [], - descr=BasicFailDescr(5), - mutable=True) + op2 = create_resop_0(rop.FINISH, None, + descr=BasicFailDescr(5), + mutable=True) operations = [op0, op1, op2] looptoken = JitCellToken() # Use "set" to unique-ify inputargs @@ -1884,7 +1840,7 @@ i1 = same_as_i(1) call_v(ConstClass(fptr), i0, descr=calldescr) p2 = guard_exception(ConstClass(xtp), descr=faildescr2) - finish(p2, descr=faildescr1) + finish(descr=faildescr1) ''' FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) fptr = llhelper(FPTR, func) @@ -1906,7 +1862,7 @@ inputargs, operations, looptoken = self.parse(ops, namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 1) - assert self.cpu.get_finish_value_ref(frame) == xptr + assert self.get_frame_value(frame, 'p2') == xptr frame = self.cpu.execute_token(looptoken, 0) assert self.get_frame_value(frame, "i1") == 1 excvalue = self.cpu.grab_exc_value(frame) @@ -1937,7 +1893,7 @@ i1 = same_as_i(1) call_v(ConstClass(fptr), i0, descr=calldescr) guard_no_exception(descr=faildescr1) - finish(-100, descr=faildescr2) + finish(descr=faildescr2) ''' inputargs, operations, looptoken = self.parse(ops, namespace=locals()) self.cpu.compile_loop(inputargs, operations, looptoken) @@ -1946,7 +1902,7 @@ excvalue = self.cpu.grab_exc_value(frame) assert excvalue == xptr frame = self.cpu.execute_token(looptoken, 0) - assert self.cpu.get_finish_value_int(frame) == -100 + assert self.cpu.get_latest_descr(frame) is faildescr2 def test_cond_call_gc_wb(self): def func_void(a): @@ -2124,12 +2080,12 @@ ptok = jit_frame() call_may_force_v(ConstClass(func_ptr), ptok, i1, descr=calldescr) guard_not_forced(descr=faildescr) - finish(i0, descr=faildescr0) + finish(descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 - assert self.cpu.get_finish_value_int(frame) == 20 + assert self.get_frame_value(frame, "i0") == 20 assert values == [] frame = self.cpu.execute_token(looptoken, 10, 1) @@ -2160,12 +2116,12 @@ ptok = jit_frame() i2 = call_may_force_i(ConstClass(func_ptr), ptok, i1, descr=calldescr) guard_not_forced(descr=faildescr) - finish(i2, descr=faildescr0) + finish(descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 - assert self.cpu.get_finish_value_int(frame) == 42 + assert self.get_frame_value(frame, "i2") == 42 assert values == [] frame = self.cpu.execute_token(looptoken, 10, 1) @@ -2199,12 +2155,12 @@ ptok = jit_frame() f2 = call_may_force_f(ConstClass(func_ptr), ptok, i1, descr=calldescr) guard_not_forced(descr=faildescr) - finish(f2, descr=faildescr0) + finish(descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) assert self.cpu.get_latest_descr(frame).identifier == 0 - x = self.cpu.get_finish_value_float(frame) + x = self.get_frame_value(frame, "f2") assert longlong.getrealfloat(x) == 42.5 assert values == [] @@ -2220,7 +2176,7 @@ inputargs, operations, looptoken = self.parse(''' [i1, i2] p0 = jit_frame() - finish(p0, descr=faildescr1) + finish(descr=faildescr1) ''', namespace={'faildescr1': finishdescr}) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, 20, 0) @@ -2246,12 +2202,12 @@ [i1] i2 = call_release_gil_i(ConstClass(func_adr), i1, descr=calldescr) guard_not_forced(descr=faildescr) - finish(i2, descr=faildescr0) + finish(descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, operations, looptoken) frame = self.cpu.execute_token(looptoken, ord('G')) assert self.cpu.get_latest_descr(frame).identifier == 0 - assert self.cpu.get_finish_value_int(frame) == ord('g') + assert self.get_frame_value(frame, "i2") == ord('g') def test_call_to_c_function_with_callback(self): from pypy.rlib.libffi import CDLL, types, ArgChain, clibffi @@ -2371,13 +2327,14 @@ inputargs, ops, looptoken = self.parse(""" [i0, i1] guard_not_invalidated(descr=faildescr) - finish(i0, descr=faildescr0) + i2 = int_add(i0, 2) + finish(descr=faildescr0) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) frame = self.cpu.execute_token(looptoken, -42, 9) assert self.cpu.get_latest_descr(frame).identifier == 0 - assert self.cpu.get_finish_value_int(frame) == -42 + assert self.get_frame_value(frame, "i2") == -40 print 'step 1 ok' print '-'*79 @@ -2397,13 +2354,14 @@ inputargs, ops, _ = self.parse(""" [i1] guard_not_invalidated(descr=faildescr2) - finish(i1, descr=faildescr3) + i3 = int_add(i1, 1000) + finish(descr=faildescr3) """, locals()) self.cpu.compile_bridge(faildescr, inputargs, ops, looptoken) frame = self.cpu.execute_token(looptoken, -42, 9) assert self.cpu.get_latest_descr(frame).identifier == 3 - assert self.cpu.get_finish_value_int(frame) == 9 + assert self.get_frame_value(frame, "i3") == 1009 print 'step 3 ok' print '-'*79 @@ -2426,7 +2384,8 @@ [i0] guard_not_invalidated(descr=faildescr) label(i0, descr=labeldescr) - finish(i0, descr=faildescr3) + i1 = int_add(i0, 100) + finish(descr=faildescr3) """, locals()) self.cpu.compile_loop(inputargs, ops, looptoken) # mark as failing @@ -2440,7 +2399,8 @@ # run: must not be caught in an infinite loop frame = self.cpu.execute_token(looptoken, 16) assert self.cpu.get_latest_descr(frame).identifier == 3 - assert self.cpu.get_finish_value_int(frame) == 333 + assert self.get_frame_value(frame, "i0") == 333 + assert self.get_frame_value(frame, "i1") == 433 # pure do_ / descr features @@ -2615,10 +2575,11 @@ faildescr = self.cpu.get_latest_descr(jitframe) failindex = self.cpu.get_fail_descr_number(faildescr) called.append(failindex) - return 4 + 9 + self.cpu.set_latest_descr(xxxxxx) + return jitframe FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], - lltype.Signed)) + llmemory.GCREF)) class FakeJitDriverSD: _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper) assembler_helper_adr = llmemory.cast_ptr_to_adr( @@ -2639,7 +2600,7 @@ i16 = int_add(i15, i7) i17 = int_add(i16, i8) i18 = int_add(i17, i9) - finish(i18, descr=faildescr1)''' + finish(descr=faildescr1)''' inputargs, operations, looptoken = self.parse( ops, namespace={'faildescr1': BasicFailDescr(1)}) operations[-1].getdescr().fast_path_done = True @@ -2654,16 +2615,19 @@ EffectInfo.MOST_GENERAL) args = [i+1 for i in range(10)] frame = self.cpu.execute_token(looptoken, *args) - assert self.cpu.get_finish_value_int(frame) == 55 + assert self.get_frame_value(frame, "i18") == 55 ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] i10 = int_add(i0, 42) - i11 = call_assembler_i(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, descr=looptoken) + p11 = call_assembler(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, descr=looptoken) guard_not_forced(descr=faildescr1) - finish(i11, descr=faildescr2) + i13 = getinteriorfield_gc_i(p11, 18, descr=jfdescr_for_int) + i12 = int_add(i13, 1000) + finish(descr=faildescr2) ''' faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) + jfdescr_for_int = self.cpu.jfdescr_for_int otherargs, otheroperations, othertoken = self.parse( ops, namespace=locals()) @@ -2671,14 +2635,15 @@ self.cpu.compile_loop(otherargs, otheroperations, othertoken) args = [i+1 for i in range(10)] frame = self.cpu.execute_token(othertoken, *args) - res = self.cpu.get_finish_value_int(frame) - assert res == 97 + res = self.get_frame_value(frame, "i12") + assert res == 1097 assert called == [] # test the slow path, going via assembler_helper() args[1] = sys.maxint frame = self.cpu.execute_token(othertoken, *args) - assert self.cpu.get_finish_value_int(frame) == 13 + res = self.get_frame_value(frame, "i12") + assert res == 1013 assert called == [fail_number] def test_assembler_call_float(self): diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py --- a/pypy/jit/metainterp/executor.py +++ b/pypy/jit/metainterp/executor.py @@ -320,10 +320,7 @@ execute[value] = func continue if value in (rop.JIT_FRAME, - rop.CALL_ASSEMBLER_i, - rop.CALL_ASSEMBLER_r, - rop.CALL_ASSEMBLER_f, - rop.CALL_ASSEMBLER_v, + rop.CALL_ASSEMBLER, rop.COND_CALL_GC_WB, rop.COND_CALL_GC_WB_ARRAY, rop.DEBUG_MERGE_POINT, diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -1232,7 +1232,7 @@ '_FINAL_FIRST', 'JUMP/*d/v', - 'FINISH/*d/v', + 'FINISH/0d/v', '_FINAL_LAST', 'LABEL/*d/v', @@ -1385,7 +1385,7 @@ '_CANRAISE_FIRST', # ----- start of can_raise operations ----- '_CALL_FIRST', 'CALL/*d/*', - 'CALL_ASSEMBLER/*d/*', # call already compiled assembler + 'CALL_ASSEMBLER/*d/r', # call already compiled assembler 'CALL_MAY_FORCE/*d/*', 'CALL_LOOPINVARIANT/*d/*', 'CALL_RELEASE_GIL/*d/*', # release the GIL and "close the stack" for asmgcc From noreply at buildbot.pypy.org Wed Oct 31 15:11:03 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 31 Oct 2012 15:11:03 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: conjugate Message-ID: <20121031141103.412021C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58637:02887579c3d1 Date: 2012-10-29 15:46 +0100 http://bitbucket.org/pypy/pypy/changeset/02887579c3d1/ Log: conjugate 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 @@ -422,10 +422,6 @@ loop.clip(space, self, shape, min, max, out) return out - def descr_conj(self, space): - raise OperationError(space.w_NotImplementedError, space.wrap( - "conj not implemented yet")) - def descr_ctypes(self, space): raise OperationError(space.w_NotImplementedError, space.wrap( "ctypes not implemented yet")) @@ -467,10 +463,6 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "getfield not implemented yet")) - def descr_imag(self, space): - raise OperationError(space.w_NotImplementedError, space.wrap( - "imag not implemented yet")) - def descr_itemset(self, space, w_arg): raise OperationError(space.w_NotImplementedError, space.wrap( "itemset not implemented yet")) @@ -488,10 +480,6 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "put not implemented yet")) - def descr_real(self, space): - raise OperationError(space.w_NotImplementedError, space.wrap( - "real not implemented yet")) - def descr_resize(self, space, w_new_shape, w_refcheck=True): raise OperationError(space.w_NotImplementedError, space.wrap( "resize not implemented yet")) @@ -557,6 +545,8 @@ descr_get_real = _unaryop_impl("real") descr_get_imag = _unaryop_impl("imag") + descr_conj = _unaryop_impl('conjugate') + def descr_nonzero(self, space): if self.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap( @@ -804,6 +794,7 @@ item = interp2app(W_NDimArray.descr_item), real = GetSetProperty(W_NDimArray.descr_get_real), imag = GetSetProperty(W_NDimArray.descr_get_imag), + conj = interp2app(W_NDimArray.descr_conj), argsort = interp2app(W_NDimArray.descr_argsort), astype = interp2app(W_NDimArray.descr_astype), 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 @@ -552,6 +552,12 @@ assert(real(c2) == 3.0) assert(imag(c2) == 4.0) + def test_conj(self): + from _numpypy import array + + a = array([1 + 2j, 1 - 2j]) + assert (a.conj() == [1 - 2j, 1 + 2j]).all() + def test_math(self): if self.isWindows: skip('windows does not support c99 complex') From noreply at buildbot.pypy.org Wed Oct 31 15:11:04 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 31 Oct 2012 15:11:04 +0100 (CET) Subject: [pypy-commit] pypy default: numpy has opinions. It has it's own opinion what's a sequence and it's own Message-ID: <20121031141104.998C51C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58638:de6cd9aa69b0 Date: 2012-10-31 16:09 +0200 http://bitbucket.org/pypy/pypy/changeset/de6cd9aa69b0/ Log: numpy has opinions. It has it's own opinion what's a sequence and it's own opinion what's an int. Deal with that 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 @@ -3,6 +3,11 @@ from pypy.tool.pairtype import extendabletype from pypy.module.micronumpy.support import calc_strides +def issequence_w(space, w_obj): + return (space.isinstance_w(w_obj, space.w_tuple) or + space.isinstance_w(w_obj, space.w_list) or + isinstance(w_obj, W_NDimArray)) + class ArrayArgumentException(Exception): pass @@ -44,7 +49,7 @@ if isinstance(w_obj, W_NDimArray): return w_obj - elif space.issequence_w(w_obj): + elif issequence_w(space, w_obj): # Convert to array. return array(space, w_obj, w_order=None) else: 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 @@ -3,7 +3,7 @@ from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\ - ArrayArgumentException + ArrayArgumentException, issequence_w from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes from pypy.module.micronumpy.strides import find_shape_and_elems,\ get_shape_from_iterable, to_coords, shape_agreement @@ -644,7 +644,7 @@ @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): - if not space.issequence_w(w_object): + if not issequence_w(space, w_object): if space.is_none(w_dtype): w_dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object) dtype = space.interp_w(interp_dtype.W_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 @@ -2272,6 +2272,11 @@ raises(TypeError, a, 'sum') raises(TypeError, 'a+a') + def test_string_scalar(self): + from _numpypy import array + a = array('ffff') + assert a.shape == () + def test_flexible_repr(self): # import overrides str(), repr() for array from numpypy.core import arrayprint From noreply at buildbot.pypy.org Wed Oct 31 15:11:05 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 31 Oct 2012 15:11:05 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20121031141105.DA0791C00FA@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r58639:1fa8fb721755 Date: 2012-10-31 16:10 +0200 http://bitbucket.org/pypy/pypy/changeset/1fa8fb721755/ Log: merge 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 @@ -323,6 +323,7 @@ rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void) rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) class CffiFileObj(object): @@ -331,6 +332,7 @@ self.llf = rffi_fdopen(fd, mode) if not self.llf: raise OSError(rposix.get_errno(), "fdopen failed") + rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) def close(self): rffi_fclose(self.llf) 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 @@ -6,6 +6,7 @@ mandatory_b_prefix = '' mandatory_u_prefix = 'u' bytechr = chr + bitem2bchr = lambda x: x class U(object): def __add__(self, other): return eval('u'+repr(other).replace(r'\\u', r'\u') @@ -19,6 +20,7 @@ mandatory_b_prefix = 'b' mandatory_u_prefix = '' bytechr = lambda n: bytes([n]) + bitem2bchr = bytechr u = "" def size_of_int(): @@ -1804,7 +1806,10 @@ assert (p < s) ^ (p > s) def test_buffer(): - import __builtin__ + try: + import __builtin__ + except ImportError: + import builtins as __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() @@ -1826,7 +1831,7 @@ except IndexError: py.test.raises(IndexError, "buf[i]") else: - assert buf[i] == expected + assert buf[i] == bitem2bchr(expected) # --mb_slice-- assert buf[:] == b"hi there\x00" for i in range(-12, 12): @@ -1835,33 +1840,34 @@ for j in range(-12, 12): assert buf[i:j] == b"hi there\x00"[i:j] # --misc-- - assert list(buf) == list(b"hi there\x00") + assert list(buf) == list(map(bitem2bchr, b"hi there\x00")) # --mb_as_buffer-- - py.test.raises(TypeError, __builtin__.buffer, c) - bf1 = __builtin__.buffer(buf) - assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'buffer'): # Python <= 2.7 + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 py.test.raises(TypeError, memoryview, c) mv1 = memoryview(buf) - assert len(mv1) == len(buf) and mv1[3] == "t" + assert len(mv1) == len(buf) and mv1[3] in (b"t", ord(b"t")) # --mb_ass_item-- - expected = list(b"hi there\x00") + expected = list(map(bitem2bchr, b"hi there\x00")) for i in range(-12, 12): try: - expected[i] = chr(i & 0xff) + expected[i] = bytechr(i & 0xff) except IndexError: - py.test.raises(IndexError, "buf[i] = chr(i & 0xff)") + py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") else: - buf[i] = chr(i & 0xff) + buf[i] = bytechr(i & 0xff) assert list(buf) == expected # --mb_ass_slice-- buf[:] = b"hi there\x00" - assert list(buf) == list(c) == list(b"hi there\x00") + assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) py.test.raises(ValueError, 'buf[:] = b"shorter"') py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') buf[4:2] = b"" # no effect, but should work assert buf[:] == b"hi there\x00" - expected = list(b"hi there\x00") + expected = list(map(bitem2bchr, b"hi there\x00")) x = 0 for i in range(-12, 12): for j in range(-12, 12): @@ -1869,10 +1875,10 @@ stop = j if j >= 0 else j + len(buf) start = max(0, min(len(buf), start)) stop = max(0, min(len(buf), stop)) - sample = chr(x & 0xff) * (stop - start) + sample = bytechr(x & 0xff) * (stop - start) x += 1 buf[i:j] = sample - expected[i:j] = sample + expected[i:j] = map(bitem2bchr, sample) assert list(buf) == expected def test_getcname(): @@ -2245,6 +2251,11 @@ assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] +# XXX hack +if sys.version_info >= (3,): + import posix, io + posix.fdopen = io.open + def test_FILE(): if sys.platform == "win32": py.test.skip("testing FILE not implemented") @@ -2262,19 +2273,20 @@ # import posix fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r', 256) - fw1 = posix.fdopen(fdw, 'w', 256) + fr1 = posix.fdopen(fdr, 'rb', 256) + fw1 = posix.fdopen(fdw, 'wb', 256) # fw1.write(b"X") res = fputs(b"hello world\n", fw1) assert res >= 0 - fw1.close() + fw1.flush() # should not be needed # p = newp(new_array_type(BCharP, 100), None) res = fscanf(fr1, b"%s\n", p) assert res == 1 assert string(p) == b"Xhello" fr1.close() + fw1.close() def test_FILE_only_for_FILE_arg(): if sys.platform == "win32": @@ -2295,8 +2307,9 @@ fw1 = posix.fdopen(fdw, 'w') # e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not file") + assert str(e.value).startswith( + "initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not ") def test_FILE_object(): if sys.platform == "win32": @@ -2323,7 +2336,7 @@ res = fputs(b"hello\n", fw1p) assert res >= 0 res = fileno(fw1p) - assert res == fdw + assert (res == fdw) == (sys.version_info < (3,)) fw1.close() # data = posix.read(fdr, 256) From noreply at buildbot.pypy.org Wed Oct 31 15:24:09 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 15:24:09 +0100 (CET) Subject: [pypy-commit] pypy default: Attempt a fix. Hard to test. Message-ID: <20121031142409.073EE1C0290@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58640:d9a653fb6785 Date: 2012-10-31 15:15 +0100 http://bitbucket.org/pypy/pypy/changeset/d9a653fb6785/ Log: Attempt a fix. Hard to test. diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -700,7 +700,7 @@ return r def not_const(s_obj): - if s_obj.is_constant(): + if s_obj.is_constant() and not isinstance(s_obj, SomePBC): new_s_obj = SomeObject.__new__(s_obj.__class__) dic = new_s_obj.__dict__ = s_obj.__dict__.copy() if 'const' in dic: From noreply at buildbot.pypy.org Wed Oct 31 15:24:10 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 15:24:10 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20121031142410.537BE1C0290@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58641:ee9fe199c7cb Date: 2012-10-31 15:23 +0100 http://bitbucket.org/pypy/pypy/changeset/ee9fe199c7cb/ Log: merge heads 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 @@ -3,6 +3,11 @@ from pypy.tool.pairtype import extendabletype from pypy.module.micronumpy.support import calc_strides +def issequence_w(space, w_obj): + return (space.isinstance_w(w_obj, space.w_tuple) or + space.isinstance_w(w_obj, space.w_list) or + isinstance(w_obj, W_NDimArray)) + class ArrayArgumentException(Exception): pass @@ -44,7 +49,7 @@ if isinstance(w_obj, W_NDimArray): return w_obj - elif space.issequence_w(w_obj): + elif issequence_w(space, w_obj): # Convert to array. return array(space, w_obj, w_order=None) else: 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 @@ -3,7 +3,7 @@ from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\ - ArrayArgumentException + ArrayArgumentException, issequence_w from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes from pypy.module.micronumpy.strides import find_shape_and_elems,\ get_shape_from_iterable, to_coords, shape_agreement @@ -644,7 +644,7 @@ @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): - if not space.issequence_w(w_object): + if not issequence_w(space, w_object): if space.is_none(w_dtype): w_dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object) dtype = space.interp_w(interp_dtype.W_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 @@ -2272,6 +2272,11 @@ raises(TypeError, a, 'sum') raises(TypeError, 'a+a') + def test_string_scalar(self): + from _numpypy import array + a = array('ffff') + assert a.shape == () + def test_flexible_repr(self): # import overrides str(), repr() for array from numpypy.core import arrayprint From noreply at buildbot.pypy.org Wed Oct 31 16:04:52 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 31 Oct 2012 16:04:52 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: cumsum and cumprod Message-ID: <20121031150453.001651C002D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58642:9010050912c8 Date: 2012-10-31 17:04 +0200 http://bitbucket.org/pypy/pypy/changeset/9010050912c8/ Log: cumsum and cumprod 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 @@ -220,8 +220,8 @@ backstrides) return loop.setslice(self.get_shape(), impl, self) - def create_axis_iter(self, shape, dim): - return iter.AxisIterator(self, shape, dim) + def create_axis_iter(self, shape, dim, cum): + return iter.AxisIterator(self, shape, dim, cum) def create_dot_iter(self, shape, skip): r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), 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 @@ -83,7 +83,7 @@ def reshape(self, space, orig_array, new_shape): return self.set_shape(space, orig_array, new_shape) - def create_axis_iter(self, shape, dim): + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") def swapaxes(self, axis1, axis2): diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -100,9 +100,9 @@ if axis < 0 or axis > len(shape): raise OperationError(space.w_IndexError("Wrong axis %d" % axis)) iterable_shape = shape[:axis] + [0] + shape[axis + 1:] - iter = AxisIterator(arr, iterable_shape, axis) + iter = AxisIterator(arr, iterable_shape, axis, False) index_impl = index_arr.implementation - index_iter = AxisIterator(index_impl, iterable_shape, axis) + index_iter = AxisIterator(index_impl, iterable_shape, axis, False) stride_size = arr.strides[axis] index_stride_size = index_impl.strides[axis] axis_size = arr.shape[axis] 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 @@ -210,8 +210,8 @@ def create_iter(self, shape=None): return self.implementation.create_iter(shape) - def create_axis_iter(self, shape, dim): - return self.implementation.create_axis_iter(shape, dim) + def create_axis_iter(self, shape, dim, cum): + return self.implementation.create_axis_iter(shape, dim, cum) def create_dot_iter(self, shape, skip): return self.implementation.create_dot_iter(shape, skip) @@ -430,10 +430,6 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "cumprod not implemented yet")) - def descr_cumsum(self, space, w_axis=None, w_dtype=None, w_out=None): - raise OperationError(space.w_NotImplementedError, space.wrap( - "cumsum not implemented yet")) - def descr_data(self, space): raise OperationError(space.w_NotImplementedError, space.wrap( "data not implemented yet")) @@ -644,7 +640,8 @@ # ----------------------- reduce ------------------------------- - def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False): + def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False, + cumultative=False): def impl(self, space, w_axis=None, w_out=None, w_dtype=None): if space.is_none(w_out): out = None @@ -653,9 +650,9 @@ 'output must be an array')) else: out = w_out - return getattr(interp_ufuncs.get(space), ufunc_name).reduce(space, - self, True, promote_to_largest, w_axis, - False, out, w_dtype) + return getattr(interp_ufuncs.get(space), ufunc_name).reduce( + space, self, True, promote_to_largest, w_axis, + False, out, w_dtype, cumultative=cumultative) return func_with_new_name(impl, "reduce_%s_impl" % ufunc_name) descr_sum = _reduce_ufunc_impl("add") @@ -666,6 +663,9 @@ 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) + def descr_mean(self, space, w_axis=None, w_out=None): if space.is_none(w_axis): w_denom = space.wrap(self.get_size()) @@ -779,6 +779,9 @@ var = interp2app(W_NDimArray.descr_var), std = interp2app(W_NDimArray.descr_std), + cumsum = interp2app(W_NDimArray.descr_cumsum), + cumprod = interp2app(W_NDimArray.descr_cumprod), + copy = interp2app(W_NDimArray.descr_copy), reshape = interp2app(W_NDimArray.descr_reshape), T = GetSetProperty(W_NDimArray.descr_get_transpose), 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): + keepdims=False, out=None, dtype=None, cumultative=False): if self.argcount != 2: raise OperationError(space.w_ValueError, space.wrap("reduce only " "supported for binary functions")) @@ -158,7 +158,7 @@ return obj.get_scalar_value() shapelen = len(obj_shape) axis = unwrap_axis_arg(space, shapelen, w_axis) - assert axis>=0 + assert axis >= 0 size = obj.get_size() dtype = interp_dtype.decode_w_dtype(space, dtype) if dtype is None: @@ -175,7 +175,14 @@ raise operationerrfmt(space.w_ValueError, "zero-size array to " "%s.reduce without identity", self.name) if shapelen > 1 and axis < shapelen: - if keepdims: + temp = None + if cumultative: + shape = obj_shape[:] + temp_shape = obj_shape[:axis] + obj_shape[axis + 1:] + if out: + dtype = out.get_dtype() + temp = W_NDimArray.from_shape(temp_shape, dtype) + elif keepdims: shape = obj_shape[:axis] + [1] + obj_shape[axis + 1:] else: shape = obj_shape[:axis] + obj_shape[axis + 1:] @@ -202,7 +209,17 @@ else: out = W_NDimArray.from_shape(shape, dtype) return loop.do_axis_reduce(shape, self.func, obj, dtype, axis, out, - self.identity) + self.identity, cumultative, temp) + if cumultative: + if out: + if out.get_shape() != [obj.get_size()]: + raise OperationError(space.w_ValueError, space.wrap( + "out of incompatible size")) + else: + out = W_NDimArray.from_shape([obj.get_size()], dtype) + loop.compute_reduce_cumultative(obj, out, dtype, self.func, + self.identity) + return out if out: if len(out.get_shape())>0: raise operationerrfmt(space.w_ValueError, "output parameter " 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 @@ -259,11 +259,14 @@ self.offset %= self.size class AxisIterator(base.BaseArrayIterator): - def __init__(self, array, shape, dim): + def __init__(self, array, shape, dim, cumultative): self.shape = shape strides = array.strides backstrides = array.backstrides - if len(shape) == len(strides): + if cumultative: + self.strides = strides + self.backstrides = backstrides + elif len(shape) == len(strides): # keepdims = True self.strides = strides[:dim] + [0] + strides[dim + 1:] self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:] 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 @@ -112,6 +112,24 @@ obj_iter.next() return cur_value +reduce_cum_driver = jit.JitDriver(greens = ['shapelen', 'func', 'dtype'], + reds = ['obj_iter', 'out_iter']) + +def compute_reduce_cumultative(obj, out, calc_dtype, func, identity): + obj_iter = obj.create_iter() + out_iter = out.create_iter() + cur_value = identity.convert_to(calc_dtype) + shapelen = len(obj.get_shape()) + while not obj_iter.done(): + reduce_cum_driver.jit_merge_point(shapelen=shapelen, func=func, + dtype=calc_dtype, obj_iter=obj_iter, + out_iter=out_iter) + rval = obj_iter.getitem().convert_to(calc_dtype) + cur_value = func(calc_dtype, cur_value, rval) + out_iter.setitem(cur_value) + out_iter.next() + obj_iter.next() + def fill(arr, box): arr_iter = arr.create_iter() while not arr_iter.done(): @@ -156,13 +174,20 @@ return out axis_reduce__driver = jit.JitDriver(name='numpy_axis_reduce', - greens=['shapelen', 'func', 'dtype', + greens=['shapelen', 'cumultative', + 'func', 'dtype', 'identity'], reds=['axis', 'arr', 'out', 'shape', - 'out_iter', 'arr_iter']) + 'out_iter', 'arr_iter', + 'temp_iter']) -def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): - out_iter = out.create_axis_iter(arr.get_shape(), axis) +def do_axis_reduce(shape, func, arr, dtype, axis, out, identity, cumultative, + temp): + out_iter = out.create_axis_iter(arr.get_shape(), axis, cumultative) + if cumultative: + temp_iter = temp.create_axis_iter(arr.get_shape(), axis, False) + else: + temp_iter = out_iter # hack arr_iter = arr.create_iter() if identity is not None: identity = identity.convert_to(dtype) @@ -172,15 +197,20 @@ dtype=dtype, identity=identity, axis=axis, arr=arr, out=out, shape=shape, out_iter=out_iter, - arr_iter=arr_iter) + arr_iter=arr_iter, + cumultative=cumultative, + temp_iter=temp_iter) w_val = arr_iter.getitem().convert_to(dtype) if out_iter.first_line: if identity is not None: w_val = func(dtype, identity, w_val) else: - cur = out_iter.getitem() + cur = temp_iter.getitem() w_val = func(dtype, cur, w_val) out_iter.setitem(w_val) + if cumultative: + temp_iter.setitem(w_val) + temp_iter.next() arr_iter.next() out_iter.next() return out 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 @@ -2077,6 +2077,29 @@ a[array([0, 2]), slice(0, 2)] = [[10, 11], [12, 13]] assert (a == [[10, 11], [3, 4], [12, 13]]).all() + def test_cumsum(self): + from _numpypy import arange + a = arange(6).reshape(3, 2) + b = arange(6) + assert (a.cumsum() == [0, 1, 3, 6, 10, 15]).all() + a.cumsum(out=b) + assert (b == [0, 1, 3, 6, 10, 15]).all() + raises(ValueError, "a.cumsum(out=arange(6).reshape(3, 2))") + + def test_cumprod(self): + from _numpypy import array + a = array([[1, 2], [3, 4], [5, 6]]) + assert (a.cumprod() == [1, 2, 6, 24, 120, 720]).all() + + def test_cumsum_axis(self): + from _numpypy import arange, array + a = arange(6).reshape(3, 2) + assert (a.cumsum(0) == [[0, 1], [2, 4], [6, 9]]).all() + assert (a.cumsum(1) == [[0, 1], [2, 5], [4, 9]]).all() + a = array([[1, 1], [2, 2], [3, 4]]) + assert (a.cumsum(1) == [[1, 2], [2, 4], [3, 7]]).all() + assert (a.cumsum(0) == [[1, 1], [3, 3], [6, 7]]).all() + class AppTestSupport(BaseNumpyAppTest): def setup_class(cls): import struct From noreply at buildbot.pypy.org Wed Oct 31 16:53:06 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 31 Oct 2012 16:53:06 +0100 (CET) Subject: [pypy-commit] pypy unicode-strategies: hg merge default Message-ID: <20121031155306.53C841C00FA@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58643:8e1d2da10583 Date: 2012-10-31 16:52 +0100 http://bitbucket.org/pypy/pypy/changeset/8e1d2da10583/ Log: hg merge default diff too long, truncating to 2000 out of 2638 lines diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,5 +1,5 @@ -from _numpypy import array, ndarray, int_, float_, bool_ #, complex_# , longlong +from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math @@ -200,7 +200,7 @@ typename = "'%s'" % typename lf = '' - if 0: # or issubclass(arr.dtype.type, flexible): + if issubclass(arr.dtype.type, flexible): if arr.dtype.names: typename = "%s" % str(arr.dtype) else: 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 @@ -233,7 +233,7 @@ try: return unicode(line, ENCODING) except UnicodeDecodeError: # bah, silently fall back... - return unicode(line, 'utf-8') + return unicode(line, 'utf-8', 'replace') def get_history_length(self): return self.saved_history_length diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -496,7 +496,7 @@ if iscode: self.__tputs(text) else: - os.write(self.output_fd, text.encode(self.encoding)) + os.write(self.output_fd, text.encode(self.encoding, 'replace')) del self.__buffer[:] def __tputs(self, fmt, prog=delayprog): diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -118,7 +118,7 @@ # 1. find the start of the statement from codeop import compile_command end = None - for start in range(lineno, -1, max(-1, lineno - 10)): + for start in range(lineno, -1, -1): if assertion: line = self.lines[start] # the following lines are not fully tested, change with care @@ -135,9 +135,9 @@ compile_command(trysource) except (SyntaxError, OverflowError, ValueError): continue - + # 2. find the end of the statement - for end in range(lineno+1, min(len(self)+1, lineno + 10)): + for end in range(lineno+1, len(self)+1): trysource = self[start:end] if trysource.isparseable(): return start, end diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -548,7 +548,7 @@ if cell.is_constant(): newcell.const = cell.const cell = newcell - cell.knowntypedata = renamed_knowntypedata + cell.set_knowntypedata(renamed_knowntypedata) cells.append(cell) diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -144,7 +144,7 @@ # XXX HACK HACK HACK bk = getbookkeeper() if bk is not None: # for testing - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key annotator = bk.annotator @@ -168,6 +168,7 @@ bind(obj2, obj1, 0) bind(obj1, obj2, 1) + r.set_knowntypedata(knowntypedata) return r @@ -337,8 +338,7 @@ case = opname in ('gt', 'ge', 'eq') add_knowntypedata(knowntypedata, case, [op.args[0]], SomeInteger(nonneg=True, knowntype=tointtype(int1))) - if knowntypedata: - r.knowntypedata = knowntypedata + r.set_knowntypedata(knowntypedata) # a special case for 'x < 0' or 'x >= 0', # where 0 is a flow graph Constant # (in this case we are sure that it cannot become a r_uint later) @@ -369,8 +369,7 @@ if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) - if ktd: - s.knowntypedata = ktd + s.set_knowntypedata(ktd) return s def and_((boo1, boo2)): diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -188,10 +188,10 @@ variables = [op.args[1]] for variable in variables: assert bk.annotator.binding(variable) == s_obj - r.knowntypedata = {} - + knowntypedata = {} if not hasattr(typ, '_freeze_') and isinstance(s_type, SomePBC): - add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) + add_knowntypedata(knowntypedata, True, variables, bk.valueoftype(typ)) + r.set_knowntypedata(knowntypedata) return r # note that this one either needs to be constant, or we will create SomeObject diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -195,6 +195,10 @@ unsigned = False def __init__(self): pass + def set_knowntypedata(self, knowntypedata): + assert not hasattr(self, 'knowntypedata') + if knowntypedata: + self.knowntypedata = knowntypedata class SomeStringOrUnicode(SomeObject): immutable = True diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -76,7 +76,7 @@ s_obj.is_true_behavior(r) bk = getbookkeeper() - knowntypedata = r.knowntypedata = {} + knowntypedata = {} fn, block, i = bk.position_key op = block.operations[i] assert op.opname == "is_true" or op.opname == "nonzero" @@ -86,8 +86,8 @@ if s_obj.can_be_none(): s_nonnone_obj = s_obj.nonnoneify() add_knowntypedata(knowntypedata, True, [arg], s_nonnone_obj) + r.set_knowntypedata(knowntypedata) return r - def nonzero(obj): return obj.is_true() diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -118,7 +118,7 @@ ("translation.gcrootfinder", DEFL_ROOTFINDER_WITHJIT), ("translation.list_comprehension_operations", True)]), ChoiceOption("jit_backend", "choose the backend for the JIT", - ["auto", "x86", "x86-without-sse2", "llvm", 'arm'], + ["auto", "x86", "x86-without-sse2", 'arm'], default="auto", cmdline="--jit-backend"), ChoiceOption("jit_profiler", "integrate profiler support into the JIT", ["off", "oprofile"], 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 @@ -38,6 +38,8 @@ .. branch: numpypy-complex2 Complex dtype support for numpy +.. branch: numpypy-problems +Improve dtypes intp, uintp, void, string and record .. branch: kill-someobject major cleanups including killing some object support diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -74,8 +74,11 @@ elif step == 1: length = stop - start if length != len(newstring): - msg = "buffer slice assignment is wrong size" - raise OperationError(space.w_ValueError, space.wrap(msg)) + if length < 0 and len(newstring) == 0: + pass # ok anyway + else: + msg = "right operand length must match slice length" + raise OperationError(space.w_ValueError, space.wrap(msg)) self.setslice(start, newstring) else: raise OperationError(space.w_ValueError, diff --git a/pypy/jit/backend/detect_cpu.py b/pypy/jit/backend/detect_cpu.py --- a/pypy/jit/backend/detect_cpu.py +++ b/pypy/jit/backend/detect_cpu.py @@ -77,8 +77,6 @@ return "pypy.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "pypy.jit.backend.cli.runner", "CliCPU" - elif backend_name == 'llvm': - return "pypy.jit.backend.llvm.runner", "LLVMCPU" elif backend_name == 'arm': return "pypy.jit.backend.arm.runner", "CPU_ARM" elif backend_name == 'armhf': diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -1,17 +1,17 @@ from pypy.jit.metainterp import jitprof, resume, compile from pypy.jit.metainterp.executor import execute_nonspec -from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF, INT +from pypy.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF from pypy.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded, \ ImmutableIntUnbounded, \ IntLowerBound, MININT, MAXINT -from pypy.jit.metainterp.optimizeopt.util import (make_dispatcher_method, - args_dict) +from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method from pypy.jit.metainterp.resoperation import rop, ResOperation, AbstractResOp from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.tool.pairtype import extendabletype -from pypy.rlib.debug import debug_start, debug_stop, debug_print +from pypy.rlib.debug import debug_print from pypy.rlib.objectmodel import specialize + LEVEL_UNKNOWN = '\x00' LEVEL_NONNULL = '\x01' LEVEL_KNOWNCLASS = '\x02' # might also mean KNOWNARRAYDESCR, for arrays @@ -20,6 +20,8 @@ MODE_ARRAY = '\x00' MODE_STR = '\x01' MODE_UNICODE = '\x02' + + class LenBound(object): def __init__(self, mode, descr, bound): self.mode = mode diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -1,8 +1,11 @@ from pypy.jit.codewriter.effectinfo import EffectInfo -from pypy.jit.metainterp.history import ConstInt, make_hashable_int +from pypy.jit.metainterp import compile +from pypy.jit.metainterp.history import (Const, ConstInt, BoxInt, BoxFloat, + BoxPtr, make_hashable_int) from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.optimizeopt.intutils import IntBound -from pypy.jit.metainterp.optimizeopt.optimizer import * +from pypy.jit.metainterp.optimizeopt.optimizer import (Optimization, REMOVED, + CONST_0, CONST_1) from pypy.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method from pypy.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ResOperation) @@ -426,14 +429,33 @@ source_start_box = self.get_constant_box(op.getarg(3)) dest_start_box = self.get_constant_box(op.getarg(4)) length = self.get_constant_box(op.getarg(5)) - if (source_value.is_virtual() and source_start_box and dest_start_box - and length and (dest_value.is_virtual() or length.getint() <= 8)): + extrainfo = op.getdescr().get_extra_info() + if (source_start_box and dest_start_box + and length and (dest_value.is_virtual() or length.getint() <= 8) and + (source_value.is_virtual() or length.getint() <= 8) and + len(extrainfo.write_descrs_arrays) == 1): # <-sanity check from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue - assert isinstance(source_value, VArrayValue) source_start = source_start_box.getint() dest_start = dest_start_box.getint() + # XXX fish fish fish + arraydescr = extrainfo.write_descrs_arrays[0] for index in range(length.getint()): - val = source_value.getitem(index + source_start) + if source_value.is_virtual(): + assert isinstance(source_value, VArrayValue) + val = source_value.getitem(index + source_start) + else: + if arraydescr.is_array_of_pointers(): + resbox = BoxPtr() + elif arraydescr.is_array_of_floats(): + resbox = BoxFloat() + else: + resbox = BoxInt() + newop = ResOperation(rop.GETARRAYITEM_GC, + [op.getarg(1), + ConstInt(index + source_start)], resbox, + descr=arraydescr) + self.optimizer.propagate_forward(newop) + val = self.getvalue(resbox) if dest_value.is_virtual(): dest_value.setitem(index + dest_start, val) else: @@ -441,7 +463,7 @@ [op.getarg(2), ConstInt(index + dest_start), val.get_key_box()], None, - descr=source_value.arraydescr) + descr=arraydescr) self.emit_operation(newop) return True if length and length.getint() == 0: diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -3239,6 +3239,42 @@ ''' self.optimize_loop(ops, expected) + def test_arraycopy_not_virtual_2(self): + ops = ''' + [p0] + p1 = new_array(3, descr=arraydescr) + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) # removed by the backend + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) # removed by the backend + jump(i0) + ''' + self.optimize_loop(ops, expected) + + def test_arraycopy_not_virtual_3(self): + ops = ''' + [p0, p1] + call(0, p0, p1, 0, 0, 3, descr=arraycopydescr) + i0 = getarrayitem_gc(p1, 0, descr=arraydescr) + jump(i0) + ''' + expected = ''' + [p0, p1] + i0 = getarrayitem_gc(p0, 0, descr=arraydescr) + i1 = getarrayitem_gc(p0, 1, descr=arraydescr) + i2 = getarrayitem_gc(p0, 2, descr=arraydescr) + setarrayitem_gc(p1, 0, i0, descr=arraydescr) + setarrayitem_gc(p1, 1, i1, descr=arraydescr) + setarrayitem_gc(p1, 2, i2, descr=arraydescr) + jump(i0) + ''' + self.optimize_loop(ops, expected) + def test_arraycopy_no_elem(self): """ this was actually observed in the wild """ diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -4,6 +4,7 @@ from pypy.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken from pypy.jit.metainterp.jitexc import JitException from pypy.jit.metainterp.optimize import InvalidLoop +from pypy.rlib.debug import debug_print, debug_start, debug_stop from pypy.jit.metainterp.optimizeopt.optimizer import * from pypy.jit.metainterp.optimizeopt.generalize import KillHugeIntBounds from pypy.jit.metainterp.inliner import Inliner diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py --- a/pypy/jit/metainterp/test/test_list.py +++ b/pypy/jit/metainterp/test/test_list.py @@ -128,6 +128,17 @@ res = self.interp_operations(f, [], listops=True) assert res == 10 + def test_arraycopy_bug(self): + def f(): + l = [1, 2, 3, 4] + l2 = [1, 2, 3, 4] + l[2] = 13 + l2[0:len(l2)] = l[:] + return l2[0] + l2[1] + l2[2] + l2[3] + + res = self.interp_operations(f, [], listops=True) + assert res == f() + def test_arraycopy_full(self): jitdriver = JitDriver(greens = [], reds = ['n']) def f(n): diff --git a/pypy/module/__builtin__/test/test_buffer.py b/pypy/module/__builtin__/test/test_buffer.py --- a/pypy/module/__builtin__/test/test_buffer.py +++ b/pypy/module/__builtin__/test/test_buffer.py @@ -117,6 +117,8 @@ b[:] = '12345' assert a.tostring() == 'hello 12345' raises(IndexError, 'b[5] = "."') + b[4:2] = '' + assert a.tostring() == 'hello 12345' b = buffer(b, 2) assert len(b) == 3 diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,6 +1,7 @@ from pypy.interpreter.error import operationerrfmt from pypy.interpreter.buffer import RWBuffer -from pypy.interpreter.gateway import unwrap_spec +from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.interpreter.typedef import TypeDef from pypy.rpython.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -34,6 +35,16 @@ for i in range(len(string)): raw_cdata[i] = string[i] +LLBuffer.typedef = TypeDef( + "buffer", + __module__ = "_cffi_backend", + __len__ = interp2app(RWBuffer.descr_len), + __getitem__ = interp2app(RWBuffer.descr_getitem), + __setitem__ = interp2app(RWBuffer.descr_setitem), + __buffer__ = interp2app(RWBuffer.descr__buffer__), + ) +LLBuffer.typedef.acceptable_as_base_class = False + @unwrap_spec(cdata=cdataobj.W_CData, size=int) def buffer(space, cdata, size=-1): diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,9 +4,8 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, llmemory, rffi -from pypy.rlib import jit, clibffi, jit_libffi, rposix +from pypy.rlib import jit, clibffi, jit_libffi from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG @@ -152,9 +151,6 @@ if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor='raw') - elif flag == 2: - file = rffi.cast(rffi.CCHARPP, data)[0] - rffi_fclose(file) lltype.free(buffer, flavor='raw') return w_res @@ -169,27 +165,6 @@ assert isinstance(abi, int) return space.wrap(abi) -rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) - -def prepare_file_call_argument(fileobj): - import os - space = fileobj.space - fileobj.direct_flush() - fd = fileobj.direct_fileno() - if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file has no OS file descriptor")) - try: - fd2 = os.dup(fd) - f = rffi_fdopen(fd2, fileobj.mode) - if not f: - os.close(fd2) - raise OSError(rposix.get_errno(), "fdopen failed") - except OSError, e: - raise wrap_oserror(space, e) - return f - # ____________________________________________________________ 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 @@ -3,9 +3,11 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import wrap_oserror from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.rarithmetic import ovfcheck +from pypy.rlib import rposix from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend import cdataobj, misc, ctypeprim @@ -236,6 +238,22 @@ p = rffi.ptradd(cdata, i * self.ctitem.size) return cdataobj.W_CData(space, p, self) + def cast(self, w_ob): + if self.is_file: + value = self.prepare_file(w_ob) + if value: + return cdataobj.W_CData(self.space, value, self) + return W_CTypePtrBase.cast(self, w_ob) + + def prepare_file(self, w_ob): + from pypy.module._file.interp_file import W_File + from pypy.module._cffi_backend import ctypefunc + ob = self.space.interpclass_w(w_ob) + if isinstance(ob, W_File): + return prepare_file_argument(self.space, ob) + else: + return lltype.nullptr(rffi.CCHARP.TO) + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space if (space.isinstance_w(w_init, space.w_list) or @@ -245,11 +263,8 @@ # from a string, we add the null terminator length = space.int_w(space.len(w_init)) + 1 elif self.is_file: - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc - ob = space.interpclass_w(w_init) - if isinstance(ob, W_File): - result = ctypefunc.prepare_file_call_argument(ob) + result = self.prepare_file(w_init) + if result: rffi.cast(rffi.CCHARPP, cdata)[0] = result return 2 return 0 @@ -303,3 +318,33 @@ else: raise OperationError(space.w_TypeError, space.wrap("expected a 'cdata struct-or-union' object")) + +# ____________________________________________________________ + + +rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void) +rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) + +class CffiFileObj(object): + _immutable_ = True + def __init__(self, fd, mode): + self.llf = rffi_fdopen(fd, mode) + if not self.llf: + raise OSError(rposix.get_errno(), "fdopen failed") + rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) + def close(self): + rffi_fclose(self.llf) + +def prepare_file_argument(space, fileobj): + fileobj.direct_flush() + if fileobj.cffi_fileobj is None: + fd = fileobj.direct_fileno() + if fd < 0: + raise OperationError(space.w_ValueError, + space.wrap("file has no OS file descriptor")) + try: + fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + except OSError, e: + raise wrap_oserror(space, e) + return fileobj.cffi_fileobj.llf diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -5,9 +5,8 @@ type_or_class = "type" mandatory_b_prefix = '' mandatory_u_prefix = 'u' - readbuf = str - bufchar = lambda x: x bytechr = chr + bitem2bchr = lambda x: x class U(object): def __add__(self, other): return eval('u'+repr(other).replace(r'\\u', r'\u') @@ -20,12 +19,8 @@ unichr = chr mandatory_b_prefix = 'b' mandatory_u_prefix = '' - readbuf = lambda buf: buf.tobytes() - if sys.version_info < (3, 3): - bufchar = lambda x: bytes([ord(x)]) - else: - bufchar = ord bytechr = lambda n: bytes([n]) + bitem2bchr = bytechr u = "" def size_of_int(): @@ -1811,36 +1806,80 @@ assert (p < s) ^ (p > s) def test_buffer(): + try: + import __builtin__ + except ImportError: + import builtins as __builtin__ BShort = new_primitive_type("short") s = newp(new_pointer_type(BShort), 100) assert sizeof(s) == size_of_ptr() assert sizeof(BShort) == 2 - assert len(readbuf(buffer(s))) == 2 + assert len(buffer(s)) == 2 # BChar = new_primitive_type("char") BCharArray = new_array_type(new_pointer_type(BChar), None) c = newp(BCharArray, b"hi there") + # buf = buffer(c) - assert readbuf(buf) == b"hi there\x00" + assert str(buf).startswith('<_cffi_backend.buffer object at 0x') + # --mb_length-- assert len(buf) == len(b"hi there\x00") - assert buf[0] == bufchar('h') - assert buf[2] == bufchar(' ') - assert list(buf) == list(map(bufchar, "hi there\x00")) - buf[2] = bufchar('-') - assert c[2] == b'-' - assert readbuf(buf) == b"hi-there\x00" - c[2] = b'!' - assert buf[2] == bufchar('!') - assert readbuf(buf) == b"hi!there\x00" - c[2] = b'-' - buf[:2] = b'HI' - assert string(c) == b'HI-there' - if sys.version_info < (3,) or sys.version_info >= (3, 3): - assert buf[:4:2] == b'H-' - if '__pypy__' not in sys.builtin_module_names: - # XXX pypy doesn't support the following assignment so far - buf[:4:2] = b'XY' - assert string(c) == b'XIYthere' + # --mb_item-- + for i in range(-12, 12): + try: + expected = b"hi there\x00"[i] + except IndexError: + py.test.raises(IndexError, "buf[i]") + else: + assert buf[i] == bitem2bchr(expected) + # --mb_slice-- + assert buf[:] == b"hi there\x00" + for i in range(-12, 12): + assert buf[i:] == b"hi there\x00"[i:] + assert buf[:i] == b"hi there\x00"[:i] + for j in range(-12, 12): + assert buf[i:j] == b"hi there\x00"[i:j] + # --misc-- + assert list(buf) == list(map(bitem2bchr, b"hi there\x00")) + # --mb_as_buffer-- + if hasattr(__builtin__, 'buffer'): # Python <= 2.7 + py.test.raises(TypeError, __builtin__.buffer, c) + bf1 = __builtin__.buffer(buf) + assert len(bf1) == len(buf) and bf1[3] == "t" + if hasattr(__builtin__, 'memoryview'): # Python >= 2.7 + py.test.raises(TypeError, memoryview, c) + mv1 = memoryview(buf) + assert len(mv1) == len(buf) and mv1[3] in (b"t", ord(b"t")) + # --mb_ass_item-- + expected = list(map(bitem2bchr, b"hi there\x00")) + for i in range(-12, 12): + try: + expected[i] = bytechr(i & 0xff) + except IndexError: + py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)") + else: + buf[i] = bytechr(i & 0xff) + assert list(buf) == expected + # --mb_ass_slice-- + buf[:] = b"hi there\x00" + assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00")) + py.test.raises(ValueError, 'buf[:] = b"shorter"') + py.test.raises(ValueError, 'buf[:] = b"this is much too long!"') + buf[4:2] = b"" # no effect, but should work + assert buf[:] == b"hi there\x00" + expected = list(map(bitem2bchr, b"hi there\x00")) + x = 0 + for i in range(-12, 12): + for j in range(-12, 12): + start = i if i >= 0 else i + len(buf) + stop = j if j >= 0 else j + len(buf) + start = max(0, min(len(buf), start)) + stop = max(0, min(len(buf), stop)) + sample = bytechr(x & 0xff) * (stop - start) + x += 1 + buf[i:j] = sample + expected[i:j] = map(bitem2bchr, sample) + assert list(buf) == expected def test_getcname(): BUChar = new_primitive_type("unsigned char") @@ -2212,6 +2251,11 @@ assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] +# XXX hack +if sys.version_info >= (3,): + import posix, io + posix.fdopen = io.open + def test_FILE(): if sys.platform == "win32": py.test.skip("testing FILE not implemented") @@ -2229,19 +2273,20 @@ # import posix fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r', 256) - fw1 = posix.fdopen(fdw, 'w', 256) + fr1 = posix.fdopen(fdr, 'rb', 256) + fw1 = posix.fdopen(fdw, 'wb', 256) # fw1.write(b"X") res = fputs(b"hello world\n", fw1) assert res >= 0 - fw1.close() + fw1.flush() # should not be needed # p = newp(new_array_type(BCharP, 100), None) res = fscanf(fr1, b"%s\n", p) assert res == 1 assert string(p) == b"Xhello" fr1.close() + fw1.close() def test_FILE_only_for_FILE_arg(): if sys.platform == "win32": @@ -2262,5 +2307,38 @@ fw1 = posix.fdopen(fdw, 'w') # e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not file") + assert str(e.value).startswith( + "initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not ") + +def test_FILE_object(): + if sys.platform == "win32": + py.test.skip("testing FILE not implemented") + # + BFILE = new_struct_type("_IO_FILE") + BFILEP = new_pointer_type(BFILE) + BChar = new_primitive_type("char") + BCharP = new_pointer_type(BChar) + BInt = new_primitive_type("int") + BFunc = new_function_type((BCharP, BFILEP), BInt, False) + BFunc2 = new_function_type((BFILEP,), BInt, False) + ll = find_and_load_library('c') + fputs = ll.load_function(BFunc, "fputs") + fileno = ll.load_function(BFunc2, "fileno") + # + import posix + fdr, fdw = posix.pipe() + fw1 = posix.fdopen(fdw, 'wb', 256) + # + fw1p = cast(BFILEP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p) + assert res >= 0 + res = fileno(fw1p) + assert (res == fdw) == (sys.version_info < (3,)) + fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -1,8 +1,21 @@ from pypy.objspace.fake.checkmodule import checkmodule +from pypy.module._cffi_backend import ctypeptr +from pypy.rpython.lltypesystem import lltype, rffi # side-effect: FORMAT_LONGDOUBLE must be built before test_checkmodule() from pypy.module._cffi_backend import misc def test_checkmodule(): - checkmodule('_cffi_backend') + # prepare_file_argument() is not working without translating the _file + # module too + def dummy_prepare_file_argument(space, fileobj): + return lltype.nullptr(rffi.CCHARP.TO) + old = ctypeptr.prepare_file_argument + try: + ctypeptr.prepare_file_argument = dummy_prepare_file_argument + # + checkmodule('_cffi_backend') + # + finally: + ctypeptr.prepare_file_argument = old diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -32,6 +32,7 @@ encoding = None errors = None fd = -1 + cffi_fileobj = None # pypy/module/_cffi_backend newlines = 0 # Updated when the stream is closed @@ -148,7 +149,14 @@ del openstreams[stream] except KeyError: pass - stream.close() + # close the stream. If cffi_fileobj is None, we close the + # underlying fileno too. Otherwise, we leave that to + # cffi_fileobj.close(). + cffifo = self.cffi_fileobj + self.cffi_fileobj = None + stream.close1(cffifo is None) + if cffifo is not None: + cffifo.close() def direct_fileno(self): self.getstream() # check if the file is still open diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -10,7 +10,8 @@ class AppTestBufferTooShort: def setup_class(cls): - space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal')) + space = gettestobjspace(usemodules=('_multiprocessing', 'thread', + 'signal', 'itertools')) cls.space = space if option.runappdirect: diff --git a/pypy/module/_multiprocessing/test/test_memory.py b/pypy/module/_multiprocessing/test/test_memory.py --- a/pypy/module/_multiprocessing/test/test_memory.py +++ b/pypy/module/_multiprocessing/test/test_memory.py @@ -3,7 +3,8 @@ class AppTestMemory: def setup_class(cls): space = gettestobjspace( - usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi')) + usemodules=('_multiprocessing', 'mmap', '_rawffi', '_ffi', + 'itertools')) cls.space = space def test_address_of(self): 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 @@ -357,8 +357,8 @@ buffering = 1024 # minimum amount of compressed data read at once self.buffering = buffering - def close(self): - self.stream.close() + def close1(self, closefileno): + self.stream.close1(closefileno) def tell(self): return self.readlength @@ -479,9 +479,9 @@ self.compressor = W_BZ2Compressor(space, compresslevel) self.writtenlength = 0 - def close(self): + def close1(self, closefileno): self.stream.write(self.space.str_w(self.compressor.flush())) - self.stream.close() + self.stream.close1(closefileno) def write(self, data): self.stream.write(self.space.str_w(self.compressor.compress(data))) diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py --- a/pypy/module/cpyext/dictobject.py +++ b/pypy/module/cpyext/dictobject.py @@ -198,8 +198,8 @@ @specialize.memo() def make_frozendict(space): return space.appexec([], '''(): - import collections - class FrozenDict(collections.Mapping): + import _abcoll + class FrozenDict(_abcoll.Mapping): def __init__(self, *args, **kwargs): self._d = dict(*args, **kwargs) def __iter__(self): diff --git a/pypy/module/cpyext/test/test_import.py b/pypy/module/cpyext/test/test_import.py --- a/pypy/module/cpyext/test/test_import.py +++ b/pypy/module/cpyext/test/test_import.py @@ -4,9 +4,9 @@ class TestImport(BaseApiTest): def test_import(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - assert pdb - assert space.getattr(pdb, space.wrap("pm")) + stat = api.PyImport_Import(space.wrap("stat")) + assert stat + assert space.getattr(stat, space.wrap("S_IMODE")) def test_addmodule(self, space, api): with rffi.scoped_str2charp("sys") as modname: @@ -32,10 +32,10 @@ assert space.is_true(space.contains(w_dict, space.wrap(testmod))) def test_reload(self, space, api): - pdb = api.PyImport_Import(space.wrap("pdb")) - space.delattr(pdb, space.wrap("set_trace")) - pdb = api.PyImport_ReloadModule(pdb) - assert space.getattr(pdb, space.wrap("set_trace")) + stat = api.PyImport_Import(space.wrap("stat")) + space.delattr(stat, space.wrap("S_IMODE")) + stat = api.PyImport_ReloadModule(stat) + assert space.getattr(stat, space.wrap("S_IMODE")) class AppTestImportLogic(AppTestCpythonExtensionBase): def test_import_logic(self): diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py --- a/pypy/module/imp/test/test_app.py +++ b/pypy/module/imp/test/test_app.py @@ -3,6 +3,8 @@ class AppTestImpModule: def setup_class(cls): + from pypy.conftest import gettestobjspace + cls.space = gettestobjspace(usemodules=('imp', 'itertools')) cls.w_imp = cls.space.getbuiltinmodule('imp') cls.w_file_module = cls.space.wrap(__file__) 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 @@ -38,7 +38,7 @@ test_reload = "def test():\n raise ValueError\n", infinite_reload = "import infinite_reload; reload(infinite_reload)", del_sys_module = "import sys\ndel sys.modules['del_sys_module']\n", - itertools = "hello_world = 42\n", + _md5 = "hello_world = 42\n", gc = "should_never_be_seen = 42\n", ) root.ensure("notapackage", dir=1) # empty, no __init__.py @@ -148,7 +148,7 @@ class AppTestImport: def setup_class(cls): # interpreter-level - cls.space = gettestobjspace(usemodules=['itertools']) + cls.space = gettestobjspace(usemodules=['_md5']) cls.w_runappdirect = cls.space.wrap(conftest.option.runappdirect) cls.saved_modules = _setup(cls.space) #XXX Compile class @@ -597,34 +597,34 @@ def test_shadow_extension_1(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find itertools.py if there is + # 'import _md5' is supposed to find _md5.py if there is # one in sys.path. import sys - assert 'itertools' not in sys.modules - import itertools - assert hasattr(itertools, 'hello_world') - assert not hasattr(itertools, 'count') - assert '(built-in)' not in repr(itertools) - del sys.modules['itertools'] + assert '_md5' not in sys.modules + import _md5 + assert hasattr(_md5, 'hello_world') + assert not hasattr(_md5, 'count') + assert '(built-in)' not in repr(_md5) + del sys.modules['_md5'] def test_shadow_extension_2(self): if self.runappdirect: skip("hard to test: module is already imported") - # 'import itertools' is supposed to find the built-in module even + # 'import _md5' is supposed to find the built-in module even # if there is also one in sys.path as long as it is *after* the # special entry '.../lib_pypy/__extensions__'. (Note that for now - # there is one in lib_pypy/itertools.py, which should not be seen + # there is one in lib_pypy/_md5.py, which should not be seen # either; hence the (built-in) test below.) import sys - assert 'itertools' not in sys.modules + assert '_md5' not in sys.modules sys.path.append(sys.path.pop(0)) try: - import itertools - assert not hasattr(itertools, 'hello_world') - assert hasattr(itertools, 'izip') - assert '(built-in)' in repr(itertools) + import _md5 + assert not hasattr(_md5, 'hello_world') + assert hasattr(_md5, 'digest_size') + assert '(built-in)' in repr(_md5) finally: sys.path.insert(0, sys.path.pop()) - del sys.modules['itertools'] + del sys.modules['_md5'] def test_invalid_pathname(self): import imp @@ -1005,7 +1005,7 @@ class AppTestImportHooks(object): def setup_class(cls): - space = cls.space = gettestobjspace(usemodules=('struct',)) + space = cls.space = gettestobjspace(usemodules=('struct', 'itertools')) mydir = os.path.dirname(__file__) cls.w_hooktest = space.wrap(os.path.join(mydir, 'hooktest')) space.appexec([space.wrap(mydir)], """ diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -6,7 +6,7 @@ class AppTestMath: def setup_class(cls): - cls.space = gettestobjspace(usemodules=['math', 'struct']) + cls.space = gettestobjspace(usemodules=['math', 'struct', 'itertools']) cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES) cls.w_consistent_host = cls.space.wrap(test_direct.consistent_host) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -62,6 +62,7 @@ 'flexible': 'interp_boxes.W_FlexibleBox', 'character': 'interp_boxes.W_CharacterBox', 'str_': 'interp_boxes.W_StringBox', + 'string_': 'interp_boxes.W_StringBox', 'unicode_': 'interp_boxes.W_UnicodeBox', 'void': 'interp_boxes.W_VoidBox', 'complexfloating': 'interp_boxes.W_ComplexFloatingBox', 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 @@ -10,6 +10,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rlib import jit from pypy.rlib.rawstorage import free_raw_storage +from pypy.rlib.debug import make_sure_not_resized class ConcreteArrayIterator(base.BaseArrayIterator): def __init__(self, array): @@ -44,10 +45,10 @@ def __init__(self, array): self.array = array self.offset = array.start - self.skip = array.strides[0] + self.skip = array.get_strides()[0] self.dtype = array.dtype self.index = 0 - self.size = array.shape[0] + self.size = array.get_shape()[0] def next(self): self.offset += self.skip @@ -115,8 +116,8 @@ class AxisIterator(base.BaseArrayIterator): def __init__(self, array, shape, dim): self.shape = shape - strides = array.strides - backstrides = array.backstrides + strides = array.get_strides() + backstrides = array.get_backstrides() if len(shape) == len(strides): # keepdims = True self.strides = strides[:dim] + [0] + strides[dim + 1:] @@ -166,9 +167,23 @@ class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None + + # JIT hints that length of all those arrays is a constant def get_shape(self): - return self.shape + shape = self.shape + jit.hint(len(shape), promote=True) + return shape + + def get_strides(self): + strides = self.strides + jit.hint(len(strides), promote=True) + return strides + + def get_backstrides(self): + backstrides = self.backstrides + jit.hint(len(backstrides), promote=True) + return backstrides def getitem(self, index): return self.dtype.getitem(self, index) @@ -181,7 +196,7 @@ if impl.is_scalar(): self.fill(impl.get_scalar_value()) return - shape = shape_agreement(space, self.shape, arr) + shape = shape_agreement(space, self.get_shape(), arr) if impl.storage == self.storage: impl = impl.copy() loop.setslice(shape, self, impl) @@ -193,8 +208,8 @@ # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: - new_strides = calc_new_strides(new_shape, self.shape, - self.strides, self.order) + new_strides = calc_new_strides(new_shape, self.get_shape(), + self.get_strides(), self.order) if new_strides: # We can create a view, strides somehow match up. ndims = len(new_shape) @@ -211,31 +226,34 @@ @jit.unroll_safe def _lookup_by_index(self, space, view_w): item = self.start + strides = self.get_strides() for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError idx = int_w(space, w_index) if idx < 0: - idx = self.shape[i] + idx - if idx < 0 or idx >= self.shape[i]: + idx = self.get_shape()[i] + idx + if idx < 0 or idx >= self.get_shape()[i]: raise operationerrfmt(space.w_IndexError, - "index (%d) out of range (0<=index<%d", i, self.shape[i], + "index (%d) out of range (0<=index<%d", i, self.get_shape()[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item @jit.unroll_safe def _lookup_by_unwrapped_index(self, space, lst): item = self.start - assert len(lst) == len(self.shape) + shape = self.get_shape() + strides = self.get_strides() + assert len(lst) == len(shape) for i, idx in enumerate(lst): if idx < 0: - idx = self.shape[i] + idx - if idx < 0 or idx >= self.shape[i]: + idx = shape[i] + idx + if idx < 0 or idx >= shape[i]: raise operationerrfmt(space.w_IndexError, - "index (%d) out of range (0<=index<%d", i, self.shape[i], + "index (%d) out of range (0<=index<%d", i, shape[i], ) - item += idx * self.strides[i] + item += idx * strides[i] return item def getitem_index(self, space, index): @@ -255,7 +273,8 @@ raise IndexError if isinstance(w_idx, W_NDimArray): raise ArrayArgumentException - shape_len = len(self.shape) + shape = self.get_shape() + shape_len = len(shape) if shape_len == 0: raise OperationError(space.w_IndexError, space.wrap( "0-d arrays can't be indexed")) @@ -299,7 +318,7 @@ return RecordChunk(idx) if (space.isinstance_w(w_idx, space.w_int) or space.isinstance_w(w_idx, space.w_slice)): - return Chunks([Chunk(*space.decode_index4(w_idx, self.shape[0]))]) + return Chunks([Chunk(*space.decode_index4(w_idx, self.get_shape()[0]))]) elif space.is_w(w_idx, space.w_None): return Chunks([NewAxisChunk()]) result = [] @@ -309,7 +328,7 @@ result.append(NewAxisChunk()) else: result.append(Chunk(*space.decode_index4(w_item, - self.shape[i]))) + self.get_shape()[i]))) i += 1 return Chunks(result) @@ -333,37 +352,37 @@ view.implementation.setslice(space, w_value) def transpose(self): - if len(self.shape) < 2: + if len(self.get_shape()) < 2: return self strides = [] backstrides = [] shape = [] - for i in range(len(self.shape) - 1, -1, -1): - strides.append(self.strides[i]) - backstrides.append(self.backstrides[i]) - shape.append(self.shape[i]) + for i in range(len(self.get_shape()) - 1, -1, -1): + strides.append(self.get_strides()[i]) + backstrides.append(self.get_backstrides()[i]) + shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, backstrides, shape, self) def copy(self): - strides, backstrides = support.calc_strides(self.shape, self.dtype, + strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, self.order) - impl = ConcreteArray(self.shape, self.dtype, self.order, strides, + impl = ConcreteArray(self.get_shape(), self.dtype, self.order, strides, backstrides) - return loop.setslice(self.shape, impl, self) + return loop.setslice(self.get_shape(), impl, self) def create_axis_iter(self, shape, dim): return AxisIterator(self, shape, dim) def create_dot_iter(self, shape, skip): - r = calculate_dot_strides(self.strides, self.backstrides, + r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) return MultiDimViewIterator(self, self.start, r[0], r[1], shape) def swapaxes(self, axis1, axis2): - shape = self.shape[:] - strides = self.strides[:] - backstrides = self.backstrides[:] + shape = self.get_shape()[:] + strides = self.get_strides()[:] + backstrides = self.get_backstrides()[:] shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] @@ -375,6 +394,9 @@ class ConcreteArray(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides): + make_sure_not_resized(shape) + make_sure_not_resized(strides) + make_sure_not_resized(backstrides) self.shape = shape self.size = support.product(shape) * dtype.get_size() self.storage = dtype.itemtype.malloc(self.size) @@ -383,11 +405,12 @@ self.strides = strides self.backstrides = backstrides - def create_iter(self, shape): - if shape == self.shape: + def create_iter(self, shape=None): + if shape is None or shape == self.get_shape(): return ConcreteArrayIterator(self) - r = calculate_broadcast_strides(self.strides, self.backstrides, - self.shape, shape) + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), + self.get_shape(), shape) return MultiDimViewIterator(self, 0, r[0], r[1], shape) def fill(self, box): @@ -420,25 +443,27 @@ def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) - def create_iter(self, shape): - if shape != self.shape: - r = calculate_broadcast_strides(self.strides, self.backstrides, - self.shape, shape) + def create_iter(self, shape=None): + if shape is not None and shape != self.get_shape(): + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), + self.get_shape(), shape) return MultiDimViewIterator(self.parent, self.start, r[0], r[1], shape) - if len(self.shape) == 1: + if len(self.get_shape()) == 1: return OneDimViewIterator(self) - return MultiDimViewIterator(self.parent, self.start, self.strides, - self.backstrides, self.shape) + return MultiDimViewIterator(self.parent, self.start, + self.get_strides(), + self.get_backstrides(), self.get_shape()) def set_shape(self, space, new_shape): - if len(self.shape) < 2 or self.size == 0: + if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor strides = [] backstrides = [] dtype = self.dtype - s = self.strides[0] // dtype.get_size() + s = self.get_strides()[0] // dtype.get_size() if self.order == 'C': new_shape.reverse() for sh in new_shape: @@ -451,7 +476,8 @@ new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, self) - new_strides = calc_new_strides(new_shape, self.shape, self.strides, + new_strides = calc_new_strides(new_shape, self.get_shape(), + self.get_strides(), self.order) if new_strides is None: raise OperationError(space.w_AttributeError, space.wrap( 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 @@ -34,7 +34,7 @@ def get_shape(self): return [] - def create_iter(self, shape): + def create_iter(self, shape=None): return ScalarIterator(self.value) def get_scalar_value(self): diff --git a/pypy/module/micronumpy/arrayimpl/voidbox.py b/pypy/module/micronumpy/arrayimpl/voidbox.py --- a/pypy/module/micronumpy/arrayimpl/voidbox.py +++ b/pypy/module/micronumpy/arrayimpl/voidbox.py @@ -6,6 +6,7 @@ def __init__(self, size, dtype): self.storage = alloc_raw_storage(size) self.dtype = dtype + self.size = size def __del__(self): free_raw_storage(self.storage) diff --git a/pypy/module/micronumpy/dot.py b/pypy/module/micronumpy/dot.py --- a/pypy/module/micronumpy/dot.py +++ b/pypy/module/micronumpy/dot.py @@ -11,12 +11,12 @@ right_critical_dim = len(right_shape) - 2 right_critical_dim_size = right_shape[right_critical_dim] assert right_critical_dim >= 0 - out_shape += left_shape[:-1] + \ - right_shape[0:right_critical_dim] + \ - right_shape[right_critical_dim + 1:] + out_shape = out_shape + left_shape[:-1] + \ + right_shape[0:right_critical_dim] + \ + right_shape[right_critical_dim + 1:] elif len(right_shape) > 0: #dot does not reduce for scalars - out_shape += left_shape[:-1] + out_shape = out_shape + left_shape[:-1] if my_critical_dim_size != right_critical_dim_size: raise OperationError(space.w_ValueError, space.wrap( "objects are not aligned")) 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 @@ -246,7 +246,11 @@ except KeyError: raise OperationError(space.w_IndexError, space.wrap("Field %s does not exist" % item)) - return dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype) + if isinstance (read_val, W_StringBox): + # StringType returns a str + return space.wrap(dtype.itemtype.to_str(read_val)) + return read_val @unwrap_spec(item=str) def descr_setitem(self, space, item, w_value): @@ -271,7 +275,6 @@ arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): from pypy.module.micronumpy.interp_dtype import new_unicode_dtype @@ -474,6 +477,7 @@ W_VoidBox.typedef = TypeDef("void", W_FlexibleBox.typedef, __module__ = "numpypy", + __new__ = interp2app(W_VoidBox.descr__new__.im_func), __getitem__ = interp2app(W_VoidBox.descr_getitem), __setitem__ = interp2app(W_VoidBox.descr_setitem), ) 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 @@ -8,6 +8,7 @@ from pypy.module.micronumpy import types, interp_boxes from pypy.rlib.objectmodel import specialize from pypy.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong +from pypy.rpython.lltypesystem import rffi UNSIGNEDLTR = "u" @@ -17,6 +18,8 @@ VOIDLTR = 'V' STRINGLTR = 'S' UNICODELTR = 'U' +INTPLTR = 'p' +UINTPLTR = 'P' def decode_w_dtype(space, w_dtype): if space.is_none(w_dtype): @@ -66,11 +69,16 @@ def fill(self, storage, box, start, stop): self.itemtype.fill(storage, self.get_size(), box, start, stop, 0) + def get_name(self): + if self.char == 'S': + return '|S' + str(self.get_size()) + return self.name + def descr_str(self, space): - return space.wrap(self.name) + return space.wrap(self.get_name()) def descr_repr(self, space): - return space.wrap("dtype('%s')" % self.name) + return space.wrap("dtype('%s')" % self.get_name()) def descr_get_itemsize(self, space): return space.wrap(self.itemtype.get_element_size()) @@ -135,6 +143,9 @@ def is_record_type(self): return self.fields is not None + def is_flexible_type(self): + return (self.num == 18 or self.num == 19 or self.num == 20) + def __repr__(self): if self.fields is not None: return '' % self.fields @@ -454,6 +465,35 @@ #alternate_constructors=[space.w_buffer], # XXX no buffer in space ) + ptr_size = rffi.sizeof(rffi.CCHARP) + if ptr_size == 4: + intp_box = interp_boxes.W_Int32Box + intp_type = types.Int32() + uintp_box = interp_boxes.W_UInt32Box + uintp_type = types.UInt32() + elif ptr_size == 8: + intp_box = interp_boxes.W_Int64Box + intp_type = types.Int64() + uintp_box = interp_boxes.W_UInt64Box + uintp_type = types.UInt64() + else: + raise ValueError('unknown point size %d' % ptr_size) + self.w_intpdtype = W_Dtype( + intp_type, + num=5, + kind=INTPLTR, + name='intp', + char=INTPLTR, + w_box_type = space.gettypefor(intp_box), + ) + self.w_uintpdtype = W_Dtype( + uintp_type, + num=6, + kind=UINTPLTR, + name='uintp', + char=UINTPLTR, + w_box_type = space.gettypefor(uintp_box), + ) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, @@ -462,7 +502,7 @@ self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype, self.w_complex128dtype, self.w_stringdtype, self.w_unicodedtype, - self.w_voiddtype, + self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) @@ -504,7 +544,8 @@ #'CDOUBLE', #'DATETIME', 'UINT': self.w_uint32dtype, - 'INTP': self.w_longdtype, + 'INTP': self.w_intpdtype, + 'UINTP': self.w_uintpdtype, #'HALF', 'BYTE': self.w_int8dtype, #'CFLOAT': , 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 @@ -25,7 +25,7 @@ shape = [] for w_item in space.fixedview(w_size): shape.append(space.int_w(w_item)) - return shape + return shape[:] class __extend__(W_NDimArray): @jit.unroll_safe @@ -190,7 +190,7 @@ return space.call_function(cache.w_array_str, self) def dump_data(self): - i = self.create_iter(self.get_shape()) + i = self.create_iter() first = True dtype = self.get_dtype() s = StringBuilder() @@ -206,8 +206,6 @@ return s.build() def create_iter(self, shape=None): - if shape is None: - shape = self.get_shape() return self.implementation.create_iter(shape) def create_axis_iter(self, shape, dim): @@ -396,7 +394,7 @@ 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()")) - iter = self.create_iter(self.get_shape()) + iter = self.create_iter() return space.wrap(space.is_true(iter.getitem())) def _binop_impl(ufunc_name): @@ -681,7 +679,7 @@ if ndmin > len(shape): shape = [1] * (ndmin - len(shape)) + shape arr = W_NDimArray.from_shape(shape, dtype, order=order) - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() for w_elem in elems_w: arr_iter.setitem(dtype.coerce(space, w_elem)) arr_iter.next() 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 @@ -150,6 +150,9 @@ "supported for binary functions")) assert isinstance(self, W_Ufunc2) obj = convert_to_array(space, w_obj) + if obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('cannot perform reduce for flexible type')) obj_shape = obj.get_shape() if obj.is_scalar(): return obj.get_scalar_value() @@ -235,6 +238,9 @@ if space.is_w(out, space.w_None): out = None w_obj = convert_to_array(space, w_obj) + if w_obj.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('Not implemented for this type')) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -301,6 +307,10 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) + if w_lhs.get_dtype().is_flexible_type() or \ + w_rhs.get_dtype().is_flexible_type(): + raise OperationError(space.w_TypeError, + space.wrap('unsupported operand types')) calc_dtype = find_binop_result_dtype(space, w_lhs.get_dtype(), w_rhs.get_dtype(), int_only=self.int_only, @@ -413,6 +423,7 @@ return interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] + at jit.unroll_safe def find_unaryop_result_dtype(space, dt, promote_to_float=False, promote_bools=False, promote_to_largest=False, allow_complex=True): if promote_bools and (dt.kind == interp_dtype.BOOLLTR): @@ -446,6 +457,7 @@ int64_dtype = interp_dtype.get_dtype_cache(space).w_int64dtype complex_type = interp_dtype.get_dtype_cache(space).w_complex128dtype float_type = interp_dtype.get_dtype_cache(space).w_float64dtype + str_dtype = interp_dtype.get_dtype_cache(space).w_stringdtype if isinstance(w_obj, interp_boxes.W_GenericBox): dtype = w_obj.get_dtype(space) if current_guess is None: @@ -472,6 +484,15 @@ current_guess is complex_type or current_guess is float_type): return complex_type return current_guess + elif space.isinstance_w(w_obj, space.w_str): + if (current_guess is None): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + elif current_guess.num ==18: + if current_guess.itemtype.get_size() < space.len_w(w_obj): + return interp_dtype.variable_dtype(space, + 'S%d' % space.len_w(w_obj)) + return current_guess if current_guess is complex_type: return complex_type return interp_dtype.get_dtype_cache(space).w_float64dtype 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 @@ -59,8 +59,8 @@ def apply(self, arr): ofs, subdtype = arr.dtype.fields[self.name] # strides backstrides are identical, ofs only changes start - return W_NDimArray.new_slice(arr.start + ofs, arr.strides, - arr.backstrides, + return W_NDimArray.new_slice(arr.start + ofs, arr.get_strides(), + arr.get_backstrides(), arr.shape, arr, subdtype) class Chunks(BaseChunk): @@ -80,8 +80,8 @@ def apply(self, arr): shape = self.extend_shape(arr.shape) - r = calculate_slice_strides(arr.shape, arr.start, arr.strides, - arr.backstrides, self.l) + r = calculate_slice_strides(arr.shape, arr.start, arr.get_strides(), + arr.get_backstrides(), self.l) _, start, strides, backstrides = r return W_NDimArray.new_slice(start, strides[:], backstrides[:], shape[:], arr) diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py --- a/pypy/module/micronumpy/loop.py +++ b/pypy/module/micronumpy/loop.py @@ -89,7 +89,7 @@ reds = ['obj', 'obj_iter', 'cur_value']) def compute_reduce(obj, calc_dtype, func, done_func, identity): - obj_iter = obj.create_iter(obj.get_shape()) + obj_iter = obj.create_iter() if identity is None: cur_value = obj_iter.getitem().convert_to(calc_dtype) obj_iter.next() @@ -109,7 +109,7 @@ return cur_value def fill(arr, box): - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() while not arr_iter.done(): arr_iter.setitem(box) arr_iter.next() @@ -159,7 +159,7 @@ def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): out_iter = out.create_axis_iter(arr.get_shape(), axis) - arr_iter = arr.create_iter(arr.get_shape()) + arr_iter = arr.create_iter() if identity is not None: identity = identity.convert_to(dtype) shapelen = len(shape) @@ -192,7 +192,7 @@ result = 0 idx = 1 dtype = arr.get_dtype() - iter = arr.create_iter(arr.get_shape()) + iter = arr.create_iter() cur_best = iter.getitem() iter.next() shapelen = len(arr.get_shape()) diff --git a/pypy/module/micronumpy/stdobjspace.py b/pypy/module/micronumpy/stdobjspace.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/stdobjspace.py @@ -0,0 +1,11 @@ + +from pypy.objspace.std import stringobject +from pypy.module.micronumpy import interp_boxes + +def delegate_stringbox2stringobj(space, w_box): + return space.wrap(w_box.dtype.itemtype.to_str(w_box)) + +def register_delegates(typeorder): + typeorder[interp_boxes.W_StringBox] = [ + (stringobject.W_StringObject, delegate_stringbox2stringobj), + ] diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -15,16 +15,22 @@ jit.isconstant(len(chunks)) ) def calculate_slice_strides(shape, start, strides, backstrides, chunks): - rstrides = [] - rbackstrides = [] + size = 0 + for chunk in chunks: + if chunk.step != 0: + size += 1 + rstrides = [0] * size + rbackstrides = [0] * size rstart = start - rshape = [] + rshape = [0] * size i = -1 + j = 0 for i, chunk in enumerate_chunks(chunks): if chunk.step != 0: - rstrides.append(strides[i] * chunk.step) - rbackstrides.append(strides[i] * (chunk.lgt - 1) * chunk.step) - rshape.append(chunk.lgt) + rstrides[j] = strides[i] * chunk.step + rbackstrides[j] = strides[i] * (chunk.lgt - 1) * chunk.step + rshape[j] = chunk.lgt + j += 1 rstart += strides[i] * chunk.start # add a reminder s = i + 1 @@ -64,13 +70,13 @@ while True: new_batch = [] if not batch: - return shape, [] + return shape[:], [] if is_single_elem(space, batch[0], is_rec_type): for w_elem in batch: if not is_single_elem(space, w_elem, is_rec_type): raise OperationError(space.w_ValueError, space.wrap( "setting an array element with a sequence")) - return shape, batch + return shape[:], batch size = space.len_w(batch[0]) for w_elem in batch: if (is_single_elem(space, w_elem, is_rec_type) or @@ -104,6 +110,7 @@ i //= shape[s] return coords, step, lngth + at jit.unroll_safe def shape_agreement(space, shape1, w_arr2, broadcast_down=True): if w_arr2 is None: return shape1 @@ -126,6 +133,7 @@ ) return ret + at jit.unroll_safe def _shape_agreement(shape1, shape2): """ Checks agreement about two shapes with respect to broadcasting. Returns the resulting shape. @@ -255,19 +263,19 @@ cur_step = steps[oldI] n_old_elems_to_use *= old_shape[oldI] assert len(new_strides) == len(new_shape) - return new_strides + return new_strides[:] def calculate_dot_strides(strides, backstrides, res_shape, skip_dims): - rstrides = [] - rbackstrides = [] - j=0 + rstrides = [0] * len(res_shape) + rbackstrides = [0] * len(res_shape) + j = 0 for i in range(len(res_shape)): if i in skip_dims: - rstrides.append(0) - rbackstrides.append(0) + rstrides[i] = 0 + rbackstrides[i] = 0 else: - rstrides.append(strides[j]) - rbackstrides.append(backstrides[j]) + rstrides[i] = strides[j] + rbackstrides[i] = backstrides[j] j += 1 return rstrides, rbackstrides diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py --- a/pypy/module/micronumpy/support.py +++ b/pypy/module/micronumpy/support.py @@ -8,6 +8,7 @@ i *= x return i + at jit.unroll_safe def calc_strides(shape, dtype, order): strides = [] backstrides = [] 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 @@ -31,6 +31,8 @@ from _numpypy import dtype assert dtype(bool).num == 0 + assert dtype('intp').num == 5 + assert dtype('uintp').num == 6 assert dtype(int).num == 7 assert dtype(long).num == 9 assert dtype(float).num == 12 @@ -176,10 +178,15 @@ def test_cant_subclass(self): from _numpypy import dtype - # You can't subclass dtype raises(TypeError, type, "Foo", (dtype,), {}) + def test_can_subclass(self): + import _numpypy + class xyz(_numpypy.void): + pass + assert True + def test_aliases(self): from _numpypy import dtype @@ -228,6 +235,17 @@ class AppTestTypes(BaseNumpyAppTest): + def setup_class(cls): + BaseNumpyAppTest.setup_class.im_func(cls) + if option.runappdirect: + import platform + bits, linkage = platform.architecture() + ptr_size = int(bits[:-3]) // 8 + else: + from pypy.rpython.lltypesystem import rffi + ptr_size = rffi.sizeof(rffi.CCHARP) + cls.w_ptr_size = cls.space.wrap(ptr_size) + def test_abstract_types(self): import _numpypy as numpy raises(TypeError, numpy.generic, 0) @@ -269,7 +287,9 @@ def test_int8(self): import _numpypy as numpy - assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, object] a = numpy.array([1, 2, 3], numpy.int8) assert type(a[1]) is numpy.int8 @@ -291,7 +311,9 @@ def test_uint8(self): import _numpypy as numpy - assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, + numpy.integer, numpy.number, + numpy.generic, object] a = numpy.array([1, 2, 3], numpy.uint8) assert type(a[1]) is numpy.uint8 @@ -361,16 +383,22 @@ import _numpypy as numpy assert numpy.int_ is numpy.dtype(int).type - assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, int, object] + assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, int, object] def test_int64(self): import sys import _numpypy as numpy if sys.maxint == 2 ** 63 -1: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, int, object] + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, int, object] else: - assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, + numpy.integer, numpy.number, + numpy.generic, object] assert numpy.dtype(numpy.int64).type is numpy.int64 assert numpy.int64(3) == 3 @@ -385,7 +413,9 @@ import sys import _numpypy as numpy - assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, numpy.integer, numpy.number, numpy.generic, object] + assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, + numpy.integer, numpy.number, + numpy.generic, object] assert numpy.dtype(numpy.uint64).type is numpy.uint64 skip("see comment") @@ -400,7 +430,9 @@ def test_float32(self): import _numpypy as numpy - assert numpy.float32.mro() == [numpy.float32, numpy.floating, numpy.inexact, numpy.number, numpy.generic, object] + assert numpy.float32.mro() == [numpy.float32, numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, object] assert numpy.float32(12) == numpy.float64(12) assert numpy.float32('23.4') == numpy.float32(23.4) @@ -409,7 +441,9 @@ def test_float64(self): import _numpypy as numpy - assert numpy.float64.mro() == [numpy.float64, numpy.floating, numpy.inexact, numpy.number, numpy.generic, float, object] + assert numpy.float64.mro() == [numpy.float64, numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, float, object] a = numpy.array([1, 2, 3], numpy.float64) assert type(a[1]) is numpy.float64 @@ -508,15 +542,16 @@ def test_various_types(self): import _numpypy as numpy - import sys assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte assert numpy.bool_ is numpy.bool8 - if sys.maxint == (1 << 63) - 1: - assert '%r' % numpy.intp == '%r' % numpy.int64 - else: - assert '%r' % numpy.intp == '%r' % numpy.int32 + if self.ptr_size == 4: + assert numpy.intp is numpy.int32 + assert numpy.uintp is numpy.uint32 + elif self.ptr_size == 8: + assert numpy.intp is numpy.int64 + assert numpy.uintp is numpy.uint64 def test_mro(self): import _numpypy as numpy @@ -562,6 +597,11 @@ assert dtype('=i8').byteorder == '=' assert dtype(byteorder + 'i8').byteorder == '=' + def test_intp(self): + from _numpypy import dtype + assert dtype('p') == dtype('intp') + assert dtype('P') == dtype('uintp') + def test_alignment(self): from _numpypy import dtype assert dtype('i4').alignment == 4 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 @@ -344,6 +344,13 @@ assert a[-1] == 8 raises(IndexError, "a[-6]") + def test_getitem_float(self): + from _numpypy import array + a = array([1, 2, 3, 4]) + assert a[1.2] == 2 + assert a[1.6] == 2 + assert a[-1.2] == 4 + def test_getitem_tuple(self): from _numpypy import array a = array(range(5)) @@ -2238,7 +2245,49 @@ assert arr[1]['y']['y'] == 3.5 assert arr[1]['y']['x'] == 0.0 assert arr[1]['x'] == 15 - + + def test_string_record(self): + from _numpypy import dtype, array + d = dtype([('x', str), ('y', 'int32')]) + assert d.fields['x'] == (dtype(str), 0) + assert d.fields['y'] == (dtype('int32'), 1) + d = dtype([('x', 'S1'), ('y', 'int32')]) + assert d.fields['x'] == (dtype(str), 0) + assert d.fields['y'] == (dtype('int32'), 1) + a = array([('a', 2), ('c', 1)], dtype=d) + assert a[1]['y'] == 1 + assert a[0]['x'] == 'a' + From noreply at buildbot.pypy.org Wed Oct 31 17:06:37 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 17:06:37 +0100 (CET) Subject: [pypy-commit] pypy default: Add the '--opt=..' option to py.py, as a way to enable all pypy-specific Message-ID: <20121031160637.5FBB81C00FA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58644:2d138f334c76 Date: 2012-10-31 17:06 +0100 http://bitbucket.org/pypy/pypy/changeset/2d138f334c76/ Log: Add the '--opt=..' option to py.py, as a way to enable all pypy- specific options at a certain optimization level. diff --git a/pypy/bin/py.py b/pypy/bin/py.py --- a/pypy/bin/py.py +++ b/pypy/bin/py.py @@ -65,10 +65,17 @@ config, parser = option.get_standard_options() interactiveconfig = Config(cmdline_optiondescr) to_optparse(interactiveconfig, parser=parser) + def set_family_of_options(option, opt, value, parser): + from pypy.config.pypyoption import set_pypy_opt_level + set_pypy_opt_level(config, value) parser.add_option( '--cc', type=str, action="callback", callback=set_compiler, help="Compiler to use for compiling generated C") + parser.add_option( + '--opt', type=str, action="callback", + callback=set_family_of_options, + help="Set the family of options based on -opt=0,1,2,jit...") args = option.process_options(parser, argv[1:]) if interactiveconfig.verbose: error.RECORD_INTERPLEVEL_TRACEBACK = True From noreply at buildbot.pypy.org Wed Oct 31 17:47:52 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 17:47:52 +0100 (CET) Subject: [pypy-commit] pypy default: Add a sanity check. Message-ID: <20121031164752.7400B1C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58645:1946e86bd7a5 Date: 2012-10-31 17:34 +0100 http://bitbucket.org/pypy/pypy/changeset/1946e86bd7a5/ Log: Add a sanity check. 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 @@ -843,10 +843,14 @@ isinstance(w_newtype, W_TypeObject) and not w_newtype.is_heaptype() and not space.is_w(w_newtype, space.w_type)): - w_type.w_bltin_new = w_newfunc + w_type.w_bltin_new = w_bltin_new = w_newfunc w_newobject = space.call_obj_args(w_newfunc, w_type, __args__) call_init = space.isinstance_w(w_newobject, w_type) + # sanity check + if not we_are_translated() and w_bltin_new is not None: + assert space.isinstance_w(w_newobject, w_type) + # maybe invoke the __init__ of the type if (call_init and not (space.is_w(w_type, space.w_type) and not __args__.keywords and len(__args__.arguments_w) == 1)): From noreply at buildbot.pypy.org Wed Oct 31 17:47:53 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 17:47:53 +0100 (CET) Subject: [pypy-commit] pypy default: Simplify the logic. Message-ID: <20121031164753.8E7051C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58646:fd45b4a00ced Date: 2012-10-31 17:37 +0100 http://bitbucket.org/pypy/pypy/changeset/fd45b4a00ced/ Log: Simplify the logic. diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py --- a/pypy/interpreter/buffer.py +++ b/pypy/interpreter/buffer.py @@ -64,7 +64,7 @@ if not isinstance(self, RWBuffer): raise OperationError(space.w_TypeError, space.wrap("buffer is read-only")) - start, stop, step = space.decode_index(w_index, self.getlength()) + start, stop, step, size = space.decode_index4(w_index, self.getlength()) if step == 0: # index only if len(newstring) != 1: msg = 'buffer[index]=x: x must be a single character' @@ -72,13 +72,9 @@ char = newstring[0] # annotator hint self.setitem(start, char) elif step == 1: - length = stop - start - if length != len(newstring): - if length < 0 and len(newstring) == 0: - pass # ok anyway - else: - msg = "right operand length must match slice length" - raise OperationError(space.w_ValueError, space.wrap(msg)) + if len(newstring) != size: + msg = "right operand length must match slice length" + raise OperationError(space.w_ValueError, space.wrap(msg)) self.setslice(start, newstring) else: raise OperationError(space.w_ValueError, From noreply at buildbot.pypy.org Wed Oct 31 17:47:54 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 17:47:54 +0100 (CET) Subject: [pypy-commit] pypy default: Hopefully, fixes for 'test_buffer' after O2 or Ojit translation. Message-ID: <20121031164754.E47481C0185@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58647:e3a20a600eaf Date: 2012-10-31 17:47 +0100 http://bitbucket.org/pypy/pypy/changeset/e3a20a600eaf/ Log: Hopefully, fixes for 'test_buffer' after O2 or Ojit translation. Hard to test... diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,4 +1,5 @@ from pypy.interpreter.error import operationerrfmt +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.typedef import TypeDef @@ -35,15 +36,37 @@ for i in range(len(string)): raw_cdata[i] = string[i] -LLBuffer.typedef = TypeDef( + +class MiniBuffer(Wrappable): + # a different subclass of Wrappable for the MiniBuffer, because we + # want a slightly different (simplified) API at the level of Python. + + def __init__(self, buffer): + self.buffer = buffer + + def descr_len(self, space): + return self.buffer.descr_len(space) + + def descr_getitem(self, space, w_index): + return self.buffer.descr_getitem(space, w_index) + + @unwrap_spec(newstring='bufferstr') + def descr_setitem(self, space, w_index, newstring): + self.buffer.descr_setitem(space, w_index, newstring) + + def descr__buffer__(self, space): + return self.buffer.descr__buffer__(space) + + +MiniBuffer.typedef = TypeDef( "buffer", __module__ = "_cffi_backend", - __len__ = interp2app(RWBuffer.descr_len), - __getitem__ = interp2app(RWBuffer.descr_getitem), - __setitem__ = interp2app(RWBuffer.descr_setitem), - __buffer__ = interp2app(RWBuffer.descr__buffer__), + __len__ = interp2app(MiniBuffer.descr_len), + __getitem__ = interp2app(MiniBuffer.descr_getitem), + __setitem__ = interp2app(MiniBuffer.descr_setitem), + __buffer__ = interp2app(MiniBuffer.descr__buffer__), ) -LLBuffer.typedef.acceptable_as_base_class = False +MiniBuffer.typedef.acceptable_as_base_class = False @unwrap_spec(cdata=cdataobj.W_CData, size=int) @@ -63,4 +86,4 @@ raise operationerrfmt(space.w_TypeError, "don't know the size pointed to by '%s'", ctype.name) - return space.wrap(LLBuffer(cdata._cdata, size)) + return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size))) From noreply at buildbot.pypy.org Wed Oct 31 18:00:29 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 31 Oct 2012 18:00:29 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: data Message-ID: <20121031170029.94A411C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58648:758f72ee68e7 Date: 2012-10-31 17:18 +0200 http://bitbucket.org/pypy/pypy/changeset/758f72ee68e7/ Log: data 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 @@ -7,9 +7,11 @@ calculate_broadcast_strides, calculate_dot_strides from pypy.module.micronumpy.iter import Chunk, Chunks, NewAxisChunk, RecordChunk from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.buffer import RWBuffer from pypy.rpython.lltypesystem import rffi, lltype from pypy.rlib import jit -from pypy.rlib.rawstorage import free_raw_storage +from pypy.rlib.rawstorage import free_raw_storage, raw_storage_getitem,\ + raw_storage_setitem from pypy.module.micronumpy.arrayimpl.sort import argsort_array from pypy.rlib.debug import make_sure_not_resized @@ -244,6 +246,9 @@ def get_storage(self): return self.storage + def get_buffer(self, space): + return ArrayBuffer(self) + class ConcreteArray(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides): make_sure_not_resized(shape) @@ -356,3 +361,17 @@ new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, new_shape, self, orig_array) + +class ArrayBuffer(RWBuffer): + def __init__(self, impl): + self.impl = impl + + def getitem(self, item): + return raw_storage_getitem(lltype.Char, self.impl.storage, item) + + def setitem(self, item, v): + return raw_storage_setitem(self.impl.storage, item, + rffi.cast(lltype.Char, v)) + + def getlength(self): + return self.impl.size 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 @@ -104,3 +104,8 @@ def base(self): return None + + def get_buffer(self, space): + raise OperationError(space.w_ValueError, space.wrap( + "cannot point buffer to a scalar")) + diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -422,17 +422,12 @@ loop.clip(space, self, shape, min, max, out) return out - def descr_ctypes(self, space): + def descr_get_ctypes(self, space): raise OperationError(space.w_NotImplementedError, space.wrap( "ctypes not implemented yet")) - def descr_cumprod(self, space, w_axis=None, w_dtype=None, w_out=None): - raise OperationError(space.w_NotImplementedError, space.wrap( - "cumprod not implemented yet")) - - def descr_data(self, space): - raise OperationError(space.w_NotImplementedError, space.wrap( - "data not implemented yet")) + def descr_get_data(self, space): + return self.implementation.get_buffer(space) def descr_diagonal(self, space, w_offset=0, w_axis1=0, w_axis2=1): raise OperationError(space.w_NotImplementedError, space.wrap( @@ -805,6 +800,9 @@ byteswap = interp2app(W_NDimArray.descr_byteswap), choose = interp2app(W_NDimArray.descr_choose), clip = interp2app(W_NDimArray.descr_clip), + data = GetSetProperty(W_NDimArray.descr_get_data), + + ctypes = GetSetProperty(W_NDimArray.descr_get_ctypes), # XXX unimplemented __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), ) 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 @@ -1608,6 +1608,16 @@ assert (a.clip(-2, 13, out=a) == [1, 2, 13, -2, 12]).all() assert (a == [1, 2, 13, -2, 12]).all() + def test_data(self): + from _numpypy import array + a = array([1, 2, 3, 4], dtype='i4') + assert a.data[0] == '\x01' + assert a.data[1] == '\x00' + assert a.data[4] == '\x02' + a.data[4] = '\xff' + assert a[1] == 0xff + assert len(a.data) == 16 + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import _numpypy From noreply at buildbot.pypy.org Wed Oct 31 18:00:30 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 31 Oct 2012 18:00:30 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: simple case of diagonal Message-ID: <20121031170030.D86851C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58649:254c84940fc7 Date: 2012-10-31 18:21 +0200 http://bitbucket.org/pypy/pypy/changeset/254c84940fc7/ Log: simple case of diagonal diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -170,3 +170,15 @@ space.wrap("mode %s not known" % (mode,))) loop.choose(space, arr, choices, shape, dtype, out, MODES[mode]) return out + +def diagonal(space, arr, offset, axis1, axis2): + shape = arr.get_shape() + size = min(shape[axis1], shape[axis2] - offset) + dtype = arr.dtype + if len(shape) == 2: + # simple case + out = W_NDimArray.from_shape([size], dtype) + loop.diagonal_simple(space, arr, out, offset, axis1, axis2, size) + return out + else: + xxx 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 @@ -429,10 +429,19 @@ def descr_get_data(self, space): return self.implementation.get_buffer(space) - def descr_diagonal(self, space, w_offset=0, w_axis1=0, w_axis2=1): - raise OperationError(space.w_NotImplementedError, space.wrap( - "diagonal not implemented yet")) - + @unwrap_spec(offset=int, axis1=int, axis2=int) + def descr_diagonal(self, space, offset=0, axis1=0, axis2=1): + if len(self.get_shape()) < 2: + raise OperationError(space.w_ValueError, space.wrap( + "need at least 2 dimensions for diagonal")) + if (axis1 < 0 or axis2 < 0 or axis1 >= len(self.get_shape()) or + axis2 >= len(self.get_shape())): + raise operationerrfmt(space.w_ValueError, + "axis1(=%d) and axis2(=%d) must be withing range (ndim=%d)", + axis1, axis2, len(self.get_shape())) + return interp_arrayops.diagonal(space, self.implementation, offset, + axis1, axis2) + def descr_dump(self, space, w_file): raise OperationError(space.w_NotImplementedError, space.wrap( "dump not implemented yet")) @@ -801,6 +810,7 @@ choose = interp2app(W_NDimArray.descr_choose), clip = interp2app(W_NDimArray.descr_clip), data = GetSetProperty(W_NDimArray.descr_get_data), + diagonal = interp2app(W_NDimArray.descr_diagonal), ctypes = GetSetProperty(W_NDimArray.descr_get_ctypes), # XXX unimplemented 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 @@ -580,3 +580,21 @@ max_iter.next() out_iter.next() min_iter.next() + +diagonal_simple_driver = jit.JitDriver(greens = ['axis1', 'axis2'], + reds = ['i', 'offset', 'out_iter', + 'arr']) + +def diagonal_simple(space, arr, out, offset, axis1, axis2, size): + out_iter = out.create_iter() + i = 0 + index = [0] * 2 + while i < size: + diagonal_simple_driver.jit_merge_point(axis1=axis1, axis2=axis2, + out_iter=out_iter, offset=offset, + i=i, arr=arr) + index[axis1] = i + index[axis2] = i + offset + out_iter.setitem(arr.getitem_index(space, index)) + i += 1 + out_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 @@ -2110,6 +2110,13 @@ assert (a.cumsum(1) == [[1, 2], [2, 4], [3, 7]]).all() assert (a.cumsum(0) == [[1, 1], [3, 3], [6, 7]]).all() + def test_diagonal(self): + from _numpypy import array + a = array([[1, 2], [3, 4], [5, 6]]) + raises(ValueError, 'array([1, 2]).diagonal()') + assert (a.diagonal() == [1, 4]).all() + assert (a.diagonal(1) == [2]).all() + class AppTestSupport(BaseNumpyAppTest): def setup_class(cls): import struct From noreply at buildbot.pypy.org Wed Oct 31 18:00:32 2012 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 31 Oct 2012 18:00:32 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: implement diagonal. I wonder if the jit would help here Message-ID: <20121031170032.12ACA1C0185@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r58650:e28b7a70729c Date: 2012-10-31 18:59 +0200 http://bitbucket.org/pypy/pypy/changeset/e28b7a70729c/ Log: implement diagonal. I wonder if the jit would help here diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -173,12 +173,24 @@ def diagonal(space, arr, offset, axis1, axis2): shape = arr.get_shape() + shapelen = len(shape) + if offset < 0: + offset = -offset + axis1, axis2 = axis2, axis1 size = min(shape[axis1], shape[axis2] - offset) dtype = arr.dtype - if len(shape) == 2: + if axis1 < axis2: + shape = (shape[:axis1] + shape[axis1 + 1:axis2] + + shape[axis2 + 1:] + [size]) + else: + shape = (shape[:axis2] + shape[axis2 + 1:axis1] + + shape[axis1 + 1:] + [size]) + out = W_NDimArray.from_shape(shape, dtype) + if size == 0: + return out + if shapelen == 2: # simple case - out = W_NDimArray.from_shape([size], dtype) loop.diagonal_simple(space, arr, out, offset, axis1, axis2, size) - return out else: - xxx + loop.diagonal_array(space, arr, out, offset, axis1, axis2, shape) + return out 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,6 +439,9 @@ raise operationerrfmt(space.w_ValueError, "axis1(=%d) and axis2(=%d) must be withing range (ndim=%d)", axis1, axis2, len(self.get_shape())) + if axis1 == axis2: + raise OperationError(space.w_ValueError, space.wrap( + "axis1 and axis2 cannot be the same")) return interp_arrayops.diagonal(space, self.implementation, offset, axis1, axis2) 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 @@ -9,7 +9,7 @@ from pypy.rlib import jit from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.micronumpy.base import W_NDimArray -from pypy.module.micronumpy.iter import PureShapeIterator +from pypy.module.micronumpy.iter import PureShapeIterator, ConcreteArrayIterator from pypy.module.micronumpy import constants from pypy.module.micronumpy.support import int_w @@ -598,3 +598,21 @@ out_iter.setitem(arr.getitem_index(space, index)) i += 1 out_iter.next() + +def diagonal_array(space, arr, out, offset, axis1, axis2, shape): + out_iter = out.create_iter() + iter = PureShapeIterator(shape, []) + shapelen = len(shape) + while not iter.done(): + last_index = iter.indexes[-1] + if axis1 < axis2: + indexes = (iter.indexes[:axis1] + [last_index] + + iter.indexes[axis1:axis2 - 1] + [last_index + offset] + + iter.indexes[axis2 - 1:shapelen - 1]) + else: + indexes = (iter.indexes[:axis2] + [last_index + offset] + + iter.indexes[axis2:axis1 - 1] + [last_index] + + iter.indexes[axis1 - 1:shapelen - 1]) + out_iter.setitem(arr.getitem_index(space, indexes)) + iter.next() + out_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 @@ -2114,9 +2114,27 @@ from _numpypy import array a = array([[1, 2], [3, 4], [5, 6]]) raises(ValueError, 'array([1, 2]).diagonal()') + raises(ValueError, 'a.diagonal(0, 0, 0)') + raises(ValueError, 'a.diagonal(0, 0, 13)') assert (a.diagonal() == [1, 4]).all() assert (a.diagonal(1) == [2]).all() + def test_diagonal_axis(self): + from _numpypy import arange + a = arange(12).reshape(2, 3, 2) + assert (a.diagonal(0, 0, 1) == [[0, 8], [1, 9]]).all() + assert a.diagonal(3, 0, 1).shape == (2, 0) + assert (a.diagonal(1, 0, 1) == [[2, 10], [3, 11]]).all() + assert (a.diagonal(0, 2, 1) == [[0, 3], [6, 9]]).all() + assert (a.diagonal(2, 2, 1) == [[4], [10]]).all() + assert (a.diagonal(1, 2, 1) == [[2, 5], [8, 11]]).all() + + def test_diagonal_axis_neg_ofs(self): + from _numpypy import arange + a = arange(12).reshape(2, 3, 2) + assert (a.diagonal(-1, 0, 1) == [[6], [7]]).all() + assert a.diagonal(-2, 0, 1).shape == (2, 0) + class AppTestSupport(BaseNumpyAppTest): def setup_class(cls): import struct From noreply at buildbot.pypy.org Wed Oct 31 18:06:37 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 31 Oct 2012 18:06:37 +0100 (CET) Subject: [pypy-commit] pypy unicode-strategies: fix test_stressdict Message-ID: <20121031170637.E5E6A1C0185@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58651:f48a80508682 Date: 2012-10-31 17:58 +0100 http://bitbucket.org/pypy/pypy/changeset/f48a80508682/ Log: fix test_stressdict diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -859,7 +859,7 @@ raises(RuntimeError, list, it) -class FakeString(str): +class FakeWrapper(object): hash_count = 0 def unwrap(self, space): self.unwrapped = True @@ -869,6 +869,12 @@ self.hash_count += 1 return str.__hash__(self) +class FakeString(FakeWrapper, str): + pass + +class FakeUnicode(FakeWrapper, unicode): + pass + # the minimal 'space' needed to use a W_DictMultiObject class FakeSpace: hash_count = 0 @@ -941,6 +947,7 @@ w_bool = bool w_float = float StringObjectCls = FakeString + UnicodeObjectCls = FakeUnicode w_dict = W_DictMultiObject iter = iter fixedview = list From noreply at buildbot.pypy.org Wed Oct 31 18:06:39 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 31 Oct 2012 18:06:39 +0100 (CET) Subject: [pypy-commit] pypy unicode-strategies: implement listview_unicode for W_UnicodeObject Message-ID: <20121031170639.1F78D1C0185@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: unicode-strategies Changeset: r58652:09dfbb4ed8dd Date: 2012-10-31 18:03 +0100 http://bitbucket.org/pypy/pypy/changeset/09dfbb4ed8dd/ Log: implement listview_unicode for W_UnicodeObject 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 @@ -473,8 +473,8 @@ return w_obj.listview_unicode() if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject: return w_obj.listview_unicode() - ## if isinstance(w_obj, W_UnicodeObject): - ## return w_obj.listview_unicode() + if isinstance(w_obj, W_UnicodeObject): + return w_obj.listview_unicode() if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj): return w_obj.getitems_unicode() return None diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -23,6 +23,10 @@ print self.space.config.objspace.std.withrope assert len(warnings) == 2 + def test_listview_unicode(self): + w_str = self.space.wrap(u'abcd') + assert self.space.listview_unicode(w_str) == list(u"abcd") + class AppTestUnicodeStringStdOnly: def test_compares(self): diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -66,6 +66,15 @@ def unicode_w(self, space): return self._value + def listview_unicode(w_self): + return _create_list_from_unicode(w_self._value) + +def _create_list_from_unicode(value): + # need this helper function to allow the jit to look inside and inline + # listview_unicode + return [s for s in value] + + W_UnicodeObject.EMPTY = W_UnicodeObject(u'') registerimplementation(W_UnicodeObject) From noreply at buildbot.pypy.org Wed Oct 31 18:11:14 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 18:11:14 +0100 (CET) Subject: [pypy-commit] pypy default: Tweak tweak. Unclear if this gives enough win any more to care... Message-ID: <20121031171114.D3A421C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58653:66ca6d9f3739 Date: 2012-10-31 18:09 +0100 http://bitbucket.org/pypy/pypy/changeset/66ca6d9f3739/ Log: Tweak tweak. Unclear if this gives enough win any more to care... diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py --- a/pypy/objspace/std/test/test_typeobject.py +++ b/pypy/objspace/std/test/test_typeobject.py @@ -1175,9 +1175,9 @@ """) w_A, w_B, w_M = space.unpackiterable(w_tup) - assert w_A.w_bltin_new is None - assert w_B.w_bltin_new is None - assert w_M.w_bltin_new is None + assert w_A.w_new_function is None + assert w_B.w_new_function is None + assert w_M.w_new_function is None _, w_object_newdescr = space.lookup_in_type_where(space.w_object, '__new__') @@ -1185,17 +1185,18 @@ w_type=space.w_object) w_a = space.call_function(w_A) - assert w_A.w_bltin_new is w_object___new__ + assert w_A.w_new_function is w_object___new__ # will shortcut w_a = space.call_function(w_A) w_b = space.call_function(w_B) - assert w_B.w_bltin_new is None + assert w_B.w_new_function is not None + w_b = space.call_function(w_B) w_m = space.call_function(w_M, space.wrap('C'), space.newlist([]), space.newdict()) - assert w_M.w_bltin_new is None + assert w_M.w_new_function is not None class AppTestNewShortcut: 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 @@ -113,10 +113,8 @@ # for config.objspace.std.withidentitydict compares_by_identity_status = UNKNOWN - # used to cache the type __new__ function if it comes from a builtin type - # != 'type', in that case call__Type will also assumes the result - # of the __new__ is an instance of the type - w_bltin_new = None + # used to cache the type's __new__ function + w_new_function = None @dont_look_inside def __init__(w_self, space, name, bases_w, dict_w, @@ -181,7 +179,7 @@ w_self.compares_by_identity_status = UNKNOWN if space.config.objspace.std.newshortcut: - w_self.w_bltin_new = None + w_self.w_new_function = None if (space.config.objspace.std.withtypeversion and w_self._version_tag is not None): @@ -824,32 +822,23 @@ promote(w_type) # invoke the __new__ of the type if not we_are_jitted(): - # note that the annotator will figure out that w_type.w_bltin_new can - # only be None if the newshortcut config option is not set - w_bltin_new = w_type.w_bltin_new + # note that the annotator will figure out that w_type.w_new_function + # can only be None if the newshortcut config option is not set + w_newfunc = w_type.w_new_function else: # for the JIT it is better to take the slow path because normal lookup - # is nicely optimized, but the w_type.w_bltin_new attribute is not + # is nicely optimized, but the w_type.w_new_function attribute is not # known to the JIT - w_bltin_new = None - call_init = True - if w_bltin_new is not None: - w_newobject = space.call_obj_args(w_bltin_new, w_type, __args__) - else: + w_newfunc = None + if w_newfunc is None: w_newtype, w_newdescr = w_type.lookup_where('__new__') w_newfunc = space.get(w_newdescr, w_type) if (space.config.objspace.std.newshortcut and not we_are_jitted() and - isinstance(w_newtype, W_TypeObject) and - not w_newtype.is_heaptype() and - not space.is_w(w_newtype, space.w_type)): - w_type.w_bltin_new = w_bltin_new = w_newfunc - w_newobject = space.call_obj_args(w_newfunc, w_type, __args__) - call_init = space.isinstance_w(w_newobject, w_type) - - # sanity check - if not we_are_translated() and w_bltin_new is not None: - assert space.isinstance_w(w_newobject, w_type) + isinstance(w_newtype, W_TypeObject)): + w_type.w_new_function = w_newfunc + w_newobject = space.call_obj_args(w_newfunc, w_type, __args__) + call_init = space.isinstance_w(w_newobject, w_type) # maybe invoke the __init__ of the type if (call_init and not (space.is_w(w_type, space.w_type) and From noreply at buildbot.pypy.org Wed Oct 31 18:11:16 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 18:11:16 +0100 (CET) Subject: [pypy-commit] pypy default: Comment it out until we figure out (1) if it has a measurable performance Message-ID: <20121031171116.05C001C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58654:3ef72b75102b Date: 2012-10-31 18:10 +0100 http://bitbucket.org/pypy/pypy/changeset/3ef72b75102b/ Log: Comment it out until we figure out (1) if it has a measurable performance impact nowadays, and (2) if it's really really really correct diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -372,7 +372,7 @@ config.objspace.std.suggest(builtinshortcut=True) config.objspace.std.suggest(optimized_list_getitem=True) config.objspace.std.suggest(getattributeshortcut=True) - config.objspace.std.suggest(newshortcut=True) + #config.objspace.std.suggest(newshortcut=True) config.objspace.std.suggest(withspecialisedtuple=True) config.objspace.std.suggest(withidentitydict=True) #if not IS_64_BITS: From noreply at buildbot.pypy.org Wed Oct 31 18:16:49 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 18:16:49 +0100 (CET) Subject: [pypy-commit] pypy default: fix this test Message-ID: <20121031171649.506641C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58655:bf186ea46cc9 Date: 2012-10-31 18:16 +0100 http://bitbucket.org/pypy/pypy/changeset/bf186ea46cc9/ Log: fix this test diff --git a/pypy/interpreter/test/test_zzpickle_and_slow.py b/pypy/interpreter/test/test_zzpickle_and_slow.py --- a/pypy/interpreter/test/test_zzpickle_and_slow.py +++ b/pypy/interpreter/test/test_zzpickle_and_slow.py @@ -6,7 +6,7 @@ class AppTestSlow: def setup_class(cls): - space = gettestobjspace() + space = gettestobjspace(usemodules=['itertools']) cls.space = space if py.test.config.option.runappdirect: filename = __file__ From noreply at buildbot.pypy.org Wed Oct 31 18:18:39 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 18:18:39 +0100 (CET) Subject: [pypy-commit] pypy default: fix this test too Message-ID: <20121031171839.B88891C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58656:2598c9981962 Date: 2012-10-31 18:18 +0100 http://bitbucket.org/pypy/pypy/changeset/2598c9981962/ Log: fix this test too diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -94,7 +94,7 @@ class AppTestSocketConnection(BaseConnectionTest): def setup_class(cls): space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal', - 'struct', 'array')) + 'struct', 'array', 'itertools')) cls.space = space cls.w_connections = space.newlist([]) From noreply at buildbot.pypy.org Wed Oct 31 20:15:35 2012 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 31 Oct 2012 20:15:35 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: beginnings of another py3k update Message-ID: <20121031191535.1A9FF1C002D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: extradoc Changeset: r4897:99dabe072e29 Date: 2012-10-31 12:16 -0700 http://bitbucket.org/pypy/extradoc/changeset/99dabe072e29/ Log: beginnings of another py3k update diff --git a/blog/draft/py3k-status-update-7.rst b/blog/draft/py3k-status-update-7.rst new file mode 100644 --- /dev/null +++ b/blog/draft/py3k-status-update-7.rst @@ -0,0 +1,40 @@ +Py3k status update #7 +--------------------- + +This is the seventh status update about our work on the `py3k branch`_, which +we can work on thanks to all of the people who donated_ to the `py3k +proposal`_. + +There was an increased amount of activity this month. + +The `py3k buildbots`_ now fully translate the branch every night and run the +Python standard library tests. + +We currently pass 160 out of approximately 355 test modules, fail 144 and skip +apprixmately 51. + +o work on dictviews (keys/values/items) + +o _csv + +o more parser fixes, py3 list comprehension semantics + +o 2to3'd most of our custom lib_pypy + +o py3-enabled pyrepl (readline works in the repl!), builtins.input() (pdb seems to work!) + +o py3 round + +o further tightening/cleanup of the unicode handling (more usage of +surrogateescape, surrogatepass among other things) + +o as well as keeping up with some big changes happening on the default branch + +Finally, I would like to thank Amaury Forgeot d'Arc for his significant +contributions; among other things, Amaury recently worked on + +.. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html +.. _`py3k proposal`: http://pypy.org/py3donate.html +.. _`py3k branch`: https://bitbucket.org/pypy/pypy/src/py3k +.. _`py3k buildbots`: http://buildbot.pypy.org/summary?branch=py3k From noreply at buildbot.pypy.org Wed Oct 31 20:38:35 2012 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 31 Oct 2012 20:38:35 +0100 (CET) Subject: [pypy-commit] pypy default: document merged branch Message-ID: <20121031193835.29B9C1C002D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r58657:37267ef01375 Date: 2012-10-31 20:38 +0100 http://bitbucket.org/pypy/pypy/changeset/37267ef01375/ Log: document merged branch diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -42,6 +42,8 @@ Improve dtypes intp, uintp, void, string and record .. branch: kill-someobject major cleanups including killing some object support +.. branch: cpyext-PyThreadState_New +implement threadstate-related functions in cpyext .. "uninteresting" branches that we should just ignore for the whatsnew: From noreply at buildbot.pypy.org Wed Oct 31 20:40:24 2012 From: noreply at buildbot.pypy.org (antocuni) Date: Wed, 31 Oct 2012 20:40:24 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: tweaks Message-ID: <20121031194024.AC4571C002D@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: extradoc Changeset: r4898:be5b7511331f Date: 2012-10-31 20:40 +0100 http://bitbucket.org/pypy/extradoc/changeset/be5b7511331f/ Log: tweaks diff --git a/blog/draft/py3k-status-update-7.rst b/blog/draft/py3k-status-update-7.rst --- a/blog/draft/py3k-status-update-7.rst +++ b/blog/draft/py3k-status-update-7.rst @@ -5,23 +5,33 @@ we can work on thanks to all of the people who donated_ to the `py3k proposal`_. -There was an increased amount of activity this month. +The biggest news is that this month Philip started to work on py3k in parallel +to Antonio. As such, there was an increased amount of activity. The `py3k buildbots`_ now fully translate the branch every night and run the Python standard library tests. -We currently pass 160 out of approximately 355 test modules, fail 144 and skip -apprixmately 51. +We currently pass 160 out of approximately 355 modules of CPython's standard +test suite, fail 144 and skip apprixmately 51. -o work on dictviews (keys/values/items) +Some highlights: -o _csv +o dictviews (the objects returned by dict.keys/values/items) has been greatly + improved, and now they full support set operators -o more parser fixes, py3 list comprehension semantics +o a lot of tests has been fixed wrt complex numbers (and in particular the +``__complex__`` method) + +o _csv has been fixed and now it correctly handles unicode instead of bytes + +o more parser fixes, py3k list comprehension semantics; now you can no longer + access the list comprehension variable after it finishes o 2to3'd most of our custom lib_pypy -o py3-enabled pyrepl (readline works in the repl!), builtins.input() (pdb seems to work!) +o py3-enabled pyrepl: this means that finally readline works at the command + prompt, as well as builtins.input(). ``pdb`` seems to work, as well as + fancycompleter_ to get colorful TAB completions :-) o py3 round @@ -34,6 +44,10 @@ contributions; among other things, Amaury recently worked on + +cheers, +Philip&Antonio + .. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html .. _`py3k proposal`: http://pypy.org/py3donate.html .. _`py3k branch`: https://bitbucket.org/pypy/pypy/src/py3k